diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 801 |
1 files changed, 500 insertions, 301 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index c223474..14ef0fb 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,11 +87,14 @@ 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; |
91 | m_inventorySerial++; | 96 | m_inventorySerial++; |
97 | QueryScriptStates(); | ||
92 | } | 98 | } |
93 | } | 99 | } |
94 | 100 | ||
@@ -123,38 +129,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
123 | public void ResetInventoryIDs() | 129 | public void ResetInventoryIDs() |
124 | { | 130 | { |
125 | if (null == m_part) | 131 | if (null == m_part) |
126 | return; | 132 | m_items.LockItemsForWrite(true); |
127 | 133 | ||
128 | lock (m_items) | 134 | if (Items.Count == 0) |
129 | { | 135 | { |
130 | if (0 == m_items.Count) | 136 | m_items.LockItemsForWrite(false); |
131 | return; | 137 | return; |
138 | } | ||
132 | 139 | ||
133 | IList<TaskInventoryItem> items = GetInventoryItems(); | 140 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
134 | m_items.Clear(); | 141 | Items.Clear(); |
135 | 142 | ||
136 | foreach (TaskInventoryItem item in items) | 143 | foreach (TaskInventoryItem item in items) |
137 | { | 144 | { |
138 | item.ResetIDs(m_part.UUID); | 145 | item.ResetIDs(m_part.UUID); |
139 | m_items.Add(item.ItemID, item); | 146 | Items.Add(item.ItemID, item); |
140 | } | ||
141 | } | 147 | } |
148 | m_items.LockItemsForWrite(false); | ||
142 | } | 149 | } |
143 | 150 | ||
144 | public void ResetObjectID() | 151 | public void ResetObjectID() |
145 | { | 152 | { |
146 | lock (Items) | 153 | m_items.LockItemsForWrite(true); |
154 | |||
155 | if (Items.Count == 0) | ||
147 | { | 156 | { |
148 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 157 | m_items.LockItemsForWrite(false); |
149 | Items.Clear(); | 158 | return; |
150 | |||
151 | foreach (TaskInventoryItem item in items) | ||
152 | { | ||
153 | item.ParentPartID = m_part.UUID; | ||
154 | item.ParentID = m_part.UUID; | ||
155 | Items.Add(item.ItemID, item); | ||
156 | } | ||
157 | } | 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); | ||
158 | } | 171 | } |
159 | 172 | ||
160 | /// <summary> | 173 | /// <summary> |
@@ -163,17 +176,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
163 | /// <param name="ownerId"></param> | 176 | /// <param name="ownerId"></param> |
164 | public void ChangeInventoryOwner(UUID ownerId) | 177 | public void ChangeInventoryOwner(UUID ownerId) |
165 | { | 178 | { |
166 | lock (Items) | 179 | List<TaskInventoryItem> items = GetInventoryItems(); |
167 | { | ||
168 | if (0 == Items.Count) | ||
169 | { | ||
170 | return; | ||
171 | } | ||
172 | } | ||
173 | 180 | ||
181 | if (items.Count == 0) | ||
182 | return; | ||
183 | |||
184 | m_items.LockItemsForWrite(true); | ||
174 | HasInventoryChanged = true; | 185 | HasInventoryChanged = true; |
175 | m_part.ParentGroup.HasGroupChanged = true; | 186 | m_part.ParentGroup.HasGroupChanged = true; |
176 | List<TaskInventoryItem> items = GetInventoryItems(); | ||
177 | foreach (TaskInventoryItem item in items) | 187 | foreach (TaskInventoryItem item in items) |
178 | { | 188 | { |
179 | if (ownerId != item.OwnerID) | 189 | if (ownerId != item.OwnerID) |
@@ -184,6 +194,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
184 | item.PermsGranter = UUID.Zero; | 194 | item.PermsGranter = UUID.Zero; |
185 | item.OwnerChanged = true; | 195 | item.OwnerChanged = true; |
186 | } | 196 | } |
197 | m_items.LockItemsForWrite(false); | ||
187 | } | 198 | } |
188 | 199 | ||
189 | /// <summary> | 200 | /// <summary> |
@@ -192,12 +203,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
192 | /// <param name="groupID"></param> | 203 | /// <param name="groupID"></param> |
193 | public void ChangeInventoryGroup(UUID groupID) | 204 | public void ChangeInventoryGroup(UUID groupID) |
194 | { | 205 | { |
195 | lock (Items) | 206 | m_items.LockItemsForWrite(true); |
207 | if (0 == Items.Count) | ||
196 | { | 208 | { |
197 | if (0 == Items.Count) | 209 | m_items.LockItemsForWrite(false); |
198 | { | 210 | return; |
199 | return; | ||
200 | } | ||
201 | } | 211 | } |
202 | 212 | ||
203 | // Don't let this set the HasGroupChanged flag for attachments | 213 | // Don't let this set the HasGroupChanged flag for attachments |
@@ -209,12 +219,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
209 | m_part.ParentGroup.HasGroupChanged = true; | 219 | m_part.ParentGroup.HasGroupChanged = true; |
210 | } | 220 | } |
211 | 221 | ||
212 | List<TaskInventoryItem> items = GetInventoryItems(); | 222 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
213 | foreach (TaskInventoryItem item in items) | 223 | foreach (TaskInventoryItem item in items) |
214 | { | 224 | { |
215 | if (groupID != item.GroupID) | 225 | if (groupID != item.GroupID) |
226 | { | ||
216 | item.GroupID = groupID; | 227 | item.GroupID = groupID; |
228 | } | ||
217 | } | 229 | } |
230 | m_items.LockItemsForWrite(false); | ||
231 | } | ||
232 | |||
233 | private void QueryScriptStates() | ||
234 | { | ||
235 | if (m_part == null || m_part.ParentGroup == null) | ||
236 | return; | ||
237 | |||
238 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | ||
239 | if (engines == null) // No engine at all | ||
240 | return; | ||
241 | |||
242 | Items.LockItemsForRead(true); | ||
243 | foreach (TaskInventoryItem item in Items.Values) | ||
244 | { | ||
245 | if (item.InvType == (int)InventoryType.LSL) | ||
246 | { | ||
247 | foreach (IScriptModule e in engines) | ||
248 | { | ||
249 | bool running; | ||
250 | |||
251 | if (e.HasScript(item.ItemID, out running)) | ||
252 | { | ||
253 | item.ScriptRunning = running; | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | Items.LockItemsForRead(false); | ||
218 | } | 261 | } |
219 | 262 | ||
220 | public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 263 | public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
@@ -259,7 +302,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
259 | { | 302 | { |
260 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); | 303 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
261 | foreach (TaskInventoryItem item in scripts) | 304 | foreach (TaskInventoryItem item in scripts) |
305 | { | ||
262 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 306 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); |
307 | m_part.RemoveScriptEvents(item.ItemID); | ||
308 | } | ||
263 | } | 309 | } |
264 | 310 | ||
265 | /// <summary> | 311 | /// <summary> |
@@ -273,7 +319,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
273 | // 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); |
274 | 320 | ||
275 | 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"); | ||
276 | return false; | 324 | return false; |
325 | } | ||
277 | 326 | ||
278 | m_part.AddFlag(PrimFlags.Scripted); | 327 | m_part.AddFlag(PrimFlags.Scripted); |
279 | 328 | ||
@@ -283,14 +332,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
283 | if (stateSource == 2 && // Prim crossing | 332 | if (stateSource == 2 && // Prim crossing |
284 | m_part.ParentGroup.Scene.m_trustBinaries) | 333 | m_part.ParentGroup.Scene.m_trustBinaries) |
285 | { | 334 | { |
286 | lock (m_items) | 335 | m_items.LockItemsForWrite(true); |
287 | { | 336 | m_items[item.ItemID].PermsMask = 0; |
288 | m_items[item.ItemID].PermsMask = 0; | 337 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
289 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 338 | m_items.LockItemsForWrite(false); |
290 | } | ||
291 | |||
292 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 339 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
293 | 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); | ||
294 | m_part.ParentGroup.AddActiveScriptCount(1); | 342 | m_part.ParentGroup.AddActiveScriptCount(1); |
295 | m_part.ScheduleFullUpdate(); | 343 | m_part.ScheduleFullUpdate(); |
296 | return true; | 344 | return true; |
@@ -311,16 +359,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
311 | if (m_part.ParentGroup.m_savedScriptState != null) | 359 | if (m_part.ParentGroup.m_savedScriptState != null) |
312 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 360 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
313 | 361 | ||
314 | lock (m_items) | 362 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); |
315 | { | 363 | StoreScriptError(item.ItemID, msg); |
316 | m_items[item.ItemID].OldItemID = item.OldItemID; | 364 | m_log.ErrorFormat( |
317 | 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", |
318 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 366 | item.Name, item.ItemID, m_part.AbsolutePosition, |
319 | } | 367 | m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); |
368 | |||
369 | m_items.LockItemsForWrite(true); | ||
320 | 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 | |||
321 | string script = Utils.BytesToString(asset.Data); | 377 | string script = Utils.BytesToString(asset.Data); |
322 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 378 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
323 | 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); | ||
381 | if (!item.ScriptRunning) | ||
382 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | ||
383 | m_part.LocalId, item.ItemID); | ||
324 | m_part.ParentGroup.AddActiveScriptCount(1); | 384 | m_part.ParentGroup.AddActiveScriptCount(1); |
325 | m_part.ScheduleFullUpdate(); | 385 | m_part.ScheduleFullUpdate(); |
326 | 386 | ||
@@ -390,22 +450,149 @@ namespace OpenSim.Region.Framework.Scenes | |||
390 | return stateID; | 450 | return stateID; |
391 | } | 451 | } |
392 | 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> | ||
393 | 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) |
394 | { | 461 | { |
395 | TaskInventoryItem item = GetInventoryItem(itemId); | 462 | lock (m_scriptErrors) |
396 | if (item != null) | ||
397 | { | 463 | { |
398 | 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 | } | ||
399 | } | 491 | } |
400 | else | 492 | else |
401 | { | 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); | ||
402 | m_log.ErrorFormat( | 497 | m_log.ErrorFormat( |
403 | "[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}", |
404 | itemId, m_part.Name, m_part.UUID, | 499 | itemId, m_part.Name, m_part.UUID, |
405 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 500 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
501 | } | ||
502 | |||
503 | } | ||
406 | 504 | ||
407 | 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); | ||
408 | } | 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 | } | ||
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); | ||
409 | } | 596 | } |
410 | 597 | ||
411 | /// <summary> | 598 | /// <summary> |
@@ -418,15 +605,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
418 | /// </param> | 605 | /// </param> |
419 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 606 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
420 | { | 607 | { |
421 | bool scriptPresent = false; | 608 | if (m_items.ContainsKey(itemId)) |
422 | |||
423 | lock (m_items) | ||
424 | { | ||
425 | if (m_items.ContainsKey(itemId)) | ||
426 | scriptPresent = true; | ||
427 | } | ||
428 | |||
429 | if (scriptPresent) | ||
430 | { | 609 | { |
431 | if (!sceneObjectBeingDeleted) | 610 | if (!sceneObjectBeingDeleted) |
432 | m_part.RemoveScriptEvents(itemId); | 611 | m_part.RemoveScriptEvents(itemId); |
@@ -451,14 +630,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
451 | /// <returns></returns> | 630 | /// <returns></returns> |
452 | private bool InventoryContainsName(string name) | 631 | private bool InventoryContainsName(string name) |
453 | { | 632 | { |
454 | lock (m_items) | 633 | m_items.LockItemsForRead(true); |
634 | foreach (TaskInventoryItem item in m_items.Values) | ||
455 | { | 635 | { |
456 | foreach (TaskInventoryItem item in m_items.Values) | 636 | if (item.Name == name) |
457 | { | 637 | { |
458 | if (item.Name == name) | 638 | m_items.LockItemsForRead(false); |
459 | return true; | 639 | return true; |
460 | } | 640 | } |
461 | } | 641 | } |
642 | m_items.LockItemsForRead(false); | ||
462 | return false; | 643 | return false; |
463 | } | 644 | } |
464 | 645 | ||
@@ -500,8 +681,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
500 | /// <param name="item"></param> | 681 | /// <param name="item"></param> |
501 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 682 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
502 | { | 683 | { |
503 | List<TaskInventoryItem> il = GetInventoryItems(); | 684 | m_items.LockItemsForRead(true); |
504 | 685 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
686 | m_items.LockItemsForRead(false); | ||
505 | foreach (TaskInventoryItem i in il) | 687 | foreach (TaskInventoryItem i in il) |
506 | { | 688 | { |
507 | if (i.Name == item.Name) | 689 | if (i.Name == item.Name) |
@@ -539,14 +721,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
539 | item.Name = name; | 721 | item.Name = name; |
540 | item.GroupID = m_part.GroupID; | 722 | item.GroupID = m_part.GroupID; |
541 | 723 | ||
542 | lock (m_items) | 724 | m_items.LockItemsForWrite(true); |
543 | m_items.Add(item.ItemID, item); | 725 | m_items.Add(item.ItemID, item); |
544 | 726 | m_items.LockItemsForWrite(false); | |
545 | if (allowedDrop) | 727 | if (allowedDrop) |
546 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 728 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
547 | else | 729 | else |
548 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 730 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
549 | 731 | ||
550 | m_inventorySerial++; | 732 | m_inventorySerial++; |
551 | //m_inventorySerial += 2; | 733 | //m_inventorySerial += 2; |
552 | HasInventoryChanged = true; | 734 | HasInventoryChanged = true; |
@@ -562,15 +744,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
562 | /// <param name="items"></param> | 744 | /// <param name="items"></param> |
563 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 745 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
564 | { | 746 | { |
565 | lock (m_items) | 747 | m_items.LockItemsForWrite(true); |
748 | foreach (TaskInventoryItem item in items) | ||
566 | { | 749 | { |
567 | foreach (TaskInventoryItem item in items) | 750 | m_items.Add(item.ItemID, item); |
568 | { | 751 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
569 | m_items.Add(item.ItemID, item); | ||
570 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
571 | } | ||
572 | m_inventorySerial++; | ||
573 | } | 752 | } |
753 | m_items.LockItemsForWrite(false); | ||
754 | |||
755 | m_inventorySerial++; | ||
574 | } | 756 | } |
575 | 757 | ||
576 | /// <summary> | 758 | /// <summary> |
@@ -581,23 +763,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
581 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 763 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
582 | { | 764 | { |
583 | TaskInventoryItem item; | 765 | TaskInventoryItem item; |
584 | 766 | m_items.LockItemsForRead(true); | |
585 | lock (m_items) | 767 | m_items.TryGetValue(itemId, out item); |
586 | m_items.TryGetValue(itemId, out item); | 768 | m_items.LockItemsForRead(false); |
587 | |||
588 | return item; | 769 | return item; |
589 | } | 770 | } |
590 | 771 | ||
591 | public TaskInventoryItem GetInventoryItem(string name) | 772 | public TaskInventoryItem GetInventoryItem(string name) |
592 | { | 773 | { |
593 | lock (m_items) | 774 | m_items.LockItemsForRead(true); |
775 | foreach (TaskInventoryItem item in m_items.Values) | ||
594 | { | 776 | { |
595 | foreach (TaskInventoryItem item in m_items.Values) | 777 | if (item.Name == name) |
596 | { | 778 | { |
597 | if (item.Name == name) | 779 | m_items.LockItemsForRead(false); |
598 | return item; | 780 | return item; |
599 | } | 781 | } |
600 | } | 782 | } |
783 | m_items.LockItemsForRead(false); | ||
601 | 784 | ||
602 | return null; | 785 | return null; |
603 | } | 786 | } |
@@ -606,15 +789,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
606 | { | 789 | { |
607 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 790 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
608 | 791 | ||
609 | lock (m_items) | 792 | m_items.LockItemsForRead(true); |
793 | |||
794 | foreach (TaskInventoryItem item in m_items.Values) | ||
610 | { | 795 | { |
611 | foreach (TaskInventoryItem item in m_items.Values) | 796 | if (item.Name == name) |
612 | { | 797 | items.Add(item); |
613 | if (item.Name == name) | ||
614 | items.Add(item); | ||
615 | } | ||
616 | } | 798 | } |
617 | 799 | ||
800 | m_items.LockItemsForRead(false); | ||
801 | |||
618 | return items; | 802 | return items; |
619 | } | 803 | } |
620 | 804 | ||
@@ -633,6 +817,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
633 | string xmlData = Utils.BytesToString(rezAsset.Data); | 817 | string xmlData = Utils.BytesToString(rezAsset.Data); |
634 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 818 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
635 | 819 | ||
820 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
821 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
822 | group.RootPart.AttachRotation = group.GroupRotation; | ||
823 | |||
636 | group.ResetIDs(); | 824 | group.ResetIDs(); |
637 | 825 | ||
638 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 826 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -707,8 +895,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
707 | 895 | ||
708 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 896 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
709 | { | 897 | { |
710 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 898 | m_items.LockItemsForWrite(true); |
711 | if (it != null) | 899 | |
900 | if (m_items.ContainsKey(item.ItemID)) | ||
712 | { | 901 | { |
713 | // 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); |
714 | 903 | ||
@@ -721,14 +910,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
721 | item.GroupID = m_part.GroupID; | 910 | item.GroupID = m_part.GroupID; |
722 | 911 | ||
723 | if (item.AssetID == UUID.Zero) | 912 | if (item.AssetID == UUID.Zero) |
724 | item.AssetID = it.AssetID; | 913 | item.AssetID = m_items[item.ItemID].AssetID; |
725 | 914 | ||
726 | lock (m_items) | 915 | m_items[item.ItemID] = item; |
727 | { | 916 | m_inventorySerial++; |
728 | m_items[item.ItemID] = item; | ||
729 | m_inventorySerial++; | ||
730 | } | ||
731 | |||
732 | if (fireScriptEvents) | 917 | if (fireScriptEvents) |
733 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 918 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
734 | 919 | ||
@@ -737,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
737 | HasInventoryChanged = true; | 922 | HasInventoryChanged = true; |
738 | m_part.ParentGroup.HasGroupChanged = true; | 923 | m_part.ParentGroup.HasGroupChanged = true; |
739 | } | 924 | } |
740 | 925 | m_items.LockItemsForWrite(false); | |
741 | return true; | 926 | return true; |
742 | } | 927 | } |
743 | else | 928 | else |
@@ -748,8 +933,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
748 | item.ItemID, m_part.Name, m_part.UUID, | 933 | item.ItemID, m_part.Name, m_part.UUID, |
749 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 934 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
750 | } | 935 | } |
751 | return false; | 936 | m_items.LockItemsForWrite(false); |
752 | 937 | ||
938 | return false; | ||
753 | } | 939 | } |
754 | 940 | ||
755 | /// <summary> | 941 | /// <summary> |
@@ -760,43 +946,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
760 | /// in this prim's inventory.</returns> | 946 | /// in this prim's inventory.</returns> |
761 | public int RemoveInventoryItem(UUID itemID) | 947 | public int RemoveInventoryItem(UUID itemID) |
762 | { | 948 | { |
763 | TaskInventoryItem item = GetInventoryItem(itemID); | 949 | m_items.LockItemsForRead(true); |
764 | if (item != null) | 950 | |
951 | if (m_items.ContainsKey(itemID)) | ||
765 | { | 952 | { |
766 | int type = m_items[itemID].InvType; | 953 | int type = m_items[itemID].InvType; |
954 | m_items.LockItemsForRead(false); | ||
767 | if (type == 10) // Script | 955 | if (type == 10) // Script |
768 | { | 956 | { |
769 | m_part.RemoveScriptEvents(itemID); | ||
770 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 957 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
771 | } | 958 | } |
959 | m_items.LockItemsForWrite(true); | ||
772 | m_items.Remove(itemID); | 960 | m_items.Remove(itemID); |
961 | m_items.LockItemsForWrite(false); | ||
773 | m_inventorySerial++; | 962 | m_inventorySerial++; |
774 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 963 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
775 | 964 | ||
776 | HasInventoryChanged = true; | 965 | HasInventoryChanged = true; |
777 | m_part.ParentGroup.HasGroupChanged = true; | 966 | m_part.ParentGroup.HasGroupChanged = true; |
778 | 967 | ||
779 | 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 | { | ||
780 | m_part.RemFlag(PrimFlags.Scripted); | 982 | m_part.RemFlag(PrimFlags.Scripted); |
983 | } | ||
781 | 984 | ||
782 | m_part.ScheduleFullUpdate(); | 985 | m_part.ScheduleFullUpdate(); |
783 | 986 | ||
784 | return type; | 987 | return type; |
785 | |||
786 | } | 988 | } |
787 | else | 989 | else |
788 | { | 990 | { |
991 | m_items.LockItemsForRead(false); | ||
789 | m_log.ErrorFormat( | 992 | m_log.ErrorFormat( |
790 | "[PRIM INVENTORY]: " + | 993 | "[PRIM INVENTORY]: " + |
791 | "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", |
792 | itemID, m_part.Name, m_part.UUID, | 995 | itemID, m_part.Name, m_part.UUID); |
793 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
794 | } | 996 | } |
795 | 997 | ||
796 | return -1; | 998 | return -1; |
797 | } | 999 | } |
798 | 1000 | ||
799 | private bool CreateInventoryFile() | 1001 | private bool CreateInventoryFileName() |
800 | { | 1002 | { |
801 | // m_log.DebugFormat( | 1003 | // m_log.DebugFormat( |
802 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | 1004 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", |
@@ -805,70 +1007,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
805 | if (m_inventoryFileName == String.Empty || | 1007 | if (m_inventoryFileName == String.Empty || |
806 | m_inventoryFileNameSerial < m_inventorySerial) | 1008 | m_inventoryFileNameSerial < m_inventorySerial) |
807 | { | 1009 | { |
808 | // Something changed, we need to create a new file | ||
809 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 1010 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
810 | m_inventoryFileNameSerial = m_inventorySerial; | 1011 | m_inventoryFileNameSerial = m_inventorySerial; |
811 | 1012 | ||
812 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
813 | |||
814 | lock (m_items) | ||
815 | { | ||
816 | foreach (TaskInventoryItem item in m_items.Values) | ||
817 | { | ||
818 | // m_log.DebugFormat( | ||
819 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | ||
820 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
821 | |||
822 | UUID ownerID = item.OwnerID; | ||
823 | uint everyoneMask = 0; | ||
824 | uint baseMask = item.BasePermissions; | ||
825 | uint ownerMask = item.CurrentPermissions; | ||
826 | uint groupMask = item.GroupPermissions; | ||
827 | |||
828 | invString.AddItemStart(); | ||
829 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
830 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
831 | |||
832 | invString.AddPermissionsStart(); | ||
833 | |||
834 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
835 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
836 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
837 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
838 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
839 | |||
840 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
841 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
842 | |||
843 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
844 | |||
845 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
846 | invString.AddSectionEnd(); | ||
847 | |||
848 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
849 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
850 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
851 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
852 | |||
853 | invString.AddSaleStart(); | ||
854 | invString.AddNameValueLine("sale_type", "not"); | ||
855 | invString.AddNameValueLine("sale_price", "0"); | ||
856 | invString.AddSectionEnd(); | ||
857 | |||
858 | invString.AddNameValueLine("name", item.Name + "|"); | ||
859 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
860 | |||
861 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
862 | invString.AddSectionEnd(); | ||
863 | } | ||
864 | } | ||
865 | |||
866 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
867 | |||
868 | return true; | 1013 | return true; |
869 | } | 1014 | } |
870 | 1015 | ||
871 | // No need to recreate, the existing file is fine | ||
872 | return false; | 1016 | return false; |
873 | } | 1017 | } |
874 | 1018 | ||
@@ -878,43 +1022,110 @@ namespace OpenSim.Region.Framework.Scenes | |||
878 | /// <param name="xferManager"></param> | 1022 | /// <param name="xferManager"></param> |
879 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1023 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
880 | { | 1024 | { |
881 | lock (m_items) | 1025 | bool changed = CreateInventoryFileName(); |
882 | { | ||
883 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing | ||
884 | // a new script if any previous deletion has left the prim inventory empty. | ||
885 | if (m_items.Count == 0) // No inventory | ||
886 | { | ||
887 | // m_log.DebugFormat( | ||
888 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", | ||
889 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); | ||
890 | 1026 | ||
891 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1027 | bool includeAssets = false; |
892 | return; | 1028 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) |
893 | } | 1029 | includeAssets = true; |
1030 | |||
1031 | if (m_inventoryPrivileged != includeAssets) | ||
1032 | changed = true; | ||
1033 | |||
1034 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
894 | 1035 | ||
895 | CreateInventoryFile(); | 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 | } | ||
1044 | |||
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 | } | ||
896 | 1051 | ||
897 | // In principle, we should only do the rest if the inventory changed; | 1052 | if (!changed) |
898 | // by sending m_inventorySerial to the client, it ought to know | 1053 | { |
899 | // that nothing changed and that it doesn't need to request the file. | ||
900 | // Unfortunately, it doesn't look like the client optimizes this; | ||
901 | // the client seems to always come back and request the Xfer, | ||
902 | // no matter what value m_inventorySerial has. | ||
903 | // FIXME: Could probably be > 0 here rather than > 2 | ||
904 | if (m_inventoryFileData.Length > 2) | 1054 | if (m_inventoryFileData.Length > 2) |
905 | { | 1055 | { |
906 | // Add the file for Xfer | 1056 | xferManager.AddNewFile(m_inventoryFileName, |
907 | // m_log.DebugFormat( | 1057 | m_inventoryFileData); |
908 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | 1058 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
909 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | 1059 | Util.StringToBytes256(m_inventoryFileName)); |
910 | 1060 | ||
911 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1061 | Items.LockItemsForRead(false); |
1062 | return; | ||
912 | } | 1063 | } |
913 | |||
914 | // Tell the client we're ready to Xfer the file | ||
915 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
916 | Util.StringToBytes256(m_inventoryFileName)); | ||
917 | } | 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]); | ||
918 | } | 1129 | } |
919 | 1130 | ||
920 | /// <summary> | 1131 | /// <summary> |
@@ -923,13 +1134,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
923 | /// <param name="datastore"></param> | 1134 | /// <param name="datastore"></param> |
924 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1135 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
925 | { | 1136 | { |
926 | if (HasInventoryChanged) | 1137 | // Removed this because linking will cause an immediate delete of the new |
927 | { | 1138 | // child prim from the database and the subsequent storing of the prim sees |
928 | HasInventoryChanged = false; | 1139 | // the inventory of it as unchanged and doesn't store it at all. The overhead |
929 | List<TaskInventoryItem> items = GetInventoryItems(); | 1140 | // of storing prim inventory needlessly is much less than the aggravation |
930 | 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); | ||
931 | 1147 | ||
932 | } | 1148 | HasInventoryChanged = false; |
1149 | // } | ||
933 | } | 1150 | } |
934 | 1151 | ||
935 | public class InventoryStringBuilder | 1152 | public class InventoryStringBuilder |
@@ -995,87 +1212,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
995 | { | 1212 | { |
996 | uint mask=0x7fffffff; | 1213 | uint mask=0x7fffffff; |
997 | 1214 | ||
998 | lock (m_items) | 1215 | foreach (TaskInventoryItem item in m_items.Values) |
999 | { | 1216 | { |
1000 | 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) | ||
1001 | { | 1225 | { |
1002 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1226 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1003 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1227 | mask &= ~((uint)PermissionMask.Copy >> 13); |
1004 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1228 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1005 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1229 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
1006 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1230 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1007 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1231 | mask &= ~((uint)PermissionMask.Modify >> 13); |
1008 | |||
1009 | if (item.InvType != (int)InventoryType.Object) | ||
1010 | { | ||
1011 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
1012 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1013 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1014 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1015 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1016 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1017 | } | ||
1018 | else | ||
1019 | { | ||
1020 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1021 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1022 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1023 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1024 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1025 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1026 | } | ||
1027 | |||
1028 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1029 | mask &= ~(uint)PermissionMask.Copy; | ||
1030 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1031 | mask &= ~(uint)PermissionMask.Transfer; | ||
1032 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1033 | mask &= ~(uint)PermissionMask.Modify; | ||
1034 | } | 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; | ||
1035 | } | 1240 | } |
1036 | |||
1037 | return mask; | 1241 | return mask; |
1038 | } | 1242 | } |
1039 | 1243 | ||
1040 | public void ApplyNextOwnerPermissions() | 1244 | public void ApplyNextOwnerPermissions() |
1041 | { | 1245 | { |
1042 | lock (m_items) | 1246 | foreach (TaskInventoryItem item in m_items.Values) |
1043 | { | 1247 | { |
1044 | foreach (TaskInventoryItem item in m_items.Values) | 1248 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1045 | { | 1249 | { |
1046 | // m_log.DebugFormat ( | 1250 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1047 | // "[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; |
1048 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1252 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1049 | 1253 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | |
1050 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1254 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1051 | { | 1255 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1052 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1053 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
1054 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1055 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
1056 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1057 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1058 | } | ||
1059 | |||
1060 | item.CurrentPermissions &= item.NextPermissions; | ||
1061 | item.BasePermissions &= item.NextPermissions; | ||
1062 | item.EveryonePermissions &= item.NextPermissions; | ||
1063 | item.OwnerChanged = true; | ||
1064 | item.PermsMask = 0; | ||
1065 | item.PermsGranter = UUID.Zero; | ||
1066 | } | 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; | ||
1067 | } | 1263 | } |
1068 | } | 1264 | } |
1069 | 1265 | ||
1070 | public void ApplyGodPermissions(uint perms) | 1266 | public void ApplyGodPermissions(uint perms) |
1071 | { | 1267 | { |
1072 | lock (m_items) | 1268 | foreach (TaskInventoryItem item in m_items.Values) |
1073 | { | 1269 | { |
1074 | foreach (TaskInventoryItem item in m_items.Values) | 1270 | item.CurrentPermissions = perms; |
1075 | { | 1271 | item.BasePermissions = perms; |
1076 | item.CurrentPermissions = perms; | ||
1077 | item.BasePermissions = perms; | ||
1078 | } | ||
1079 | } | 1272 | } |
1080 | 1273 | ||
1081 | m_inventorySerial++; | 1274 | m_inventorySerial++; |
@@ -1088,14 +1281,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1088 | /// <returns></returns> | 1281 | /// <returns></returns> |
1089 | public bool ContainsScripts() | 1282 | public bool ContainsScripts() |
1090 | { | 1283 | { |
1091 | lock (m_items) | 1284 | foreach (TaskInventoryItem item in m_items.Values) |
1092 | { | 1285 | { |
1093 | foreach (TaskInventoryItem item in m_items.Values) | 1286 | if (item.InvType == (int)InventoryType.LSL) |
1094 | { | 1287 | { |
1095 | if (item.InvType == (int)InventoryType.LSL) | 1288 | return true; |
1096 | { | ||
1097 | return true; | ||
1098 | } | ||
1099 | } | 1289 | } |
1100 | } | 1290 | } |
1101 | 1291 | ||
@@ -1109,17 +1299,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1109 | public int ScriptCount() | 1299 | public int ScriptCount() |
1110 | { | 1300 | { |
1111 | int count = 0; | 1301 | int count = 0; |
1112 | lock (m_items) | 1302 | Items.LockItemsForRead(true); |
1303 | foreach (TaskInventoryItem item in m_items.Values) | ||
1113 | { | 1304 | { |
1114 | foreach (TaskInventoryItem item in m_items.Values) | 1305 | if (item.InvType == (int)InventoryType.LSL) |
1115 | { | 1306 | { |
1116 | if (item.InvType == (int)InventoryType.LSL) | 1307 | count++; |
1117 | { | ||
1118 | count++; | ||
1119 | } | ||
1120 | } | 1308 | } |
1121 | } | 1309 | } |
1122 | 1310 | Items.LockItemsForRead(false); | |
1123 | return count; | 1311 | return count; |
1124 | } | 1312 | } |
1125 | /// <summary> | 1313 | /// <summary> |
@@ -1155,11 +1343,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1155 | { | 1343 | { |
1156 | List<UUID> ret = new List<UUID>(); | 1344 | List<UUID> ret = new List<UUID>(); |
1157 | 1345 | ||
1158 | lock (m_items) | 1346 | foreach (TaskInventoryItem item in m_items.Values) |
1159 | { | 1347 | ret.Add(item.ItemID); |
1160 | foreach (TaskInventoryItem item in m_items.Values) | ||
1161 | ret.Add(item.ItemID); | ||
1162 | } | ||
1163 | 1348 | ||
1164 | return ret; | 1349 | return ret; |
1165 | } | 1350 | } |
@@ -1168,8 +1353,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1168 | { | 1353 | { |
1169 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1354 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1170 | 1355 | ||
1171 | lock (m_items) | 1356 | Items.LockItemsForRead(true); |
1172 | ret = new List<TaskInventoryItem>(m_items.Values); | 1357 | ret = new List<TaskInventoryItem>(m_items.Values); |
1358 | Items.LockItemsForRead(false); | ||
1173 | 1359 | ||
1174 | return ret; | 1360 | return ret; |
1175 | } | 1361 | } |
@@ -1178,18 +1364,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1178 | { | 1364 | { |
1179 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1365 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1180 | 1366 | ||
1181 | lock (m_items) | 1367 | Items.LockItemsForRead(true); |
1182 | { | 1368 | |
1183 | foreach (TaskInventoryItem item in m_items.Values) | 1369 | foreach (TaskInventoryItem item in m_items.Values) |
1184 | if (item.InvType == (int)type) | 1370 | if (item.InvType == (int)type) |
1185 | ret.Add(item); | 1371 | ret.Add(item); |
1186 | } | 1372 | |
1373 | Items.LockItemsForRead(false); | ||
1187 | 1374 | ||
1188 | return ret; | 1375 | return ret; |
1189 | } | 1376 | } |
1190 | 1377 | ||
1191 | public Dictionary<UUID, string> GetScriptStates() | 1378 | public Dictionary<UUID, string> GetScriptStates() |
1192 | { | 1379 | { |
1380 | return GetScriptStates(false); | ||
1381 | } | ||
1382 | |||
1383 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1384 | { | ||
1193 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1385 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1194 | 1386 | ||
1195 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1387 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1211,14 +1403,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1211 | string n = e.GetXMLState(item.ItemID); | 1403 | string n = e.GetXMLState(item.ItemID); |
1212 | if (n != String.Empty) | 1404 | if (n != String.Empty) |
1213 | { | 1405 | { |
1214 | if (!ret.ContainsKey(item.ItemID)) | 1406 | if (oldIDs) |
1215 | 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 | } | ||
1216 | break; | 1416 | break; |
1217 | } | 1417 | } |
1218 | } | 1418 | } |
1219 | } | 1419 | } |
1220 | } | 1420 | } |
1221 | |||
1222 | return ret; | 1421 | return ret; |
1223 | } | 1422 | } |
1224 | 1423 | ||
@@ -1251,4 +1450,4 @@ namespace OpenSim.Region.Framework.Scenes | |||
1251 | } | 1450 | } |
1252 | } | 1451 | } |
1253 | } | 1452 | } |
1254 | } \ No newline at end of file | 1453 | } |