diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 759 |
1 files changed, 488 insertions, 271 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3b60f8c..56680df 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 | 156 | } | |
149 | foreach (TaskInventoryItem item in items) | 157 | |
150 | { | 158 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
151 | item.ParentPartID = m_part.UUID; | 159 | Items.Clear(); |
152 | item.ParentID = m_part.UUID; | 160 | |
153 | Items.Add(item.ItemID, item); | 161 | foreach (TaskInventoryItem item in items) |
154 | } | 162 | { |
163 | item.ParentPartID = m_part.UUID; | ||
164 | item.ParentID = m_part.UUID; | ||
165 | Items.Add(item.ItemID, item); | ||
155 | } | 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 | item.OwnerChanged = true; | 194 | item.OwnerChanged = true; |
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 | ||
@@ -617,6 +803,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
617 | string xmlData = Utils.BytesToString(rezAsset.Data); | 803 | string xmlData = Utils.BytesToString(rezAsset.Data); |
618 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 804 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
619 | 805 | ||
806 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
807 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
808 | |||
620 | group.ResetIDs(); | 809 | group.ResetIDs(); |
621 | 810 | ||
622 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); | 811 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); |
@@ -691,8 +880,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
691 | 880 | ||
692 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 881 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
693 | { | 882 | { |
694 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 883 | m_items.LockItemsForWrite(true); |
695 | if (it != null) | 884 | |
885 | if (m_items.ContainsKey(item.ItemID)) | ||
696 | { | 886 | { |
697 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 887 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
698 | 888 | ||
@@ -705,14 +895,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
705 | item.GroupID = m_part.GroupID; | 895 | item.GroupID = m_part.GroupID; |
706 | 896 | ||
707 | if (item.AssetID == UUID.Zero) | 897 | if (item.AssetID == UUID.Zero) |
708 | item.AssetID = it.AssetID; | 898 | item.AssetID = m_items[item.ItemID].AssetID; |
709 | 899 | ||
710 | lock (m_items) | 900 | m_items[item.ItemID] = item; |
711 | { | 901 | m_inventorySerial++; |
712 | m_items[item.ItemID] = item; | ||
713 | m_inventorySerial++; | ||
714 | } | ||
715 | |||
716 | if (fireScriptEvents) | 902 | if (fireScriptEvents) |
717 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 903 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
718 | 904 | ||
@@ -721,7 +907,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
721 | HasInventoryChanged = true; | 907 | HasInventoryChanged = true; |
722 | m_part.ParentGroup.HasGroupChanged = true; | 908 | m_part.ParentGroup.HasGroupChanged = true; |
723 | } | 909 | } |
724 | 910 | m_items.LockItemsForWrite(false); | |
725 | return true; | 911 | return true; |
726 | } | 912 | } |
727 | else | 913 | else |
@@ -732,8 +918,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
732 | item.ItemID, m_part.Name, m_part.UUID, | 918 | item.ItemID, m_part.Name, m_part.UUID, |
733 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 919 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
734 | } | 920 | } |
735 | return false; | 921 | m_items.LockItemsForWrite(false); |
736 | 922 | ||
923 | return false; | ||
737 | } | 924 | } |
738 | 925 | ||
739 | /// <summary> | 926 | /// <summary> |
@@ -744,107 +931,68 @@ namespace OpenSim.Region.Framework.Scenes | |||
744 | /// in this prim's inventory.</returns> | 931 | /// in this prim's inventory.</returns> |
745 | public int RemoveInventoryItem(UUID itemID) | 932 | public int RemoveInventoryItem(UUID itemID) |
746 | { | 933 | { |
747 | TaskInventoryItem item = GetInventoryItem(itemID); | 934 | m_items.LockItemsForRead(true); |
748 | if (item != null) | 935 | |
936 | if (m_items.ContainsKey(itemID)) | ||
749 | { | 937 | { |
750 | int type = m_items[itemID].InvType; | 938 | int type = m_items[itemID].InvType; |
939 | m_items.LockItemsForRead(false); | ||
751 | if (type == 10) // Script | 940 | if (type == 10) // Script |
752 | { | 941 | { |
753 | m_part.RemoveScriptEvents(itemID); | ||
754 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 942 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
755 | } | 943 | } |
944 | m_items.LockItemsForWrite(true); | ||
756 | m_items.Remove(itemID); | 945 | m_items.Remove(itemID); |
946 | m_items.LockItemsForWrite(false); | ||
757 | m_inventorySerial++; | 947 | m_inventorySerial++; |
758 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 948 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
759 | 949 | ||
760 | HasInventoryChanged = true; | 950 | HasInventoryChanged = true; |
761 | m_part.ParentGroup.HasGroupChanged = true; | 951 | m_part.ParentGroup.HasGroupChanged = true; |
762 | 952 | ||
763 | if (!ContainsScripts()) | 953 | int scriptcount = 0; |
954 | m_items.LockItemsForRead(true); | ||
955 | foreach (TaskInventoryItem item in m_items.Values) | ||
956 | { | ||
957 | if (item.Type == 10) | ||
958 | { | ||
959 | scriptcount++; | ||
960 | } | ||
961 | } | ||
962 | m_items.LockItemsForRead(false); | ||
963 | |||
964 | |||
965 | if (scriptcount <= 0) | ||
966 | { | ||
764 | m_part.RemFlag(PrimFlags.Scripted); | 967 | m_part.RemFlag(PrimFlags.Scripted); |
968 | } | ||
765 | 969 | ||
766 | m_part.ScheduleFullUpdate(); | 970 | m_part.ScheduleFullUpdate(); |
767 | 971 | ||
768 | return type; | 972 | return type; |
769 | |||
770 | } | 973 | } |
771 | else | 974 | else |
772 | { | 975 | { |
976 | m_items.LockItemsForRead(false); | ||
773 | m_log.ErrorFormat( | 977 | m_log.ErrorFormat( |
774 | "[PRIM INVENTORY]: " + | 978 | "[PRIM INVENTORY]: " + |
775 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 979 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
776 | itemID, m_part.Name, m_part.UUID, | 980 | itemID, m_part.Name, m_part.UUID); |
777 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
778 | } | 981 | } |
779 | 982 | ||
780 | return -1; | 983 | return -1; |
781 | } | 984 | } |
782 | 985 | ||
783 | private bool CreateInventoryFile() | 986 | private bool CreateInventoryFileName() |
784 | { | 987 | { |
785 | if (m_inventoryFileName == String.Empty || | 988 | if (m_inventoryFileName == String.Empty || |
786 | m_inventoryFileNameSerial < m_inventorySerial) | 989 | m_inventoryFileNameSerial < m_inventorySerial) |
787 | { | 990 | { |
788 | // Something changed, we need to create a new file | ||
789 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 991 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
790 | m_inventoryFileNameSerial = m_inventorySerial; | 992 | m_inventoryFileNameSerial = m_inventorySerial; |
791 | |||
792 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
793 | |||
794 | lock (m_items) | ||
795 | { | ||
796 | foreach (TaskInventoryItem item in m_items.Values) | ||
797 | { | ||
798 | UUID ownerID = item.OwnerID; | ||
799 | uint everyoneMask = 0; | ||
800 | uint baseMask = item.BasePermissions; | ||
801 | uint ownerMask = item.CurrentPermissions; | ||
802 | uint groupMask = item.GroupPermissions; | ||
803 | |||
804 | invString.AddItemStart(); | ||
805 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
806 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
807 | |||
808 | invString.AddPermissionsStart(); | ||
809 | |||
810 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
811 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
812 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
813 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
814 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
815 | |||
816 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
817 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
818 | |||
819 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
820 | |||
821 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
822 | invString.AddSectionEnd(); | ||
823 | |||
824 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
825 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
826 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
827 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
828 | |||
829 | invString.AddSaleStart(); | ||
830 | invString.AddNameValueLine("sale_type", "not"); | ||
831 | invString.AddNameValueLine("sale_price", "0"); | ||
832 | invString.AddSectionEnd(); | ||
833 | |||
834 | invString.AddNameValueLine("name", item.Name + "|"); | ||
835 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
836 | |||
837 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
838 | invString.AddSectionEnd(); | ||
839 | } | ||
840 | } | ||
841 | |||
842 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
843 | |||
844 | return true; | 993 | return true; |
845 | } | 994 | } |
846 | 995 | ||
847 | // No need to recreate, the existing file is fine | ||
848 | return false; | 996 | return false; |
849 | } | 997 | } |
850 | 998 | ||
@@ -854,26 +1002,99 @@ namespace OpenSim.Region.Framework.Scenes | |||
854 | /// <param name="xferManager"></param> | 1002 | /// <param name="xferManager"></param> |
855 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1003 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
856 | { | 1004 | { |
857 | CreateInventoryFile(); | 1005 | bool changed = CreateInventoryFileName(); |
1006 | |||
1007 | bool includeAssets = false; | ||
1008 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) | ||
1009 | includeAssets = true; | ||
1010 | |||
1011 | if (m_inventoryPrivileged != includeAssets) | ||
1012 | changed = true; | ||
1013 | |||
1014 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
1015 | |||
1016 | Items.LockItemsForRead(true); | ||
858 | 1017 | ||
859 | if (m_inventorySerial == 0) // No inventory | 1018 | if (m_inventorySerial == 0) // No inventory |
860 | { | 1019 | { |
861 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1020 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
1021 | Items.LockItemsForRead(false); | ||
862 | return; | 1022 | return; |
863 | } | 1023 | } |
864 | 1024 | ||
865 | // In principle, we should only do the rest if the inventory changed; | 1025 | if (!changed) |
866 | // by sending m_inventorySerial to the client, it ought to know | 1026 | { |
867 | // that nothing changed and that it doesn't need to request the file. | 1027 | if (m_inventoryFileData.Length > 2) |
868 | // Unfortunately, it doesn't look like the client optimizes this; | 1028 | { |
869 | // the client seems to always come back and request the Xfer, | 1029 | xferManager.AddNewFile(m_inventoryFileName, |
870 | // no matter what value m_inventorySerial has. | 1030 | m_inventoryFileData); |
1031 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1032 | Util.StringToBytes256(m_inventoryFileName)); | ||
1033 | |||
1034 | Items.LockItemsForRead(false); | ||
1035 | return; | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | m_inventoryPrivileged = includeAssets; | ||
1040 | |||
1041 | foreach (TaskInventoryItem item in m_items.Values) | ||
1042 | { | ||
1043 | UUID ownerID = item.OwnerID; | ||
1044 | uint everyoneMask = 0; | ||
1045 | uint baseMask = item.BasePermissions; | ||
1046 | uint ownerMask = item.CurrentPermissions; | ||
1047 | uint groupMask = item.GroupPermissions; | ||
1048 | |||
1049 | invString.AddItemStart(); | ||
1050 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
1051 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
1052 | |||
1053 | invString.AddPermissionsStart(); | ||
1054 | |||
1055 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
1056 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1057 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1058 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1059 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1060 | |||
1061 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1062 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1063 | |||
1064 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1065 | |||
1066 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1067 | invString.AddSectionEnd(); | ||
1068 | |||
1069 | if (includeAssets) | ||
1070 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1071 | else | ||
1072 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1073 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
1074 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
1075 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1076 | |||
1077 | invString.AddSaleStart(); | ||
1078 | invString.AddNameValueLine("sale_type", "not"); | ||
1079 | invString.AddNameValueLine("sale_price", "0"); | ||
1080 | invString.AddSectionEnd(); | ||
1081 | |||
1082 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1083 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1084 | |||
1085 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1086 | invString.AddSectionEnd(); | ||
1087 | } | ||
1088 | |||
1089 | Items.LockItemsForRead(false); | ||
1090 | |||
1091 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
871 | 1092 | ||
872 | if (m_inventoryFileData.Length > 2) | 1093 | if (m_inventoryFileData.Length > 2) |
873 | // Add the file for Xfer | 1094 | { |
874 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1095 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); |
1096 | } | ||
875 | 1097 | ||
876 | // Tell the client we're ready to Xfer the file | ||
877 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | 1098 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
878 | Util.StringToBytes256(m_inventoryFileName)); | 1099 | Util.StringToBytes256(m_inventoryFileName)); |
879 | } | 1100 | } |
@@ -886,10 +1107,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
886 | { | 1107 | { |
887 | if (HasInventoryChanged) | 1108 | if (HasInventoryChanged) |
888 | { | 1109 | { |
889 | HasInventoryChanged = false; | 1110 | Items.LockItemsForRead(true); |
890 | List<TaskInventoryItem> items = GetInventoryItems(); | 1111 | datastore.StorePrimInventory(m_part.UUID, Items.Values); |
891 | datastore.StorePrimInventory(m_part.UUID, items); | 1112 | Items.LockItemsForRead(false); |
892 | 1113 | ||
1114 | HasInventoryChanged = false; | ||
893 | } | 1115 | } |
894 | } | 1116 | } |
895 | 1117 | ||
@@ -956,82 +1178,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
956 | { | 1178 | { |
957 | uint mask=0x7fffffff; | 1179 | uint mask=0x7fffffff; |
958 | 1180 | ||
959 | lock (m_items) | 1181 | foreach (TaskInventoryItem item in m_items.Values) |
960 | { | 1182 | { |
961 | foreach (TaskInventoryItem item in m_items.Values) | 1183 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1184 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1185 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1186 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1187 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1188 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1189 | |||
1190 | if (item.InvType == (int)InventoryType.Object) | ||
962 | { | 1191 | { |
963 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1192 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
964 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1193 | mask &= ~((uint)PermissionMask.Copy >> 13); |
965 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1194 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
966 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1195 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
967 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1196 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
968 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1197 | mask &= ~((uint)PermissionMask.Modify >> 13); |
969 | |||
970 | if (item.InvType != (int)InventoryType.Object) | ||
971 | { | ||
972 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
973 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
974 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
975 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
976 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
977 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
978 | } | ||
979 | else | ||
980 | { | ||
981 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
982 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
983 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
984 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
985 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
986 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
987 | } | ||
988 | |||
989 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
990 | mask &= ~(uint)PermissionMask.Copy; | ||
991 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
992 | mask &= ~(uint)PermissionMask.Transfer; | ||
993 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
994 | mask &= ~(uint)PermissionMask.Modify; | ||
995 | } | 1198 | } |
1199 | |||
1200 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1201 | mask &= ~(uint)PermissionMask.Copy; | ||
1202 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1203 | mask &= ~(uint)PermissionMask.Transfer; | ||
1204 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1205 | mask &= ~(uint)PermissionMask.Modify; | ||
996 | } | 1206 | } |
997 | |||
998 | return mask; | 1207 | return mask; |
999 | } | 1208 | } |
1000 | 1209 | ||
1001 | public void ApplyNextOwnerPermissions() | 1210 | public void ApplyNextOwnerPermissions() |
1002 | { | 1211 | { |
1003 | lock (m_items) | 1212 | foreach (TaskInventoryItem item in m_items.Values) |
1004 | { | 1213 | { |
1005 | foreach (TaskInventoryItem item in m_items.Values) | 1214 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1006 | { | 1215 | { |
1007 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1216 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1008 | { | 1217 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1009 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1218 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1010 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | 1219 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; |
1011 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1220 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1012 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | 1221 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1013 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1014 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1015 | } | ||
1016 | item.CurrentPermissions &= item.NextPermissions; | ||
1017 | item.BasePermissions &= item.NextPermissions; | ||
1018 | item.EveryonePermissions &= item.NextPermissions; | ||
1019 | item.OwnerChanged = true; | ||
1020 | item.PermsMask = 0; | ||
1021 | item.PermsGranter = UUID.Zero; | ||
1022 | } | 1222 | } |
1223 | item.OwnerChanged = true; | ||
1224 | item.CurrentPermissions &= item.NextPermissions; | ||
1225 | item.BasePermissions &= item.NextPermissions; | ||
1226 | item.EveryonePermissions &= item.NextPermissions; | ||
1227 | item.PermsMask = 0; | ||
1228 | item.PermsGranter = UUID.Zero; | ||
1023 | } | 1229 | } |
1024 | } | 1230 | } |
1025 | 1231 | ||
1026 | public void ApplyGodPermissions(uint perms) | 1232 | public void ApplyGodPermissions(uint perms) |
1027 | { | 1233 | { |
1028 | lock (m_items) | 1234 | foreach (TaskInventoryItem item in m_items.Values) |
1029 | { | 1235 | { |
1030 | foreach (TaskInventoryItem item in m_items.Values) | 1236 | item.CurrentPermissions = perms; |
1031 | { | 1237 | item.BasePermissions = perms; |
1032 | item.CurrentPermissions = perms; | ||
1033 | item.BasePermissions = perms; | ||
1034 | } | ||
1035 | } | 1238 | } |
1036 | m_inventorySerial++; | 1239 | m_inventorySerial++; |
1037 | HasInventoryChanged = true; | 1240 | HasInventoryChanged = true; |
@@ -1039,17 +1242,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1039 | 1242 | ||
1040 | public bool ContainsScripts() | 1243 | public bool ContainsScripts() |
1041 | { | 1244 | { |
1042 | lock (m_items) | 1245 | foreach (TaskInventoryItem item in m_items.Values) |
1043 | { | 1246 | { |
1044 | foreach (TaskInventoryItem item in m_items.Values) | 1247 | if (item.InvType == (int)InventoryType.LSL) |
1045 | { | 1248 | { |
1046 | if (item.InvType == (int)InventoryType.LSL) | 1249 | return true; |
1047 | { | ||
1048 | return true; | ||
1049 | } | ||
1050 | } | 1250 | } |
1051 | } | 1251 | } |
1052 | |||
1053 | return false; | 1252 | return false; |
1054 | } | 1253 | } |
1055 | 1254 | ||
@@ -1057,11 +1256,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1057 | { | 1256 | { |
1058 | List<UUID> ret = new List<UUID>(); | 1257 | List<UUID> ret = new List<UUID>(); |
1059 | 1258 | ||
1060 | lock (m_items) | 1259 | foreach (TaskInventoryItem item in m_items.Values) |
1061 | { | 1260 | ret.Add(item.ItemID); |
1062 | foreach (TaskInventoryItem item in m_items.Values) | ||
1063 | ret.Add(item.ItemID); | ||
1064 | } | ||
1065 | 1261 | ||
1066 | return ret; | 1262 | return ret; |
1067 | } | 1263 | } |
@@ -1092,6 +1288,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1092 | 1288 | ||
1093 | public Dictionary<UUID, string> GetScriptStates() | 1289 | public Dictionary<UUID, string> GetScriptStates() |
1094 | { | 1290 | { |
1291 | return GetScriptStates(false); | ||
1292 | } | ||
1293 | |||
1294 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1295 | { | ||
1095 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1296 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1096 | 1297 | ||
1097 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1298 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1102,25 +1303,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
1102 | if (engines == null) // No engine at all | 1303 | if (engines == null) // No engine at all |
1103 | return ret; | 1304 | return ret; |
1104 | 1305 | ||
1105 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 1306 | Items.LockItemsForRead(true); |
1106 | 1307 | foreach (TaskInventoryItem item in m_items.Values) | |
1107 | foreach (TaskInventoryItem item in scripts) | ||
1108 | { | 1308 | { |
1109 | foreach (IScriptModule e in engines) | 1309 | if (item.InvType == (int)InventoryType.LSL) |
1110 | { | 1310 | { |
1111 | if (e != null) | 1311 | foreach (IScriptModule e in engines) |
1112 | { | 1312 | { |
1113 | string n = e.GetXMLState(item.ItemID); | 1313 | if (e != null) |
1114 | if (n != String.Empty) | ||
1115 | { | 1314 | { |
1116 | if (!ret.ContainsKey(item.ItemID)) | 1315 | string n = e.GetXMLState(item.ItemID); |
1117 | ret[item.ItemID] = n; | 1316 | if (n != String.Empty) |
1118 | break; | 1317 | { |
1318 | if (oldIDs) | ||
1319 | { | ||
1320 | if (!ret.ContainsKey(item.OldItemID)) | ||
1321 | ret[item.OldItemID] = n; | ||
1322 | } | ||
1323 | else | ||
1324 | { | ||
1325 | if (!ret.ContainsKey(item.ItemID)) | ||
1326 | ret[item.ItemID] = n; | ||
1327 | } | ||
1328 | break; | ||
1329 | } | ||
1119 | } | 1330 | } |
1120 | } | 1331 | } |
1121 | } | 1332 | } |
1122 | } | 1333 | } |
1123 | 1334 | Items.LockItemsForRead(false); | |
1124 | return ret; | 1335 | return ret; |
1125 | } | 1336 | } |
1126 | 1337 | ||
@@ -1130,21 +1341,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1130 | if (engines == null) | 1341 | if (engines == null) |
1131 | return; | 1342 | return; |
1132 | 1343 | ||
1133 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | ||
1134 | 1344 | ||
1135 | foreach (TaskInventoryItem item in scripts) | 1345 | Items.LockItemsForRead(true); |
1346 | |||
1347 | foreach (TaskInventoryItem item in m_items.Values) | ||
1136 | { | 1348 | { |
1137 | foreach (IScriptModule engine in engines) | 1349 | if (item.InvType == (int)InventoryType.LSL) |
1138 | { | 1350 | { |
1139 | if (engine != null) | 1351 | foreach (IScriptModule engine in engines) |
1140 | { | 1352 | { |
1141 | if (item.OwnerChanged) | 1353 | if (engine != null) |
1142 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); | 1354 | { |
1143 | item.OwnerChanged = false; | 1355 | if (item.OwnerChanged) |
1144 | engine.ResumeScript(item.ItemID); | 1356 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); |
1357 | item.OwnerChanged = false; | ||
1358 | engine.ResumeScript(item.ItemID); | ||
1359 | } | ||
1145 | } | 1360 | } |
1146 | } | 1361 | } |
1147 | } | 1362 | } |
1363 | |||
1364 | Items.LockItemsForRead(false); | ||
1148 | } | 1365 | } |
1149 | } | 1366 | } |
1150 | } | 1367 | } |