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