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