aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-11-21 21:16:42 +0000
committerJustin Clarke Casey2008-11-21 21:16:42 +0000
commit915593bfbc2f0d6729efe4dfe8d4c8a3f0fc9fbe (patch)
tree1f62bf777f73c4f3fffb2f5237cd7e5eaeddcb6f /OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs
parent* Extend sog delete to inventory test to crank the normally async sog deleter... (diff)
downloadopensim-SC-915593bfbc2f0d6729efe4dfe8d4c8a3f0fc9fbe.zip
opensim-SC-915593bfbc2f0d6729efe4dfe8d4c8a3f0fc9fbe.tar.gz
opensim-SC-915593bfbc2f0d6729efe4dfe8d4c8a3f0fc9fbe.tar.bz2
opensim-SC-915593bfbc2f0d6729efe4dfe8d4c8a3f0fc9fbe.tar.xz
* refactor: Rip out SOP inventory from the partial into a separate class
* SceneObjectPartInventory.cs isn't a particularly good name but it's probably not got a long life * A proper inventory interface to follow * Parallel changes for other inventory partial classes to follow at a later date
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs872
1 files changed, 872 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs
new file mode 100644
index 0000000..0a6f22c
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs
@@ -0,0 +1,872 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using OpenMetaverse;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Cache;
35using OpenSim.Region.Interfaces;
36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Scenes.Scripting;
38
39namespace OpenSim.Region.Environment.Scenes
40{
41 public class SceneObjectPartInventory
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 private string m_inventoryFileName = String.Empty;
46 private int m_inventoryFileNameSerial = 0;
47
48 /// <value>
49 /// The part to which the inventory belongs.
50 /// </value>
51 private SceneObjectPart m_part;
52
53 /// <summary>
54 /// Serial count for inventory file , used to tell if inventory has changed
55 /// no need for this to be part of Database backup
56 /// </summary>
57 protected uint m_inventorySerial = 0;
58
59 /// <summary>
60 /// Holds in memory prim inventory
61 /// </summary>
62 protected TaskInventoryDictionary m_items = new TaskInventoryDictionary();
63
64 /// <summary>
65 /// Tracks whether inventory has changed since the last persistent backup
66 /// </summary>
67 protected bool HasInventoryChanged;
68
69 /// <value>
70 /// Inventory serial number
71 /// </value>
72 public uint Serial
73 {
74 get { return m_inventorySerial; }
75 set { m_inventorySerial = value; }
76 }
77
78 /// <value>
79 /// Raw inventory data
80 /// </value>
81 public TaskInventoryDictionary Items
82 {
83 get { return m_items; }
84 set { m_items = value; }
85 }
86
87 /// <summary>
88 /// Constructor
89 /// </summary>
90 /// <param name="part">
91 /// A <see cref="SceneObjectPart"/>
92 /// </param>
93 public SceneObjectPartInventory(SceneObjectPart part)
94 {
95 m_part = part;
96 }
97
98 /// <summary>
99 /// Force the task inventory of this prim to persist at the next update sweep
100 /// </summary>
101 public void ForceInventoryPersistence()
102 {
103 HasInventoryChanged = true;
104 }
105
106 /// <summary>
107 /// Reset UUIDs for all the items in the prim's inventory. This involves either generating
108 /// new ones or setting existing UUIDs to the correct parent UUIDs.
109 ///
110 /// If this method is called and there are inventory items, then we regard the inventory as having changed.
111 /// </summary>
112 /// <param name="linkNum">Link number for the part</param>
113 public void ResetInventoryIDs()
114 {
115 lock (Items)
116 {
117 if (0 == Items.Count)
118 return;
119
120 HasInventoryChanged = true;
121 m_part.ParentGroup.HasGroupChanged = true;
122 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
123 Items.Clear();
124
125 foreach (TaskInventoryItem item in items)
126 {
127 item.ResetIDs(m_part.UUID);
128 Items.Add(item.ItemID, item);
129 }
130 }
131 }
132
133 /// <summary>
134 /// Change every item in this inventory to a new owner.
135 /// </summary>
136 /// <param name="ownerId"></param>
137 public void ChangeInventoryOwner(UUID ownerId)
138 {
139 lock (Items)
140 {
141 if (0 == Items.Count)
142 {
143 return;
144 }
145
146 HasInventoryChanged = true;
147 m_part.ParentGroup.HasGroupChanged = true;
148 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
149 foreach (TaskInventoryItem item in items)
150 {
151 if (ownerId != item.OwnerID)
152 {
153 item.LastOwnerID = item.OwnerID;
154 item.OwnerID = ownerId;
155 }
156 }
157 }
158 }
159
160 /// <summary>
161 /// Change every item in this inventory to a new group.
162 /// </summary>
163 /// <param name="groupID"></param>
164 public void ChangeInventoryGroup(UUID groupID)
165 {
166 lock (Items)
167 {
168 if (0 == Items.Count)
169 {
170 return;
171 }
172
173 HasInventoryChanged = true;
174 m_part.ParentGroup.HasGroupChanged = true;
175 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
176 foreach (TaskInventoryItem item in items)
177 {
178 if (groupID != item.GroupID)
179 {
180 item.GroupID = groupID;
181 }
182 }
183 }
184 }
185
186 /// <summary>
187 /// Start all the scripts contained in this prim's inventory
188 /// </summary>
189 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
190 {
191 lock (m_items)
192 {
193 foreach (TaskInventoryItem item in Items.Values)
194 {
195 if ((int)InventoryType.LSL == item.InvType)
196 {
197 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
198 }
199 }
200 }
201 }
202
203 /// <summary>
204 /// Stop all the scripts in this prim.
205 /// </summary>
206 public void RemoveScriptInstances()
207 {
208 lock (Items)
209 {
210 foreach (TaskInventoryItem item in Items.Values)
211 {
212 if ((int)InventoryType.LSL == item.InvType)
213 {
214 RemoveScriptInstance(item.ItemID);
215 m_part.RemoveScriptEvents(item.ItemID);
216 }
217 }
218 }
219 }
220
221 /// <summary>
222 /// Start a script which is in this prim's inventory.
223 /// </summary>
224 /// <param name="item"></param>
225 /// <returns></returns>
226 public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource)
227 {
228 // m_log.InfoFormat(
229 // "[PRIM INVENTORY]: " +
230 // "Starting script {0}, {1} in prim {2}, {3}",
231 // item.Name, item.ItemID, Name, UUID);
232
233 if (!m_part.ParentGroup.Scene.ExternalChecks.ExternalChecksCanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
234 return;
235
236 m_part.AddFlag(PrimFlags.Scripted);
237
238 if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts)
239 {
240 AssetCache cache = m_part.ParentGroup.Scene.AssetCache;
241
242 cache.GetAsset(item.AssetID, delegate(UUID assetID, AssetBase asset)
243 {
244 if (null == asset)
245 {
246 m_log.ErrorFormat(
247 "[PRIM INVENTORY]: " +
248 "Couldn't start script {0}, {1} since asset ID {2} could not be found",
249 item.Name, item.ItemID, item.AssetID);
250 }
251 else
252 {
253 m_items[item.ItemID].PermsMask = 0;
254 m_items[item.ItemID].PermsGranter = UUID.Zero;
255 string script = Utils.BytesToString(asset.Data);
256 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
257 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
258 m_part.ParentGroup.AddActiveScriptCount(1);
259 m_part.ScheduleFullUpdate();
260 }
261 }, false);
262 }
263 }
264
265 /// <summary>
266 /// Start a script which is in this prim's inventory.
267 /// </summary>
268 /// <param name="itemId">
269 /// A <see cref="UUID"/>
270 /// </param>
271 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
272 {
273 lock (m_items)
274 {
275 if (m_items.ContainsKey(itemId))
276 {
277 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
278 }
279 else
280 {
281 m_log.ErrorFormat(
282 "[PRIM INVENTORY]: " +
283 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
284 itemId, m_part.Name, m_part.UUID);
285 }
286 }
287 }
288
289 /// <summary>
290 /// Stop a script which is in this prim's inventory.
291 /// </summary>
292 /// <param name="itemId"></param>
293 public void RemoveScriptInstance(UUID itemId)
294 {
295 if (m_items.ContainsKey(itemId))
296 {
297 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId);
298 m_part.ParentGroup.AddActiveScriptCount(-1);
299 }
300 else
301 {
302 m_log.ErrorFormat(
303 "[PRIM INVENTORY]: " +
304 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}",
305 itemId, m_part.Name, m_part.UUID);
306 }
307 }
308
309 /// <summary>
310 /// Check if the inventory holds an item with a given name.
311 /// This method assumes that the task inventory is already locked.
312 /// </summary>
313 /// <param name="name"></param>
314 /// <returns></returns>
315 private bool InventoryContainsName(string name)
316 {
317 foreach (TaskInventoryItem item in Items.Values)
318 {
319 if (item.Name == name)
320 return true;
321 }
322 return false;
323 }
324
325 /// <summary>
326 /// For a given item name, return that name if it is available. Otherwise, return the next available
327 /// similar name (which is currently the original name with the next available numeric suffix).
328 /// </summary>
329 /// <param name="name"></param>
330 /// <returns></returns>
331 private string FindAvailableInventoryName(string name)
332 {
333 if (!InventoryContainsName(name))
334 return name;
335
336 int suffix=1;
337 while (suffix < 256)
338 {
339 string tryName=String.Format("{0} {1}", name, suffix);
340 if (!InventoryContainsName(tryName))
341 return tryName;
342 suffix++;
343 }
344 return String.Empty;
345 }
346
347 /// <summary>
348 /// Add an item to this prim's inventory. If an item with the same name already exists, then an alternative
349 /// name is chosen.
350 /// </summary>
351 /// <param name="item"></param>
352 public void AddInventoryItem(TaskInventoryItem item, bool allowedDrop)
353 {
354 AddInventoryItem(item.Name, item, allowedDrop);
355 }
356
357 /// <summary>
358 /// Add an item to this prim's inventory. If an item with the same name already exists, it is replaced.
359 /// </summary>
360 /// <param name="item"></param>
361 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
362 {
363 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
364 foreach (TaskInventoryItem i in il)
365 {
366 if (i.Name == item.Name)
367 {
368 if (i.InvType == (int)InventoryType.LSL)
369 RemoveScriptInstance(i.ItemID);
370
371 RemoveInventoryItem(i.ItemID);
372 break;
373 }
374 }
375
376 AddInventoryItem(item.Name, item, allowedDrop);
377 }
378
379 /// <summary>
380 /// Add an item to this prim's inventory.
381 /// </summary>
382 /// <param name="name">The name that the new item should have.</param>
383 /// <param name="item">
384 /// The item itself. The name within this structure is ignored in favour of the name
385 /// given in this method's arguments
386 /// </param>
387 /// <param name="allowedDrop">
388 /// Item was only added to inventory because AllowedDrop is set
389 /// </param>
390 protected void AddInventoryItem(string name, TaskInventoryItem item, bool allowedDrop)
391 {
392 name = FindAvailableInventoryName(name);
393 if (name == String.Empty)
394 return;
395
396 item.ParentID = m_part.UUID;
397 item.ParentPartID = m_part.UUID;
398 item.Name = name;
399
400 lock (m_items)
401 {
402 m_items.Add(item.ItemID, item);
403
404 if (allowedDrop)
405 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
406 else
407 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
408 }
409
410 m_inventorySerial++;
411 //m_inventorySerial += 2;
412 HasInventoryChanged = true;
413 m_part.ParentGroup.HasGroupChanged = true;
414 }
415
416 /// <summary>
417 /// Restore a whole collection of items to the prim's inventory at once.
418 /// We assume that the items already have all their fields correctly filled out.
419 /// The items are not flagged for persistence to the database, since they are being restored
420 /// from persistence rather than being newly added.
421 /// </summary>
422 /// <param name="items"></param>
423 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
424 {
425 lock (m_items)
426 {
427 foreach (TaskInventoryItem item in items)
428 {
429 m_items.Add(item.ItemID, item);
430 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
431 }
432 }
433
434 m_inventorySerial++;
435 }
436
437 /// <summary>
438 /// Returns an existing inventory item. Returns the original, so any changes will be live.
439 /// </summary>
440 /// <param name="itemID"></param>
441 /// <returns>null if the item does not exist</returns>
442 public TaskInventoryItem GetInventoryItem(UUID itemId)
443 {
444 TaskInventoryItem item;
445 m_items.TryGetValue(itemId, out item);
446
447 return item;
448 }
449
450 /// <summary>
451 /// Update an existing inventory item.
452 /// </summary>
453 /// <param name="item">The updated item. An item with the same id must already exist
454 /// in this prim's inventory.</param>
455 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
456 public bool UpdateInventoryItem(TaskInventoryItem item)
457 {
458 lock (m_items)
459 {
460 if (m_items.ContainsKey(item.ItemID))
461 {
462 item.ParentID = m_part.UUID;
463 item.ParentPartID = m_part.UUID;
464 item.Flags = m_items[item.ItemID].Flags;
465 if (item.AssetID == UUID.Zero)
466 {
467 item.AssetID = m_items[item.ItemID].AssetID;
468 }
469 else if ((InventoryType)item.Type == InventoryType.Notecard)
470 {
471 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
472
473 if (presence != null)
474 {
475 presence.ControllingClient.SendAgentAlertMessage(
476 "Notecard saved", false);
477 }
478 }
479
480 m_items[item.ItemID] = item;
481 m_inventorySerial++;
482 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
483
484 HasInventoryChanged = true;
485 m_part.ParentGroup.HasGroupChanged = true;
486
487 return true;
488 }
489 else
490 {
491 m_log.ErrorFormat(
492 "[PRIM INVENTORY]: " +
493 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
494 item.ItemID, m_part.Name, m_part.UUID);
495 }
496 }
497
498 return false;
499 }
500
501 /// <summary>
502 /// Remove an item from this prim's inventory
503 /// </summary>
504 /// <param name="itemID"></param>
505 /// <returns>Numeric asset type of the item removed. Returns -1 if the item did not exist
506 /// in this prim's inventory.</returns>
507 public int RemoveInventoryItem(UUID itemID)
508 {
509 lock (m_items)
510 {
511 if (m_items.ContainsKey(itemID))
512 {
513 int type = m_items[itemID].InvType;
514 m_items.Remove(itemID);
515 m_inventorySerial++;
516 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
517
518 HasInventoryChanged = true;
519 m_part.ParentGroup.HasGroupChanged = true;
520
521 int scriptcount = 0;
522 lock (m_items)
523 {
524 foreach (TaskInventoryItem item in m_items.Values)
525 {
526 if (item.Type == 10)
527 {
528 scriptcount++;
529 }
530 }
531 }
532
533 if (scriptcount <= 0)
534 {
535 m_part.RemFlag(PrimFlags.Scripted);
536 }
537
538 m_part.ScheduleFullUpdate();
539
540 return type;
541 }
542 else
543 {
544 m_log.ErrorFormat(
545 "[PRIM INVENTORY]: " +
546 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
547 itemID, m_part.Name, m_part.UUID);
548 }
549 }
550
551 return -1;
552 }
553
554 public string GetInventoryFileName()
555 {
556 if (m_inventoryFileName == String.Empty)
557 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
558 if (m_inventoryFileNameSerial < m_inventorySerial)
559 {
560 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
561 }
562 return m_inventoryFileName;
563 }
564
565 /// <summary>
566 /// Return the name with which a client can request a xfer of this prim's inventory metadata
567 /// </summary>
568 /// <param name="client"></param>
569 /// <param name="localID"></param>
570 public bool GetInventoryFileName(IClientAPI client, uint localID)
571 {
572// m_log.DebugFormat(
573// "[PRIM INVENTORY]: Received request from client {0} for inventory file name of {1}, {2}",
574// client.AgentId, Name, UUID);
575
576 if (m_inventorySerial > 0)
577 {
578 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
579 Utils.StringToBytes(GetInventoryFileName()));
580 return true;
581 }
582 else
583 {
584 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
585 return false;
586 }
587 }
588
589 /// <summary>
590 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
591 /// </summary>
592 /// <param name="xferManager"></param>
593 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
594 {
595 byte[] fileData = new byte[0];
596
597 // Confusingly, the folder item has to be the object id, while the 'parent id' has to be zero. This matches
598 // what appears to happen in the Second Life protocol. If this isn't the case. then various functionality
599 // isn't available (such as drag from prim inventory to agent inventory)
600 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
601
602 lock (m_items)
603 {
604 foreach (TaskInventoryItem item in m_items.Values)
605 {
606 UUID ownerID = item.OwnerID;
607 uint everyoneMask = 0;
608 uint baseMask = item.BasePermissions;
609 uint ownerMask = item.CurrentPermissions;
610
611 invString.AddItemStart();
612 invString.AddNameValueLine("item_id", item.ItemID.ToString());
613 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
614
615 invString.AddPermissionsStart();
616
617 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
618 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
619 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
620 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
621 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
622
623 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
624 invString.AddNameValueLine("owner_id", ownerID.ToString());
625
626 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
627
628 invString.AddNameValueLine("group_id", item.GroupID.ToString());
629 invString.AddSectionEnd();
630
631 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
632 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
633 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
634 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
635
636 invString.AddSaleStart();
637 invString.AddNameValueLine("sale_type", "not");
638 invString.AddNameValueLine("sale_price", "0");
639 invString.AddSectionEnd();
640
641 invString.AddNameValueLine("name", item.Name + "|");
642 invString.AddNameValueLine("desc", item.Description + "|");
643
644 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
645 invString.AddSectionEnd();
646 }
647 }
648
649 fileData = Utils.StringToBytes(invString.BuildString);
650
651 //Console.WriteLine(Utils.BytesToString(fileData));
652 //m_log.Debug("[PRIM INVENTORY]: RequestInventoryFile fileData: " + Utils.BytesToString(fileData));
653
654 if (fileData.Length > 2)
655 {
656 xferManager.AddNewFile(m_inventoryFileName, fileData);
657 }
658 }
659
660 /// <summary>
661 /// Process inventory backup
662 /// </summary>
663 /// <param name="datastore"></param>
664 public void ProcessInventoryBackup(IRegionDataStore datastore)
665 {
666 if (HasInventoryChanged)
667 {
668 lock (Items)
669 {
670 datastore.StorePrimInventory(m_part.UUID, Items.Values);
671 }
672
673 HasInventoryChanged = false;
674 }
675 }
676
677 public class InventoryStringBuilder
678 {
679 public string BuildString = String.Empty;
680
681 public InventoryStringBuilder(UUID folderID, UUID parentID)
682 {
683 BuildString += "\tinv_object\t0\n\t{\n";
684 AddNameValueLine("obj_id", folderID.ToString());
685 AddNameValueLine("parent_id", parentID.ToString());
686 AddNameValueLine("type", "category");
687 AddNameValueLine("name", "Contents|");
688 AddSectionEnd();
689 }
690
691 public void AddItemStart()
692 {
693 BuildString += "\tinv_item\t0\n";
694 AddSectionStart();
695 }
696
697 public void AddPermissionsStart()
698 {
699 BuildString += "\tpermissions 0\n";
700 AddSectionStart();
701 }
702
703 public void AddSaleStart()
704 {
705 BuildString += "\tsale_info\t0\n";
706 AddSectionStart();
707 }
708
709 protected void AddSectionStart()
710 {
711 BuildString += "\t{\n";
712 }
713
714 public void AddSectionEnd()
715 {
716 BuildString += "\t}\n";
717 }
718
719 public void AddLine(string addLine)
720 {
721 BuildString += addLine;
722 }
723
724 public void AddNameValueLine(string name, string value)
725 {
726 BuildString += "\t\t";
727 BuildString += name + "\t";
728 BuildString += value + "\n";
729 }
730
731 public void Close()
732 {
733 }
734 }
735
736 public uint MaskEffectivePermissions()
737 {
738 uint mask=0x7fffffff;
739
740 foreach (TaskInventoryItem item in m_items.Values)
741 {
742 if (item.InvType != 6)
743 {
744 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
745 mask &= ~((uint)PermissionMask.Copy >> 13);
746 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
747 mask &= ~((uint)PermissionMask.Transfer >> 13);
748 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
749 mask &= ~((uint)PermissionMask.Modify >> 13);
750 }
751 else
752 {
753 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
754 mask &= ~((uint)PermissionMask.Copy >> 13);
755 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
756 mask &= ~((uint)PermissionMask.Transfer >> 13);
757 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
758 mask &= ~((uint)PermissionMask.Modify >> 13);
759 }
760
761 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
762 mask &= ~(uint)PermissionMask.Copy;
763 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
764 mask &= ~(uint)PermissionMask.Transfer;
765 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
766 mask &= ~(uint)PermissionMask.Modify;
767 }
768 return mask;
769 }
770
771 public void ApplyNextOwnerPermissions()
772 {
773 foreach (TaskInventoryItem item in m_items.Values)
774 {
775 if (item.InvType == 6 && (item.CurrentPermissions & 7) != 0)
776 {
777 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
778 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
779 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
780 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
781 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
782 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
783 }
784 item.CurrentPermissions &= item.NextPermissions;
785 item.BasePermissions &= item.NextPermissions;
786 item.EveryonePermissions &= item.NextPermissions;
787 }
788
789 m_part.TriggerScriptChangedEvent(Changed.OWNER);
790 }
791
792 public void ApplyGodPermissions(uint perms)
793 {
794 foreach (TaskInventoryItem item in m_items.Values)
795 {
796 item.CurrentPermissions = perms;
797 item.BasePermissions = perms;
798 }
799 }
800
801 public bool ContainsScripts()
802 {
803 foreach (TaskInventoryItem item in m_items.Values)
804 {
805 if (item.InvType == 10)
806 {
807 return true;
808 }
809 }
810 return false;
811 }
812
813 public List<UUID> GetInventoryList()
814 {
815 List<UUID> ret = new List<UUID>();
816
817 foreach (TaskInventoryItem item in m_items.Values)
818 ret.Add(item.ItemID);
819
820 return ret;
821 }
822
823 public string[] GetScriptAssemblies()
824 {
825 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
826
827 List<string> ret = new List<string>();
828
829 foreach (TaskInventoryItem item in m_items.Values)
830 {
831 if (item.InvType == 10)
832 {
833 foreach (IScriptModule e in engines)
834 {
835 string n = e.GetAssemblyName(item.ItemID);
836 if (n != "")
837 {
838 if (!ret.Contains(n))
839 ret.Add(n);
840 break;
841 }
842 }
843 }
844 }
845 return ret.ToArray();
846 }
847
848 public Dictionary<UUID, string> GetScriptStates()
849 {
850 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
851 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
852
853 foreach (TaskInventoryItem item in m_items.Values)
854 {
855 if (item.InvType == 10)
856 {
857 foreach (IScriptModule e in engines)
858 {
859 string n = e.GetXMLState(item.ItemID);
860 if (n != "")
861 {
862 if (!ret.ContainsKey(item.ItemID))
863 ret[item.ItemID] = n;
864 break;
865 }
866 }
867 }
868 }
869 return ret;
870 }
871 }
872}