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