aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
diff options
context:
space:
mode:
authorDr Scofield2009-02-06 16:55:34 +0000
committerDr Scofield2009-02-06 16:55:34 +0000
commit9b66108081a8c8cf79faaa6c541554091c40850e (patch)
tree095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
parent* removed superfluous constants class (diff)
downloadopensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.zip
opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz
opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2
opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx!
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}