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 866311a..1dff088 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 | { | 180 | |
169 | if (0 == Items.Count) | 181 | if (items.Count == 0) |
170 | { | 182 | return; |
171 | return; | ||
172 | } | ||
173 | } | ||
174 | 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> |
@@ -304,7 +319,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
304 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 319 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
305 | 320 | ||
306 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 321 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
322 | { | ||
323 | StoreScriptError(item.ItemID, "no permission"); | ||
307 | return false; | 324 | return false; |
325 | } | ||
308 | 326 | ||
309 | m_part.AddFlag(PrimFlags.Scripted); | 327 | m_part.AddFlag(PrimFlags.Scripted); |
310 | 328 | ||
@@ -314,14 +332,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
314 | if (stateSource == 2 && // Prim crossing | 332 | if (stateSource == 2 && // Prim crossing |
315 | m_part.ParentGroup.Scene.m_trustBinaries) | 333 | m_part.ParentGroup.Scene.m_trustBinaries) |
316 | { | 334 | { |
317 | lock (m_items) | 335 | m_items.LockItemsForWrite(true); |
318 | { | 336 | m_items[item.ItemID].PermsMask = 0; |
319 | m_items[item.ItemID].PermsMask = 0; | 337 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
320 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 338 | m_items.LockItemsForWrite(false); |
321 | } | ||
322 | |||
323 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 339 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
324 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 340 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
341 | StoreScriptErrors(item.ItemID, null); | ||
325 | m_part.ParentGroup.AddActiveScriptCount(1); | 342 | m_part.ParentGroup.AddActiveScriptCount(1); |
326 | m_part.ScheduleFullUpdate(); | 343 | m_part.ScheduleFullUpdate(); |
327 | return true; | 344 | return true; |
@@ -342,16 +359,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
342 | if (m_part.ParentGroup.m_savedScriptState != null) | 359 | if (m_part.ParentGroup.m_savedScriptState != null) |
343 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 360 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
344 | 361 | ||
345 | lock (m_items) | 362 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); |
346 | { | 363 | StoreScriptError(item.ItemID, msg); |
347 | m_items[item.ItemID].OldItemID = item.OldItemID; | 364 | m_log.ErrorFormat( |
348 | m_items[item.ItemID].PermsMask = 0; | 365 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
349 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 366 | item.Name, item.ItemID, m_part.AbsolutePosition, |
350 | } | 367 | m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); |
368 | |||
369 | m_items.LockItemsForWrite(true); | ||
351 | 370 | ||
371 | m_items[item.ItemID].OldItemID = item.OldItemID; | ||
372 | m_items[item.ItemID].PermsMask = 0; | ||
373 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
374 | |||
375 | m_items.LockItemsForWrite(false); | ||
376 | |||
352 | string script = Utils.BytesToString(asset.Data); | 377 | string script = Utils.BytesToString(asset.Data); |
353 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 378 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
354 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 379 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
380 | StoreScriptErrors(item.ItemID, null); | ||
355 | if (!item.ScriptRunning) | 381 | if (!item.ScriptRunning) |
356 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | 382 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( |
357 | m_part.LocalId, item.ItemID); | 383 | m_part.LocalId, item.ItemID); |
@@ -424,22 +450,149 @@ namespace OpenSim.Region.Framework.Scenes | |||
424 | return stateID; | 450 | return stateID; |
425 | } | 451 | } |
426 | 452 | ||
453 | /// <summary> | ||
454 | /// Start a script which is in this prim's inventory. | ||
455 | /// Some processing may occur in the background, but this routine returns asap. | ||
456 | /// </summary> | ||
457 | /// <param name="itemId"> | ||
458 | /// A <see cref="UUID"/> | ||
459 | /// </param> | ||
427 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 460 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
428 | { | 461 | { |
429 | TaskInventoryItem item = GetInventoryItem(itemId); | 462 | lock (m_scriptErrors) |
430 | if (item != null) | ||
431 | { | 463 | { |
432 | return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 464 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
465 | m_scriptErrors.Remove(itemId); | ||
466 | } | ||
467 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
468 | return true; | ||
469 | } | ||
470 | |||
471 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
472 | { | ||
473 | m_items.LockItemsForRead(true); | ||
474 | if (m_items.ContainsKey(itemId)) | ||
475 | { | ||
476 | if (m_items.ContainsKey(itemId)) | ||
477 | { | ||
478 | m_items.LockItemsForRead(false); | ||
479 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
480 | } | ||
481 | else | ||
482 | { | ||
483 | m_items.LockItemsForRead(false); | ||
484 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
485 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
486 | StoreScriptError(itemId, msg); | ||
487 | m_log.ErrorFormat( | ||
488 | "[PRIM INVENTORY]: " + | ||
489 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
490 | } | ||
433 | } | 491 | } |
434 | else | 492 | else |
435 | { | 493 | { |
494 | m_items.LockItemsForRead(false); | ||
495 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
496 | StoreScriptError(itemId, msg); | ||
436 | m_log.ErrorFormat( | 497 | m_log.ErrorFormat( |
437 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 498 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
438 | itemId, m_part.Name, m_part.UUID, | 499 | itemId, m_part.Name, m_part.UUID, |
439 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 500 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
501 | } | ||
502 | |||
503 | } | ||
440 | 504 | ||
441 | return false; | 505 | /// <summary> |
506 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
507 | /// </summary> | ||
508 | /// <param name="itemId"> | ||
509 | /// A <see cref="UUID"/> | ||
510 | /// </param> | ||
511 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
512 | { | ||
513 | ArrayList errors; | ||
514 | |||
515 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
516 | // post any compilation/loading error messages | ||
517 | lock (m_scriptErrors) | ||
518 | { | ||
519 | m_scriptErrors[itemId] = null; | ||
520 | } | ||
521 | |||
522 | // Perform compilation/loading | ||
523 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
524 | |||
525 | // Wait for and retrieve any errors | ||
526 | lock (m_scriptErrors) | ||
527 | { | ||
528 | while ((errors = m_scriptErrors[itemId]) == null) | ||
529 | { | ||
530 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
531 | { | ||
532 | m_log.ErrorFormat( | ||
533 | "[PRIM INVENTORY]: " + | ||
534 | "timedout waiting for script {0} errors", itemId); | ||
535 | errors = m_scriptErrors[itemId]; | ||
536 | if (errors == null) | ||
537 | { | ||
538 | errors = new ArrayList(1); | ||
539 | errors.Add("timedout waiting for errors"); | ||
540 | } | ||
541 | break; | ||
542 | } | ||
543 | } | ||
544 | m_scriptErrors.Remove(itemId); | ||
545 | } | ||
546 | return errors; | ||
547 | } | ||
548 | |||
549 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
550 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
551 | { | ||
552 | lock (m_scriptErrors) | ||
553 | { | ||
554 | // If compilation/loading initiated via CreateScriptInstance(), | ||
555 | // it does not want the errors, so just get out | ||
556 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
557 | { | ||
558 | return; | ||
559 | } | ||
560 | |||
561 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
562 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
563 | if (errors != null) | ||
564 | { | ||
565 | m_scriptErrors[itemId] = errors; | ||
566 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
567 | return; | ||
568 | } | ||
442 | } | 569 | } |
570 | |||
571 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
572 | // the errors are yet, so retrieve them from the script engine. | ||
573 | // This may involve some waiting internal to GetScriptErrors(). | ||
574 | errors = GetScriptErrors(itemId); | ||
575 | |||
576 | // Get a default non-null value to indicate success. | ||
577 | if (errors == null) | ||
578 | { | ||
579 | errors = new ArrayList(); | ||
580 | } | ||
581 | |||
582 | // Post to CreateScriptInstanceEr() and wake it up | ||
583 | lock (m_scriptErrors) | ||
584 | { | ||
585 | m_scriptErrors[itemId] = errors; | ||
586 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | // Like StoreScriptErrors(), but just posts a single string message | ||
591 | private void StoreScriptError(UUID itemId, string message) | ||
592 | { | ||
593 | ArrayList errors = new ArrayList(1); | ||
594 | errors.Add(message); | ||
595 | StoreScriptErrors(itemId, errors); | ||
443 | } | 596 | } |
444 | 597 | ||
445 | /// <summary> | 598 | /// <summary> |
@@ -452,15 +605,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
452 | /// </param> | 605 | /// </param> |
453 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 606 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
454 | { | 607 | { |
455 | bool scriptPresent = false; | 608 | if (m_items.ContainsKey(itemId)) |
456 | |||
457 | lock (m_items) | ||
458 | { | ||
459 | if (m_items.ContainsKey(itemId)) | ||
460 | scriptPresent = true; | ||
461 | } | ||
462 | |||
463 | if (scriptPresent) | ||
464 | { | 609 | { |
465 | if (!sceneObjectBeingDeleted) | 610 | if (!sceneObjectBeingDeleted) |
466 | m_part.RemoveScriptEvents(itemId); | 611 | m_part.RemoveScriptEvents(itemId); |
@@ -485,14 +630,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
485 | /// <returns></returns> | 630 | /// <returns></returns> |
486 | private bool InventoryContainsName(string name) | 631 | private bool InventoryContainsName(string name) |
487 | { | 632 | { |
488 | lock (m_items) | 633 | m_items.LockItemsForRead(true); |
634 | foreach (TaskInventoryItem item in m_items.Values) | ||
489 | { | 635 | { |
490 | foreach (TaskInventoryItem item in m_items.Values) | 636 | if (item.Name == name) |
491 | { | 637 | { |
492 | if (item.Name == name) | 638 | m_items.LockItemsForRead(false); |
493 | return true; | 639 | return true; |
494 | } | 640 | } |
495 | } | 641 | } |
642 | m_items.LockItemsForRead(false); | ||
496 | return false; | 643 | return false; |
497 | } | 644 | } |
498 | 645 | ||
@@ -534,8 +681,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
534 | /// <param name="item"></param> | 681 | /// <param name="item"></param> |
535 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 682 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
536 | { | 683 | { |
537 | List<TaskInventoryItem> il = GetInventoryItems(); | 684 | m_items.LockItemsForRead(true); |
538 | 685 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
686 | m_items.LockItemsForRead(false); | ||
539 | foreach (TaskInventoryItem i in il) | 687 | foreach (TaskInventoryItem i in il) |
540 | { | 688 | { |
541 | if (i.Name == item.Name) | 689 | if (i.Name == item.Name) |
@@ -573,14 +721,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
573 | item.Name = name; | 721 | item.Name = name; |
574 | item.GroupID = m_part.GroupID; | 722 | item.GroupID = m_part.GroupID; |
575 | 723 | ||
576 | lock (m_items) | 724 | m_items.LockItemsForWrite(true); |
577 | m_items.Add(item.ItemID, item); | 725 | m_items.Add(item.ItemID, item); |
578 | 726 | m_items.LockItemsForWrite(false); | |
579 | if (allowedDrop) | 727 | if (allowedDrop) |
580 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 728 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
581 | else | 729 | else |
582 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 730 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
583 | 731 | ||
584 | m_inventorySerial++; | 732 | m_inventorySerial++; |
585 | //m_inventorySerial += 2; | 733 | //m_inventorySerial += 2; |
586 | HasInventoryChanged = true; | 734 | HasInventoryChanged = true; |
@@ -596,15 +744,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
596 | /// <param name="items"></param> | 744 | /// <param name="items"></param> |
597 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 745 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
598 | { | 746 | { |
599 | lock (m_items) | 747 | m_items.LockItemsForWrite(true); |
748 | foreach (TaskInventoryItem item in items) | ||
600 | { | 749 | { |
601 | foreach (TaskInventoryItem item in items) | 750 | m_items.Add(item.ItemID, item); |
602 | { | 751 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
603 | m_items.Add(item.ItemID, item); | ||
604 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
605 | } | ||
606 | m_inventorySerial++; | ||
607 | } | 752 | } |
753 | m_items.LockItemsForWrite(false); | ||
754 | |||
755 | m_inventorySerial++; | ||
608 | } | 756 | } |
609 | 757 | ||
610 | /// <summary> | 758 | /// <summary> |
@@ -615,23 +763,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
615 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 763 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
616 | { | 764 | { |
617 | TaskInventoryItem item; | 765 | TaskInventoryItem item; |
618 | 766 | m_items.LockItemsForRead(true); | |
619 | lock (m_items) | 767 | m_items.TryGetValue(itemId, out item); |
620 | m_items.TryGetValue(itemId, out item); | 768 | m_items.LockItemsForRead(false); |
621 | |||
622 | return item; | 769 | return item; |
623 | } | 770 | } |
624 | 771 | ||
625 | public TaskInventoryItem GetInventoryItem(string name) | 772 | public TaskInventoryItem GetInventoryItem(string name) |
626 | { | 773 | { |
627 | lock (m_items) | 774 | m_items.LockItemsForRead(true); |
775 | foreach (TaskInventoryItem item in m_items.Values) | ||
628 | { | 776 | { |
629 | foreach (TaskInventoryItem item in m_items.Values) | 777 | if (item.Name == name) |
630 | { | 778 | { |
631 | if (item.Name == name) | 779 | m_items.LockItemsForRead(false); |
632 | return item; | 780 | return item; |
633 | } | 781 | } |
634 | } | 782 | } |
783 | m_items.LockItemsForRead(false); | ||
635 | 784 | ||
636 | return null; | 785 | return null; |
637 | } | 786 | } |
@@ -640,15 +789,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
640 | { | 789 | { |
641 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 790 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
642 | 791 | ||
643 | lock (m_items) | 792 | m_items.LockItemsForRead(true); |
793 | |||
794 | foreach (TaskInventoryItem item in m_items.Values) | ||
644 | { | 795 | { |
645 | foreach (TaskInventoryItem item in m_items.Values) | 796 | if (item.Name == name) |
646 | { | 797 | items.Add(item); |
647 | if (item.Name == name) | ||
648 | items.Add(item); | ||
649 | } | ||
650 | } | 798 | } |
651 | 799 | ||
800 | m_items.LockItemsForRead(false); | ||
801 | |||
652 | return items; | 802 | return items; |
653 | } | 803 | } |
654 | 804 | ||
@@ -667,6 +817,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
667 | string xmlData = Utils.BytesToString(rezAsset.Data); | 817 | string xmlData = Utils.BytesToString(rezAsset.Data); |
668 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 818 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
669 | 819 | ||
820 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
821 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
822 | group.RootPart.AttachRotation = group.GroupRotation; | ||
823 | |||
670 | group.ResetIDs(); | 824 | group.ResetIDs(); |
671 | 825 | ||
672 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 826 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -741,8 +895,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
741 | 895 | ||
742 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 896 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
743 | { | 897 | { |
744 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 898 | m_items.LockItemsForWrite(true); |
745 | if (it != null) | 899 | |
900 | if (m_items.ContainsKey(item.ItemID)) | ||
746 | { | 901 | { |
747 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 902 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
748 | 903 | ||
@@ -755,14 +910,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
755 | item.GroupID = m_part.GroupID; | 910 | item.GroupID = m_part.GroupID; |
756 | 911 | ||
757 | if (item.AssetID == UUID.Zero) | 912 | if (item.AssetID == UUID.Zero) |
758 | item.AssetID = it.AssetID; | 913 | item.AssetID = m_items[item.ItemID].AssetID; |
759 | 914 | ||
760 | lock (m_items) | 915 | m_items[item.ItemID] = item; |
761 | { | 916 | m_inventorySerial++; |
762 | m_items[item.ItemID] = item; | ||
763 | m_inventorySerial++; | ||
764 | } | ||
765 | |||
766 | if (fireScriptEvents) | 917 | if (fireScriptEvents) |
767 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 918 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
768 | 919 | ||
@@ -771,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
771 | HasInventoryChanged = true; | 922 | HasInventoryChanged = true; |
772 | m_part.ParentGroup.HasGroupChanged = true; | 923 | m_part.ParentGroup.HasGroupChanged = true; |
773 | } | 924 | } |
774 | 925 | m_items.LockItemsForWrite(false); | |
775 | return true; | 926 | return true; |
776 | } | 927 | } |
777 | else | 928 | else |
@@ -782,8 +933,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
782 | item.ItemID, m_part.Name, m_part.UUID, | 933 | item.ItemID, m_part.Name, m_part.UUID, |
783 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 934 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
784 | } | 935 | } |
785 | return false; | 936 | m_items.LockItemsForWrite(false); |
786 | 937 | ||
938 | return false; | ||
787 | } | 939 | } |
788 | 940 | ||
789 | /// <summary> | 941 | /// <summary> |
@@ -794,43 +946,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
794 | /// in this prim's inventory.</returns> | 946 | /// in this prim's inventory.</returns> |
795 | public int RemoveInventoryItem(UUID itemID) | 947 | public int RemoveInventoryItem(UUID itemID) |
796 | { | 948 | { |
797 | TaskInventoryItem item = GetInventoryItem(itemID); | 949 | m_items.LockItemsForRead(true); |
798 | if (item != null) | 950 | |
951 | if (m_items.ContainsKey(itemID)) | ||
799 | { | 952 | { |
800 | int type = m_items[itemID].InvType; | 953 | int type = m_items[itemID].InvType; |
954 | m_items.LockItemsForRead(false); | ||
801 | if (type == 10) // Script | 955 | if (type == 10) // Script |
802 | { | 956 | { |
803 | m_part.RemoveScriptEvents(itemID); | ||
804 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 957 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
805 | } | 958 | } |
959 | m_items.LockItemsForWrite(true); | ||
806 | m_items.Remove(itemID); | 960 | m_items.Remove(itemID); |
961 | m_items.LockItemsForWrite(false); | ||
807 | m_inventorySerial++; | 962 | m_inventorySerial++; |
808 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 963 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
809 | 964 | ||
810 | HasInventoryChanged = true; | 965 | HasInventoryChanged = true; |
811 | m_part.ParentGroup.HasGroupChanged = true; | 966 | m_part.ParentGroup.HasGroupChanged = true; |
812 | 967 | ||
813 | if (!ContainsScripts()) | 968 | int scriptcount = 0; |
969 | m_items.LockItemsForRead(true); | ||
970 | foreach (TaskInventoryItem item in m_items.Values) | ||
971 | { | ||
972 | if (item.Type == 10) | ||
973 | { | ||
974 | scriptcount++; | ||
975 | } | ||
976 | } | ||
977 | m_items.LockItemsForRead(false); | ||
978 | |||
979 | |||
980 | if (scriptcount <= 0) | ||
981 | { | ||
814 | m_part.RemFlag(PrimFlags.Scripted); | 982 | m_part.RemFlag(PrimFlags.Scripted); |
983 | } | ||
815 | 984 | ||
816 | m_part.ScheduleFullUpdate(); | 985 | m_part.ScheduleFullUpdate(); |
817 | 986 | ||
818 | return type; | 987 | return type; |
819 | |||
820 | } | 988 | } |
821 | else | 989 | else |
822 | { | 990 | { |
991 | m_items.LockItemsForRead(false); | ||
823 | m_log.ErrorFormat( | 992 | m_log.ErrorFormat( |
824 | "[PRIM INVENTORY]: " + | 993 | "[PRIM INVENTORY]: " + |
825 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 994 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
826 | itemID, m_part.Name, m_part.UUID, | 995 | itemID, m_part.Name, m_part.UUID); |
827 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
828 | } | 996 | } |
829 | 997 | ||
830 | return -1; | 998 | return -1; |
831 | } | 999 | } |
832 | 1000 | ||
833 | private bool CreateInventoryFile() | 1001 | private bool CreateInventoryFileName() |
834 | { | 1002 | { |
835 | // m_log.DebugFormat( | 1003 | // m_log.DebugFormat( |
836 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | 1004 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", |
@@ -839,70 +1007,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
839 | if (m_inventoryFileName == String.Empty || | 1007 | if (m_inventoryFileName == String.Empty || |
840 | m_inventoryFileNameSerial < m_inventorySerial) | 1008 | m_inventoryFileNameSerial < m_inventorySerial) |
841 | { | 1009 | { |
842 | // Something changed, we need to create a new file | ||
843 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 1010 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
844 | m_inventoryFileNameSerial = m_inventorySerial; | 1011 | m_inventoryFileNameSerial = m_inventorySerial; |
845 | 1012 | ||
846 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
847 | |||
848 | lock (m_items) | ||
849 | { | ||
850 | foreach (TaskInventoryItem item in m_items.Values) | ||
851 | { | ||
852 | // m_log.DebugFormat( | ||
853 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | ||
854 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
855 | |||
856 | UUID ownerID = item.OwnerID; | ||
857 | uint everyoneMask = 0; | ||
858 | uint baseMask = item.BasePermissions; | ||
859 | uint ownerMask = item.CurrentPermissions; | ||
860 | uint groupMask = item.GroupPermissions; | ||
861 | |||
862 | invString.AddItemStart(); | ||
863 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
864 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
865 | |||
866 | invString.AddPermissionsStart(); | ||
867 | |||
868 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
869 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
870 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
871 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
872 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
873 | |||
874 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
875 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
876 | |||
877 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
878 | |||
879 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
880 | invString.AddSectionEnd(); | ||
881 | |||
882 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
883 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
884 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
885 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
886 | |||
887 | invString.AddSaleStart(); | ||
888 | invString.AddNameValueLine("sale_type", "not"); | ||
889 | invString.AddNameValueLine("sale_price", "0"); | ||
890 | invString.AddSectionEnd(); | ||
891 | |||
892 | invString.AddNameValueLine("name", item.Name + "|"); | ||
893 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
894 | |||
895 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
896 | invString.AddSectionEnd(); | ||
897 | } | ||
898 | } | ||
899 | |||
900 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
901 | |||
902 | return true; | 1013 | return true; |
903 | } | 1014 | } |
904 | 1015 | ||
905 | // No need to recreate, the existing file is fine | ||
906 | return false; | 1016 | return false; |
907 | } | 1017 | } |
908 | 1018 | ||
@@ -912,43 +1022,110 @@ namespace OpenSim.Region.Framework.Scenes | |||
912 | /// <param name="xferManager"></param> | 1022 | /// <param name="xferManager"></param> |
913 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1023 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
914 | { | 1024 | { |
915 | lock (m_items) | 1025 | bool changed = CreateInventoryFileName(); |
916 | { | ||
917 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing | ||
918 | // a new script if any previous deletion has left the prim inventory empty. | ||
919 | if (m_items.Count == 0) // No inventory | ||
920 | { | ||
921 | // m_log.DebugFormat( | ||
922 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", | ||
923 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); | ||
924 | 1026 | ||
925 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1027 | bool includeAssets = false; |
926 | return; | 1028 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) |
927 | } | 1029 | includeAssets = true; |
1030 | |||
1031 | if (m_inventoryPrivileged != includeAssets) | ||
1032 | changed = true; | ||
1033 | |||
1034 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
1035 | |||
1036 | Items.LockItemsForRead(true); | ||
1037 | |||
1038 | if (m_inventorySerial == 0) // No inventory | ||
1039 | { | ||
1040 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1041 | Items.LockItemsForRead(false); | ||
1042 | return; | ||
1043 | } | ||
928 | 1044 | ||
929 | CreateInventoryFile(); | 1045 | if (m_items.Count == 0) // No inventory |
1046 | { | ||
1047 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1048 | Items.LockItemsForRead(false); | ||
1049 | return; | ||
1050 | } | ||
930 | 1051 | ||
931 | // In principle, we should only do the rest if the inventory changed; | 1052 | if (!changed) |
932 | // by sending m_inventorySerial to the client, it ought to know | 1053 | { |
933 | // that nothing changed and that it doesn't need to request the file. | ||
934 | // Unfortunately, it doesn't look like the client optimizes this; | ||
935 | // the client seems to always come back and request the Xfer, | ||
936 | // no matter what value m_inventorySerial has. | ||
937 | // FIXME: Could probably be > 0 here rather than > 2 | ||
938 | if (m_inventoryFileData.Length > 2) | 1054 | if (m_inventoryFileData.Length > 2) |
939 | { | 1055 | { |
940 | // Add the file for Xfer | 1056 | xferManager.AddNewFile(m_inventoryFileName, |
941 | // m_log.DebugFormat( | 1057 | m_inventoryFileData); |
942 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | 1058 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
943 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | 1059 | Util.StringToBytes256(m_inventoryFileName)); |
944 | 1060 | ||
945 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1061 | Items.LockItemsForRead(false); |
1062 | return; | ||
946 | } | 1063 | } |
947 | |||
948 | // Tell the client we're ready to Xfer the file | ||
949 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
950 | Util.StringToBytes256(m_inventoryFileName)); | ||
951 | } | 1064 | } |
1065 | |||
1066 | m_inventoryPrivileged = includeAssets; | ||
1067 | |||
1068 | foreach (TaskInventoryItem item in m_items.Values) | ||
1069 | { | ||
1070 | UUID ownerID = item.OwnerID; | ||
1071 | uint everyoneMask = 0; | ||
1072 | uint baseMask = item.BasePermissions; | ||
1073 | uint ownerMask = item.CurrentPermissions; | ||
1074 | uint groupMask = item.GroupPermissions; | ||
1075 | |||
1076 | invString.AddItemStart(); | ||
1077 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
1078 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
1079 | |||
1080 | invString.AddPermissionsStart(); | ||
1081 | |||
1082 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
1083 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1084 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1085 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1086 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1087 | |||
1088 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1089 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1090 | |||
1091 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1092 | |||
1093 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1094 | invString.AddSectionEnd(); | ||
1095 | |||
1096 | if (includeAssets) | ||
1097 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1098 | else | ||
1099 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1100 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
1101 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
1102 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1103 | |||
1104 | invString.AddSaleStart(); | ||
1105 | invString.AddNameValueLine("sale_type", "not"); | ||
1106 | invString.AddNameValueLine("sale_price", "0"); | ||
1107 | invString.AddSectionEnd(); | ||
1108 | |||
1109 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1110 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1111 | |||
1112 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1113 | invString.AddSectionEnd(); | ||
1114 | } | ||
1115 | |||
1116 | Items.LockItemsForRead(false); | ||
1117 | |||
1118 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
1119 | |||
1120 | if (m_inventoryFileData.Length > 2) | ||
1121 | { | ||
1122 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
1123 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1124 | Util.StringToBytes256(m_inventoryFileName)); | ||
1125 | return; | ||
1126 | } | ||
1127 | |||
1128 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
952 | } | 1129 | } |
953 | 1130 | ||
954 | /// <summary> | 1131 | /// <summary> |
@@ -957,13 +1134,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
957 | /// <param name="datastore"></param> | 1134 | /// <param name="datastore"></param> |
958 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1135 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
959 | { | 1136 | { |
960 | if (HasInventoryChanged) | 1137 | // Removed this because linking will cause an immediate delete of the new |
961 | { | 1138 | // child prim from the database and the subsequent storing of the prim sees |
962 | HasInventoryChanged = false; | 1139 | // the inventory of it as unchanged and doesn't store it at all. The overhead |
963 | List<TaskInventoryItem> items = GetInventoryItems(); | 1140 | // of storing prim inventory needlessly is much less than the aggravation |
964 | datastore.StorePrimInventory(m_part.UUID, items); | 1141 | // of prim inventory loss. |
1142 | // if (HasInventoryChanged) | ||
1143 | // { | ||
1144 | Items.LockItemsForRead(true); | ||
1145 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | ||
1146 | Items.LockItemsForRead(false); | ||
965 | 1147 | ||
966 | } | 1148 | HasInventoryChanged = false; |
1149 | // } | ||
967 | } | 1150 | } |
968 | 1151 | ||
969 | public class InventoryStringBuilder | 1152 | public class InventoryStringBuilder |
@@ -1029,87 +1212,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
1029 | { | 1212 | { |
1030 | uint mask=0x7fffffff; | 1213 | uint mask=0x7fffffff; |
1031 | 1214 | ||
1032 | lock (m_items) | 1215 | foreach (TaskInventoryItem item in m_items.Values) |
1033 | { | 1216 | { |
1034 | foreach (TaskInventoryItem item in m_items.Values) | 1217 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1218 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1219 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1220 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1221 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1222 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1223 | |||
1224 | if (item.InvType == (int)InventoryType.Object) | ||
1035 | { | 1225 | { |
1036 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1226 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1037 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1227 | mask &= ~((uint)PermissionMask.Copy >> 13); |
1038 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1228 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1039 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1229 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
1040 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1230 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1041 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1231 | mask &= ~((uint)PermissionMask.Modify >> 13); |
1042 | |||
1043 | if (item.InvType != (int)InventoryType.Object) | ||
1044 | { | ||
1045 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
1046 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1047 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1048 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1049 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1050 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1051 | } | ||
1052 | else | ||
1053 | { | ||
1054 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1055 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1056 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1057 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1058 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1059 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1060 | } | ||
1061 | |||
1062 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1063 | mask &= ~(uint)PermissionMask.Copy; | ||
1064 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1065 | mask &= ~(uint)PermissionMask.Transfer; | ||
1066 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1067 | mask &= ~(uint)PermissionMask.Modify; | ||
1068 | } | 1232 | } |
1233 | |||
1234 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1235 | mask &= ~(uint)PermissionMask.Copy; | ||
1236 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1237 | mask &= ~(uint)PermissionMask.Transfer; | ||
1238 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1239 | mask &= ~(uint)PermissionMask.Modify; | ||
1069 | } | 1240 | } |
1070 | |||
1071 | return mask; | 1241 | return mask; |
1072 | } | 1242 | } |
1073 | 1243 | ||
1074 | public void ApplyNextOwnerPermissions() | 1244 | public void ApplyNextOwnerPermissions() |
1075 | { | 1245 | { |
1076 | lock (m_items) | 1246 | foreach (TaskInventoryItem item in m_items.Values) |
1077 | { | 1247 | { |
1078 | foreach (TaskInventoryItem item in m_items.Values) | 1248 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1079 | { | 1249 | { |
1080 | // m_log.DebugFormat ( | 1250 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1081 | // "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", | 1251 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1082 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1252 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1083 | 1253 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | |
1084 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1254 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1085 | { | 1255 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1086 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1087 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
1088 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1089 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
1090 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1091 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1092 | } | ||
1093 | |||
1094 | item.CurrentPermissions &= item.NextPermissions; | ||
1095 | item.BasePermissions &= item.NextPermissions; | ||
1096 | item.EveryonePermissions &= item.NextPermissions; | ||
1097 | item.OwnerChanged = true; | ||
1098 | item.PermsMask = 0; | ||
1099 | item.PermsGranter = UUID.Zero; | ||
1100 | } | 1256 | } |
1257 | item.CurrentPermissions &= item.NextPermissions; | ||
1258 | item.BasePermissions &= item.NextPermissions; | ||
1259 | item.EveryonePermissions &= item.NextPermissions; | ||
1260 | item.OwnerChanged = true; | ||
1261 | item.PermsMask = 0; | ||
1262 | item.PermsGranter = UUID.Zero; | ||
1101 | } | 1263 | } |
1102 | } | 1264 | } |
1103 | 1265 | ||
1104 | public void ApplyGodPermissions(uint perms) | 1266 | public void ApplyGodPermissions(uint perms) |
1105 | { | 1267 | { |
1106 | lock (m_items) | 1268 | foreach (TaskInventoryItem item in m_items.Values) |
1107 | { | 1269 | { |
1108 | foreach (TaskInventoryItem item in m_items.Values) | 1270 | item.CurrentPermissions = perms; |
1109 | { | 1271 | item.BasePermissions = perms; |
1110 | item.CurrentPermissions = perms; | ||
1111 | item.BasePermissions = perms; | ||
1112 | } | ||
1113 | } | 1272 | } |
1114 | 1273 | ||
1115 | m_inventorySerial++; | 1274 | m_inventorySerial++; |
@@ -1122,14 +1281,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1122 | /// <returns></returns> | 1281 | /// <returns></returns> |
1123 | public bool ContainsScripts() | 1282 | public bool ContainsScripts() |
1124 | { | 1283 | { |
1125 | lock (m_items) | 1284 | foreach (TaskInventoryItem item in m_items.Values) |
1126 | { | 1285 | { |
1127 | foreach (TaskInventoryItem item in m_items.Values) | 1286 | if (item.InvType == (int)InventoryType.LSL) |
1128 | { | 1287 | { |
1129 | if (item.InvType == (int)InventoryType.LSL) | 1288 | return true; |
1130 | { | ||
1131 | return true; | ||
1132 | } | ||
1133 | } | 1289 | } |
1134 | } | 1290 | } |
1135 | 1291 | ||
@@ -1143,17 +1299,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1143 | public int ScriptCount() | 1299 | public int ScriptCount() |
1144 | { | 1300 | { |
1145 | int count = 0; | 1301 | int count = 0; |
1146 | lock (m_items) | 1302 | Items.LockItemsForRead(true); |
1303 | foreach (TaskInventoryItem item in m_items.Values) | ||
1147 | { | 1304 | { |
1148 | foreach (TaskInventoryItem item in m_items.Values) | 1305 | if (item.InvType == (int)InventoryType.LSL) |
1149 | { | 1306 | { |
1150 | if (item.InvType == (int)InventoryType.LSL) | 1307 | count++; |
1151 | { | ||
1152 | count++; | ||
1153 | } | ||
1154 | } | 1308 | } |
1155 | } | 1309 | } |
1156 | 1310 | Items.LockItemsForRead(false); | |
1157 | return count; | 1311 | return count; |
1158 | } | 1312 | } |
1159 | /// <summary> | 1313 | /// <summary> |
@@ -1189,11 +1343,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1189 | { | 1343 | { |
1190 | List<UUID> ret = new List<UUID>(); | 1344 | List<UUID> ret = new List<UUID>(); |
1191 | 1345 | ||
1192 | lock (m_items) | 1346 | foreach (TaskInventoryItem item in m_items.Values) |
1193 | { | 1347 | ret.Add(item.ItemID); |
1194 | foreach (TaskInventoryItem item in m_items.Values) | ||
1195 | ret.Add(item.ItemID); | ||
1196 | } | ||
1197 | 1348 | ||
1198 | return ret; | 1349 | return ret; |
1199 | } | 1350 | } |
@@ -1202,8 +1353,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1202 | { | 1353 | { |
1203 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1354 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1204 | 1355 | ||
1205 | lock (m_items) | 1356 | Items.LockItemsForRead(true); |
1206 | ret = new List<TaskInventoryItem>(m_items.Values); | 1357 | ret = new List<TaskInventoryItem>(m_items.Values); |
1358 | Items.LockItemsForRead(false); | ||
1207 | 1359 | ||
1208 | return ret; | 1360 | return ret; |
1209 | } | 1361 | } |
@@ -1212,18 +1364,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1212 | { | 1364 | { |
1213 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1365 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1214 | 1366 | ||
1215 | lock (m_items) | 1367 | Items.LockItemsForRead(true); |
1216 | { | 1368 | |
1217 | foreach (TaskInventoryItem item in m_items.Values) | 1369 | foreach (TaskInventoryItem item in m_items.Values) |
1218 | if (item.InvType == (int)type) | 1370 | if (item.InvType == (int)type) |
1219 | ret.Add(item); | 1371 | ret.Add(item); |
1220 | } | 1372 | |
1373 | Items.LockItemsForRead(false); | ||
1221 | 1374 | ||
1222 | return ret; | 1375 | return ret; |
1223 | } | 1376 | } |
1224 | 1377 | ||
1225 | public Dictionary<UUID, string> GetScriptStates() | 1378 | public Dictionary<UUID, string> GetScriptStates() |
1226 | { | 1379 | { |
1380 | return GetScriptStates(false); | ||
1381 | } | ||
1382 | |||
1383 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1384 | { | ||
1227 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1385 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1228 | 1386 | ||
1229 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1387 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1245,14 +1403,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1245 | string n = e.GetXMLState(item.ItemID); | 1403 | string n = e.GetXMLState(item.ItemID); |
1246 | if (n != String.Empty) | 1404 | if (n != String.Empty) |
1247 | { | 1405 | { |
1248 | if (!ret.ContainsKey(item.ItemID)) | 1406 | if (oldIDs) |
1249 | ret[item.ItemID] = n; | 1407 | { |
1408 | if (!ret.ContainsKey(item.OldItemID)) | ||
1409 | ret[item.OldItemID] = n; | ||
1410 | } | ||
1411 | else | ||
1412 | { | ||
1413 | if (!ret.ContainsKey(item.ItemID)) | ||
1414 | ret[item.ItemID] = n; | ||
1415 | } | ||
1250 | break; | 1416 | break; |
1251 | } | 1417 | } |
1252 | } | 1418 | } |
1253 | } | 1419 | } |
1254 | } | 1420 | } |
1255 | |||
1256 | return ret; | 1421 | return ret; |
1257 | } | 1422 | } |
1258 | 1423 | ||