diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 758 |
1 files changed, 488 insertions, 270 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index e40e57d..1f0840d 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 | 159 | } | |
151 | foreach (TaskInventoryItem item in items) | 160 | |
152 | { | 161 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
153 | item.ParentPartID = m_part.UUID; | 162 | Items.Clear(); |
154 | item.ParentID = m_part.UUID; | 163 | |
155 | Items.Add(item.ItemID, item); | 164 | foreach (TaskInventoryItem item in items) |
156 | } | 165 | { |
166 | item.ParentPartID = m_part.UUID; | ||
167 | item.ParentID = m_part.UUID; | ||
168 | Items.Add(item.ItemID, item); | ||
157 | } | 169 | } |
170 | m_items.LockItemsForWrite(false); | ||
158 | } | 171 | } |
159 | 172 | ||
160 | /// <summary> | 173 | /// <summary> |
@@ -163,12 +176,11 @@ 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 | m_items.LockItemsForWrite(true); |
180 | if (0 == Items.Count) | ||
167 | { | 181 | { |
168 | if (0 == Items.Count) | 182 | m_items.LockItemsForWrite(false); |
169 | { | 183 | return; |
170 | return; | ||
171 | } | ||
172 | } | 184 | } |
173 | 185 | ||
174 | HasInventoryChanged = true; | 186 | HasInventoryChanged = true; |
@@ -184,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
184 | item.PermsGranter = UUID.Zero; | 196 | item.PermsGranter = UUID.Zero; |
185 | item.OwnerChanged = true; | 197 | item.OwnerChanged = true; |
186 | } | 198 | } |
199 | m_items.LockItemsForWrite(false); | ||
187 | } | 200 | } |
188 | 201 | ||
189 | /// <summary> | 202 | /// <summary> |
@@ -192,12 +205,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
192 | /// <param name="groupID"></param> | 205 | /// <param name="groupID"></param> |
193 | public void ChangeInventoryGroup(UUID groupID) | 206 | public void ChangeInventoryGroup(UUID groupID) |
194 | { | 207 | { |
195 | lock (Items) | 208 | m_items.LockItemsForWrite(true); |
209 | if (0 == Items.Count) | ||
196 | { | 210 | { |
197 | if (0 == Items.Count) | 211 | m_items.LockItemsForWrite(false); |
198 | { | 212 | return; |
199 | return; | ||
200 | } | ||
201 | } | 213 | } |
202 | 214 | ||
203 | // Don't let this set the HasGroupChanged flag for attachments | 215 | // Don't let this set the HasGroupChanged flag for attachments |
@@ -209,12 +221,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
209 | m_part.ParentGroup.HasGroupChanged = true; | 221 | m_part.ParentGroup.HasGroupChanged = true; |
210 | } | 222 | } |
211 | 223 | ||
212 | List<TaskInventoryItem> items = GetInventoryItems(); | 224 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
213 | foreach (TaskInventoryItem item in items) | 225 | foreach (TaskInventoryItem item in items) |
214 | { | 226 | { |
215 | if (groupID != item.GroupID) | 227 | if (groupID != item.GroupID) |
228 | { | ||
216 | item.GroupID = groupID; | 229 | item.GroupID = groupID; |
230 | } | ||
217 | } | 231 | } |
232 | m_items.LockItemsForWrite(false); | ||
233 | } | ||
234 | |||
235 | private void QueryScriptStates() | ||
236 | { | ||
237 | if (m_part == null || m_part.ParentGroup == null) | ||
238 | return; | ||
239 | |||
240 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | ||
241 | if (engines == null) // No engine at all | ||
242 | return; | ||
243 | |||
244 | Items.LockItemsForRead(true); | ||
245 | foreach (TaskInventoryItem item in Items.Values) | ||
246 | { | ||
247 | if (item.InvType == (int)InventoryType.LSL) | ||
248 | { | ||
249 | foreach (IScriptModule e in engines) | ||
250 | { | ||
251 | bool running; | ||
252 | |||
253 | if (e.HasScript(item.ItemID, out running)) | ||
254 | { | ||
255 | item.ScriptRunning = running; | ||
256 | break; | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | Items.LockItemsForRead(false); | ||
218 | } | 263 | } |
219 | 264 | ||
220 | /// <summary> | 265 | /// <summary> |
@@ -222,9 +267,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
222 | /// </summary> | 267 | /// </summary> |
223 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 268 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
224 | { | 269 | { |
225 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 270 | Items.LockItemsForRead(true); |
226 | foreach (TaskInventoryItem item in scripts) | 271 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
227 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 272 | Items.LockItemsForRead(false); |
273 | foreach (TaskInventoryItem item in items) | ||
274 | { | ||
275 | if ((int)InventoryType.LSL == item.InvType) | ||
276 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | ||
277 | } | ||
228 | } | 278 | } |
229 | 279 | ||
230 | public ArrayList GetScriptErrors(UUID itemID) | 280 | public ArrayList GetScriptErrors(UUID itemID) |
@@ -257,9 +307,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
257 | /// </param> | 307 | /// </param> |
258 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 308 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
259 | { | 309 | { |
260 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 310 | Items.LockItemsForRead(true); |
261 | foreach (TaskInventoryItem item in scripts) | 311 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
262 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 312 | Items.LockItemsForRead(false); |
313 | |||
314 | foreach (TaskInventoryItem item in items) | ||
315 | { | ||
316 | if ((int)InventoryType.LSL == item.InvType) | ||
317 | { | ||
318 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | ||
319 | m_part.RemoveScriptEvents(item.ItemID); | ||
320 | } | ||
321 | } | ||
263 | } | 322 | } |
264 | 323 | ||
265 | /// <summary> | 324 | /// <summary> |
@@ -275,7 +334,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
275 | // item.Name, item.ItemID, Name, UUID); | 334 | // item.Name, item.ItemID, Name, UUID); |
276 | 335 | ||
277 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 336 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
337 | { | ||
338 | StoreScriptError(item.ItemID, "no permission"); | ||
278 | return; | 339 | return; |
340 | } | ||
279 | 341 | ||
280 | m_part.AddFlag(PrimFlags.Scripted); | 342 | m_part.AddFlag(PrimFlags.Scripted); |
281 | 343 | ||
@@ -284,14 +346,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
284 | if (stateSource == 2 && // Prim crossing | 346 | if (stateSource == 2 && // Prim crossing |
285 | m_part.ParentGroup.Scene.m_trustBinaries) | 347 | m_part.ParentGroup.Scene.m_trustBinaries) |
286 | { | 348 | { |
287 | lock (m_items) | 349 | m_items.LockItemsForWrite(true); |
288 | { | 350 | m_items[item.ItemID].PermsMask = 0; |
289 | m_items[item.ItemID].PermsMask = 0; | 351 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
290 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 352 | m_items.LockItemsForWrite(false); |
291 | } | ||
292 | |||
293 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 353 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
294 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 354 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
355 | StoreScriptErrors(item.ItemID, null); | ||
295 | m_part.ParentGroup.AddActiveScriptCount(1); | 356 | m_part.ParentGroup.AddActiveScriptCount(1); |
296 | m_part.ScheduleFullUpdate(); | 357 | m_part.ScheduleFullUpdate(); |
297 | return; | 358 | return; |
@@ -300,6 +361,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
300 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 361 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
301 | if (null == asset) | 362 | if (null == asset) |
302 | { | 363 | { |
364 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
365 | StoreScriptError(item.ItemID, msg); | ||
303 | m_log.ErrorFormat( | 366 | m_log.ErrorFormat( |
304 | "[PRIM INVENTORY]: " + | 367 | "[PRIM INVENTORY]: " + |
305 | "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 368 | "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
@@ -311,15 +374,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
311 | if (m_part.ParentGroup.m_savedScriptState != null) | 374 | if (m_part.ParentGroup.m_savedScriptState != null) |
312 | RestoreSavedScriptState(item.OldItemID, item.ItemID); | 375 | RestoreSavedScriptState(item.OldItemID, item.ItemID); |
313 | 376 | ||
314 | lock (m_items) | 377 | m_items.LockItemsForWrite(true); |
315 | { | 378 | |
316 | m_items[item.ItemID].PermsMask = 0; | 379 | m_items[item.ItemID].PermsMask = 0; |
317 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 380 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
318 | } | 381 | |
382 | m_items.LockItemsForWrite(false); | ||
319 | 383 | ||
320 | string script = Utils.BytesToString(asset.Data); | 384 | string script = Utils.BytesToString(asset.Data); |
321 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 385 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
322 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 386 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
387 | StoreScriptErrors(item.ItemID, null); | ||
388 | if (!item.ScriptRunning) | ||
389 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | ||
390 | m_part.LocalId, item.ItemID); | ||
323 | m_part.ParentGroup.AddActiveScriptCount(1); | 391 | m_part.ParentGroup.AddActiveScriptCount(1); |
324 | m_part.ScheduleFullUpdate(); | 392 | m_part.ScheduleFullUpdate(); |
325 | } | 393 | } |
@@ -383,21 +451,145 @@ namespace OpenSim.Region.Framework.Scenes | |||
383 | 451 | ||
384 | /// <summary> | 452 | /// <summary> |
385 | /// Start a script which is in this prim's inventory. | 453 | /// Start a script which is in this prim's inventory. |
454 | /// Some processing may occur in the background, but this routine returns asap. | ||
386 | /// </summary> | 455 | /// </summary> |
387 | /// <param name="itemId"> | 456 | /// <param name="itemId"> |
388 | /// A <see cref="UUID"/> | 457 | /// A <see cref="UUID"/> |
389 | /// </param> | 458 | /// </param> |
390 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 459 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
391 | { | 460 | { |
392 | TaskInventoryItem item = GetInventoryItem(itemId); | 461 | lock (m_scriptErrors) |
393 | if (item != null) | 462 | { |
394 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 463 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
464 | m_scriptErrors.Remove(itemId); | ||
465 | } | ||
466 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
467 | } | ||
468 | |||
469 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
470 | { | ||
471 | m_items.LockItemsForRead(true); | ||
472 | if (m_items.ContainsKey(itemId)) | ||
473 | { | ||
474 | if (m_items.ContainsKey(itemId)) | ||
475 | { | ||
476 | m_items.LockItemsForRead(false); | ||
477 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
478 | } | ||
479 | else | ||
480 | { | ||
481 | m_items.LockItemsForRead(false); | ||
482 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
483 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
484 | StoreScriptError(itemId, msg); | ||
485 | m_log.ErrorFormat( | ||
486 | "[PRIM INVENTORY]: " + | ||
487 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
488 | } | ||
489 | } | ||
395 | else | 490 | else |
491 | { | ||
492 | m_items.LockItemsForRead(false); | ||
493 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
494 | StoreScriptError(itemId, msg); | ||
396 | m_log.ErrorFormat( | 495 | m_log.ErrorFormat( |
397 | "[PRIM INVENTORY]: " + | 496 | "[PRIM INVENTORY]: " + |
398 | "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 497 | "Couldn't start script with ID {0} since it {1}", itemId, msg); |
399 | itemId, m_part.Name, m_part.UUID, | 498 | } |
400 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 499 | |
500 | } | ||
501 | |||
502 | /// <summary> | ||
503 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
504 | /// </summary> | ||
505 | /// <param name="itemId"> | ||
506 | /// A <see cref="UUID"/> | ||
507 | /// </param> | ||
508 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
509 | { | ||
510 | ArrayList errors; | ||
511 | |||
512 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
513 | // post any compilation/loading error messages | ||
514 | lock (m_scriptErrors) | ||
515 | { | ||
516 | m_scriptErrors[itemId] = null; | ||
517 | } | ||
518 | |||
519 | // Perform compilation/loading | ||
520 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
521 | |||
522 | // Wait for and retrieve any errors | ||
523 | lock (m_scriptErrors) | ||
524 | { | ||
525 | while ((errors = m_scriptErrors[itemId]) == null) | ||
526 | { | ||
527 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
528 | { | ||
529 | m_log.ErrorFormat( | ||
530 | "[PRIM INVENTORY]: " + | ||
531 | "timedout waiting for script {0} errors", itemId); | ||
532 | errors = m_scriptErrors[itemId]; | ||
533 | if (errors == null) | ||
534 | { | ||
535 | errors = new ArrayList(1); | ||
536 | errors.Add("timedout waiting for errors"); | ||
537 | } | ||
538 | break; | ||
539 | } | ||
540 | } | ||
541 | m_scriptErrors.Remove(itemId); | ||
542 | } | ||
543 | return errors; | ||
544 | } | ||
545 | |||
546 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
547 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
548 | { | ||
549 | lock (m_scriptErrors) | ||
550 | { | ||
551 | // If compilation/loading initiated via CreateScriptInstance(), | ||
552 | // it does not want the errors, so just get out | ||
553 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
554 | { | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
559 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
560 | if (errors != null) | ||
561 | { | ||
562 | m_scriptErrors[itemId] = errors; | ||
563 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
564 | return; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
569 | // the errors are yet, so retrieve them from the script engine. | ||
570 | // This may involve some waiting internal to GetScriptErrors(). | ||
571 | errors = GetScriptErrors(itemId); | ||
572 | |||
573 | // Get a default non-null value to indicate success. | ||
574 | if (errors == null) | ||
575 | { | ||
576 | errors = new ArrayList(); | ||
577 | } | ||
578 | |||
579 | // Post to CreateScriptInstanceEr() and wake it up | ||
580 | lock (m_scriptErrors) | ||
581 | { | ||
582 | m_scriptErrors[itemId] = errors; | ||
583 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
584 | } | ||
585 | } | ||
586 | |||
587 | // Like StoreScriptErrors(), but just posts a single string message | ||
588 | private void StoreScriptError(UUID itemId, string message) | ||
589 | { | ||
590 | ArrayList errors = new ArrayList(1); | ||
591 | errors.Add(message); | ||
592 | StoreScriptErrors(itemId, errors); | ||
401 | } | 593 | } |
402 | 594 | ||
403 | /// <summary> | 595 | /// <summary> |
@@ -410,15 +602,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
410 | /// </param> | 602 | /// </param> |
411 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 603 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
412 | { | 604 | { |
413 | bool scriptPresent = false; | 605 | if (m_items.ContainsKey(itemId)) |
414 | |||
415 | lock (m_items) | ||
416 | { | ||
417 | if (m_items.ContainsKey(itemId)) | ||
418 | scriptPresent = true; | ||
419 | } | ||
420 | |||
421 | if (scriptPresent) | ||
422 | { | 606 | { |
423 | if (!sceneObjectBeingDeleted) | 607 | if (!sceneObjectBeingDeleted) |
424 | m_part.RemoveScriptEvents(itemId); | 608 | m_part.RemoveScriptEvents(itemId); |
@@ -443,14 +627,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
443 | /// <returns></returns> | 627 | /// <returns></returns> |
444 | private bool InventoryContainsName(string name) | 628 | private bool InventoryContainsName(string name) |
445 | { | 629 | { |
446 | lock (m_items) | 630 | m_items.LockItemsForRead(true); |
631 | foreach (TaskInventoryItem item in m_items.Values) | ||
447 | { | 632 | { |
448 | foreach (TaskInventoryItem item in m_items.Values) | 633 | if (item.Name == name) |
449 | { | 634 | { |
450 | if (item.Name == name) | 635 | m_items.LockItemsForRead(false); |
451 | return true; | 636 | return true; |
452 | } | 637 | } |
453 | } | 638 | } |
639 | m_items.LockItemsForRead(false); | ||
454 | return false; | 640 | return false; |
455 | } | 641 | } |
456 | 642 | ||
@@ -492,8 +678,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
492 | /// <param name="item"></param> | 678 | /// <param name="item"></param> |
493 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 679 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
494 | { | 680 | { |
495 | List<TaskInventoryItem> il = GetInventoryItems(); | 681 | m_items.LockItemsForRead(true); |
496 | 682 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
683 | m_items.LockItemsForRead(false); | ||
497 | foreach (TaskInventoryItem i in il) | 684 | foreach (TaskInventoryItem i in il) |
498 | { | 685 | { |
499 | if (i.Name == item.Name) | 686 | if (i.Name == item.Name) |
@@ -531,14 +718,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
531 | item.Name = name; | 718 | item.Name = name; |
532 | item.GroupID = m_part.GroupID; | 719 | item.GroupID = m_part.GroupID; |
533 | 720 | ||
534 | lock (m_items) | 721 | m_items.LockItemsForWrite(true); |
535 | m_items.Add(item.ItemID, item); | 722 | m_items.Add(item.ItemID, item); |
536 | 723 | m_items.LockItemsForWrite(false); | |
537 | if (allowedDrop) | 724 | if (allowedDrop) |
538 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 725 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
539 | else | 726 | else |
540 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 727 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
541 | 728 | ||
542 | m_inventorySerial++; | 729 | m_inventorySerial++; |
543 | //m_inventorySerial += 2; | 730 | //m_inventorySerial += 2; |
544 | HasInventoryChanged = true; | 731 | HasInventoryChanged = true; |
@@ -554,15 +741,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
554 | /// <param name="items"></param> | 741 | /// <param name="items"></param> |
555 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 742 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
556 | { | 743 | { |
557 | lock (m_items) | 744 | m_items.LockItemsForWrite(true); |
745 | foreach (TaskInventoryItem item in items) | ||
558 | { | 746 | { |
559 | foreach (TaskInventoryItem item in items) | 747 | m_items.Add(item.ItemID, item); |
560 | { | 748 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
561 | m_items.Add(item.ItemID, item); | ||
562 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
563 | } | ||
564 | m_inventorySerial++; | ||
565 | } | 749 | } |
750 | m_items.LockItemsForWrite(false); | ||
751 | |||
752 | m_inventorySerial++; | ||
566 | } | 753 | } |
567 | 754 | ||
568 | /// <summary> | 755 | /// <summary> |
@@ -573,10 +760,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
573 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 760 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
574 | { | 761 | { |
575 | TaskInventoryItem item; | 762 | TaskInventoryItem item; |
576 | 763 | m_items.LockItemsForRead(true); | |
577 | lock (m_items) | 764 | m_items.TryGetValue(itemId, out item); |
578 | m_items.TryGetValue(itemId, out item); | 765 | m_items.LockItemsForRead(false); |
579 | |||
580 | return item; | 766 | return item; |
581 | } | 767 | } |
582 | 768 | ||
@@ -592,15 +778,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
592 | { | 778 | { |
593 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 779 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
594 | 780 | ||
595 | lock (m_items) | 781 | m_items.LockItemsForRead(true); |
782 | |||
783 | foreach (TaskInventoryItem item in m_items.Values) | ||
596 | { | 784 | { |
597 | foreach (TaskInventoryItem item in m_items.Values) | 785 | if (item.Name == name) |
598 | { | 786 | items.Add(item); |
599 | if (item.Name == name) | ||
600 | items.Add(item); | ||
601 | } | ||
602 | } | 787 | } |
603 | 788 | ||
789 | m_items.LockItemsForRead(false); | ||
790 | |||
604 | return items; | 791 | return items; |
605 | } | 792 | } |
606 | 793 | ||
@@ -619,6 +806,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
619 | string xmlData = Utils.BytesToString(rezAsset.Data); | 806 | string xmlData = Utils.BytesToString(rezAsset.Data); |
620 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 807 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
621 | 808 | ||
809 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
810 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
811 | |||
622 | group.ResetIDs(); | 812 | group.ResetIDs(); |
623 | 813 | ||
624 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); | 814 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); |
@@ -693,8 +883,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
693 | 883 | ||
694 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 884 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
695 | { | 885 | { |
696 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 886 | m_items.LockItemsForWrite(true); |
697 | if (it != null) | 887 | |
888 | if (m_items.ContainsKey(item.ItemID)) | ||
698 | { | 889 | { |
699 | // 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); |
700 | 891 | ||
@@ -707,14 +898,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
707 | item.GroupID = m_part.GroupID; | 898 | item.GroupID = m_part.GroupID; |
708 | 899 | ||
709 | if (item.AssetID == UUID.Zero) | 900 | if (item.AssetID == UUID.Zero) |
710 | item.AssetID = it.AssetID; | 901 | item.AssetID = m_items[item.ItemID].AssetID; |
711 | 902 | ||
712 | lock (m_items) | 903 | m_items[item.ItemID] = item; |
713 | { | 904 | m_inventorySerial++; |
714 | m_items[item.ItemID] = item; | ||
715 | m_inventorySerial++; | ||
716 | } | ||
717 | |||
718 | if (fireScriptEvents) | 905 | if (fireScriptEvents) |
719 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 906 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
720 | 907 | ||
@@ -723,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
723 | HasInventoryChanged = true; | 910 | HasInventoryChanged = true; |
724 | m_part.ParentGroup.HasGroupChanged = true; | 911 | m_part.ParentGroup.HasGroupChanged = true; |
725 | } | 912 | } |
726 | 913 | m_items.LockItemsForWrite(false); | |
727 | return true; | 914 | return true; |
728 | } | 915 | } |
729 | else | 916 | else |
@@ -734,8 +921,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
734 | item.ItemID, m_part.Name, m_part.UUID, | 921 | item.ItemID, m_part.Name, m_part.UUID, |
735 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 922 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
736 | } | 923 | } |
737 | return false; | 924 | m_items.LockItemsForWrite(false); |
738 | 925 | ||
926 | return false; | ||
739 | } | 927 | } |
740 | 928 | ||
741 | /// <summary> | 929 | /// <summary> |
@@ -746,107 +934,68 @@ namespace OpenSim.Region.Framework.Scenes | |||
746 | /// in this prim's inventory.</returns> | 934 | /// in this prim's inventory.</returns> |
747 | public int RemoveInventoryItem(UUID itemID) | 935 | public int RemoveInventoryItem(UUID itemID) |
748 | { | 936 | { |
749 | TaskInventoryItem item = GetInventoryItem(itemID); | 937 | m_items.LockItemsForRead(true); |
750 | if (item != null) | 938 | |
939 | if (m_items.ContainsKey(itemID)) | ||
751 | { | 940 | { |
752 | int type = m_items[itemID].InvType; | 941 | int type = m_items[itemID].InvType; |
942 | m_items.LockItemsForRead(false); | ||
753 | if (type == 10) // Script | 943 | if (type == 10) // Script |
754 | { | 944 | { |
755 | m_part.RemoveScriptEvents(itemID); | ||
756 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 945 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
757 | } | 946 | } |
947 | m_items.LockItemsForWrite(true); | ||
758 | m_items.Remove(itemID); | 948 | m_items.Remove(itemID); |
949 | m_items.LockItemsForWrite(false); | ||
759 | m_inventorySerial++; | 950 | m_inventorySerial++; |
760 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 951 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
761 | 952 | ||
762 | HasInventoryChanged = true; | 953 | HasInventoryChanged = true; |
763 | m_part.ParentGroup.HasGroupChanged = true; | 954 | m_part.ParentGroup.HasGroupChanged = true; |
764 | 955 | ||
765 | 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 | { | ||
766 | m_part.RemFlag(PrimFlags.Scripted); | 970 | m_part.RemFlag(PrimFlags.Scripted); |
971 | } | ||
767 | 972 | ||
768 | m_part.ScheduleFullUpdate(); | 973 | m_part.ScheduleFullUpdate(); |
769 | 974 | ||
770 | return type; | 975 | return type; |
771 | |||
772 | } | 976 | } |
773 | else | 977 | else |
774 | { | 978 | { |
979 | m_items.LockItemsForRead(false); | ||
775 | m_log.ErrorFormat( | 980 | m_log.ErrorFormat( |
776 | "[PRIM INVENTORY]: " + | 981 | "[PRIM INVENTORY]: " + |
777 | "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", |
778 | itemID, m_part.Name, m_part.UUID, | 983 | itemID, m_part.Name, m_part.UUID); |
779 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
780 | } | 984 | } |
781 | 985 | ||
782 | return -1; | 986 | return -1; |
783 | } | 987 | } |
784 | 988 | ||
785 | private bool CreateInventoryFile() | 989 | private bool CreateInventoryFileName() |
786 | { | 990 | { |
787 | if (m_inventoryFileName == String.Empty || | 991 | if (m_inventoryFileName == String.Empty || |
788 | m_inventoryFileNameSerial < m_inventorySerial) | 992 | m_inventoryFileNameSerial < m_inventorySerial) |
789 | { | 993 | { |
790 | // Something changed, we need to create a new file | ||
791 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 994 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
792 | m_inventoryFileNameSerial = m_inventorySerial; | 995 | m_inventoryFileNameSerial = m_inventorySerial; |
793 | |||
794 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
795 | |||
796 | lock (m_items) | ||
797 | { | ||
798 | foreach (TaskInventoryItem item in m_items.Values) | ||
799 | { | ||
800 | UUID ownerID = item.OwnerID; | ||
801 | uint everyoneMask = 0; | ||
802 | uint baseMask = item.BasePermissions; | ||
803 | uint ownerMask = item.CurrentPermissions; | ||
804 | uint groupMask = item.GroupPermissions; | ||
805 | |||
806 | invString.AddItemStart(); | ||
807 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
808 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
809 | |||
810 | invString.AddPermissionsStart(); | ||
811 | |||
812 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
813 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
814 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
815 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
816 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
817 | |||
818 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
819 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
820 | |||
821 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
822 | |||
823 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
824 | invString.AddSectionEnd(); | ||
825 | |||
826 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
827 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
828 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
829 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
830 | |||
831 | invString.AddSaleStart(); | ||
832 | invString.AddNameValueLine("sale_type", "not"); | ||
833 | invString.AddNameValueLine("sale_price", "0"); | ||
834 | invString.AddSectionEnd(); | ||
835 | |||
836 | invString.AddNameValueLine("name", item.Name + "|"); | ||
837 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
838 | |||
839 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
840 | invString.AddSectionEnd(); | ||
841 | } | ||
842 | } | ||
843 | |||
844 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
845 | |||
846 | return true; | 996 | return true; |
847 | } | 997 | } |
848 | 998 | ||
849 | // No need to recreate, the existing file is fine | ||
850 | return false; | 999 | return false; |
851 | } | 1000 | } |
852 | 1001 | ||
@@ -856,26 +1005,99 @@ namespace OpenSim.Region.Framework.Scenes | |||
856 | /// <param name="xferManager"></param> | 1005 | /// <param name="xferManager"></param> |
857 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1006 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
858 | { | 1007 | { |
859 | CreateInventoryFile(); | 1008 | bool changed = CreateInventoryFileName(); |
1009 | |||
1010 | bool includeAssets = false; | ||
1011 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) | ||
1012 | includeAssets = true; | ||
1013 | |||
1014 | if (m_inventoryPrivileged != includeAssets) | ||
1015 | changed = true; | ||
1016 | |||
1017 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
1018 | |||
1019 | Items.LockItemsForRead(true); | ||
860 | 1020 | ||
861 | if (m_inventorySerial == 0) // No inventory | 1021 | if (m_inventorySerial == 0) // No inventory |
862 | { | 1022 | { |
863 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1023 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
1024 | Items.LockItemsForRead(false); | ||
864 | return; | 1025 | return; |
865 | } | 1026 | } |
866 | 1027 | ||
867 | // In principle, we should only do the rest if the inventory changed; | 1028 | if (!changed) |
868 | // by sending m_inventorySerial to the client, it ought to know | 1029 | { |
869 | // that nothing changed and that it doesn't need to request the file. | 1030 | if (m_inventoryFileData.Length > 2) |
870 | // Unfortunately, it doesn't look like the client optimizes this; | 1031 | { |
871 | // the client seems to always come back and request the Xfer, | 1032 | xferManager.AddNewFile(m_inventoryFileName, |
872 | // no matter what value m_inventorySerial has. | 1033 | m_inventoryFileData); |
1034 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1035 | Util.StringToBytes256(m_inventoryFileName)); | ||
1036 | |||
1037 | Items.LockItemsForRead(false); | ||
1038 | return; | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | m_inventoryPrivileged = includeAssets; | ||
1043 | |||
1044 | foreach (TaskInventoryItem item in m_items.Values) | ||
1045 | { | ||
1046 | UUID ownerID = item.OwnerID; | ||
1047 | uint everyoneMask = 0; | ||
1048 | uint baseMask = item.BasePermissions; | ||
1049 | uint ownerMask = item.CurrentPermissions; | ||
1050 | uint groupMask = item.GroupPermissions; | ||
1051 | |||
1052 | invString.AddItemStart(); | ||
1053 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
1054 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
1055 | |||
1056 | invString.AddPermissionsStart(); | ||
1057 | |||
1058 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
1059 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1060 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1061 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1062 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1063 | |||
1064 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1065 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1066 | |||
1067 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1068 | |||
1069 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1070 | invString.AddSectionEnd(); | ||
1071 | |||
1072 | if (includeAssets) | ||
1073 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1074 | else | ||
1075 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1076 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
1077 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
1078 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1079 | |||
1080 | invString.AddSaleStart(); | ||
1081 | invString.AddNameValueLine("sale_type", "not"); | ||
1082 | invString.AddNameValueLine("sale_price", "0"); | ||
1083 | invString.AddSectionEnd(); | ||
1084 | |||
1085 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1086 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1087 | |||
1088 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1089 | invString.AddSectionEnd(); | ||
1090 | } | ||
1091 | |||
1092 | Items.LockItemsForRead(false); | ||
1093 | |||
1094 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
873 | 1095 | ||
874 | if (m_inventoryFileData.Length > 2) | 1096 | if (m_inventoryFileData.Length > 2) |
875 | // Add the file for Xfer | 1097 | { |
876 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1098 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); |
1099 | } | ||
877 | 1100 | ||
878 | // Tell the client we're ready to Xfer the file | ||
879 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | 1101 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
880 | Util.StringToBytes256(m_inventoryFileName)); | 1102 | Util.StringToBytes256(m_inventoryFileName)); |
881 | } | 1103 | } |
@@ -888,10 +1110,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
888 | { | 1110 | { |
889 | if (HasInventoryChanged) | 1111 | if (HasInventoryChanged) |
890 | { | 1112 | { |
891 | HasInventoryChanged = false; | 1113 | Items.LockItemsForRead(true); |
892 | List<TaskInventoryItem> items = GetInventoryItems(); | 1114 | datastore.StorePrimInventory(m_part.UUID, Items.Values); |
893 | datastore.StorePrimInventory(m_part.UUID, items); | 1115 | Items.LockItemsForRead(false); |
894 | 1116 | ||
1117 | HasInventoryChanged = false; | ||
895 | } | 1118 | } |
896 | } | 1119 | } |
897 | 1120 | ||
@@ -958,82 +1181,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
958 | { | 1181 | { |
959 | uint mask=0x7fffffff; | 1182 | uint mask=0x7fffffff; |
960 | 1183 | ||
961 | lock (m_items) | 1184 | foreach (TaskInventoryItem item in m_items.Values) |
962 | { | 1185 | { |
963 | foreach (TaskInventoryItem item in m_items.Values) | 1186 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1187 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1188 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1189 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1190 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1191 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1192 | |||
1193 | if (item.InvType == (int)InventoryType.Object) | ||
964 | { | 1194 | { |
965 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1195 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
966 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1196 | mask &= ~((uint)PermissionMask.Copy >> 13); |
967 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1197 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
968 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1198 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
969 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1199 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
970 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1200 | mask &= ~((uint)PermissionMask.Modify >> 13); |
971 | |||
972 | if (item.InvType != (int)InventoryType.Object) | ||
973 | { | ||
974 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
975 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
976 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
977 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
978 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
979 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
980 | } | ||
981 | else | ||
982 | { | ||
983 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
984 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
985 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
986 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
987 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
988 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
989 | } | ||
990 | |||
991 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
992 | mask &= ~(uint)PermissionMask.Copy; | ||
993 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
994 | mask &= ~(uint)PermissionMask.Transfer; | ||
995 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
996 | mask &= ~(uint)PermissionMask.Modify; | ||
997 | } | 1201 | } |
1202 | |||
1203 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1204 | mask &= ~(uint)PermissionMask.Copy; | ||
1205 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1206 | mask &= ~(uint)PermissionMask.Transfer; | ||
1207 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1208 | mask &= ~(uint)PermissionMask.Modify; | ||
998 | } | 1209 | } |
999 | |||
1000 | return mask; | 1210 | return mask; |
1001 | } | 1211 | } |
1002 | 1212 | ||
1003 | public void ApplyNextOwnerPermissions() | 1213 | public void ApplyNextOwnerPermissions() |
1004 | { | 1214 | { |
1005 | lock (m_items) | 1215 | foreach (TaskInventoryItem item in m_items.Values) |
1006 | { | 1216 | { |
1007 | foreach (TaskInventoryItem item in m_items.Values) | 1217 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1008 | { | 1218 | { |
1009 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1219 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1010 | { | 1220 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1011 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1221 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1012 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | 1222 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; |
1013 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1223 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1014 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | 1224 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1015 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1016 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1017 | } | ||
1018 | item.CurrentPermissions &= item.NextPermissions; | ||
1019 | item.BasePermissions &= item.NextPermissions; | ||
1020 | item.EveryonePermissions &= item.NextPermissions; | ||
1021 | item.OwnerChanged = true; | ||
1022 | item.PermsMask = 0; | ||
1023 | item.PermsGranter = UUID.Zero; | ||
1024 | } | 1225 | } |
1226 | item.OwnerChanged = true; | ||
1227 | item.CurrentPermissions &= item.NextPermissions; | ||
1228 | item.BasePermissions &= item.NextPermissions; | ||
1229 | item.EveryonePermissions &= item.NextPermissions; | ||
1230 | item.PermsMask = 0; | ||
1231 | item.PermsGranter = UUID.Zero; | ||
1025 | } | 1232 | } |
1026 | } | 1233 | } |
1027 | 1234 | ||
1028 | public void ApplyGodPermissions(uint perms) | 1235 | public void ApplyGodPermissions(uint perms) |
1029 | { | 1236 | { |
1030 | lock (m_items) | 1237 | foreach (TaskInventoryItem item in m_items.Values) |
1031 | { | 1238 | { |
1032 | foreach (TaskInventoryItem item in m_items.Values) | 1239 | item.CurrentPermissions = perms; |
1033 | { | 1240 | item.BasePermissions = perms; |
1034 | item.CurrentPermissions = perms; | ||
1035 | item.BasePermissions = perms; | ||
1036 | } | ||
1037 | } | 1241 | } |
1038 | m_inventorySerial++; | 1242 | m_inventorySerial++; |
1039 | HasInventoryChanged = true; | 1243 | HasInventoryChanged = true; |
@@ -1041,17 +1245,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1041 | 1245 | ||
1042 | public bool ContainsScripts() | 1246 | public bool ContainsScripts() |
1043 | { | 1247 | { |
1044 | lock (m_items) | 1248 | foreach (TaskInventoryItem item in m_items.Values) |
1045 | { | 1249 | { |
1046 | foreach (TaskInventoryItem item in m_items.Values) | 1250 | if (item.InvType == (int)InventoryType.LSL) |
1047 | { | 1251 | { |
1048 | if (item.InvType == (int)InventoryType.LSL) | 1252 | return true; |
1049 | { | ||
1050 | return true; | ||
1051 | } | ||
1052 | } | 1253 | } |
1053 | } | 1254 | } |
1054 | |||
1055 | return false; | 1255 | return false; |
1056 | } | 1256 | } |
1057 | 1257 | ||
@@ -1059,11 +1259,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1059 | { | 1259 | { |
1060 | List<UUID> ret = new List<UUID>(); | 1260 | List<UUID> ret = new List<UUID>(); |
1061 | 1261 | ||
1062 | lock (m_items) | 1262 | foreach (TaskInventoryItem item in m_items.Values) |
1063 | { | 1263 | ret.Add(item.ItemID); |
1064 | foreach (TaskInventoryItem item in m_items.Values) | ||
1065 | ret.Add(item.ItemID); | ||
1066 | } | ||
1067 | 1264 | ||
1068 | return ret; | 1265 | return ret; |
1069 | } | 1266 | } |
@@ -1094,6 +1291,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1094 | 1291 | ||
1095 | public Dictionary<UUID, string> GetScriptStates() | 1292 | public Dictionary<UUID, string> GetScriptStates() |
1096 | { | 1293 | { |
1294 | return GetScriptStates(false); | ||
1295 | } | ||
1296 | |||
1297 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1298 | { | ||
1097 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1299 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1098 | 1300 | ||
1099 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1301 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1104,25 +1306,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
1104 | if (engines == null) // No engine at all | 1306 | if (engines == null) // No engine at all |
1105 | return ret; | 1307 | return ret; |
1106 | 1308 | ||
1107 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 1309 | Items.LockItemsForRead(true); |
1108 | 1310 | foreach (TaskInventoryItem item in m_items.Values) | |
1109 | foreach (TaskInventoryItem item in scripts) | ||
1110 | { | 1311 | { |
1111 | foreach (IScriptModule e in engines) | 1312 | if (item.InvType == (int)InventoryType.LSL) |
1112 | { | 1313 | { |
1113 | if (e != null) | 1314 | foreach (IScriptModule e in engines) |
1114 | { | 1315 | { |
1115 | string n = e.GetXMLState(item.ItemID); | 1316 | if (e != null) |
1116 | if (n != String.Empty) | ||
1117 | { | 1317 | { |
1118 | if (!ret.ContainsKey(item.ItemID)) | 1318 | string n = e.GetXMLState(item.ItemID); |
1119 | ret[item.ItemID] = n; | 1319 | if (n != String.Empty) |
1120 | break; | 1320 | { |
1321 | if (oldIDs) | ||
1322 | { | ||
1323 | if (!ret.ContainsKey(item.OldItemID)) | ||
1324 | ret[item.OldItemID] = n; | ||
1325 | } | ||
1326 | else | ||
1327 | { | ||
1328 | if (!ret.ContainsKey(item.ItemID)) | ||
1329 | ret[item.ItemID] = n; | ||
1330 | } | ||
1331 | break; | ||
1332 | } | ||
1121 | } | 1333 | } |
1122 | } | 1334 | } |
1123 | } | 1335 | } |
1124 | } | 1336 | } |
1125 | 1337 | Items.LockItemsForRead(false); | |
1126 | return ret; | 1338 | return ret; |
1127 | } | 1339 | } |
1128 | 1340 | ||
@@ -1132,21 +1344,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1132 | if (engines == null) | 1344 | if (engines == null) |
1133 | return; | 1345 | return; |
1134 | 1346 | ||
1135 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | ||
1136 | 1347 | ||
1137 | foreach (TaskInventoryItem item in scripts) | 1348 | Items.LockItemsForRead(true); |
1349 | |||
1350 | foreach (TaskInventoryItem item in m_items.Values) | ||
1138 | { | 1351 | { |
1139 | foreach (IScriptModule engine in engines) | 1352 | if (item.InvType == (int)InventoryType.LSL) |
1140 | { | 1353 | { |
1141 | if (engine != null) | 1354 | foreach (IScriptModule engine in engines) |
1142 | { | 1355 | { |
1143 | if (item.OwnerChanged) | 1356 | if (engine != null) |
1144 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); | 1357 | { |
1145 | item.OwnerChanged = false; | 1358 | if (item.OwnerChanged) |
1146 | engine.ResumeScript(item.ItemID); | 1359 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); |
1360 | item.OwnerChanged = false; | ||
1361 | engine.ResumeScript(item.ItemID); | ||
1362 | } | ||
1147 | } | 1363 | } |
1148 | } | 1364 | } |
1149 | } | 1365 | } |
1366 | |||
1367 | Items.LockItemsForRead(false); | ||
1150 | } | 1368 | } |
1151 | } | 1369 | } |
1152 | } | 1370 | } |