diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 791 |
1 files changed, 492 insertions, 299 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8810903..81477e7 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 | { | 180 | |
168 | if (0 == Items.Count) | 181 | if (items.Count == 0) |
169 | { | 182 | return; |
170 | return; | ||
171 | } | ||
172 | } | ||
173 | 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 | /// <summary> | 263 | /// <summary> |
@@ -257,7 +300,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
257 | { | 300 | { |
258 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); | 301 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
259 | foreach (TaskInventoryItem item in scripts) | 302 | foreach (TaskInventoryItem item in scripts) |
303 | { | ||
260 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 304 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); |
305 | m_part.RemoveScriptEvents(item.ItemID); | ||
306 | } | ||
261 | } | 307 | } |
262 | 308 | ||
263 | /// <summary> | 309 | /// <summary> |
@@ -271,7 +317,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
271 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 317 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
272 | 318 | ||
273 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 319 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
320 | { | ||
321 | StoreScriptError(item.ItemID, "no permission"); | ||
274 | return; | 322 | return; |
323 | } | ||
275 | 324 | ||
276 | m_part.AddFlag(PrimFlags.Scripted); | 325 | m_part.AddFlag(PrimFlags.Scripted); |
277 | 326 | ||
@@ -280,14 +329,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
280 | if (stateSource == 2 && // Prim crossing | 329 | if (stateSource == 2 && // Prim crossing |
281 | m_part.ParentGroup.Scene.m_trustBinaries) | 330 | m_part.ParentGroup.Scene.m_trustBinaries) |
282 | { | 331 | { |
283 | lock (m_items) | 332 | m_items.LockItemsForWrite(true); |
284 | { | 333 | m_items[item.ItemID].PermsMask = 0; |
285 | m_items[item.ItemID].PermsMask = 0; | 334 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
286 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 335 | m_items.LockItemsForWrite(false); |
287 | } | ||
288 | |||
289 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 336 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
290 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 337 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
338 | StoreScriptErrors(item.ItemID, null); | ||
291 | m_part.ParentGroup.AddActiveScriptCount(1); | 339 | m_part.ParentGroup.AddActiveScriptCount(1); |
292 | m_part.ScheduleFullUpdate(); | 340 | m_part.ScheduleFullUpdate(); |
293 | return; | 341 | return; |
@@ -296,6 +344,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
296 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 344 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
297 | if (null == asset) | 345 | if (null == asset) |
298 | { | 346 | { |
347 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
348 | StoreScriptError(item.ItemID, msg); | ||
299 | m_log.ErrorFormat( | 349 | m_log.ErrorFormat( |
300 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 350 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
301 | item.Name, item.ItemID, m_part.AbsolutePosition, | 351 | item.Name, item.ItemID, m_part.AbsolutePosition, |
@@ -306,16 +356,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
306 | if (m_part.ParentGroup.m_savedScriptState != null) | 356 | if (m_part.ParentGroup.m_savedScriptState != null) |
307 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 357 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
308 | 358 | ||
309 | lock (m_items) | 359 | m_items.LockItemsForWrite(true); |
310 | { | ||
311 | m_items[item.ItemID].OldItemID = item.OldItemID; | ||
312 | m_items[item.ItemID].PermsMask = 0; | ||
313 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
314 | } | ||
315 | 360 | ||
361 | m_items[item.ItemID].OldItemID = item.OldItemID; | ||
362 | m_items[item.ItemID].PermsMask = 0; | ||
363 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
364 | |||
365 | m_items.LockItemsForWrite(false); | ||
366 | |||
316 | string script = Utils.BytesToString(asset.Data); | 367 | string script = Utils.BytesToString(asset.Data); |
317 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 368 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
318 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 369 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
370 | StoreScriptErrors(item.ItemID, null); | ||
371 | if (!item.ScriptRunning) | ||
372 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | ||
373 | m_part.LocalId, item.ItemID); | ||
319 | m_part.ParentGroup.AddActiveScriptCount(1); | 374 | m_part.ParentGroup.AddActiveScriptCount(1); |
320 | m_part.ScheduleFullUpdate(); | 375 | m_part.ScheduleFullUpdate(); |
321 | } | 376 | } |
@@ -386,20 +441,146 @@ namespace OpenSim.Region.Framework.Scenes | |||
386 | 441 | ||
387 | /// <summary> | 442 | /// <summary> |
388 | /// Start a script which is in this prim's inventory. | 443 | /// Start a script which is in this prim's inventory. |
444 | /// Some processing may occur in the background, but this routine returns asap. | ||
389 | /// </summary> | 445 | /// </summary> |
390 | /// <param name="itemId"> | 446 | /// <param name="itemId"> |
391 | /// A <see cref="UUID"/> | 447 | /// A <see cref="UUID"/> |
392 | /// </param> | 448 | /// </param> |
393 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 449 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
394 | { | 450 | { |
395 | TaskInventoryItem item = GetInventoryItem(itemId); | 451 | lock (m_scriptErrors) |
396 | if (item != null) | 452 | { |
397 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 453 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
454 | m_scriptErrors.Remove(itemId); | ||
455 | } | ||
456 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
457 | } | ||
458 | |||
459 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
460 | { | ||
461 | m_items.LockItemsForRead(true); | ||
462 | if (m_items.ContainsKey(itemId)) | ||
463 | { | ||
464 | if (m_items.ContainsKey(itemId)) | ||
465 | { | ||
466 | m_items.LockItemsForRead(false); | ||
467 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
468 | } | ||
469 | else | ||
470 | { | ||
471 | m_items.LockItemsForRead(false); | ||
472 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
473 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
474 | StoreScriptError(itemId, msg); | ||
475 | m_log.ErrorFormat( | ||
476 | "[PRIM INVENTORY]: " + | ||
477 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
478 | } | ||
479 | } | ||
398 | else | 480 | else |
481 | { | ||
482 | m_items.LockItemsForRead(false); | ||
483 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
484 | StoreScriptError(itemId, msg); | ||
399 | m_log.ErrorFormat( | 485 | m_log.ErrorFormat( |
400 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 486 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
401 | itemId, m_part.Name, m_part.UUID, | 487 | itemId, m_part.Name, m_part.UUID, |
402 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 488 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
489 | } | ||
490 | |||
491 | } | ||
492 | |||
493 | /// <summary> | ||
494 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
495 | /// </summary> | ||
496 | /// <param name="itemId"> | ||
497 | /// A <see cref="UUID"/> | ||
498 | /// </param> | ||
499 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
500 | { | ||
501 | ArrayList errors; | ||
502 | |||
503 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
504 | // post any compilation/loading error messages | ||
505 | lock (m_scriptErrors) | ||
506 | { | ||
507 | m_scriptErrors[itemId] = null; | ||
508 | } | ||
509 | |||
510 | // Perform compilation/loading | ||
511 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
512 | |||
513 | // Wait for and retrieve any errors | ||
514 | lock (m_scriptErrors) | ||
515 | { | ||
516 | while ((errors = m_scriptErrors[itemId]) == null) | ||
517 | { | ||
518 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
519 | { | ||
520 | m_log.ErrorFormat( | ||
521 | "[PRIM INVENTORY]: " + | ||
522 | "timedout waiting for script {0} errors", itemId); | ||
523 | errors = m_scriptErrors[itemId]; | ||
524 | if (errors == null) | ||
525 | { | ||
526 | errors = new ArrayList(1); | ||
527 | errors.Add("timedout waiting for errors"); | ||
528 | } | ||
529 | break; | ||
530 | } | ||
531 | } | ||
532 | m_scriptErrors.Remove(itemId); | ||
533 | } | ||
534 | return errors; | ||
535 | } | ||
536 | |||
537 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
538 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
539 | { | ||
540 | lock (m_scriptErrors) | ||
541 | { | ||
542 | // If compilation/loading initiated via CreateScriptInstance(), | ||
543 | // it does not want the errors, so just get out | ||
544 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
545 | { | ||
546 | return; | ||
547 | } | ||
548 | |||
549 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
550 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
551 | if (errors != null) | ||
552 | { | ||
553 | m_scriptErrors[itemId] = errors; | ||
554 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
555 | return; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
560 | // the errors are yet, so retrieve them from the script engine. | ||
561 | // This may involve some waiting internal to GetScriptErrors(). | ||
562 | errors = GetScriptErrors(itemId); | ||
563 | |||
564 | // Get a default non-null value to indicate success. | ||
565 | if (errors == null) | ||
566 | { | ||
567 | errors = new ArrayList(); | ||
568 | } | ||
569 | |||
570 | // Post to CreateScriptInstanceEr() and wake it up | ||
571 | lock (m_scriptErrors) | ||
572 | { | ||
573 | m_scriptErrors[itemId] = errors; | ||
574 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
575 | } | ||
576 | } | ||
577 | |||
578 | // Like StoreScriptErrors(), but just posts a single string message | ||
579 | private void StoreScriptError(UUID itemId, string message) | ||
580 | { | ||
581 | ArrayList errors = new ArrayList(1); | ||
582 | errors.Add(message); | ||
583 | StoreScriptErrors(itemId, errors); | ||
403 | } | 584 | } |
404 | 585 | ||
405 | /// <summary> | 586 | /// <summary> |
@@ -412,15 +593,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
412 | /// </param> | 593 | /// </param> |
413 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 594 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
414 | { | 595 | { |
415 | bool scriptPresent = false; | 596 | if (m_items.ContainsKey(itemId)) |
416 | |||
417 | lock (m_items) | ||
418 | { | ||
419 | if (m_items.ContainsKey(itemId)) | ||
420 | scriptPresent = true; | ||
421 | } | ||
422 | |||
423 | if (scriptPresent) | ||
424 | { | 597 | { |
425 | if (!sceneObjectBeingDeleted) | 598 | if (!sceneObjectBeingDeleted) |
426 | m_part.RemoveScriptEvents(itemId); | 599 | m_part.RemoveScriptEvents(itemId); |
@@ -445,14 +618,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
445 | /// <returns></returns> | 618 | /// <returns></returns> |
446 | private bool InventoryContainsName(string name) | 619 | private bool InventoryContainsName(string name) |
447 | { | 620 | { |
448 | lock (m_items) | 621 | m_items.LockItemsForRead(true); |
622 | foreach (TaskInventoryItem item in m_items.Values) | ||
449 | { | 623 | { |
450 | foreach (TaskInventoryItem item in m_items.Values) | 624 | if (item.Name == name) |
451 | { | 625 | { |
452 | if (item.Name == name) | 626 | m_items.LockItemsForRead(false); |
453 | return true; | 627 | return true; |
454 | } | 628 | } |
455 | } | 629 | } |
630 | m_items.LockItemsForRead(false); | ||
456 | return false; | 631 | return false; |
457 | } | 632 | } |
458 | 633 | ||
@@ -494,8 +669,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
494 | /// <param name="item"></param> | 669 | /// <param name="item"></param> |
495 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 670 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
496 | { | 671 | { |
497 | List<TaskInventoryItem> il = GetInventoryItems(); | 672 | m_items.LockItemsForRead(true); |
498 | 673 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
674 | m_items.LockItemsForRead(false); | ||
499 | foreach (TaskInventoryItem i in il) | 675 | foreach (TaskInventoryItem i in il) |
500 | { | 676 | { |
501 | if (i.Name == item.Name) | 677 | if (i.Name == item.Name) |
@@ -533,14 +709,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
533 | item.Name = name; | 709 | item.Name = name; |
534 | item.GroupID = m_part.GroupID; | 710 | item.GroupID = m_part.GroupID; |
535 | 711 | ||
536 | lock (m_items) | 712 | m_items.LockItemsForWrite(true); |
537 | m_items.Add(item.ItemID, item); | 713 | m_items.Add(item.ItemID, item); |
538 | 714 | m_items.LockItemsForWrite(false); | |
539 | if (allowedDrop) | 715 | if (allowedDrop) |
540 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 716 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
541 | else | 717 | else |
542 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 718 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
543 | 719 | ||
544 | m_inventorySerial++; | 720 | m_inventorySerial++; |
545 | //m_inventorySerial += 2; | 721 | //m_inventorySerial += 2; |
546 | HasInventoryChanged = true; | 722 | HasInventoryChanged = true; |
@@ -556,15 +732,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
556 | /// <param name="items"></param> | 732 | /// <param name="items"></param> |
557 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 733 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
558 | { | 734 | { |
559 | lock (m_items) | 735 | m_items.LockItemsForWrite(true); |
736 | foreach (TaskInventoryItem item in items) | ||
560 | { | 737 | { |
561 | foreach (TaskInventoryItem item in items) | 738 | m_items.Add(item.ItemID, item); |
562 | { | 739 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
563 | m_items.Add(item.ItemID, item); | ||
564 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
565 | } | ||
566 | m_inventorySerial++; | ||
567 | } | 740 | } |
741 | m_items.LockItemsForWrite(false); | ||
742 | |||
743 | m_inventorySerial++; | ||
568 | } | 744 | } |
569 | 745 | ||
570 | /// <summary> | 746 | /// <summary> |
@@ -575,23 +751,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
575 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 751 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
576 | { | 752 | { |
577 | TaskInventoryItem item; | 753 | TaskInventoryItem item; |
578 | 754 | m_items.LockItemsForRead(true); | |
579 | lock (m_items) | 755 | m_items.TryGetValue(itemId, out item); |
580 | m_items.TryGetValue(itemId, out item); | 756 | m_items.LockItemsForRead(false); |
581 | |||
582 | return item; | 757 | return item; |
583 | } | 758 | } |
584 | 759 | ||
585 | public TaskInventoryItem GetInventoryItem(string name) | 760 | public TaskInventoryItem GetInventoryItem(string name) |
586 | { | 761 | { |
587 | lock (m_items) | 762 | m_items.LockItemsForRead(true); |
763 | foreach (TaskInventoryItem item in m_items.Values) | ||
588 | { | 764 | { |
589 | foreach (TaskInventoryItem item in m_items.Values) | 765 | if (item.Name == name) |
590 | { | 766 | { |
591 | if (item.Name == name) | 767 | m_items.LockItemsForRead(false); |
592 | return item; | 768 | return item; |
593 | } | 769 | } |
594 | } | 770 | } |
771 | m_items.LockItemsForRead(false); | ||
595 | 772 | ||
596 | return null; | 773 | return null; |
597 | } | 774 | } |
@@ -600,15 +777,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
600 | { | 777 | { |
601 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 778 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
602 | 779 | ||
603 | lock (m_items) | 780 | m_items.LockItemsForRead(true); |
781 | |||
782 | foreach (TaskInventoryItem item in m_items.Values) | ||
604 | { | 783 | { |
605 | foreach (TaskInventoryItem item in m_items.Values) | 784 | if (item.Name == name) |
606 | { | 785 | items.Add(item); |
607 | if (item.Name == name) | ||
608 | items.Add(item); | ||
609 | } | ||
610 | } | 786 | } |
611 | 787 | ||
788 | m_items.LockItemsForRead(false); | ||
789 | |||
612 | return items; | 790 | return items; |
613 | } | 791 | } |
614 | 792 | ||
@@ -627,6 +805,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
627 | string xmlData = Utils.BytesToString(rezAsset.Data); | 805 | string xmlData = Utils.BytesToString(rezAsset.Data); |
628 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 806 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
629 | 807 | ||
808 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
809 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
810 | group.RootPart.AttachRotation = group.GroupRotation; | ||
811 | |||
630 | group.ResetIDs(); | 812 | group.ResetIDs(); |
631 | 813 | ||
632 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 814 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -701,8 +883,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
701 | 883 | ||
702 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 884 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
703 | { | 885 | { |
704 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 886 | m_items.LockItemsForWrite(true); |
705 | if (it != null) | 887 | |
888 | if (m_items.ContainsKey(item.ItemID)) | ||
706 | { | 889 | { |
707 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 890 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
708 | 891 | ||
@@ -715,14 +898,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
715 | item.GroupID = m_part.GroupID; | 898 | item.GroupID = m_part.GroupID; |
716 | 899 | ||
717 | if (item.AssetID == UUID.Zero) | 900 | if (item.AssetID == UUID.Zero) |
718 | item.AssetID = it.AssetID; | 901 | item.AssetID = m_items[item.ItemID].AssetID; |
719 | 902 | ||
720 | lock (m_items) | 903 | m_items[item.ItemID] = item; |
721 | { | 904 | m_inventorySerial++; |
722 | m_items[item.ItemID] = item; | ||
723 | m_inventorySerial++; | ||
724 | } | ||
725 | |||
726 | if (fireScriptEvents) | 905 | if (fireScriptEvents) |
727 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 906 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
728 | 907 | ||
@@ -731,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
731 | HasInventoryChanged = true; | 910 | HasInventoryChanged = true; |
732 | m_part.ParentGroup.HasGroupChanged = true; | 911 | m_part.ParentGroup.HasGroupChanged = true; |
733 | } | 912 | } |
734 | 913 | m_items.LockItemsForWrite(false); | |
735 | return true; | 914 | return true; |
736 | } | 915 | } |
737 | else | 916 | else |
@@ -742,8 +921,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
742 | item.ItemID, m_part.Name, m_part.UUID, | 921 | item.ItemID, m_part.Name, m_part.UUID, |
743 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 922 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
744 | } | 923 | } |
745 | return false; | 924 | m_items.LockItemsForWrite(false); |
746 | 925 | ||
926 | return false; | ||
747 | } | 927 | } |
748 | 928 | ||
749 | /// <summary> | 929 | /// <summary> |
@@ -754,43 +934,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
754 | /// in this prim's inventory.</returns> | 934 | /// in this prim's inventory.</returns> |
755 | public int RemoveInventoryItem(UUID itemID) | 935 | public int RemoveInventoryItem(UUID itemID) |
756 | { | 936 | { |
757 | TaskInventoryItem item = GetInventoryItem(itemID); | 937 | m_items.LockItemsForRead(true); |
758 | if (item != null) | 938 | |
939 | if (m_items.ContainsKey(itemID)) | ||
759 | { | 940 | { |
760 | int type = m_items[itemID].InvType; | 941 | int type = m_items[itemID].InvType; |
942 | m_items.LockItemsForRead(false); | ||
761 | if (type == 10) // Script | 943 | if (type == 10) // Script |
762 | { | 944 | { |
763 | m_part.RemoveScriptEvents(itemID); | ||
764 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 945 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
765 | } | 946 | } |
947 | m_items.LockItemsForWrite(true); | ||
766 | m_items.Remove(itemID); | 948 | m_items.Remove(itemID); |
949 | m_items.LockItemsForWrite(false); | ||
767 | m_inventorySerial++; | 950 | m_inventorySerial++; |
768 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 951 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
769 | 952 | ||
770 | HasInventoryChanged = true; | 953 | HasInventoryChanged = true; |
771 | m_part.ParentGroup.HasGroupChanged = true; | 954 | m_part.ParentGroup.HasGroupChanged = true; |
772 | 955 | ||
773 | if (!ContainsScripts()) | 956 | int scriptcount = 0; |
957 | m_items.LockItemsForRead(true); | ||
958 | foreach (TaskInventoryItem item in m_items.Values) | ||
959 | { | ||
960 | if (item.Type == 10) | ||
961 | { | ||
962 | scriptcount++; | ||
963 | } | ||
964 | } | ||
965 | m_items.LockItemsForRead(false); | ||
966 | |||
967 | |||
968 | if (scriptcount <= 0) | ||
969 | { | ||
774 | m_part.RemFlag(PrimFlags.Scripted); | 970 | m_part.RemFlag(PrimFlags.Scripted); |
971 | } | ||
775 | 972 | ||
776 | m_part.ScheduleFullUpdate(); | 973 | m_part.ScheduleFullUpdate(); |
777 | 974 | ||
778 | return type; | 975 | return type; |
779 | |||
780 | } | 976 | } |
781 | else | 977 | else |
782 | { | 978 | { |
979 | m_items.LockItemsForRead(false); | ||
783 | m_log.ErrorFormat( | 980 | m_log.ErrorFormat( |
784 | "[PRIM INVENTORY]: " + | 981 | "[PRIM INVENTORY]: " + |
785 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 982 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
786 | itemID, m_part.Name, m_part.UUID, | 983 | itemID, m_part.Name, m_part.UUID); |
787 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
788 | } | 984 | } |
789 | 985 | ||
790 | return -1; | 986 | return -1; |
791 | } | 987 | } |
792 | 988 | ||
793 | private bool CreateInventoryFile() | 989 | private bool CreateInventoryFileName() |
794 | { | 990 | { |
795 | // m_log.DebugFormat( | 991 | // m_log.DebugFormat( |
796 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | 992 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", |
@@ -799,116 +995,125 @@ namespace OpenSim.Region.Framework.Scenes | |||
799 | if (m_inventoryFileName == String.Empty || | 995 | if (m_inventoryFileName == String.Empty || |
800 | m_inventoryFileNameSerial < m_inventorySerial) | 996 | m_inventoryFileNameSerial < m_inventorySerial) |
801 | { | 997 | { |
802 | // Something changed, we need to create a new file | ||
803 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 998 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
804 | m_inventoryFileNameSerial = m_inventorySerial; | 999 | m_inventoryFileNameSerial = m_inventorySerial; |
805 | 1000 | ||
806 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | 1001 | return true; |
1002 | } | ||
1003 | |||
1004 | return false; | ||
1005 | } | ||
807 | 1006 | ||
808 | lock (m_items) | 1007 | /// <summary> |
1008 | /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client | ||
1009 | /// </summary> | ||
1010 | /// <param name="xferManager"></param> | ||
1011 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | ||
1012 | { | ||
1013 | bool changed = CreateInventoryFileName(); | ||
1014 | |||
1015 | bool includeAssets = false; | ||
1016 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) | ||
1017 | includeAssets = true; | ||
1018 | |||
1019 | if (m_inventoryPrivileged != includeAssets) | ||
1020 | changed = true; | ||
1021 | |||
1022 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
1023 | |||
1024 | Items.LockItemsForRead(true); | ||
1025 | |||
1026 | if (m_inventorySerial == 0) // No inventory | ||
1027 | { | ||
1028 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1029 | Items.LockItemsForRead(false); | ||
1030 | return; | ||
1031 | } | ||
1032 | |||
1033 | if (m_items.Count == 0) // No inventory | ||
1034 | { | ||
1035 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1036 | Items.LockItemsForRead(false); | ||
1037 | return; | ||
1038 | } | ||
1039 | |||
1040 | if (!changed) | ||
1041 | { | ||
1042 | if (m_inventoryFileData.Length > 2) | ||
809 | { | 1043 | { |
810 | foreach (TaskInventoryItem item in m_items.Values) | 1044 | xferManager.AddNewFile(m_inventoryFileName, |
811 | { | 1045 | m_inventoryFileData); |
812 | // m_log.DebugFormat( | 1046 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
813 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | 1047 | Util.StringToBytes256(m_inventoryFileName)); |
814 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
815 | 1048 | ||
816 | UUID ownerID = item.OwnerID; | 1049 | Items.LockItemsForRead(false); |
817 | uint everyoneMask = 0; | 1050 | return; |
818 | uint baseMask = item.BasePermissions; | 1051 | } |
819 | uint ownerMask = item.CurrentPermissions; | 1052 | } |
820 | uint groupMask = item.GroupPermissions; | ||
821 | 1053 | ||
822 | invString.AddItemStart(); | 1054 | m_inventoryPrivileged = includeAssets; |
823 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
824 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
825 | 1055 | ||
826 | invString.AddPermissionsStart(); | 1056 | foreach (TaskInventoryItem item in m_items.Values) |
1057 | { | ||
1058 | UUID ownerID = item.OwnerID; | ||
1059 | uint everyoneMask = 0; | ||
1060 | uint baseMask = item.BasePermissions; | ||
1061 | uint ownerMask = item.CurrentPermissions; | ||
1062 | uint groupMask = item.GroupPermissions; | ||
827 | 1063 | ||
828 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | 1064 | invString.AddItemStart(); |
829 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | 1065 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); |
830 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | 1066 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); |
831 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
832 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
833 | 1067 | ||
834 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | 1068 | invString.AddPermissionsStart(); |
835 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
836 | 1069 | ||
837 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | 1070 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); |
1071 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1072 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1073 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1074 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
838 | 1075 | ||
839 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | 1076 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); |
840 | invString.AddSectionEnd(); | 1077 | invString.AddNameValueLine("owner_id", ownerID.ToString()); |
841 | 1078 | ||
842 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | 1079 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); |
843 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
844 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
845 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
846 | 1080 | ||
847 | invString.AddSaleStart(); | 1081 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); |
848 | invString.AddNameValueLine("sale_type", "not"); | 1082 | invString.AddSectionEnd(); |
849 | invString.AddNameValueLine("sale_price", "0"); | ||
850 | invString.AddSectionEnd(); | ||
851 | 1083 | ||
852 | invString.AddNameValueLine("name", item.Name + "|"); | 1084 | if (includeAssets) |
853 | invString.AddNameValueLine("desc", item.Description + "|"); | 1085 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); |
1086 | else | ||
1087 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1088 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
1089 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
1090 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
854 | 1091 | ||
855 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | 1092 | invString.AddSaleStart(); |
856 | invString.AddSectionEnd(); | 1093 | invString.AddNameValueLine("sale_type", "not"); |
857 | } | 1094 | invString.AddNameValueLine("sale_price", "0"); |
858 | } | 1095 | invString.AddSectionEnd(); |
859 | 1096 | ||
860 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | 1097 | invString.AddNameValueLine("name", item.Name + "|"); |
1098 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
861 | 1099 | ||
862 | return true; | 1100 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); |
1101 | invString.AddSectionEnd(); | ||
863 | } | 1102 | } |
864 | 1103 | ||
865 | // No need to recreate, the existing file is fine | 1104 | Items.LockItemsForRead(false); |
866 | return false; | ||
867 | } | ||
868 | |||
869 | /// <summary> | ||
870 | /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client | ||
871 | /// </summary> | ||
872 | /// <param name="xferManager"></param> | ||
873 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | ||
874 | { | ||
875 | lock (m_items) | ||
876 | { | ||
877 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing | ||
878 | // a new script if any previous deletion has left the prim inventory empty. | ||
879 | if (m_items.Count == 0) // No inventory | ||
880 | { | ||
881 | // m_log.DebugFormat( | ||
882 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", | ||
883 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); | ||
884 | 1105 | ||
885 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1106 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); |
886 | return; | ||
887 | } | ||
888 | 1107 | ||
889 | CreateInventoryFile(); | 1108 | if (m_inventoryFileData.Length > 2) |
890 | 1109 | { | |
891 | // In principle, we should only do the rest if the inventory changed; | 1110 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); |
892 | // by sending m_inventorySerial to the client, it ought to know | 1111 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
893 | // that nothing changed and that it doesn't need to request the file. | 1112 | Util.StringToBytes256(m_inventoryFileName)); |
894 | // Unfortunately, it doesn't look like the client optimizes this; | 1113 | return; |
895 | // the client seems to always come back and request the Xfer, | ||
896 | // no matter what value m_inventorySerial has. | ||
897 | // FIXME: Could probably be > 0 here rather than > 2 | ||
898 | if (m_inventoryFileData.Length > 2) | ||
899 | { | ||
900 | // Add the file for Xfer | ||
901 | // m_log.DebugFormat( | ||
902 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | ||
903 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | ||
904 | |||
905 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
906 | } | ||
907 | |||
908 | // Tell the client we're ready to Xfer the file | ||
909 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
910 | Util.StringToBytes256(m_inventoryFileName)); | ||
911 | } | 1114 | } |
1115 | |||
1116 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
912 | } | 1117 | } |
913 | 1118 | ||
914 | /// <summary> | 1119 | /// <summary> |
@@ -917,13 +1122,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
917 | /// <param name="datastore"></param> | 1122 | /// <param name="datastore"></param> |
918 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1123 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
919 | { | 1124 | { |
920 | if (HasInventoryChanged) | 1125 | // Removed this because linking will cause an immediate delete of the new |
921 | { | 1126 | // child prim from the database and the subsequent storing of the prim sees |
922 | HasInventoryChanged = false; | 1127 | // the inventory of it as unchanged and doesn't store it at all. The overhead |
923 | List<TaskInventoryItem> items = GetInventoryItems(); | 1128 | // of storing prim inventory needlessly is much less than the aggravation |
924 | datastore.StorePrimInventory(m_part.UUID, items); | 1129 | // of prim inventory loss. |
1130 | // if (HasInventoryChanged) | ||
1131 | // { | ||
1132 | Items.LockItemsForRead(true); | ||
1133 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | ||
1134 | Items.LockItemsForRead(false); | ||
925 | 1135 | ||
926 | } | 1136 | HasInventoryChanged = false; |
1137 | // } | ||
927 | } | 1138 | } |
928 | 1139 | ||
929 | public class InventoryStringBuilder | 1140 | public class InventoryStringBuilder |
@@ -989,87 +1200,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
989 | { | 1200 | { |
990 | uint mask=0x7fffffff; | 1201 | uint mask=0x7fffffff; |
991 | 1202 | ||
992 | lock (m_items) | 1203 | foreach (TaskInventoryItem item in m_items.Values) |
993 | { | 1204 | { |
994 | foreach (TaskInventoryItem item in m_items.Values) | 1205 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1206 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1207 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1208 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1209 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1210 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1211 | |||
1212 | if (item.InvType == (int)InventoryType.Object) | ||
995 | { | 1213 | { |
996 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1214 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
997 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1215 | mask &= ~((uint)PermissionMask.Copy >> 13); |
998 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1216 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
999 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1217 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
1000 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1218 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1001 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1219 | mask &= ~((uint)PermissionMask.Modify >> 13); |
1002 | |||
1003 | if (item.InvType != (int)InventoryType.Object) | ||
1004 | { | ||
1005 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
1006 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1007 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1008 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1009 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1010 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1011 | } | ||
1012 | else | ||
1013 | { | ||
1014 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1015 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1016 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1017 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1018 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1019 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1020 | } | ||
1021 | |||
1022 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1023 | mask &= ~(uint)PermissionMask.Copy; | ||
1024 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1025 | mask &= ~(uint)PermissionMask.Transfer; | ||
1026 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1027 | mask &= ~(uint)PermissionMask.Modify; | ||
1028 | } | 1220 | } |
1221 | |||
1222 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1223 | mask &= ~(uint)PermissionMask.Copy; | ||
1224 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1225 | mask &= ~(uint)PermissionMask.Transfer; | ||
1226 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1227 | mask &= ~(uint)PermissionMask.Modify; | ||
1029 | } | 1228 | } |
1030 | |||
1031 | return mask; | 1229 | return mask; |
1032 | } | 1230 | } |
1033 | 1231 | ||
1034 | public void ApplyNextOwnerPermissions() | 1232 | public void ApplyNextOwnerPermissions() |
1035 | { | 1233 | { |
1036 | lock (m_items) | 1234 | foreach (TaskInventoryItem item in m_items.Values) |
1037 | { | 1235 | { |
1038 | foreach (TaskInventoryItem item in m_items.Values) | 1236 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1039 | { | 1237 | { |
1040 | // m_log.DebugFormat ( | 1238 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1041 | // "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", | 1239 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1042 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1240 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1043 | 1241 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | |
1044 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1242 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1045 | { | 1243 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1046 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1047 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
1048 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1049 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
1050 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1051 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1052 | } | ||
1053 | |||
1054 | item.CurrentPermissions &= item.NextPermissions; | ||
1055 | item.BasePermissions &= item.NextPermissions; | ||
1056 | item.EveryonePermissions &= item.NextPermissions; | ||
1057 | item.OwnerChanged = true; | ||
1058 | item.PermsMask = 0; | ||
1059 | item.PermsGranter = UUID.Zero; | ||
1060 | } | 1244 | } |
1245 | item.CurrentPermissions &= item.NextPermissions; | ||
1246 | item.BasePermissions &= item.NextPermissions; | ||
1247 | item.EveryonePermissions &= item.NextPermissions; | ||
1248 | item.OwnerChanged = true; | ||
1249 | item.PermsMask = 0; | ||
1250 | item.PermsGranter = UUID.Zero; | ||
1061 | } | 1251 | } |
1062 | } | 1252 | } |
1063 | 1253 | ||
1064 | public void ApplyGodPermissions(uint perms) | 1254 | public void ApplyGodPermissions(uint perms) |
1065 | { | 1255 | { |
1066 | lock (m_items) | 1256 | foreach (TaskInventoryItem item in m_items.Values) |
1067 | { | 1257 | { |
1068 | foreach (TaskInventoryItem item in m_items.Values) | 1258 | item.CurrentPermissions = perms; |
1069 | { | 1259 | item.BasePermissions = perms; |
1070 | item.CurrentPermissions = perms; | ||
1071 | item.BasePermissions = perms; | ||
1072 | } | ||
1073 | } | 1260 | } |
1074 | 1261 | ||
1075 | m_inventorySerial++; | 1262 | m_inventorySerial++; |
@@ -1082,14 +1269,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1082 | /// <returns></returns> | 1269 | /// <returns></returns> |
1083 | public bool ContainsScripts() | 1270 | public bool ContainsScripts() |
1084 | { | 1271 | { |
1085 | lock (m_items) | 1272 | foreach (TaskInventoryItem item in m_items.Values) |
1086 | { | 1273 | { |
1087 | foreach (TaskInventoryItem item in m_items.Values) | 1274 | if (item.InvType == (int)InventoryType.LSL) |
1088 | { | 1275 | { |
1089 | if (item.InvType == (int)InventoryType.LSL) | 1276 | return true; |
1090 | { | ||
1091 | return true; | ||
1092 | } | ||
1093 | } | 1277 | } |
1094 | } | 1278 | } |
1095 | 1279 | ||
@@ -1103,17 +1287,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1103 | public int ScriptCount() | 1287 | public int ScriptCount() |
1104 | { | 1288 | { |
1105 | int count = 0; | 1289 | int count = 0; |
1106 | lock (m_items) | 1290 | Items.LockItemsForRead(true); |
1291 | foreach (TaskInventoryItem item in m_items.Values) | ||
1107 | { | 1292 | { |
1108 | foreach (TaskInventoryItem item in m_items.Values) | 1293 | if (item.InvType == (int)InventoryType.LSL) |
1109 | { | 1294 | { |
1110 | if (item.InvType == (int)InventoryType.LSL) | 1295 | count++; |
1111 | { | ||
1112 | count++; | ||
1113 | } | ||
1114 | } | 1296 | } |
1115 | } | 1297 | } |
1116 | 1298 | Items.LockItemsForRead(false); | |
1117 | return count; | 1299 | return count; |
1118 | } | 1300 | } |
1119 | /// <summary> | 1301 | /// <summary> |
@@ -1149,11 +1331,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1149 | { | 1331 | { |
1150 | List<UUID> ret = new List<UUID>(); | 1332 | List<UUID> ret = new List<UUID>(); |
1151 | 1333 | ||
1152 | lock (m_items) | 1334 | foreach (TaskInventoryItem item in m_items.Values) |
1153 | { | 1335 | ret.Add(item.ItemID); |
1154 | foreach (TaskInventoryItem item in m_items.Values) | ||
1155 | ret.Add(item.ItemID); | ||
1156 | } | ||
1157 | 1336 | ||
1158 | return ret; | 1337 | return ret; |
1159 | } | 1338 | } |
@@ -1162,8 +1341,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1162 | { | 1341 | { |
1163 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1342 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1164 | 1343 | ||
1165 | lock (m_items) | 1344 | Items.LockItemsForRead(true); |
1166 | ret = new List<TaskInventoryItem>(m_items.Values); | 1345 | ret = new List<TaskInventoryItem>(m_items.Values); |
1346 | Items.LockItemsForRead(false); | ||
1167 | 1347 | ||
1168 | return ret; | 1348 | return ret; |
1169 | } | 1349 | } |
@@ -1172,18 +1352,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1172 | { | 1352 | { |
1173 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1353 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1174 | 1354 | ||
1175 | lock (m_items) | 1355 | Items.LockItemsForRead(true); |
1176 | { | 1356 | |
1177 | foreach (TaskInventoryItem item in m_items.Values) | 1357 | foreach (TaskInventoryItem item in m_items.Values) |
1178 | if (item.InvType == (int)type) | 1358 | if (item.InvType == (int)type) |
1179 | ret.Add(item); | 1359 | ret.Add(item); |
1180 | } | 1360 | |
1361 | Items.LockItemsForRead(false); | ||
1181 | 1362 | ||
1182 | return ret; | 1363 | return ret; |
1183 | } | 1364 | } |
1184 | 1365 | ||
1185 | public Dictionary<UUID, string> GetScriptStates() | 1366 | public Dictionary<UUID, string> GetScriptStates() |
1186 | { | 1367 | { |
1368 | return GetScriptStates(false); | ||
1369 | } | ||
1370 | |||
1371 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1372 | { | ||
1187 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1373 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1188 | 1374 | ||
1189 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1375 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1205,14 +1391,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1205 | string n = e.GetXMLState(item.ItemID); | 1391 | string n = e.GetXMLState(item.ItemID); |
1206 | if (n != String.Empty) | 1392 | if (n != String.Empty) |
1207 | { | 1393 | { |
1208 | if (!ret.ContainsKey(item.ItemID)) | 1394 | if (oldIDs) |
1209 | ret[item.ItemID] = n; | 1395 | { |
1396 | if (!ret.ContainsKey(item.OldItemID)) | ||
1397 | ret[item.OldItemID] = n; | ||
1398 | } | ||
1399 | else | ||
1400 | { | ||
1401 | if (!ret.ContainsKey(item.ItemID)) | ||
1402 | ret[item.ItemID] = n; | ||
1403 | } | ||
1210 | break; | 1404 | break; |
1211 | } | 1405 | } |
1212 | } | 1406 | } |
1213 | } | 1407 | } |
1214 | } | 1408 | } |
1215 | |||
1216 | return ret; | 1409 | return ret; |
1217 | } | 1410 | } |
1218 | 1411 | ||
@@ -1245,4 +1438,4 @@ namespace OpenSim.Region.Framework.Scenes | |||
1245 | } | 1438 | } |
1246 | } | 1439 | } |
1247 | } | 1440 | } |
1248 | } \ No newline at end of file | 1441 | } |