diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 782 |
1 files changed, 471 insertions, 311 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 821fd81..e010864 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> |
@@ -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; |
@@ -338,6 +355,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
338 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 355 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
339 | if (null == asset) | 356 | if (null == asset) |
340 | { | 357 | { |
358 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
359 | StoreScriptError(item.ItemID, msg); | ||
341 | m_log.ErrorFormat( | 360 | m_log.ErrorFormat( |
342 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 361 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
343 | item.Name, item.ItemID, m_part.AbsolutePosition, | 362 | item.Name, item.ItemID, m_part.AbsolutePosition, |
@@ -350,16 +369,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
350 | if (m_part.ParentGroup.m_savedScriptState != null) | 369 | if (m_part.ParentGroup.m_savedScriptState != null) |
351 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 370 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
352 | 371 | ||
353 | lock (m_items) | 372 | m_items.LockItemsForWrite(true); |
354 | { | ||
355 | m_items[item.ItemID].OldItemID = item.OldItemID; | ||
356 | m_items[item.ItemID].PermsMask = 0; | ||
357 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
358 | } | ||
359 | 373 | ||
374 | m_items[item.ItemID].OldItemID = item.OldItemID; | ||
375 | m_items[item.ItemID].PermsMask = 0; | ||
376 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
377 | |||
378 | m_items.LockItemsForWrite(false); | ||
379 | |||
360 | string script = Utils.BytesToString(asset.Data); | 380 | string script = Utils.BytesToString(asset.Data); |
361 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 381 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
362 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 382 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
383 | StoreScriptErrors(item.ItemID, null); | ||
363 | if (!item.ScriptRunning) | 384 | if (!item.ScriptRunning) |
364 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | 385 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( |
365 | m_part.LocalId, item.ItemID); | 386 | m_part.LocalId, item.ItemID); |
@@ -432,24 +453,151 @@ namespace OpenSim.Region.Framework.Scenes | |||
432 | return stateID; | 453 | return stateID; |
433 | } | 454 | } |
434 | 455 | ||
456 | /// <summary> | ||
457 | /// Start a script which is in this prim's inventory. | ||
458 | /// Some processing may occur in the background, but this routine returns asap. | ||
459 | /// </summary> | ||
460 | /// <param name="itemId"> | ||
461 | /// A <see cref="UUID"/> | ||
462 | /// </param> | ||
435 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 463 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
436 | { | 464 | { |
437 | TaskInventoryItem item = GetInventoryItem(itemId); | 465 | lock (m_scriptErrors) |
438 | if (item != null) | 466 | { |
467 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion | ||
468 | m_scriptErrors.Remove(itemId); | ||
469 | } | ||
470 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
471 | return true; | ||
472 | } | ||
473 | |||
474 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
475 | { | ||
476 | m_items.LockItemsForRead(true); | ||
477 | if (m_items.ContainsKey(itemId)) | ||
439 | { | 478 | { |
440 | return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 479 | if (m_items.ContainsKey(itemId)) |
480 | { | ||
481 | m_items.LockItemsForRead(false); | ||
482 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
483 | } | ||
484 | else | ||
485 | { | ||
486 | m_items.LockItemsForRead(false); | ||
487 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
488 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
489 | StoreScriptError(itemId, msg); | ||
490 | m_log.ErrorFormat( | ||
491 | "[PRIM INVENTORY]: " + | ||
492 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
493 | } | ||
441 | } | 494 | } |
442 | else | 495 | else |
443 | { | 496 | { |
497 | m_items.LockItemsForRead(false); | ||
498 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
499 | StoreScriptError(itemId, msg); | ||
444 | m_log.ErrorFormat( | 500 | 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}", | 501 | "[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, | 502 | itemId, m_part.Name, m_part.UUID, |
447 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 503 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
504 | } | ||
505 | |||
506 | } | ||
448 | 507 | ||
449 | return false; | 508 | /// <summary> |
509 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
510 | /// </summary> | ||
511 | /// <param name="itemId"> | ||
512 | /// A <see cref="UUID"/> | ||
513 | /// </param> | ||
514 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
515 | { | ||
516 | ArrayList errors; | ||
517 | |||
518 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
519 | // post any compilation/loading error messages | ||
520 | lock (m_scriptErrors) | ||
521 | { | ||
522 | m_scriptErrors[itemId] = null; | ||
523 | } | ||
524 | |||
525 | // Perform compilation/loading | ||
526 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
527 | |||
528 | // Wait for and retrieve any errors | ||
529 | lock (m_scriptErrors) | ||
530 | { | ||
531 | while ((errors = m_scriptErrors[itemId]) == null) | ||
532 | { | ||
533 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
534 | { | ||
535 | m_log.ErrorFormat( | ||
536 | "[PRIM INVENTORY]: " + | ||
537 | "timedout waiting for script {0} errors", itemId); | ||
538 | errors = m_scriptErrors[itemId]; | ||
539 | if (errors == null) | ||
540 | { | ||
541 | errors = new ArrayList(1); | ||
542 | errors.Add("timedout waiting for errors"); | ||
543 | } | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | m_scriptErrors.Remove(itemId); | ||
548 | } | ||
549 | return errors; | ||
550 | } | ||
551 | |||
552 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
553 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
554 | { | ||
555 | lock (m_scriptErrors) | ||
556 | { | ||
557 | // If compilation/loading initiated via CreateScriptInstance(), | ||
558 | // it does not want the errors, so just get out | ||
559 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
560 | { | ||
561 | return; | ||
562 | } | ||
563 | |||
564 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
565 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
566 | if (errors != null) | ||
567 | { | ||
568 | m_scriptErrors[itemId] = errors; | ||
569 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
570 | return; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
575 | // the errors are yet, so retrieve them from the script engine. | ||
576 | // This may involve some waiting internal to GetScriptErrors(). | ||
577 | errors = GetScriptErrors(itemId); | ||
578 | |||
579 | // Get a default non-null value to indicate success. | ||
580 | if (errors == null) | ||
581 | { | ||
582 | errors = new ArrayList(); | ||
583 | } | ||
584 | |||
585 | // Post to CreateScriptInstanceEr() and wake it up | ||
586 | lock (m_scriptErrors) | ||
587 | { | ||
588 | m_scriptErrors[itemId] = errors; | ||
589 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
450 | } | 590 | } |
451 | } | 591 | } |
452 | 592 | ||
593 | // Like StoreScriptErrors(), but just posts a single string message | ||
594 | private void StoreScriptError(UUID itemId, string message) | ||
595 | { | ||
596 | ArrayList errors = new ArrayList(1); | ||
597 | errors.Add(message); | ||
598 | StoreScriptErrors(itemId, errors); | ||
599 | } | ||
600 | |||
453 | /// <summary> | 601 | /// <summary> |
454 | /// Stop and remove a script which is in this prim's inventory. | 602 | /// Stop and remove a script which is in this prim's inventory. |
455 | /// </summary> | 603 | /// </summary> |
@@ -460,15 +608,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
460 | /// </param> | 608 | /// </param> |
461 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 609 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
462 | { | 610 | { |
463 | bool scriptPresent = false; | 611 | 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 | { | 612 | { |
473 | if (!sceneObjectBeingDeleted) | 613 | if (!sceneObjectBeingDeleted) |
474 | m_part.RemoveScriptEvents(itemId); | 614 | m_part.RemoveScriptEvents(itemId); |
@@ -538,14 +678,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
538 | /// <returns></returns> | 678 | /// <returns></returns> |
539 | private bool InventoryContainsName(string name) | 679 | private bool InventoryContainsName(string name) |
540 | { | 680 | { |
541 | lock (m_items) | 681 | m_items.LockItemsForRead(true); |
682 | foreach (TaskInventoryItem item in m_items.Values) | ||
542 | { | 683 | { |
543 | foreach (TaskInventoryItem item in m_items.Values) | 684 | if (item.Name == name) |
544 | { | 685 | { |
545 | if (item.Name == name) | 686 | m_items.LockItemsForRead(false); |
546 | return true; | 687 | return true; |
547 | } | 688 | } |
548 | } | 689 | } |
690 | m_items.LockItemsForRead(false); | ||
549 | return false; | 691 | return false; |
550 | } | 692 | } |
551 | 693 | ||
@@ -587,8 +729,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
587 | /// <param name="item"></param> | 729 | /// <param name="item"></param> |
588 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 730 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
589 | { | 731 | { |
590 | List<TaskInventoryItem> il = GetInventoryItems(); | 732 | m_items.LockItemsForRead(true); |
591 | 733 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
734 | m_items.LockItemsForRead(false); | ||
592 | foreach (TaskInventoryItem i in il) | 735 | foreach (TaskInventoryItem i in il) |
593 | { | 736 | { |
594 | if (i.Name == item.Name) | 737 | if (i.Name == item.Name) |
@@ -626,14 +769,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
626 | item.Name = name; | 769 | item.Name = name; |
627 | item.GroupID = m_part.GroupID; | 770 | item.GroupID = m_part.GroupID; |
628 | 771 | ||
629 | lock (m_items) | 772 | m_items.LockItemsForWrite(true); |
630 | m_items.Add(item.ItemID, item); | 773 | m_items.Add(item.ItemID, item); |
631 | 774 | m_items.LockItemsForWrite(false); | |
632 | if (allowedDrop) | 775 | if (allowedDrop) |
633 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 776 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
634 | else | 777 | else |
635 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 778 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
636 | 779 | ||
637 | m_inventorySerial++; | 780 | m_inventorySerial++; |
638 | //m_inventorySerial += 2; | 781 | //m_inventorySerial += 2; |
639 | HasInventoryChanged = true; | 782 | HasInventoryChanged = true; |
@@ -649,15 +792,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
649 | /// <param name="items"></param> | 792 | /// <param name="items"></param> |
650 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 793 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
651 | { | 794 | { |
652 | lock (m_items) | 795 | m_items.LockItemsForWrite(true); |
796 | foreach (TaskInventoryItem item in items) | ||
653 | { | 797 | { |
654 | foreach (TaskInventoryItem item in items) | 798 | m_items.Add(item.ItemID, item); |
655 | { | 799 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
656 | m_items.Add(item.ItemID, item); | ||
657 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
658 | } | ||
659 | m_inventorySerial++; | ||
660 | } | 800 | } |
801 | m_items.LockItemsForWrite(false); | ||
802 | |||
803 | m_inventorySerial++; | ||
661 | } | 804 | } |
662 | 805 | ||
663 | /// <summary> | 806 | /// <summary> |
@@ -668,23 +811,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
668 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 811 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
669 | { | 812 | { |
670 | TaskInventoryItem item; | 813 | TaskInventoryItem item; |
671 | 814 | m_items.LockItemsForRead(true); | |
672 | lock (m_items) | 815 | m_items.TryGetValue(itemId, out item); |
673 | m_items.TryGetValue(itemId, out item); | 816 | m_items.LockItemsForRead(false); |
674 | |||
675 | return item; | 817 | return item; |
676 | } | 818 | } |
677 | 819 | ||
678 | public TaskInventoryItem GetInventoryItem(string name) | 820 | public TaskInventoryItem GetInventoryItem(string name) |
679 | { | 821 | { |
680 | lock (m_items) | 822 | m_items.LockItemsForRead(true); |
823 | foreach (TaskInventoryItem item in m_items.Values) | ||
681 | { | 824 | { |
682 | foreach (TaskInventoryItem item in m_items.Values) | 825 | if (item.Name == name) |
683 | { | 826 | { |
684 | if (item.Name == name) | 827 | m_items.LockItemsForRead(false); |
685 | return item; | 828 | return item; |
686 | } | 829 | } |
687 | } | 830 | } |
831 | m_items.LockItemsForRead(false); | ||
688 | 832 | ||
689 | return null; | 833 | return null; |
690 | } | 834 | } |
@@ -693,15 +837,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
693 | { | 837 | { |
694 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 838 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
695 | 839 | ||
696 | lock (m_items) | 840 | m_items.LockItemsForRead(true); |
841 | |||
842 | foreach (TaskInventoryItem item in m_items.Values) | ||
697 | { | 843 | { |
698 | foreach (TaskInventoryItem item in m_items.Values) | 844 | if (item.Name == name) |
699 | { | 845 | items.Add(item); |
700 | if (item.Name == name) | ||
701 | items.Add(item); | ||
702 | } | ||
703 | } | 846 | } |
704 | 847 | ||
848 | m_items.LockItemsForRead(false); | ||
849 | |||
705 | return items; | 850 | return items; |
706 | } | 851 | } |
707 | 852 | ||
@@ -720,6 +865,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | string xmlData = Utils.BytesToString(rezAsset.Data); | 865 | string xmlData = Utils.BytesToString(rezAsset.Data); |
721 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 866 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
722 | 867 | ||
868 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
869 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
870 | group.RootPart.AttachRotation = group.GroupRotation; | ||
871 | |||
723 | group.ResetIDs(); | 872 | group.ResetIDs(); |
724 | 873 | ||
725 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 874 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -794,8 +943,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
794 | 943 | ||
795 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 944 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
796 | { | 945 | { |
797 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 946 | m_items.LockItemsForWrite(true); |
798 | if (it != null) | 947 | |
948 | if (m_items.ContainsKey(item.ItemID)) | ||
799 | { | 949 | { |
800 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 950 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
801 | 951 | ||
@@ -808,14 +958,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
808 | item.GroupID = m_part.GroupID; | 958 | item.GroupID = m_part.GroupID; |
809 | 959 | ||
810 | if (item.AssetID == UUID.Zero) | 960 | if (item.AssetID == UUID.Zero) |
811 | item.AssetID = it.AssetID; | 961 | item.AssetID = m_items[item.ItemID].AssetID; |
812 | 962 | ||
813 | lock (m_items) | 963 | m_items[item.ItemID] = item; |
814 | { | 964 | m_inventorySerial++; |
815 | m_items[item.ItemID] = item; | ||
816 | m_inventorySerial++; | ||
817 | } | ||
818 | |||
819 | if (fireScriptEvents) | 965 | if (fireScriptEvents) |
820 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 966 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
821 | 967 | ||
@@ -824,7 +970,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
824 | HasInventoryChanged = true; | 970 | HasInventoryChanged = true; |
825 | m_part.ParentGroup.HasGroupChanged = true; | 971 | m_part.ParentGroup.HasGroupChanged = true; |
826 | } | 972 | } |
827 | 973 | m_items.LockItemsForWrite(false); | |
828 | return true; | 974 | return true; |
829 | } | 975 | } |
830 | else | 976 | else |
@@ -835,8 +981,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
835 | item.ItemID, m_part.Name, m_part.UUID, | 981 | item.ItemID, m_part.Name, m_part.UUID, |
836 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 982 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
837 | } | 983 | } |
838 | return false; | 984 | m_items.LockItemsForWrite(false); |
839 | 985 | ||
986 | return false; | ||
840 | } | 987 | } |
841 | 988 | ||
842 | /// <summary> | 989 | /// <summary> |
@@ -847,43 +994,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
847 | /// in this prim's inventory.</returns> | 994 | /// in this prim's inventory.</returns> |
848 | public int RemoveInventoryItem(UUID itemID) | 995 | public int RemoveInventoryItem(UUID itemID) |
849 | { | 996 | { |
850 | TaskInventoryItem item = GetInventoryItem(itemID); | 997 | m_items.LockItemsForRead(true); |
851 | if (item != null) | 998 | |
999 | if (m_items.ContainsKey(itemID)) | ||
852 | { | 1000 | { |
853 | int type = m_items[itemID].InvType; | 1001 | int type = m_items[itemID].InvType; |
1002 | m_items.LockItemsForRead(false); | ||
854 | if (type == 10) // Script | 1003 | if (type == 10) // Script |
855 | { | 1004 | { |
856 | m_part.RemoveScriptEvents(itemID); | ||
857 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 1005 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
858 | } | 1006 | } |
1007 | m_items.LockItemsForWrite(true); | ||
859 | m_items.Remove(itemID); | 1008 | m_items.Remove(itemID); |
1009 | m_items.LockItemsForWrite(false); | ||
860 | m_inventorySerial++; | 1010 | m_inventorySerial++; |
861 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 1011 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
862 | 1012 | ||
863 | HasInventoryChanged = true; | 1013 | HasInventoryChanged = true; |
864 | m_part.ParentGroup.HasGroupChanged = true; | 1014 | m_part.ParentGroup.HasGroupChanged = true; |
865 | 1015 | ||
866 | if (!ContainsScripts()) | 1016 | int scriptcount = 0; |
1017 | m_items.LockItemsForRead(true); | ||
1018 | foreach (TaskInventoryItem item in m_items.Values) | ||
1019 | { | ||
1020 | if (item.Type == 10) | ||
1021 | { | ||
1022 | scriptcount++; | ||
1023 | } | ||
1024 | } | ||
1025 | m_items.LockItemsForRead(false); | ||
1026 | |||
1027 | |||
1028 | if (scriptcount <= 0) | ||
1029 | { | ||
867 | m_part.RemFlag(PrimFlags.Scripted); | 1030 | m_part.RemFlag(PrimFlags.Scripted); |
1031 | } | ||
868 | 1032 | ||
869 | m_part.ScheduleFullUpdate(); | 1033 | m_part.ScheduleFullUpdate(); |
870 | 1034 | ||
871 | return type; | 1035 | return type; |
872 | |||
873 | } | 1036 | } |
874 | else | 1037 | else |
875 | { | 1038 | { |
1039 | m_items.LockItemsForRead(false); | ||
876 | m_log.ErrorFormat( | 1040 | m_log.ErrorFormat( |
877 | "[PRIM INVENTORY]: " + | 1041 | "[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", | 1042 | "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, | 1043 | itemID, m_part.Name, m_part.UUID); |
880 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
881 | } | 1044 | } |
882 | 1045 | ||
883 | return -1; | 1046 | return -1; |
884 | } | 1047 | } |
885 | 1048 | ||
886 | private bool CreateInventoryFile() | 1049 | private bool CreateInventoryFileName() |
887 | { | 1050 | { |
888 | // m_log.DebugFormat( | 1051 | // m_log.DebugFormat( |
889 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | 1052 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", |
@@ -892,70 +1055,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
892 | if (m_inventoryFileName == String.Empty || | 1055 | if (m_inventoryFileName == String.Empty || |
893 | m_inventoryFileNameSerial < m_inventorySerial) | 1056 | m_inventoryFileNameSerial < m_inventorySerial) |
894 | { | 1057 | { |
895 | // Something changed, we need to create a new file | ||
896 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 1058 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
897 | m_inventoryFileNameSerial = m_inventorySerial; | 1059 | m_inventoryFileNameSerial = m_inventorySerial; |
898 | 1060 | ||
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; | 1061 | return true; |
956 | } | 1062 | } |
957 | 1063 | ||
958 | // No need to recreate, the existing file is fine | ||
959 | return false; | 1064 | return false; |
960 | } | 1065 | } |
961 | 1066 | ||
@@ -965,43 +1070,110 @@ namespace OpenSim.Region.Framework.Scenes | |||
965 | /// <param name="xferManager"></param> | 1070 | /// <param name="xferManager"></param> |
966 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1071 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
967 | { | 1072 | { |
968 | lock (m_items) | 1073 | 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 | 1074 | ||
978 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1075 | bool includeAssets = false; |
979 | return; | 1076 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) |
980 | } | 1077 | includeAssets = true; |
1078 | |||
1079 | if (m_inventoryPrivileged != includeAssets) | ||
1080 | changed = true; | ||
981 | 1081 | ||
982 | CreateInventoryFile(); | 1082 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); |
1083 | |||
1084 | Items.LockItemsForRead(true); | ||
1085 | |||
1086 | if (m_inventorySerial == 0) // No inventory | ||
1087 | { | ||
1088 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1089 | Items.LockItemsForRead(false); | ||
1090 | return; | ||
1091 | } | ||
1092 | |||
1093 | if (m_items.Count == 0) // No inventory | ||
1094 | { | ||
1095 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1096 | Items.LockItemsForRead(false); | ||
1097 | return; | ||
1098 | } | ||
983 | 1099 | ||
984 | // In principle, we should only do the rest if the inventory changed; | 1100 | if (!changed) |
985 | // by sending m_inventorySerial to the client, it ought to know | 1101 | { |
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) | 1102 | if (m_inventoryFileData.Length > 2) |
992 | { | 1103 | { |
993 | // Add the file for Xfer | 1104 | xferManager.AddNewFile(m_inventoryFileName, |
994 | // m_log.DebugFormat( | 1105 | m_inventoryFileData); |
995 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | 1106 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
996 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | 1107 | Util.StringToBytes256(m_inventoryFileName)); |
997 | 1108 | ||
998 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1109 | Items.LockItemsForRead(false); |
1110 | return; | ||
999 | } | 1111 | } |
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 | } | 1112 | } |
1113 | |||
1114 | m_inventoryPrivileged = includeAssets; | ||
1115 | |||
1116 | foreach (TaskInventoryItem item in m_items.Values) | ||
1117 | { | ||
1118 | UUID ownerID = item.OwnerID; | ||
1119 | uint everyoneMask = 0; | ||
1120 | uint baseMask = item.BasePermissions; | ||
1121 | uint ownerMask = item.CurrentPermissions; | ||
1122 | uint groupMask = item.GroupPermissions; | ||
1123 | |||
1124 | invString.AddItemStart(); | ||
1125 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
1126 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
1127 | |||
1128 | invString.AddPermissionsStart(); | ||
1129 | |||
1130 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
1131 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1132 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1133 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1134 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1135 | |||
1136 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1137 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1138 | |||
1139 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1140 | |||
1141 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1142 | invString.AddSectionEnd(); | ||
1143 | |||
1144 | if (includeAssets) | ||
1145 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1146 | else | ||
1147 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1148 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
1149 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
1150 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1151 | |||
1152 | invString.AddSaleStart(); | ||
1153 | invString.AddNameValueLine("sale_type", "not"); | ||
1154 | invString.AddNameValueLine("sale_price", "0"); | ||
1155 | invString.AddSectionEnd(); | ||
1156 | |||
1157 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1158 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1159 | |||
1160 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1161 | invString.AddSectionEnd(); | ||
1162 | } | ||
1163 | |||
1164 | Items.LockItemsForRead(false); | ||
1165 | |||
1166 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
1167 | |||
1168 | if (m_inventoryFileData.Length > 2) | ||
1169 | { | ||
1170 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
1171 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1172 | Util.StringToBytes256(m_inventoryFileName)); | ||
1173 | return; | ||
1174 | } | ||
1175 | |||
1176 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1005 | } | 1177 | } |
1006 | 1178 | ||
1007 | /// <summary> | 1179 | /// <summary> |
@@ -1010,13 +1182,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1010 | /// <param name="datastore"></param> | 1182 | /// <param name="datastore"></param> |
1011 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1183 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
1012 | { | 1184 | { |
1013 | if (HasInventoryChanged) | 1185 | // Removed this because linking will cause an immediate delete of the new |
1014 | { | 1186 | // child prim from the database and the subsequent storing of the prim sees |
1015 | HasInventoryChanged = false; | 1187 | // the inventory of it as unchanged and doesn't store it at all. The overhead |
1016 | List<TaskInventoryItem> items = GetInventoryItems(); | 1188 | // of storing prim inventory needlessly is much less than the aggravation |
1017 | datastore.StorePrimInventory(m_part.UUID, items); | 1189 | // of prim inventory loss. |
1190 | // if (HasInventoryChanged) | ||
1191 | // { | ||
1192 | Items.LockItemsForRead(true); | ||
1193 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | ||
1194 | Items.LockItemsForRead(false); | ||
1018 | 1195 | ||
1019 | } | 1196 | HasInventoryChanged = false; |
1197 | // } | ||
1020 | } | 1198 | } |
1021 | 1199 | ||
1022 | public class InventoryStringBuilder | 1200 | public class InventoryStringBuilder |
@@ -1082,87 +1260,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
1082 | { | 1260 | { |
1083 | uint mask=0x7fffffff; | 1261 | uint mask=0x7fffffff; |
1084 | 1262 | ||
1085 | lock (m_items) | 1263 | foreach (TaskInventoryItem item in m_items.Values) |
1086 | { | 1264 | { |
1087 | foreach (TaskInventoryItem item in m_items.Values) | 1265 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1266 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1267 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1268 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1269 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1270 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1271 | |||
1272 | if (item.InvType == (int)InventoryType.Object) | ||
1088 | { | 1273 | { |
1089 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1274 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1090 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1275 | mask &= ~((uint)PermissionMask.Copy >> 13); |
1091 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1276 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1092 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1277 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
1093 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1278 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1094 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1279 | 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 | } | 1280 | } |
1281 | |||
1282 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1283 | mask &= ~(uint)PermissionMask.Copy; | ||
1284 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1285 | mask &= ~(uint)PermissionMask.Transfer; | ||
1286 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1287 | mask &= ~(uint)PermissionMask.Modify; | ||
1122 | } | 1288 | } |
1123 | |||
1124 | return mask; | 1289 | return mask; |
1125 | } | 1290 | } |
1126 | 1291 | ||
1127 | public void ApplyNextOwnerPermissions() | 1292 | public void ApplyNextOwnerPermissions() |
1128 | { | 1293 | { |
1129 | lock (m_items) | 1294 | foreach (TaskInventoryItem item in m_items.Values) |
1130 | { | 1295 | { |
1131 | foreach (TaskInventoryItem item in m_items.Values) | 1296 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1132 | { | 1297 | { |
1133 | // m_log.DebugFormat ( | 1298 | 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}", | 1299 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1135 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1300 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1136 | 1301 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | |
1137 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1302 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1138 | { | 1303 | 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 | } | 1304 | } |
1305 | item.CurrentPermissions &= item.NextPermissions; | ||
1306 | item.BasePermissions &= item.NextPermissions; | ||
1307 | item.EveryonePermissions &= item.NextPermissions; | ||
1308 | item.OwnerChanged = true; | ||
1309 | item.PermsMask = 0; | ||
1310 | item.PermsGranter = UUID.Zero; | ||
1154 | } | 1311 | } |
1155 | } | 1312 | } |
1156 | 1313 | ||
1157 | public void ApplyGodPermissions(uint perms) | 1314 | public void ApplyGodPermissions(uint perms) |
1158 | { | 1315 | { |
1159 | lock (m_items) | 1316 | foreach (TaskInventoryItem item in m_items.Values) |
1160 | { | 1317 | { |
1161 | foreach (TaskInventoryItem item in m_items.Values) | 1318 | item.CurrentPermissions = perms; |
1162 | { | 1319 | item.BasePermissions = perms; |
1163 | item.CurrentPermissions = perms; | ||
1164 | item.BasePermissions = perms; | ||
1165 | } | ||
1166 | } | 1320 | } |
1167 | 1321 | ||
1168 | m_inventorySerial++; | 1322 | m_inventorySerial++; |
@@ -1175,14 +1329,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1175 | /// <returns></returns> | 1329 | /// <returns></returns> |
1176 | public bool ContainsScripts() | 1330 | public bool ContainsScripts() |
1177 | { | 1331 | { |
1178 | lock (m_items) | 1332 | foreach (TaskInventoryItem item in m_items.Values) |
1179 | { | 1333 | { |
1180 | foreach (TaskInventoryItem item in m_items.Values) | 1334 | if (item.InvType == (int)InventoryType.LSL) |
1181 | { | 1335 | { |
1182 | if (item.InvType == (int)InventoryType.LSL) | 1336 | return true; |
1183 | { | ||
1184 | return true; | ||
1185 | } | ||
1186 | } | 1337 | } |
1187 | } | 1338 | } |
1188 | 1339 | ||
@@ -1196,17 +1347,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1196 | public int ScriptCount() | 1347 | public int ScriptCount() |
1197 | { | 1348 | { |
1198 | int count = 0; | 1349 | int count = 0; |
1199 | lock (m_items) | 1350 | Items.LockItemsForRead(true); |
1351 | foreach (TaskInventoryItem item in m_items.Values) | ||
1200 | { | 1352 | { |
1201 | foreach (TaskInventoryItem item in m_items.Values) | 1353 | if (item.InvType == (int)InventoryType.LSL) |
1202 | { | 1354 | { |
1203 | if (item.InvType == (int)InventoryType.LSL) | 1355 | count++; |
1204 | { | ||
1205 | count++; | ||
1206 | } | ||
1207 | } | 1356 | } |
1208 | } | 1357 | } |
1209 | 1358 | Items.LockItemsForRead(false); | |
1210 | return count; | 1359 | return count; |
1211 | } | 1360 | } |
1212 | /// <summary> | 1361 | /// <summary> |
@@ -1242,11 +1391,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1242 | { | 1391 | { |
1243 | List<UUID> ret = new List<UUID>(); | 1392 | List<UUID> ret = new List<UUID>(); |
1244 | 1393 | ||
1245 | lock (m_items) | 1394 | foreach (TaskInventoryItem item in m_items.Values) |
1246 | { | 1395 | ret.Add(item.ItemID); |
1247 | foreach (TaskInventoryItem item in m_items.Values) | ||
1248 | ret.Add(item.ItemID); | ||
1249 | } | ||
1250 | 1396 | ||
1251 | return ret; | 1397 | return ret; |
1252 | } | 1398 | } |
@@ -1255,8 +1401,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1255 | { | 1401 | { |
1256 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1402 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1257 | 1403 | ||
1258 | lock (m_items) | 1404 | Items.LockItemsForRead(true); |
1259 | ret = new List<TaskInventoryItem>(m_items.Values); | 1405 | ret = new List<TaskInventoryItem>(m_items.Values); |
1406 | Items.LockItemsForRead(false); | ||
1260 | 1407 | ||
1261 | return ret; | 1408 | return ret; |
1262 | } | 1409 | } |
@@ -1265,18 +1412,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1265 | { | 1412 | { |
1266 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1413 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1267 | 1414 | ||
1268 | lock (m_items) | 1415 | Items.LockItemsForRead(true); |
1269 | { | 1416 | |
1270 | foreach (TaskInventoryItem item in m_items.Values) | 1417 | foreach (TaskInventoryItem item in m_items.Values) |
1271 | if (item.InvType == (int)type) | 1418 | if (item.InvType == (int)type) |
1272 | ret.Add(item); | 1419 | ret.Add(item); |
1273 | } | 1420 | |
1421 | Items.LockItemsForRead(false); | ||
1274 | 1422 | ||
1275 | return ret; | 1423 | return ret; |
1276 | } | 1424 | } |
1277 | 1425 | ||
1278 | public Dictionary<UUID, string> GetScriptStates() | 1426 | public Dictionary<UUID, string> GetScriptStates() |
1279 | { | 1427 | { |
1428 | return GetScriptStates(false); | ||
1429 | } | ||
1430 | |||
1431 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1432 | { | ||
1280 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1433 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1281 | 1434 | ||
1282 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1435 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1302,14 +1455,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1302 | string n = e.GetXMLState(item.ItemID); | 1455 | string n = e.GetXMLState(item.ItemID); |
1303 | if (n != String.Empty) | 1456 | if (n != String.Empty) |
1304 | { | 1457 | { |
1305 | if (!ret.ContainsKey(item.ItemID)) | 1458 | if (oldIDs) |
1306 | ret[item.ItemID] = n; | 1459 | { |
1460 | if (!ret.ContainsKey(item.OldItemID)) | ||
1461 | ret[item.OldItemID] = n; | ||
1462 | } | ||
1463 | else | ||
1464 | { | ||
1465 | if (!ret.ContainsKey(item.ItemID)) | ||
1466 | ret[item.ItemID] = n; | ||
1467 | } | ||
1307 | break; | 1468 | break; |
1308 | } | 1469 | } |
1309 | } | 1470 | } |
1310 | } | 1471 | } |
1311 | } | 1472 | } |
1312 | |||
1313 | return ret; | 1473 | return ret; |
1314 | } | 1474 | } |
1315 | 1475 | ||