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