OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
Scene.Inventory.cs
Go to the documentation of this file.
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 OpenSimulator 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 
28 using System;
29 using System.Collections.Generic;
30 using System.Collections;
31 using System.Reflection;
32 using System.Text;
33 using System.Threading;
34 using System.Timers;
35 using System.Xml;
36 using OpenMetaverse;
37 using OpenMetaverse.Packets;
38 using log4net;
39 using OpenSim.Framework;
40 using OpenSim.Framework.Serialization.External;
41 using OpenSim.Region.Framework;
42 using OpenSim.Framework.Client;
43 using OpenSim.Region.Framework.Interfaces;
44 using OpenSim.Region.Framework.Scenes.Serialization;
45 using OpenSim.Services.Interfaces;
47 
48 namespace OpenSim.Region.Framework.Scenes
49 {
50  public partial class Scene
51  {
52  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53  //private static readonly string LogHeader = "[SCENE INVENTORY]";
54 
59 
64 
72  public int CreateScriptInstances()
73  {
74  m_log.InfoFormat("[SCENE]: Initializing script instances in {0}", RegionInfo.RegionName);
75 
76  int scriptsValidForStarting = 0;
77 
78  EntityBase[] entities = Entities.GetEntities();
79  foreach (EntityBase group in entities)
80  {
81  if (group is SceneObjectGroup)
82  {
83  scriptsValidForStarting
84  += ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
85  ((SceneObjectGroup) group).ResumeScripts();
86  }
87  }
88 
89  m_log.InfoFormat(
90  "[SCENE]: Initialized {0} script instances in {1}",
91  scriptsValidForStarting, RegionInfo.RegionName);
92 
93  return scriptsValidForStarting;
94  }
95 
99  public void StartScripts()
100  {
101 // m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
102 
103  IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
104 
105  foreach (IScriptModule engine in engines)
106  engine.StartProcessing();
107  }
108 
109  public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item, uint cost)
110  {
111  IMoneyModule money = RequestModuleInterface<IMoneyModule>();
112  if (money != null)
113  {
114  money.ApplyUploadCharge(agentID, (int)cost, "Asset upload");
115  }
116 
117  AddInventoryItem(item);
118  }
119 
120  public bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item)
121  {
122  if (AddInventoryItem(item))
123  return true;
124  else
125  {
126  m_log.WarnFormat(
127  "[AGENT INVENTORY]: Unable to add item {1} to agent {2} inventory", item.Name, AgentId);
128 
129  return false;
130  }
131  }
132 
134  {
135  return AddInventoryItem(item, true);
136  }
137 
142  public bool AddInventoryItem(InventoryItemBase item, bool trigger)
143  {
144  if (item.Folder != UUID.Zero && InventoryService.AddItem(item))
145  {
146  int userlevel = 0;
147  if (Permissions.IsGod(item.Owner))
148  {
149  userlevel = 1;
150  }
151  if (trigger)
152  EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
153 
154  return true;
155  }
156 
157  // OK so either the viewer didn't send a folderID or AddItem failed
158  UUID originalFolder = item.Folder;
159  InventoryFolderBase f = null;
160  if (Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
161  f = InventoryService.GetFolderForType(item.Owner, (FolderType)item.AssetType);
162  if (f != null)
163  {
164  m_log.DebugFormat(
165  "[AGENT INVENTORY]: Found folder {0} type {1} for item {2}",
166  f.Name, (AssetType)f.Type, item.Name);
167 
168  item.Folder = f.ID;
169  }
170  else
171  {
172  f = InventoryService.GetRootFolder(item.Owner);
173  if (f != null)
174  {
175  item.Folder = f.ID;
176  }
177  else
178  {
179  m_log.WarnFormat(
180  "[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
181  item.Owner, item.Name);
182  return false;
183  }
184  }
185 
186  if (InventoryService.AddItem(item))
187  {
188  int userlevel = 0;
189  if (Permissions.IsGod(item.Owner))
190  {
191  userlevel = 1;
192  }
193  if (trigger)
194  EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
195 
196  if (originalFolder != UUID.Zero)
197  {
198  // Tell the viewer that the item didn't go there
199  ChangePlacement(item, f);
200  }
201 
202  return true;
203  }
204  else
205  {
206  m_log.WarnFormat(
207  "[AGENT INVENTORY]: Agent {0} could not add item {1} {2}",
208  item.Owner, item.Name, item.ID);
209 
210  return false;
211  }
212  }
213 
214  private void ChangePlacement(InventoryItemBase item, InventoryFolderBase f)
215  {
216  ScenePresence sp = GetScenePresence(item.Owner);
217  if (sp != null)
218  {
219  if (sp.ControllingClient is IClientCore)
220  {
221  IClientCore core = (IClientCore)sp.ControllingClient;
222  IClientInventory inv;
223 
224  if (core.TryGet<IClientInventory>(out inv))
225  {
227  parent = InventoryService.GetFolder(parent);
228  inv.SendRemoveInventoryItems(new UUID[] { item.ID });
229  inv.SendBulkUpdateInventory(new InventoryFolderBase[0], new InventoryItemBase[] { item });
230  string message = "The item was placed in folder " + f.Name;
231  if (parent != null)
232  message += " under " + parent.Name;
233  sp.ControllingClient.SendAgentAlertMessage(message, false);
234  }
235  }
236  }
237  }
238 
248  [Obsolete("Use AddInventoryItem(InventoryItemBase item) instead. This was deprecated in OpenSim 0.7.1")]
249  public void AddInventoryItem(UUID AgentID, InventoryItemBase item)
250  {
251  AddInventoryItem(item);
252  }
253 
260  public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
261  {
262  AddInventoryItem(item);
263  remoteClient.SendInventoryItemCreateUpdate(item, 0);
264  }
265 
269  public UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data)
270  {
271  ScenePresence avatar;
272 
273  if (TryGetScenePresence(avatarId, out avatar))
274  {
275  IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
276  if (invAccess != null)
277  return invAccess.CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data);
278  }
279  else
280  {
281  m_log.ErrorFormat(
282  "[AGENT INVENTORY]: " +
283  "Avatar {0} cannot be found to update its inventory item asset",
284  avatarId);
285  }
286 
287  return UUID.Zero;
288  }
289 
298  public ArrayList CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId,
299  UUID primId, bool isScriptRunning, byte[] data)
300  {
301  if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId))
302  {
303  remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
304  return new ArrayList();
305  }
306 
307  // Retrieve group
308  SceneObjectPart part = GetSceneObjectPart(primId);
309  if (part == null)
310  return new ArrayList();
311 
312  SceneObjectGroup group = part.ParentGroup;
313 
314  // Retrieve item
315  TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId);
316 
317  if (null == item)
318  {
319  m_log.ErrorFormat(
320  "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update "
321  + " but the item does not exist in this inventory",
322  itemId, part.Name, part.UUID);
323 
324  return new ArrayList();
325  }
326 
327  AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId);
328  AssetService.Store(asset);
329 
330 // m_log.DebugFormat(
331 // "[PRIM INVENTORY]: Stored asset {0} when updating item {1} in prim {2} for {3}",
332 // asset.ID, item.Name, part.Name, remoteClient.Name);
333 
334  if (isScriptRunning)
335  {
336  part.Inventory.RemoveScriptInstance(item.ItemID, false);
337  }
338 
339  // Update item with new asset
340  item.AssetID = asset.FullID;
341  group.UpdateInventoryItem(item);
342 
343  part.SendPropertiesToClient(remoteClient);
344 
345  // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
346  ArrayList errors = new ArrayList();
347 
348  if (isScriptRunning)
349  {
350  // Needs to determine which engine was running it and use that
351  //
352  errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 1);
353  }
354 
355  // Tell anyone managing scripts that a script has been reloaded/changed
356  EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID);
357 
358  part.ParentGroup.ResumeScripts();
359  return errors;
360  }
361 
365  public ArrayList CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId,
366  UUID primId, bool isScriptRunning, byte[] data)
367  {
368  ScenePresence avatar;
369 
370  if (TryGetScenePresence(avatarId, out avatar))
371  {
372  return CapsUpdateTaskInventoryScriptAsset(
373  avatar.ControllingClient, itemId, primId, isScriptRunning, data);
374  }
375  else
376  {
377  m_log.ErrorFormat(
378  "[PRIM INVENTORY]: " +
379  "Avatar {0} cannot be found to update its prim item asset",
380  avatarId);
381  return new ArrayList();
382  }
383  }
384 
396 /* public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
397  UUID itemID, string name, string description,
398  uint nextOwnerMask)*/
399  public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
400  UUID itemID, InventoryItemBase itemUpd)
401  {
402 // m_log.DebugFormat(
403 // "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}",
404 // itemID, itemUpd.Name, transactionID, remoteClient.Name);
405 
406  // This one will let people set next perms on items in agent
407  // inventory. Rut-Roh. Whatever. Make this secure. Yeah.
408  //
409  // Passing something to another avatar or a an object will already
410  InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
411  item = InventoryService.GetItem(item);
412 
413  if (item != null)
414  {
415  if (item.Owner != remoteClient.AgentId)
416  return;
417 
418  item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
419  item.Name = itemUpd.Name;
420  item.Description = itemUpd.Description;
421 
422 // m_log.DebugFormat(
423 // "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
424 // itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
425 // item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
426 
427  bool sendUpdate = false;
428 
429  if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid
430  {
431  // Create a set of base permissions that will not include export if the user
432  // is not allowed to change the export flag.
433  bool denyExportChange = false;
434 
435 // m_log.DebugFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions);
436 
437  // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export
438  if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner)
439  denyExportChange = true;
440 
441 // m_log.DebugFormat("[XXX]: Deny Export Update {0}", denyExportChange);
442 
443  // If it is already set, force it set and also force full perm
444  // else prevent setting it. It can and should never be set unless
445  // set in base, so the condition above is valid
446  if (denyExportChange)
447  {
448  // If we are not allowed to change it, then force it to the
449  // original item's setting and if it was on, also force full perm
450  if ((item.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
451  {
452  itemUpd.NextPermissions = (uint)(PermissionMask.All);
453  itemUpd.EveryOnePermissions |= (uint)PermissionMask.Export;
454  }
455  else
456  {
457  itemUpd.EveryOnePermissions &= ~(uint)PermissionMask.Export;
458  }
459  }
460  else
461  {
462  // If the new state is exportable, force full perm
463  if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
464  {
465 // m_log.DebugFormat("[XXX]: Force full perm");
466  itemUpd.NextPermissions = (uint)(PermissionMask.All);
467  }
468  }
469 
470  if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
471  item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
472  item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
473 
474  if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions))
475  item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
476  item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
477 
478  if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
479  item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
480  item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
481 
482  item.GroupID = itemUpd.GroupID;
483  item.GroupOwned = itemUpd.GroupOwned;
484  item.CreationDate = itemUpd.CreationDate;
485  // The client sends zero if its newly created?
486 
487  if (itemUpd.CreationDate == 0)
488  item.CreationDate = Util.UnixTimeSinceEpoch();
489  else
490  item.CreationDate = itemUpd.CreationDate;
491 
492  // TODO: Check if folder changed and move item
493  //item.NextPermissions = itemUpd.Folder;
494  item.InvType = itemUpd.InvType;
495 
496  if (item.SalePrice != itemUpd.SalePrice ||
497  item.SaleType != itemUpd.SaleType)
498  item.Flags |= (uint)InventoryItemFlags.ObjectSlamSale;
499  item.SalePrice = itemUpd.SalePrice;
500  item.SaleType = itemUpd.SaleType;
501 
502  if (item.InvType == (int)InventoryType.Wearable && (item.Flags & 0xf) == 0 && (itemUpd.Flags & 0xf) != 0)
503  {
504  item.Flags = (uint)(item.Flags & 0xfffffff0) | (itemUpd.Flags & 0xf);
505  sendUpdate = true;
506  }
507 
508  InventoryService.UpdateItem(item);
509  }
510 
511  if (UUID.Zero != transactionID)
512  {
513  if (AgentTransactionsModule != null)
514  {
515  AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
516  }
517  }
518  else
519  {
520  // This MAY be problematic, if it is, another solution
521  // needs to be found. If inventory item flags are updated
522  // the viewer's notion of the item needs to be refreshed.
523  //
524  // In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start
525  // failing frequently. Possibly this is a race with a separate transaction that uploads the asset.
526  if (sendUpdate)
527  remoteClient.SendBulkUpdateInventory(item);
528  }
529  }
530  else
531  {
532  m_log.ErrorFormat(
533  "[AGENTINVENTORY]: Item id {0} not found for an inventory item update for {1}.",
534  itemID, remoteClient.Name);
535  }
536  }
537 
544  public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId, out string message)
545  {
546  InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId, out message);
547 
548  if (itemCopy != null)
549  recipientClient.SendBulkUpdateInventory(itemCopy);
550  }
551 
559  public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId, out string message)
560  {
561  return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero, out message);
562  }
563 
578  UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId, out string message)
579  {
580  //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem");
581 
582  if (!Permissions.CanTransferUserInventory(itemId, senderId, recipient))
583  {
584  message = "Not allowed to transfer this item.";
585  return null;
586  }
587 
588  InventoryItemBase item = new InventoryItemBase(itemId, senderId);
589  item = InventoryService.GetItem(item);
590 
591  if (item == null)
592  {
593  m_log.WarnFormat(
594  "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
595  message = string.Format("Item not found: {0}.", itemId);
596  return null;
597  }
598 
599  if (item.Owner != senderId)
600  {
601  m_log.WarnFormat(
602  "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
603  item.Name, item.ID, recipient, senderId, item.Owner);
604  message = "Sender did not match item owner.";
605  return null;
606  }
607 
608  IUserManagement uman = RequestModuleInterface<IUserManagement>();
609  if (uman != null)
610  uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
611 
612  if (!Permissions.BypassPermissions())
613  {
614  if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
615  {
616  message = "Item doesn't have the Transfer permission.";
617  return null;
618  }
619  }
620 
621  // Insert a copy of the item into the recipient
622  InventoryItemBase itemCopy = new InventoryItemBase();
623  itemCopy.Owner = recipient;
624  itemCopy.CreatorId = item.CreatorId;
625  itemCopy.CreatorData = item.CreatorData;
626  itemCopy.ID = UUID.Random();
627  itemCopy.AssetID = item.AssetID;
628  itemCopy.Description = item.Description;
629  itemCopy.Name = item.Name;
630  itemCopy.AssetType = item.AssetType;
631  itemCopy.InvType = item.InvType;
632  itemCopy.Folder = recipientFolderId;
633 
634  if (Permissions.PropagatePermissions() && recipient != senderId)
635  {
636  // Trying to do this right this time. This is evil. If
637  // you believe in Good, go elsewhere. Vampires and other
638  // evil creatores only beyond this point. You have been
639  // warned.
640 
641  // We're going to mask a lot of things by the next perms
642  // Tweak the next perms to be nicer to our data
643  //
644  // In this mask, all the bits we do NOT want to mess
645  // with are set. These are:
646  //
647  // Transfer
648  // Copy
649  // Modufy
650  uint permsMask = ~ ((uint)PermissionMask.Copy |
651  (uint)PermissionMask.Transfer |
652  (uint)PermissionMask.Modify);
653 
654  // Now, reduce the next perms to the mask bits
655  // relevant to the operation
656  uint nextPerms = permsMask | (item.NextPermissions &
657  ((uint)PermissionMask.Copy |
658  (uint)PermissionMask.Transfer |
659  (uint)PermissionMask.Modify));
660 
661  // nextPerms now has all bits set, except for the actual
662  // next permission bits.
663 
664  // This checks for no mod, no copy, no trans.
665  // This indicates an error or messed up item. Do it like
666  // SL and assume trans
667  if (nextPerms == permsMask)
668  nextPerms |= (uint)PermissionMask.Transfer;
669 
670  // Inventory owner perms are the logical AND of the
671  // folded perms and the root prim perms, however, if
672  // the root prim is mod, the inventory perms will be
673  // mod. This happens on "take" and is of little concern
674  // here, save for preventing escalation
675 
676  // This hack ensures that items previously permalocked
677  // get unlocked when they're passed or rezzed
678  uint basePerms = item.BasePermissions |
679  (uint)PermissionMask.Move;
680  uint ownerPerms = item.CurrentPermissions;
681 
682  // If this is an object, root prim perms may be more
683  // permissive than folded perms. Use folded perms as
684  // a mask
685  if (item.InvType == (int)InventoryType.Object)
686  {
687  bool isRootMod = (item.CurrentPermissions &
688  (uint)PermissionMask.Modify) != 0 ?
689  true : false;
690 
691  // Mask the owner perms to the folded perms
692  PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref ownerPerms);
693  PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref basePerms);
694 
695  // If the root was mod, let the mask reflect that
696  // We also need to adjust the base here, because
697  // we should be able to edit in-inventory perms
698  // for the root prim, if it's mod.
699  if (isRootMod)
700  {
701  ownerPerms |= (uint)PermissionMask.Modify;
702  basePerms |= (uint)PermissionMask.Modify;
703  }
704  }
705 
706  // These will be applied to the root prim at next rez.
707  // The slam bit (bit 3) and folded permission (bits 0-2)
708  // are preserved due to the above mangling
709  ownerPerms &= nextPerms;
710 
711  // Mask the base permissions. This is a conservative
712  // approach altering only the three main perms
713  basePerms &= nextPerms;
714 
715  // Assign to the actual item. Make sure the slam bit is
716  // set, if it wasn't set before.
717  itemCopy.BasePermissions = basePerms;
718  itemCopy.CurrentPermissions = ownerPerms;
719  itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
720 
721  itemCopy.NextPermissions = item.NextPermissions;
722 
723  // This preserves "everyone can move"
724  itemCopy.EveryOnePermissions = item.EveryOnePermissions &
725  nextPerms;
726 
727  // Intentionally killing "share with group" here, as
728  // the recipient will not have the group this is
729  // set to
730  itemCopy.GroupPermissions = 0;
731  }
732  else
733  {
734  itemCopy.CurrentPermissions = item.CurrentPermissions;
735  itemCopy.NextPermissions = item.NextPermissions;
736  itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
737  itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
738  itemCopy.BasePermissions = item.BasePermissions;
739  }
740 
741  if (itemCopy.Folder == UUID.Zero)
742  {
743  InventoryFolderBase folder = null;
744  if (Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
745  folder = InventoryService.GetFolderForType(recipient, (FolderType)itemCopy.AssetType);
746 
747  if (folder != null)
748  {
749  itemCopy.Folder = folder.ID;
750  }
751  else
752  {
753  InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
754 
755  if (root != null)
756  {
757  itemCopy.Folder = root.ID;
758  }
759  else
760  {
761  message = "Can't find a folder to add the item to.";
762  return null;
763  }
764  }
765  }
766 
767  itemCopy.GroupID = UUID.Zero;
768  itemCopy.GroupOwned = false;
769  itemCopy.Flags = item.Flags;
770  itemCopy.SalePrice = item.SalePrice;
771  itemCopy.SaleType = item.SaleType;
772 
773  IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
774  if (invAccess != null)
775  invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
776  AddInventoryItem(itemCopy, false);
777 
778  if (!Permissions.BypassPermissions())
779  {
780  if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
781  {
782  List<UUID> items = new List<UUID>();
783  items.Add(itemId);
784  InventoryService.DeleteItems(senderId, items);
785  }
786  }
787 
788  message = null;
789  return itemCopy;
790  }
791 
807  UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
808  {
810  InventoryFolderBase folder = InventoryService.GetFolder(new InventoryFolderBase(folderId, senderId));
811  if (null == folder)
812  {
813  m_log.ErrorFormat(
814  "[AGENT INVENTORY]: Could not find inventory folder {0} to give", folderId);
815 
816  return null;
817  }
818 
819  if (recipientParentFolderId == UUID.Zero)
820  {
821  InventoryFolderBase recipientRootFolder = InventoryService.GetRootFolder(recipientId);
822  if (recipientRootFolder != null)
823  recipientParentFolderId = recipientRootFolder.ID;
824  else
825  {
826  m_log.WarnFormat("[AGENT INVENTORY]: Unable to find root folder for receiving agent");
827  return null;
828  }
829  }
830 
831  UUID newFolderId = UUID.Random();
832  InventoryFolderBase newFolder
833  = new InventoryFolderBase(
834  newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version);
835  InventoryService.AddFolder(newFolder);
836 
837  // Give all the subfolders
838  InventoryCollection contents = InventoryService.GetFolderContent(senderId, folderId);
839  foreach (InventoryFolderBase childFolder in contents.Folders)
840  {
841  GiveInventoryFolder(client, recipientId, senderId, childFolder.ID, newFolder.ID);
842  }
843 
844  // Give all the items
845  foreach (InventoryItemBase item in contents.Items)
846  {
847  string message;
848  if (GiveInventoryItem(recipientId, senderId, item.ID, newFolder.ID, out message) == null)
849  {
850  if (client != null)
851  client.SendAgentAlertMessage(message, false);
852  }
853  }
854 
855  return newFolder;
856  }
857 
858  public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID,
859  UUID newFolderID, string newName)
860  {
861  m_log.DebugFormat(
862  "[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}",
863  remoteClient.AgentId, oldAgentID, oldItemID, newFolderID, newName);
864 
865  InventoryItemBase item = null;
866  if (LibraryService != null && LibraryService.LibraryRootFolder != null)
867  item = LibraryService.LibraryRootFolder.FindItem(oldItemID);
868 
869  if (item == null)
870  {
871  item = new InventoryItemBase(oldItemID, remoteClient.AgentId);
872  item = InventoryService.GetItem(item);
873 
874  if (item == null)
875  {
876  m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
877  return;
878  }
879 
880  if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
881  return;
882  }
883 
884  if (newName == String.Empty)
885  newName = item.Name;
886 
887  AssetBase asset = AssetService.Get(item.AssetID.ToString());
888 
889  if (asset != null)
890  {
891  if (newName != String.Empty)
892  {
893  asset.Name = newName;
894  }
895  else
896  {
897  newName = item.Name;
898  }
899 
900 
901  if (remoteClient.AgentId == oldAgentID
902  || (LibraryService != null
903  && LibraryService.LibraryRootFolder != null
904  && oldAgentID == LibraryService.LibraryRootFolder.Owner))
905  {
907  remoteClient, item.CreatorId, item.CreatorData, newFolderID,
908  newName, item.Description, item.Flags, callbackID, item.AssetID, (sbyte)item.AssetType, (sbyte)item.InvType,
909  item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions,
910  item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
911  }
912  else
913  {
914  // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
915  if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
916  && (m_permissions.BypassPermissions()
917  || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
918  {
920  remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
921  item.AssetID, (sbyte)item.AssetType, (sbyte) item.InvType,
922  item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
923  item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch(), false);
924  }
925  }
926  }
927  else
928  {
929  m_log.ErrorFormat(
930  "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
931  item.Name, item.AssetID);
932  }
933  }
934 
938  public AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, UUID creatorID)
939  {
940  AssetBase asset = new AssetBase(UUID.Random(), name, assetType, creatorID.ToString());
941  asset.Description = description;
942  asset.Data = (data == null) ? new byte[1] : data;
943 
944  return asset;
945  }
946 
950  public void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List<InventoryItemBase> items, UUID destfolder)
951  {
952  List<InventoryItemBase> moveitems = new List<InventoryItemBase>();
953  foreach (InventoryItemBase b in items)
954  {
955  CopyInventoryItem(remoteClient, 0, remoteClient.AgentId, b.ID, b.Folder, null);
956  InventoryItemBase n = InventoryService.GetItem(b);
957  n.Folder = destfolder;
958  moveitems.Add(n);
959  remoteClient.SendInventoryItemCreateUpdate(n, 0);
960  }
961 
962  MoveInventoryItem(remoteClient, moveitems);
963  }
964 
973  public void MoveInventoryItem(IClientAPI remoteClient, List<InventoryItemBase> items)
974  {
975  m_log.DebugFormat(
976  "[AGENT INVENTORY]: Moving {0} items for user {1}", items.Count, remoteClient.AgentId);
977 
978  if (!InventoryService.MoveItems(remoteClient.AgentId, items))
979  m_log.Warn("[AGENT INVENTORY]: Failed to move items for user " + remoteClient.AgentId);
980  }
981 
998  IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
999  string name, string description, uint flags, uint callbackID,
1000  UUID assetID, sbyte assetType, sbyte invType, uint nextOwnerMask, int creationDate)
1001  {
1003  remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, assetID, assetType, invType,
1004  (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, 0, nextOwnerMask, 0,
1005  creationDate, true);
1006  }
1007 
1027  private void CreateNewInventoryItem(
1028  IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
1029  string name, string description, uint flags, uint callbackID, UUID assetID, sbyte assetType, sbyte invType,
1030  uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate,
1031  bool assetUpload)
1032  {
1033  InventoryItemBase item = new InventoryItemBase();
1034  item.Owner = remoteClient.AgentId;
1035  item.CreatorId = creatorID;
1036  item.CreatorData = creatorData;
1037  item.ID = UUID.Random();
1038  item.AssetID = assetID;
1039  item.Name = name;
1040  item.Description = description;
1041  item.Flags = flags;
1042  item.AssetType = assetType;
1043  item.InvType = invType;
1044  item.Folder = folderID;
1045  item.CurrentPermissions = currentMask;
1046  item.NextPermissions = nextOwnerMask;
1047  item.EveryOnePermissions = everyoneMask;
1048  item.GroupPermissions = groupMask;
1049  item.BasePermissions = baseMask;
1050  item.CreationDate = creationDate;
1051 
1052  // special AnimationSet case
1053  if (item.InvType == (int)CustomInventoryType.AnimationSet)
1055 
1056  if (AddInventoryItem(item))
1057  {
1058  remoteClient.SendInventoryItemCreateUpdate(item, callbackID);
1059  }
1060  else
1061  {
1062  m_dialogModule.SendAlertToUser(remoteClient, "Failed to create item");
1063  m_log.WarnFormat(
1064  "Failed to add item for {0} in CreateNewInventoryItem!",
1065  remoteClient.Name);
1066  }
1067  }
1068 
1085  private void HandleLinkInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID,
1086  uint callbackID, string description, string name,
1087  sbyte invType, sbyte type, UUID olditemID)
1088  {
1089 // m_log.DebugFormat(
1090 // "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}, assetType {4}, inventoryType {5}",
1091 // remoteClient.Name, name, folderID, olditemID, (AssetType)type, (InventoryType)invType);
1092 
1093  if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
1094  return;
1095 
1096  ScenePresence presence;
1097  if (TryGetScenePresence(remoteClient.AgentId, out presence))
1098  {
1099  // Disabled the check for duplicate links.
1100  //
1101  // When outfits are being adjusted, the viewer rapidly sends delete link messages followed by
1102  // create links. However, since these are handled asynchronously, the deletes do not complete before
1103  // the creates are handled. Therefore, we cannot enforce a duplicate link check.
1104 // InventoryItemBase existingLink = null;
1105 // List<InventoryItemBase> existingItems = InventoryService.GetFolderItems(remoteClient.AgentId, folderID);
1106 // foreach (InventoryItemBase item in existingItems)
1107 // if (item.AssetID == olditemID)
1108 // existingLink = item;
1109 //
1110 // if (existingLink != null)
1111 // {
1112 // m_log.WarnFormat(
1113 // "[AGENT INVENTORY]: Ignoring request from {0} to create item link {1} in folder {2} pointing to {3} since a link named {4} with id {5} already exists",
1114 // remoteClient.Name, name, folderID, olditemID, existingLink.Name, existingLink.ID);
1115 //
1116 // return;
1117 // }
1118 
1120  remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
1121  name, description, 0, callbackID, olditemID, type, invType,
1122  (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All,
1123  (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, Util.UnixTimeSinceEpoch(),
1124  false);
1125  }
1126  else
1127  {
1128  m_log.ErrorFormat(
1129  "ScenePresence for agent uuid {0} unexpectedly not found in HandleLinkInventoryItem",
1130  remoteClient.AgentId);
1131  }
1132  }
1133 
1139  private void RemoveInventoryItem(IClientAPI remoteClient, List<UUID> itemIDs)
1140  {
1141 // m_log.DebugFormat(
1142 // "[AGENT INVENTORY]: Removing inventory items {0} for {1}",
1143 // string.Join(",", itemIDs.ConvertAll<string>(uuid => uuid.ToString()).ToArray()),
1144 // remoteClient.Name);
1145 
1146  InventoryService.DeleteItems(remoteClient.AgentId, itemIDs);
1147  }
1148 
1155  private void RemoveInventoryFolder(IClientAPI remoteClient, List<UUID> folderIDs)
1156  {
1157  m_log.DebugFormat("[SCENE INVENTORY]: RemoveInventoryFolders count {0}", folderIDs.Count);
1158  InventoryService.DeleteFolders(remoteClient.AgentId, folderIDs);
1159  }
1160 
1166  public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID)
1167  {
1168  SceneObjectPart part = GetSceneObjectPart(primLocalID);
1169  if (part == null)
1170  return;
1171 
1172  if (XferManager != null)
1173  part.Inventory.RequestInventoryFile(remoteClient, XferManager);
1174  }
1175 
1183  public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
1184  {
1185  SceneObjectPart part = GetSceneObjectPart(localID);
1186  SceneObjectGroup group = null;
1187  if (part != null)
1188  {
1189  group = part.ParentGroup;
1190  }
1191  if (part != null && group != null)
1192  {
1193  if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
1194  return;
1195 
1196  TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
1197  if (item == null)
1198  return;
1199 
1200  InventoryFolderBase destFolder = InventoryService.GetFolderForType(remoteClient.AgentId, FolderType.Trash);
1201 
1202  // Move the item to trash. If this is a copyable item, only
1203  // a copy will be moved and we will still need to delete
1204  // the item from the prim. If it was no copy, it will be
1205  // deleted by this method.
1206  string message;
1207  InventoryItemBase item2 = MoveTaskInventoryItem(remoteClient, destFolder.ID, part, itemID, out message);
1208 
1209  if (item2 == null)
1210  {
1211  m_log.WarnFormat("[SCENE INVENTORY]: RemoveTaskInventory of item {0} failed: {1}", itemID, message);
1212  remoteClient.SendAgentAlertMessage(message, false);
1213  return;
1214  }
1215 
1216  if (group.GetInventoryItem(localID, itemID) != null)
1217  {
1218  if (item.Type == 10)
1219  {
1220  part.RemoveScriptEvents(itemID);
1221  EventManager.TriggerRemoveScript(localID, itemID);
1222  }
1223 
1224  group.RemoveInventoryItem(localID, itemID);
1225  }
1226 
1227  part.SendPropertiesToClient(remoteClient);
1228  }
1229  }
1230 
1231 
1235  private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId, out string message)
1236  {
1237  TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
1238 
1239  if (null == taskItem)
1240  {
1241  m_log.ErrorFormat(
1242  "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for creating an avatar"
1243  + " inventory item from a prim's inventory item "
1244  + " but the required item does not exist in the prim's inventory",
1245  itemId, part.Name, part.UUID);
1246  message = "Item not found: " + itemId;
1247  return null;
1248  }
1249 
1250  if ((destAgent != taskItem.OwnerID) && ((taskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
1251  {
1252  message = "Item doesn't have the Transfer permission.";
1253  return null;
1254  }
1255 
1256  InventoryItemBase agentItem = new InventoryItemBase();
1257 
1258  agentItem.ID = UUID.Random();
1259  agentItem.CreatorId = taskItem.CreatorID.ToString();
1260  agentItem.CreatorData = taskItem.CreatorData;
1261  agentItem.Owner = destAgent;
1262  agentItem.AssetID = taskItem.AssetID;
1263  agentItem.Description = taskItem.Description;
1264  agentItem.Name = taskItem.Name;
1265  agentItem.AssetType = taskItem.Type;
1266  agentItem.InvType = taskItem.InvType;
1267  agentItem.Flags = taskItem.Flags;
1268 
1269  if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions())
1270  {
1271  agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
1272  if (taskItem.InvType == (int)InventoryType.Object)
1273  {
1274  // Bake the new base permissions from folded permissions
1275  // The folded perms are in the lowest 3 bits of the current perms
1276  // We use base permissions here to avoid baking the "Locked" status
1277  // into the item as it is passed.
1278  uint perms = taskItem.BasePermissions & taskItem.NextPermissions;
1279  PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms);
1280  // Avoid the "lock trap" - move must always be enabled but the above may remove it
1281  // Add it back here.
1282  agentItem.BasePermissions = perms | (uint)PermissionMask.Move;
1283  // Newly given items cannot be "locked" on rez. Make sure by
1284  // setting current equal to base.
1285  }
1286 
1287  agentItem.CurrentPermissions = agentItem.BasePermissions;
1288 
1289  agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
1290  agentItem.NextPermissions = taskItem.NextPermissions;
1291  agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
1292  agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
1293  }
1294  else
1295  {
1296  agentItem.BasePermissions = taskItem.BasePermissions;
1297  agentItem.CurrentPermissions = taskItem.CurrentPermissions;
1298  agentItem.NextPermissions = taskItem.NextPermissions;
1299  agentItem.EveryOnePermissions = taskItem.EveryonePermissions;
1300  agentItem.GroupPermissions = taskItem.GroupPermissions;
1301  }
1302 
1303  message = null;
1304  return agentItem;
1305  }
1306 
1310  private void RemoveNonCopyTaskItemFromPrim(SceneObjectPart part, UUID itemId)
1311  {
1312  TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
1313  if (taskItem == null)
1314  return;
1315 
1316  if (!Permissions.BypassPermissions())
1317  {
1318  if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1319  {
1320  if (taskItem.Type == (int)AssetType.LSLText)
1321  {
1322  part.RemoveScriptEvents(itemId);
1323  EventManager.TriggerRemoveScript(part.LocalId, itemId);
1324  }
1325 
1326  part.Inventory.RemoveInventoryItem(itemId);
1327  }
1328  }
1329  }
1330 
1338  public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
1339  {
1340  m_log.DebugFormat(
1341  "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}",
1342  itemId, part.Name, folderId, remoteClient.Name);
1343 
1344  InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId, out message);
1345  if (agentItem == null)
1346  return null;
1347 
1348  agentItem.Folder = folderId;
1349  AddInventoryItem(remoteClient, agentItem);
1350 
1351  RemoveNonCopyTaskItemFromPrim(part, itemId);
1352 
1353  message = null;
1354  return agentItem;
1355  }
1356 
1364  public void ClientMoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, uint primLocalId, UUID itemId)
1365  {
1366  SceneObjectPart part = GetSceneObjectPart(primLocalId);
1367 
1368  // Can't move a null item
1369  if (itemId == UUID.Zero)
1370  return;
1371 
1372  if (null == part)
1373  {
1374  m_log.WarnFormat(
1375  "[PRIM INVENTORY]: " +
1376  "Move of inventory item {0} from prim with local id {1} failed because the prim could not be found",
1377  itemId, primLocalId);
1378 
1379  return;
1380  }
1381 
1382  TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
1383 
1384  if (null == taskItem)
1385  {
1386  m_log.WarnFormat("[PRIM INVENTORY]: Move of inventory item {0} from prim with local id {1} failed"
1387  + " because the inventory item could not be found",
1388  itemId, primLocalId);
1389 
1390  return;
1391  }
1392 
1393  if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1394  {
1395  // If the item to be moved is no copy, we need to be able to
1396  // edit the prim.
1397  if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
1398  return;
1399  }
1400  else
1401  {
1402  // If the item is copiable, then we just need to have perms
1403  // on it. The delete check is a pure rights check
1404  if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId))
1405  return;
1406  }
1407 
1408  string message;
1409  InventoryItemBase item = MoveTaskInventoryItem(remoteClient, folderId, part, itemId, out message);
1410 
1411  if (item == null)
1412  remoteClient.SendAgentAlertMessage(message, false);
1413  }
1414 
1426  public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
1427  {
1428  ScenePresence avatar;
1429 
1430  if (TryGetScenePresence(avatarId, out avatar))
1431  {
1432  return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId, out message);
1433  }
1434  else
1435  {
1436  InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId, out message);
1437 
1438  if (agentItem == null)
1439  return null;
1440 
1441  agentItem.Folder = folderId;
1442 
1443  AddInventoryItem(agentItem);
1444 
1445  RemoveNonCopyTaskItemFromPrim(part, itemId);
1446 
1447  return agentItem;
1448  }
1449  }
1450 
1457  public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
1458  {
1459  TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
1460 
1461  if (srcTaskItem == null)
1462  {
1463  m_log.ErrorFormat(
1464  "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for moving"
1465  + " but the item does not exist in this inventory",
1466  itemId, part.Name, part.UUID);
1467 
1468  return;
1469  }
1470 
1471  SceneObjectPart destPart = GetSceneObjectPart(destId);
1472 
1473  if (destPart == null)
1474  {
1475  m_log.ErrorFormat(
1476  "[PRIM INVENTORY]: " +
1477  "Could not find prim for ID {0}",
1478  destId);
1479  return;
1480  }
1481 
1482  // Can't transfer this
1483  //
1484  if (part.OwnerID != destPart.OwnerID && (srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1485  return;
1486 
1487  bool overrideNoMod = false;
1488  if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0)
1489  overrideNoMod = true;
1490 
1491  if (part.OwnerID != destPart.OwnerID && (destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1492  {
1493  // object cannot copy items to an object owned by a different owner
1494  // unless llAllowInventoryDrop has been called
1495 
1496  return;
1497  }
1498 
1499  // must have both move and modify permission to put an item in an object
1500  if (((part.OwnerMask & (uint)PermissionMask.Modify) == 0) && (!overrideNoMod))
1501  {
1502  return;
1503  }
1504 
1505  TaskInventoryItem destTaskItem = new TaskInventoryItem();
1506 
1507  destTaskItem.ItemID = UUID.Random();
1508  destTaskItem.CreatorID = srcTaskItem.CreatorID;
1509  destTaskItem.CreatorData = srcTaskItem.CreatorData;
1510  destTaskItem.AssetID = srcTaskItem.AssetID;
1511  destTaskItem.GroupID = destPart.GroupID;
1512  destTaskItem.OwnerID = destPart.OwnerID;
1513  destTaskItem.ParentID = destPart.UUID;
1514  destTaskItem.ParentPartID = destPart.UUID;
1515 
1516  destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
1517  destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
1518  destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
1519  destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
1520  destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
1521  destTaskItem.Flags = srcTaskItem.Flags;
1522 
1523  if (destPart.OwnerID != part.OwnerID)
1524  {
1525  if (Permissions.PropagatePermissions())
1526  {
1527  destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
1528  (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1529  destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
1530  (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1531  destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
1532  (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1533  destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
1534  (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1535  destTaskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
1536  }
1537  }
1538 
1539  destTaskItem.Description = srcTaskItem.Description;
1540  destTaskItem.Name = srcTaskItem.Name;
1541  destTaskItem.InvType = srcTaskItem.InvType;
1542  destTaskItem.Type = srcTaskItem.Type;
1543 
1544  destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID);
1545 
1546  if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1547  part.Inventory.RemoveInventoryItem(itemId);
1548 
1549  ScenePresence avatar;
1550 
1551  if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
1552  {
1553  destPart.SendPropertiesToClient(avatar.ControllingClient);
1554  }
1555  }
1556 
1557  public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items)
1558  {
1559 
1560  ScenePresence avatar;
1561  IClientAPI remoteClient = null;
1562  if (TryGetScenePresence(destID, out avatar))
1563  remoteClient = avatar.ControllingClient;
1564 // ????
1565  SceneObjectPart destPart = GetSceneObjectPart(destID);
1566  if (destPart != null) // Move into a prim
1567  {
1568  foreach(UUID itemID in items)
1569  MoveTaskInventoryItem(destID, host, itemID);
1570  return destID; // Prim folder ID == prim ID
1571  }
1572 // /????
1573 
1574  InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID);
1575 
1576  UUID newFolderID = UUID.Random();
1577 
1578  InventoryFolderBase newFolder = new InventoryFolderBase(newFolderID, category, destID, -1, rootFolder.ID, rootFolder.Version);
1579  InventoryService.AddFolder(newFolder);
1580 
1581  foreach (UUID itemID in items)
1582  {
1583  string message;
1584  InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(destID, host, itemID, out message);
1585 
1586  if (agentItem != null)
1587  {
1588  agentItem.Folder = newFolderID;
1589 
1590  AddInventoryItem(agentItem);
1591 
1592  RemoveNonCopyTaskItemFromPrim(host, itemID);
1593  }
1594  else
1595  {
1596  if (remoteClient != null)
1597  remoteClient.SendAgentAlertMessage(message, false);
1598  }
1599  }
1600 
1601  if (remoteClient != null)
1602  {
1603  SendInventoryUpdate(remoteClient, rootFolder, true, false);
1604  SendInventoryUpdate(remoteClient, newFolder, false, true);
1605  }
1606 
1607  return newFolderID;
1608  }
1609 
1610  public void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
1611  {
1612  if (folder == null)
1613  return;
1614 
1615  // TODO: This code for looking in the folder for the library should be folded somewhere else
1616  // so that this class doesn't have to know the details (and so that multiple libraries, etc.
1617  // can be handled transparently).
1618  InventoryFolderImpl fold = null;
1619  if (LibraryService != null && LibraryService.LibraryRootFolder != null)
1620  {
1621  if ((fold = LibraryService.LibraryRootFolder.FindFolder(folder.ID)) != null)
1622  {
1623  client.SendInventoryFolderDetails(
1624  fold.Owner, folder.ID, fold.RequestListOfItems(),
1625  fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems);
1626  return;
1627  }
1628  }
1629 
1630  // Fetch the folder contents
1631  InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID);
1632 
1633  // Fetch the folder itself to get its current version
1634  InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId);
1635  containingFolder = InventoryService.GetFolder(containingFolder);
1636 
1637 // m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
1638 // contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
1639 
1640  if (containingFolder != null)
1641  {
1642  // If the folder requested contains links, then we need to send those folders first, otherwise the links
1643  // will be broken in the viewer.
1644  HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
1645  foreach (InventoryItemBase item in contents.Items)
1646  {
1647  if (item.AssetType == (int)AssetType.Link)
1648  {
1649  InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID));
1650 
1651  // Take care of genuinely broken links where the target doesn't exist
1652  // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
1653  // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
1654  // rather than having to keep track of every folder requested in the recursion.
1655  if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
1656  {
1657  // We don't need to send the folder if source and destination of the link are in the same
1658  // folder.
1659  if (linkedItem.Folder != containingFolder.ID)
1660  linkedItemFolderIdsToSend.Add(linkedItem.Folder);
1661  }
1662  }
1663  }
1664 
1665  foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
1666  SendInventoryUpdate(client, new InventoryFolderBase(linkedItemFolderId), false, true);
1667 
1668  client.SendInventoryFolderDetails(
1669  client.AgentId, folder.ID, contents.Items, contents.Folders,
1670  containingFolder.Version, fetchFolders, fetchItems);
1671  }
1672  }
1673 
1682  public void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem itemInfo,
1683  uint primLocalID)
1684  {
1685  UUID itemID = itemInfo.ItemID;
1686 
1687  // Find the prim we're dealing with
1688  SceneObjectPart part = GetSceneObjectPart(primLocalID);
1689 
1690  if (part != null)
1691  {
1692  TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID);
1693  bool allowInventoryDrop = (part.GetEffectiveObjectFlags()
1694  & (uint)PrimFlags.AllowInventoryDrop) != 0;
1695 
1696  // Explicity allow anyone to add to the inventory if the
1697  // AllowInventoryDrop flag has been set. Don't however let
1698  // them update an item unless they pass the external checks
1699  //
1700  if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)
1701  && (currentItem != null || !allowInventoryDrop))
1702  return;
1703 
1704  if (currentItem == null)
1705  {
1706  UUID copyID = UUID.Random();
1707  if (itemID != UUID.Zero)
1708  {
1709  InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
1710  item = InventoryService.GetItem(item);
1711 
1712  // Try library
1713  if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
1714  {
1715  item = LibraryService.LibraryRootFolder.FindItem(itemID);
1716  }
1717 
1718  // If we've found the item in the user's inventory or in the library
1719  if (item != null)
1720  {
1721  part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID);
1722  m_log.InfoFormat(
1723  "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
1724  item.Name, primLocalID, remoteClient.Name);
1725  part.SendPropertiesToClient(remoteClient);
1726  if (!Permissions.BypassPermissions())
1727  {
1728  if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1729  {
1730  List<UUID> uuids = new List<UUID>();
1731  uuids.Add(itemID);
1732  RemoveInventoryItem(remoteClient, uuids);
1733  }
1734  }
1735  }
1736  else
1737  {
1738  m_log.ErrorFormat(
1739  "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!",
1740  itemID, remoteClient.Name);
1741  }
1742  }
1743  }
1744  else // Updating existing item with new perms etc
1745  {
1746 // m_log.DebugFormat(
1747 // "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
1748 // currentItem.Name, part.Name);
1749 
1750  // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the
1751  // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update)
1752  // will not pass in a transaction ID in the update message.
1753  if (transactionID != UUID.Zero && AgentTransactionsModule != null)
1754  {
1755  AgentTransactionsModule.HandleTaskItemUpdateFromTransaction(
1756  remoteClient, part, transactionID, currentItem);
1757 
1758 // if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1759 // remoteClient.SendAgentAlertMessage("Notecard saved", false);
1760 // else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1761 // remoteClient.SendAgentAlertMessage("Script saved", false);
1762 // else
1763 // remoteClient.SendAgentAlertMessage("Item saved", false);
1764  }
1765 
1766  // Base ALWAYS has move
1767  currentItem.BasePermissions |= (uint)PermissionMask.Move;
1768 
1769  itemInfo.Flags = currentItem.Flags;
1770 
1771  // Check if we're allowed to mess with permissions
1772  if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god
1773  {
1774  if (remoteClient.AgentId != part.OwnerID) // Not owner
1775  {
1776  // Friends and group members can't change any perms
1777  itemInfo.BasePermissions = currentItem.BasePermissions;
1778  itemInfo.EveryonePermissions = currentItem.EveryonePermissions;
1779  itemInfo.GroupPermissions = currentItem.GroupPermissions;
1780  itemInfo.NextPermissions = currentItem.NextPermissions;
1781  itemInfo.CurrentPermissions = currentItem.CurrentPermissions;
1782  }
1783  else
1784  {
1785  // Owner can't change base, and can change other
1786  // only up to base
1787  itemInfo.BasePermissions = currentItem.BasePermissions;
1788  if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions)
1789  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
1790  if (itemInfo.GroupPermissions != currentItem.GroupPermissions)
1791  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
1792  if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions)
1793  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
1794  if (itemInfo.NextPermissions != currentItem.NextPermissions)
1795  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
1796  itemInfo.EveryonePermissions &= currentItem.BasePermissions;
1797  itemInfo.GroupPermissions &= currentItem.BasePermissions;
1798  itemInfo.CurrentPermissions &= currentItem.BasePermissions;
1799  itemInfo.NextPermissions &= currentItem.BasePermissions;
1800  }
1801 
1802  }
1803  else
1804  {
1805  if (itemInfo.BasePermissions != currentItem.BasePermissions)
1806  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase;
1807  if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions)
1808  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
1809  if (itemInfo.GroupPermissions != currentItem.GroupPermissions)
1810  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
1811  if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions)
1812  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
1813  if (itemInfo.NextPermissions != currentItem.NextPermissions)
1814  itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
1815  }
1816 
1817  // Next ALWAYS has move
1818  itemInfo.NextPermissions |= (uint)PermissionMask.Move;
1819 
1820  if (part.Inventory.UpdateInventoryItem(itemInfo))
1821  {
1822  part.SendPropertiesToClient(remoteClient);
1823  }
1824  }
1825  }
1826  else
1827  {
1828  m_log.WarnFormat(
1829  "[PRIM INVENTORY]: " +
1830  "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
1831  itemID, primLocalID, remoteClient.Name);
1832  }
1833  }
1834 
1842  public void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID)
1843  {
1844  SceneObjectPart partWhereRezzed;
1845 
1846  if (itemBase.ID != UUID.Zero)
1847  partWhereRezzed = RezScriptFromAgentInventory(remoteClient.AgentId, itemBase.ID, localID);
1848  else
1849  partWhereRezzed = RezNewScript(remoteClient.AgentId, itemBase);
1850 
1851  if (partWhereRezzed != null)
1852  partWhereRezzed.SendPropertiesToClient(remoteClient);
1853  }
1854 
1862  public SceneObjectPart RezScriptFromAgentInventory(UUID agentID, UUID fromItemID, uint localID)
1863  {
1864  UUID copyID = UUID.Random();
1865  InventoryItemBase item = new InventoryItemBase(fromItemID, agentID);
1866  item = InventoryService.GetItem(item);
1867 
1868  // Try library
1869  // XXX clumsy, possibly should be one call
1870  if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
1871  {
1872  item = LibraryService.LibraryRootFolder.FindItem(fromItemID);
1873  }
1874 
1875  if (item != null)
1876  {
1877  SceneObjectPart part = GetSceneObjectPart(localID);
1878  if (part != null)
1879  {
1880  if (!Permissions.CanEditObjectInventory(part.UUID, agentID))
1881  return null;
1882 
1883  part.ParentGroup.AddInventoryItem(agentID, localID, item, copyID);
1884  // TODO: switch to posting on_rez here when scripts
1885  // have state in inventory
1886  part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
1887 
1888  // tell anyone watching that there is a new script in town
1889  EventManager.TriggerNewScript(agentID, part, copyID);
1890 
1891  // m_log.InfoFormat("[PRIMINVENTORY]: " +
1892  // "Rezzed script {0} into prim local ID {1} for user {2}",
1893  // item.inventoryName, localID, remoteClient.Name);
1894 
1895  part.ParentGroup.ResumeScripts();
1896 
1897  return part;
1898  }
1899  else
1900  {
1901  m_log.ErrorFormat(
1902  "[PRIM INVENTORY]: " +
1903  "Could not rez script {0} into prim local ID {1} for user {2}"
1904  + " because the prim could not be found in the region!",
1905  item.Name, localID, agentID);
1906  }
1907  }
1908  else
1909  {
1910  m_log.ErrorFormat(
1911  "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!",
1912  fromItemID, agentID);
1913  }
1914 
1915  return null;
1916  }
1917 
1924  public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase)
1925  {
1926  return RezNewScript(
1927  agentID,
1928  itemBase,
1929  "default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}");
1930  }
1931 
1939  public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText)
1940  {
1941  // The part ID is the folder ID!
1942  SceneObjectPart part = GetSceneObjectPart(itemBase.Folder);
1943  if (part == null)
1944  {
1945 // m_log.DebugFormat(
1946 // "[SCENE INVENTORY]: Could not find part with id {0} for {1} to rez new script",
1947 // itemBase.Folder, agentID);
1948 
1949  return null;
1950  }
1951 
1952  if (!Permissions.CanCreateObjectInventory(itemBase.InvType, part.UUID, agentID))
1953  {
1954 // m_log.DebugFormat(
1955 // "[SCENE INVENTORY]: No permission to create new script in {0} for {1}", part.Name, agentID);
1956 
1957  return null;
1958  }
1959 
1960  AssetBase asset
1961  = CreateAsset(
1962  itemBase.Name,
1963  itemBase.Description,
1964  (sbyte)itemBase.AssetType,
1965  Encoding.ASCII.GetBytes(scriptText),
1966  agentID);
1967 
1968  AssetService.Store(asset);
1969 
1970  TaskInventoryItem taskItem = new TaskInventoryItem();
1971 
1972  taskItem.ResetIDs(itemBase.Folder);
1973  taskItem.ParentID = itemBase.Folder;
1974  taskItem.CreationDate = (uint)itemBase.CreationDate;
1975  taskItem.Name = itemBase.Name;
1976  taskItem.Description = itemBase.Description;
1977  taskItem.Type = itemBase.AssetType;
1978  taskItem.InvType = itemBase.InvType;
1979  taskItem.OwnerID = itemBase.Owner;
1980  taskItem.CreatorID = itemBase.CreatorIdAsUuid;
1981  taskItem.BasePermissions = itemBase.BasePermissions;
1982  taskItem.CurrentPermissions = itemBase.CurrentPermissions;
1983  taskItem.EveryonePermissions = itemBase.EveryOnePermissions;
1984  taskItem.GroupPermissions = itemBase.GroupPermissions;
1985  taskItem.NextPermissions = itemBase.NextPermissions;
1986  taskItem.GroupID = itemBase.GroupID;
1987  taskItem.GroupPermissions = 0;
1988  taskItem.Flags = itemBase.Flags;
1989  taskItem.PermsGranter = UUID.Zero;
1990  taskItem.PermsMask = 0;
1991  taskItem.AssetID = asset.FullID;
1992 
1993  part.Inventory.AddInventoryItem(taskItem, false);
1994  part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
1995 
1996  // tell anyone managing scripts that a new script exists
1997  EventManager.TriggerNewScript(agentID, part, taskItem.ItemID);
1998 
1999  part.ParentGroup.ResumeScripts();
2000 
2001  return part;
2002  }
2003 
2013  public void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
2014  {
2015  TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
2016 
2017  if (srcTaskItem == null)
2018  {
2019  m_log.ErrorFormat(
2020  "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for rezzing a script but the "
2021  + " item does not exist in this inventory",
2022  srcId, srcPart.Name, srcPart.UUID);
2023 
2024  return;
2025  }
2026 
2027  SceneObjectPart destPart = GetSceneObjectPart(destId);
2028 
2029  if (destPart == null)
2030  {
2031  m_log.ErrorFormat(
2032  "[PRIM INVENTORY]: Could not find part {0} to insert script item {1} from {2} {3} in {4}",
2033  destId, srcId, srcPart.Name, srcPart.UUID, Name);
2034  return;
2035  }
2036 
2037  // Must own the object, and have modify rights
2038  if (srcPart.OwnerID != destPart.OwnerID)
2039  {
2040  // Group permissions
2041  if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) ||
2042  ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0))
2043  return;
2044  }
2045  else
2046  {
2047  if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
2048  return;
2049  }
2050 
2051  if (destPart.ScriptAccessPin == 0 || destPart.ScriptAccessPin != pin)
2052  {
2053  m_log.WarnFormat(
2054  "[PRIM INVENTORY]: " +
2055  "Script in object {0} : {1}, attempted to load script {2} : {3} into object {4} : {5} with invalid pin {6}",
2056  srcPart.Name, srcId, srcTaskItem.Name, srcTaskItem.ItemID, destPart.Name, destId, pin);
2057  // the LSL Wiki says we are supposed to shout on the DEBUG_CHANNEL -
2058  // "Object: Task Object trying to illegally load script onto task Other_Object!"
2059  // How do we shout from in here?
2060  return;
2061  }
2062 
2063  TaskInventoryItem destTaskItem = new TaskInventoryItem();
2064 
2065  destTaskItem.ItemID = UUID.Random();
2066  destTaskItem.CreatorID = srcTaskItem.CreatorID;
2067  destTaskItem.CreatorData = srcTaskItem.CreatorData;
2068  destTaskItem.AssetID = srcTaskItem.AssetID;
2069  destTaskItem.GroupID = destPart.GroupID;
2070  destTaskItem.OwnerID = destPart.OwnerID;
2071  destTaskItem.ParentID = destPart.UUID;
2072  destTaskItem.ParentPartID = destPart.UUID;
2073 
2074  destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
2075  destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
2076  destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
2077  destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
2078  destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
2079  destTaskItem.Flags = srcTaskItem.Flags;
2080 
2081  if (destPart.OwnerID != srcPart.OwnerID)
2082  {
2083  if (Permissions.PropagatePermissions())
2084  {
2085  destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
2086  srcTaskItem.NextPermissions;
2087  destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
2088  srcTaskItem.NextPermissions;
2089  destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
2090  srcTaskItem.NextPermissions;
2091  destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
2092  srcTaskItem.NextPermissions;
2093  destTaskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
2094  }
2095  }
2096 
2097  destTaskItem.Description = srcTaskItem.Description;
2098  destTaskItem.Name = srcTaskItem.Name;
2099  destTaskItem.InvType = srcTaskItem.InvType;
2100  destTaskItem.Type = srcTaskItem.Type;
2101 
2102  destPart.Inventory.AddInventoryItemExclusive(destTaskItem, false);
2103 
2104  if (running > 0)
2105  {
2106  destPart.Inventory.CreateScriptInstance(destTaskItem, start_param, false, DefaultScriptEngine, 0);
2107  }
2108 
2109  destPart.ParentGroup.ResumeScripts();
2110 
2111  ScenePresence avatar;
2112 
2113  if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
2114  {
2115  destPart.SendPropertiesToClient(avatar.ControllingClient);
2116  }
2117  }
2118 
2130  public virtual void DeRezObjects(
2131  IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID)
2132  {
2133  // First, see of we can perform the requested action and
2134  // build a list of eligible objects
2135  List<uint> deleteIDs = new List<uint>();
2136  List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
2137  List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
2138 
2139  // Start with true for both, then remove the flags if objects
2140  // that we can't derez are part of the selection
2141  bool permissionToTake = true;
2142  bool permissionToTakeCopy = true;
2143  bool permissionToDelete = true;
2144 
2145  foreach (uint localID in localIDs)
2146  {
2147 
2148 
2149  // Invalid id
2150  SceneObjectPart part = GetSceneObjectPart(localID);
2151  if (part == null)
2152  {
2153  //Client still thinks the object exists, kill it
2154  deleteIDs.Add(localID);
2155  continue;
2156  }
2157 
2158  // Already deleted by someone else
2159  if (part.ParentGroup.IsDeleted)
2160  {
2161  //Client still thinks the object exists, kill it
2162  deleteIDs.Add(localID);
2163  continue;
2164  }
2165 
2166  // Can't delete child prims
2167  if (part != part.ParentGroup.RootPart)
2168  continue;
2169 
2170  SceneObjectGroup grp = part.ParentGroup;
2171 
2172  // If child prims have invalid perms, fix them
2173  grp.AdjustChildPrimPermissions(false);
2174 
2175  if (remoteClient == null)
2176  {
2177  // Autoreturn has a null client. Nothing else does. So
2178  // allow only returns
2179  if (action != DeRezAction.Return)
2180  {
2181  m_log.WarnFormat(
2182  "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client",
2183  action, grp.Name, grp.UUID);
2184  return;
2185  }
2186 
2187  permissionToTakeCopy = false;
2188  }
2189  else
2190  {
2191  if (action == DeRezAction.TakeCopy)
2192  {
2193  if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId))
2194  permissionToTakeCopy = false;
2195  }
2196  else
2197  {
2198  permissionToTakeCopy = false;
2199  }
2200  if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId))
2201  permissionToTake = false;
2202 
2203  if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId))
2204  permissionToDelete = false;
2205  }
2206 
2207  // Handle god perms
2208  if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
2209  {
2210  permissionToTake = true;
2211  permissionToTakeCopy = true;
2212  permissionToDelete = true;
2213  }
2214 
2215  // If we're re-saving, we don't even want to delete
2216  if (action == DeRezAction.SaveToExistingUserInventoryItem)
2217  permissionToDelete = false;
2218 
2219  // if we want to take a copy, we also don't want to delete
2220  // Note: after this point, the permissionToTakeCopy flag
2221  // becomes irrelevant. It already includes the permissionToTake
2222  // permission and after excluding no copy items here, we can
2223  // just use that.
2224  if (action == DeRezAction.TakeCopy)
2225  {
2226  // If we don't have permission, stop right here
2227  if (!permissionToTakeCopy)
2228  {
2229  remoteClient.SendAlertMessage("You don't have permission to take the object");
2230  return;
2231  }
2232 
2233  permissionToTake = true;
2234  // Don't delete
2235  permissionToDelete = false;
2236  }
2237 
2238  if (action == DeRezAction.Return)
2239  {
2240  if (remoteClient != null)
2241  {
2242  if (Permissions.CanReturnObjects(
2243  null,
2244  remoteClient.AgentId,
2245  new List<SceneObjectGroup>() {grp}))
2246  {
2247  permissionToTake = true;
2248  permissionToDelete = true;
2249 
2250  AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
2251  }
2252  }
2253  else // Auto return passes through here with null agent
2254  {
2255  permissionToTake = true;
2256  permissionToDelete = true;
2257  }
2258  }
2259 
2260  if (permissionToTake && (!permissionToDelete))
2261  takeGroups.Add(grp);
2262 
2263  if (permissionToDelete)
2264  {
2265  if (permissionToTake)
2266  deleteGroups.Add(grp);
2267  deleteIDs.Add(grp.LocalId);
2268  }
2269  }
2270 
2271  SendKillObject(deleteIDs);
2272 
2273  if (deleteGroups.Count > 0)
2274  {
2275  foreach (SceneObjectGroup g in deleteGroups)
2276  deleteIDs.Remove(g.LocalId);
2277 
2278  m_asyncSceneObjectDeleter.DeleteToInventory(
2279  action, destinationID, deleteGroups, remoteClient,
2280  true);
2281  }
2282  if (takeGroups.Count > 0)
2283  {
2284  m_asyncSceneObjectDeleter.DeleteToInventory(
2285  action, destinationID, takeGroups, remoteClient,
2286  false);
2287  }
2288  if (deleteIDs.Count > 0)
2289  {
2290  foreach (SceneObjectGroup g in deleteGroups)
2291  DeleteSceneObject(g, true);
2292  }
2293  }
2294 
2295  public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
2296  {
2297  itemID = UUID.Zero;
2298  if (grp != null)
2299  {
2300  Vector3 inventoryStoredPosition = new Vector3(
2301  Math.Min(grp.AbsolutePosition.X, RegionInfo.RegionSizeX - 6),
2302  Math.Min(grp.AbsolutePosition.Y, RegionInfo.RegionSizeY - 6),
2303  grp.AbsolutePosition.Z);
2304 
2305  Vector3 originalPosition = grp.AbsolutePosition;
2306 
2307  grp.AbsolutePosition = inventoryStoredPosition;
2308 
2309  string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
2310 
2311  grp.AbsolutePosition = originalPosition;
2312 
2313  AssetBase asset = CreateAsset(
2314  grp.GetPartName(grp.LocalId),
2315  grp.GetPartDescription(grp.LocalId),
2316  (sbyte)AssetType.Object,
2317  Utils.StringToBytes(sceneObjectXml),
2318  remoteClient.AgentId);
2319  AssetService.Store(asset);
2320 
2321  InventoryItemBase item = new InventoryItemBase();
2322  item.CreatorId = grp.RootPart.CreatorID.ToString();
2323  item.CreatorData = grp.RootPart.CreatorData;
2324  item.Owner = remoteClient.AgentId;
2325  item.ID = UUID.Random();
2326  item.AssetID = asset.FullID;
2327  item.Description = asset.Description;
2328  item.Name = asset.Name;
2329  item.AssetType = asset.Type;
2330  item.InvType = (int)InventoryType.Object;
2331 
2332  InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, FolderType.Object);
2333  if (folder != null)
2334  item.Folder = folder.ID;
2335  else // oopsies
2336  item.Folder = UUID.Zero;
2337 
2338  // Set up base perms properly
2339  uint permsBase = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify);
2340  permsBase &= grp.RootPart.BaseMask;
2341  permsBase |= (uint)PermissionMask.Move;
2342 
2343  // Make sure we don't lock it
2344  grp.RootPart.NextOwnerMask |= (uint)PermissionMask.Move;
2345 
2346  if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions())
2347  {
2348  item.BasePermissions = permsBase & grp.RootPart.NextOwnerMask;
2349  item.CurrentPermissions = permsBase & grp.RootPart.NextOwnerMask;
2350  item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask;
2351  item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
2352  item.GroupPermissions = permsBase & grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
2353  }
2354  else
2355  {
2356  item.BasePermissions = permsBase;
2357  item.CurrentPermissions = permsBase & grp.RootPart.OwnerMask;
2358  item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask;
2359  item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask;
2360  item.GroupPermissions = permsBase & grp.RootPart.GroupMask;
2361  }
2362  item.CreationDate = Util.UnixTimeSinceEpoch();
2363 
2364  // sets itemID so client can show item as 'attached' in inventory
2365  grp.FromItemID = item.ID;
2366 
2367  if (AddInventoryItem(item))
2368  remoteClient.SendInventoryItemCreateUpdate(item, 0);
2369  else
2370  m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
2371 
2372  itemID = item.ID;
2373  return item.AssetID;
2374  }
2375  return UUID.Zero;
2376  }
2377 
2395  public bool GetObjectsToRez(
2396  byte[] assetData, bool isAttachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist,
2397  out Vector3 bbox, out float offsetHeight)
2398  {
2399  objlist = new List<SceneObjectGroup>();
2400  veclist = new List<Vector3>();
2401  bbox = Vector3.Zero;
2402  offsetHeight = 0;
2403 
2404  string xmlData = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(assetData));
2405 
2406  try
2407  {
2408  using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
2409  {
2410  using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
2411  {
2412  reader.Read();
2413  bool isSingleObject = reader.Name != "CoalescedObject";
2414 
2415  if (isSingleObject || isAttachment)
2416  {
2417  SceneObjectGroup g;
2418  try
2419  {
2420  g = SceneObjectSerializer.FromOriginalXmlFormat(reader);
2421  }
2422  catch (Exception e)
2423  {
2424  m_log.Error("[AGENT INVENTORY]: Deserialization of xml failed ", e);
2425  Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2426  g = null;
2427  }
2428 
2429  if (g != null)
2430  {
2431  objlist.Add(g);
2432  veclist.Add(Vector3.Zero);
2433  bbox = g.GetAxisAlignedBoundingBox(out offsetHeight);
2434  }
2435 
2436  return true;
2437  }
2438  else
2439  {
2440  XmlDocument doc = new XmlDocument();
2441  doc.LoadXml(xmlData);
2442  XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
2443  XmlElement coll = (XmlElement)e;
2444  float bx = Convert.ToSingle(coll.GetAttribute("x"));
2445  float by = Convert.ToSingle(coll.GetAttribute("y"));
2446  float bz = Convert.ToSingle(coll.GetAttribute("z"));
2447  bbox = new Vector3(bx, by, bz);
2448  offsetHeight = 0;
2449 
2450  XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
2451  foreach (XmlNode n in groups)
2452  {
2453  SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
2454  if (g != null)
2455  {
2456  objlist.Add(g);
2457 
2458  XmlElement el = (XmlElement)n;
2459  string rawX = el.GetAttribute("offsetx");
2460  string rawY = el.GetAttribute("offsety");
2461  string rawZ = el.GetAttribute("offsetz");
2462 
2463  float x = Convert.ToSingle(rawX);
2464  float y = Convert.ToSingle(rawY);
2465  float z = Convert.ToSingle(rawZ);
2466  veclist.Add(new Vector3(x, y, z));
2467  }
2468  }
2469 
2470  return false;
2471  }
2472  }
2473  }
2474  }
2475  catch (Exception e)
2476  {
2477  m_log.Error("[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag ", e);
2478  Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2479  }
2480 
2481  return true;
2482  }
2483 
2500  public virtual void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
2501  UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
2502  bool RezSelected, bool RemoveItem, UUID fromTaskID)
2503  {
2504 // m_log.DebugFormat(
2505 // "[PRIM INVENTORY]: RezObject from {0} for item {1} from task id {2}",
2506 // remoteClient.Name, itemID, fromTaskID);
2507 
2508  if (fromTaskID == UUID.Zero)
2509  {
2510  IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
2511  if (invAccess != null)
2512  invAccess.RezObject(
2513  remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
2514  RezSelected, RemoveItem, fromTaskID, false);
2515  }
2516  else
2517  {
2518  SceneObjectPart part = GetSceneObjectPart(fromTaskID);
2519  if (part == null)
2520  {
2521  m_log.ErrorFormat(
2522  "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such scene object",
2523  remoteClient.Name, itemID, fromTaskID);
2524 
2525  return;
2526  }
2527 
2528  TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID);
2529  if (item == null)
2530  {
2531  m_log.ErrorFormat(
2532  "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such item",
2533  remoteClient.Name, itemID, fromTaskID);
2534 
2535  return;
2536  }
2537 
2538  byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
2539  Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
2540  Vector3 pos
2541  = GetNewRezLocation(
2542  RayStart, RayEnd, RayTargetID, Quaternion.Identity,
2543  BypassRayCast, bRayEndIsIntersection, true, scale, false);
2544 
2545  RezObject(part, item, pos, null, Vector3.Zero, 0, false);
2546  }
2547  }
2548 
2560  public virtual List<SceneObjectGroup> RezObject(
2561  SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param, bool atRoot)
2562  {
2563  if (null == item)
2564  return null;
2565 
2566  List<SceneObjectGroup> objlist;
2567  List<Vector3> veclist;
2568  Vector3 bbox;
2569  float offsetHeight;
2570 
2571  bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist,out bbox, out offsetHeight);
2572 
2573  if (!success)
2574  return null;
2575 
2576  int totalPrims = 0;
2577  foreach (SceneObjectGroup group in objlist)
2578  totalPrims += group.PrimCount;
2579 
2580  if (!Permissions.CanRezObject(totalPrims, item.OwnerID, pos))
2581  return null;
2582 
2583  if (!Permissions.BypassPermissions())
2584  {
2585  if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
2586  sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
2587  }
2588 
2589  SceneObjectGroup sog;
2590 
2591  bool fixrot = false;
2592  Quaternion netRot = Quaternion.Identity;
2593 
2594  // position adjust
2595  if (totalPrims > 1) // nothing to do on a single prim
2596  {
2597  if (objlist.Count == 1)
2598  {
2599  // current object position is root position
2600  if(!atRoot)
2601  {
2602  sog = objlist[0];
2603  Quaternion orot;
2604  if (rot == null)
2605  orot = sog.RootPart.GetWorldRotation();
2606  else
2607  orot = rot.Value;
2608  // possible should be bbox, but geometric center looks better
2609  Vector3 off = sog.GetGeometricCenter();
2610 // Vector3 off = bbox * 0.5f;
2611  off *= orot;
2612  pos -= off;
2613  }
2614  }
2615  else
2616  {
2617  //veclist[] are relative to bbox corner with min X,Y and Z
2618  // rez at root, and rot will be referenced to first object in list
2619  if (rot == null)
2620  {
2621  // use original rotations
2622  if (atRoot)
2623  pos -= veclist[0];
2624  else
2625  pos -= bbox / 2;
2626  }
2627  else
2628  {
2629  fixrot = true;
2630  sog = objlist[0];
2631  netRot = Quaternion.Conjugate(sog.RootPart.GetWorldRotation());
2632  netRot = netRot * rot.Value;
2633  Vector3 off;
2634  if (atRoot)
2635  off = veclist[0];
2636  else
2637  off = bbox / 2;
2638  off *= netRot;
2639  pos -= off;
2640  }
2641  }
2642  }
2643 
2644  for (int i = 0; i < objlist.Count; i++)
2645  {
2646  SceneObjectGroup group = objlist[i];
2647  Vector3 curpos;
2648  if(fixrot)
2649  curpos = pos + veclist[i] * netRot;
2650  else
2651  curpos = pos + veclist[i];
2652 
2653  if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
2654  {
2655  group.RootPart.AttachedPos = group.AbsolutePosition;
2656  group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
2657  }
2658 
2659  group.FromPartID = sourcePart.UUID;
2660  if( i == 0)
2661  AddNewSceneObject(group, true, curpos, rot, vel);
2662  else
2663  {
2664  Quaternion crot = objlist[i].RootPart.GetWorldRotation();
2665  if (fixrot)
2666  {
2667  crot *= netRot;
2668  }
2669  AddNewSceneObject(group, true, curpos, crot, vel);
2670  }
2671 
2672  // We can only call this after adding the scene object, since the scene object references the scene
2673  // to find out if scripts should be activated at all.
2674  group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
2675 
2676  group.ScheduleGroupForFullUpdate();
2677  }
2678 
2679  return objlist;
2680  }
2681 
2682  public virtual bool returnObjects(SceneObjectGroup[] returnobjects,
2683  UUID AgentId)
2684  {
2685  List<uint> localIDs = new List<uint>();
2686 
2687  foreach (SceneObjectGroup grp in returnobjects)
2688  {
2689  AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition,
2690  "parcel owner return");
2691  localIDs.Add(grp.RootPart.LocalId);
2692  }
2693  DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return,
2694  UUID.Zero);
2695 
2696  return true;
2697  }
2698 
2699  public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
2700  {
2701  if (!Permissions.CanEditScript(itemID, objectID, controllingClient.AgentId))
2702  return;
2703 
2704  SceneObjectPart part = GetSceneObjectPart(objectID);
2705  if (part == null)
2706  return;
2707 
2708  if (running)
2709  EventManager.TriggerStartScript(part.LocalId, itemID);
2710  else
2711  EventManager.TriggerStopScript(part.LocalId, itemID);
2712  }
2713 
2714  public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
2715  {
2716  EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID);
2717  }
2718 
2719  void ObjectOwner(IClientAPI remoteClient, UUID ownerID, UUID groupID, List<uint> localIDs)
2720  {
2721  if (!Permissions.IsGod(remoteClient.AgentId))
2722  {
2723  if (ownerID != UUID.Zero)
2724  return;
2725 
2726  if (!Permissions.CanDeedObject(remoteClient.AgentId, groupID))
2727  return;
2728  }
2729 
2730  List<SceneObjectGroup> groups = new List<SceneObjectGroup>();
2731 
2732  foreach (uint localID in localIDs)
2733  {
2734  SceneObjectPart part = GetSceneObjectPart(localID);
2735  if (part == null)
2736  continue;
2737 
2738  if (!groups.Contains(part.ParentGroup))
2739  groups.Add(part.ParentGroup);
2740  }
2741 
2742  foreach (SceneObjectGroup sog in groups)
2743  {
2744  if (ownerID != UUID.Zero)
2745  {
2746  sog.SetOwnerId(ownerID);
2747  sog.SetGroup(groupID, remoteClient);
2748  sog.ScheduleGroupForFullUpdate();
2749 
2750  SceneObjectPart[] partList = sog.Parts;
2751 
2752  foreach (SceneObjectPart child in partList)
2753  {
2754  child.Inventory.ChangeInventoryOwner(ownerID);
2755  child.TriggerScriptChangedEvent(Changed.OWNER);
2756  }
2757  }
2758  else
2759  {
2760  if (!Permissions.IsGod(remoteClient.AgentId) && sog.OwnerID != remoteClient.AgentId)
2761  continue;
2762 
2763  if (!Permissions.CanTransferObject(sog.UUID, groupID))
2764  continue;
2765 
2766  if (sog.GroupID != groupID)
2767  continue;
2768 
2769  SceneObjectPart[] partList = sog.Parts;
2770 
2771  foreach (SceneObjectPart child in partList)
2772  {
2773  child.LastOwnerID = child.OwnerID;
2774  child.Inventory.ChangeInventoryOwner(groupID);
2775  child.TriggerScriptChangedEvent(Changed.OWNER);
2776  }
2777 
2778  sog.SetOwnerId(groupID);
2779  sog.ApplyNextOwnerPermissions();
2780  }
2781  }
2782 
2783  foreach (uint localID in localIDs)
2784  {
2785  SceneObjectPart part = GetSceneObjectPart(localID);
2786  if (part == null)
2787  continue;
2788  part.SendPropertiesToClient(remoteClient);
2789  }
2790  }
2791 
2792  public void DelinkObjects(List<uint> primIds, IClientAPI client)
2793  {
2794  List<SceneObjectPart> parts = new List<SceneObjectPart>();
2795 
2796  foreach (uint localID in primIds)
2797  {
2798  SceneObjectPart part = GetSceneObjectPart(localID);
2799 
2800  if (part == null)
2801  continue;
2802 
2803  if (Permissions.CanDelinkObject(client.AgentId, part.ParentGroup.RootPart.UUID))
2804  parts.Add(part);
2805  }
2806 
2807  m_sceneGraph.DelinkObjects(parts);
2808  }
2809 
2816  public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
2817  {
2818  LinkObjects(client.AgentId, parentPrimId, childPrimIds);
2819  }
2820 
2827  public void LinkObjects(UUID agentId, uint parentPrimId, List<uint> childPrimIds)
2828  {
2829  List<UUID> owners = new List<UUID>();
2830 
2831  List<SceneObjectPart> children = new List<SceneObjectPart>();
2832  SceneObjectPart root = GetSceneObjectPart(parentPrimId);
2833 
2834  if (root == null)
2835  {
2836  m_log.DebugFormat("[LINK]: Can't find linkset root prim {0}", parentPrimId);
2837  return;
2838  }
2839 
2840  if (!Permissions.CanLinkObject(agentId, root.ParentGroup.RootPart.UUID))
2841  {
2842  m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim");
2843  return;
2844  }
2845 
2846  foreach (uint localID in childPrimIds)
2847  {
2848  SceneObjectPart part = GetSceneObjectPart(localID);
2849 
2850  if (part == null)
2851  continue;
2852 
2853  if (!owners.Contains(part.OwnerID))
2854  owners.Add(part.OwnerID);
2855 
2856  if (Permissions.CanLinkObject(agentId, part.ParentGroup.RootPart.UUID))
2857  children.Add(part);
2858  }
2859 
2860  // Must be all one owner
2861  //
2862  if (owners.Count > 1)
2863  {
2864  m_log.DebugFormat("[LINK]: Refusing link. Too many owners");
2865  return;
2866  }
2867 
2868  if (children.Count == 0)
2869  {
2870  m_log.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children");
2871  return;
2872  }
2873 
2874  bool oldUsePhysics = (root.Flags & PrimFlags.Physics) != 0;
2875  m_sceneGraph.LinkObjects(root, children);
2876 
2877  ScenePresence sp;
2878  if (TryGetScenePresence(agentId, out sp))
2879  {
2880  root.SendPropertiesToClient(sp.ControllingClient);
2881  if (oldUsePhysics && (root.Flags & PrimFlags.Physics) == 0)
2882  {
2883  sp.ControllingClient.SendAlertMessage("Object physics canceled");
2884  }
2885  }
2886  }
2887 
2888  private string PermissionString(uint permissions)
2889  {
2890  PermissionMask perms = (PermissionMask)permissions &
2891  (PermissionMask.Move |
2892  PermissionMask.Copy |
2893  PermissionMask.Transfer |
2894  PermissionMask.Modify);
2895  return perms.ToString();
2896  }
2897  }
2898 }
bool AddInventoryItem(InventoryItemBase item)
virtual InventoryFolderBase GiveInventoryFolder(IClientAPI client, UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
Give an entire inventory folder from one user to another. The entire contents (including all descende...
virtual List< SceneObjectGroup > RezObject(SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion?rot, Vector3 vel, int param, bool atRoot)
Rez an object into the scene from a prim's inventory.
delegate void RemoveInventoryItem(IClientAPI remoteClient, List< UUID > itemIDs)
IEntityInventory Inventory
This part's inventory
void AddInventoryItem(UUID AgentID, InventoryItemBase item)
Add the given inventory item to a user's inventory.
void ClientMoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, uint primLocalId, UUID itemId)
ClientMoveTaskInventoryItem
bool AddInventoryItem(InventoryItemBase item, bool trigger)
Add the given inventory item to a user's inventory.
void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
Copy a task (prim) inventory item to another task (prim)
Send FetchInventoryReply information to clients asynchronously on a single thread rather than asynchr...
List< InventoryFolderBase > RequestListOfFolders()
Return a copy of the list of child folders in this folder. The folders themselves are the originals...
UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, UUID creatorID)
Create a new asset data structure.
void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID)
Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory ...
InventoryFolderImpl FindFolder(UUID folderID)
Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth first.
void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID)
Send the details of a prim's inventory to the client.
delegate void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID)
bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item)
uint RegionSizeX
X dimension of the region.
Definition: RegionInfo.cs:161
void MoveInventoryItem(IClientAPI remoteClient, List< InventoryItemBase > items)
Move an item within the agent's inventory.
virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId, out string message)
Give an inventory item from one user to another
Asynchronously derez objects. This is used to derez large number of objects to inventory without hold...
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
Represents an item in a task inventory
ArrayList CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId, UUID primId, bool isScriptRunning, byte[] data)
CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])
AsyncSceneObjectGroupDeleter m_asyncSceneObjectDeleter
Allows asynchronous derezzing of objects from the scene into a client's inventory.
SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase)
Rez a new script from nothing.
bool GetObjectsToRez(byte[] assetData, bool isAttachment, out List< SceneObjectGroup > objlist, out List< Vector3 > veclist, out Vector3 bbox, out float offsetHeight)
Returns the list of Scene Objects in an asset.
delegate void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, UUID newFolderID, string newName)
virtual void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID)
Event Handler Rez an object into a scene Calls the non-void event handler
virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId, out string message)
Give an inventory item from one user to another
virtual UUID Owner
The agent who's inventory this is contained by
void LinkObjects(IClientAPI client, uint parentPrimId, List< uint > childPrimIds)
Link the scene objects containing the indicated parts to a root object.
void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
Move the given item in the given prim to a folder in the client's inventory
bool UpdateInventoryItem(TaskInventoryItem item)
Update an existing inventory item.
ArrayList CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId, UUID primId, bool isScriptRunning, byte[] data)
Capability originating call to update the asset of a script in a prim's (task's) inventory ...
bool IsDeleted
Signals whether this entity was in a scene but has since been removed from it.
Definition: EntityBase.cs:73
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data)
CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])
static void enforceItemPermitions(InventoryItemBase it, bool IsCreator)
Definition: AnimationSet.cs:60
int CreateScriptInstances()
Creates all the scripts in the scene which should be started.
void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem itemInfo, uint primLocalID)
Update an item in a prim (task) inventory. This method does not handle scripts, RezScript(IClientAPI...
void StartScripts()
Lets the script engines start processing scripts.
void AddInventoryItem(TaskInventoryItem item, bool allowedDrop)
Add an item to this entity's inventory. If an item with the same name already exists, then an alternative name is chosen.
void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
Rez a script into a prim's inventory from another prim
void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, UUID newFolderID, string newName)
uint AttachmentPoint
Attachment point of this scene object to an avatar.
Inventory Item - contains all the properties associated with an individual inventory piece...
void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, UUID itemID, InventoryItemBase itemUpd)
Update an item which is either already in the client's inventory or is within a transaction ...
TaskInventoryItem GetInventoryItem(uint primID, UUID itemID)
Returns an existing inventory item. Returns the original, so any changes will be live.
virtual void DeRezObjects(IClientAPI remoteClient, List< uint > localIDs, UUID groupID, DeRezAction action, UUID destinationID)
Derez one or more objects from the scene.
delegate void ObjectOwner(IClientAPI remoteClient, UUID ownerID, UUID groupID, List< uint > localIDs)
void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
Remove an item from a prim (task) inventory
void DelinkObjects(List< uint > primIds, IClientAPI client)
delegate void MoveInventoryItem(IClientAPI remoteClient, List< InventoryItemBase > items)
void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List< InventoryItemBase > items, UUID destfolder)
Move an item within the agent's inventory, and leave a copy (used in making a new outfit) ...
delegate void LinkObjects(IClientAPI remoteClient, uint parent, List< uint > children)
void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
Tell the client that we have created the item it requested.
InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId, out string message)
MoveTaskInventoryItem
UUID ID
A UUID containing the ID for the inventory node itself
void LinkObjects(UUID agentId, uint parentPrimId, List< uint > childPrimIds)
Link the scene objects containing the indicated parts to a root object.
void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
Add an inventory item to an avatar's inventory.
void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
virtual string Name
The name of the node (64 characters or less)
UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List< UUID > items)
SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText)
Rez a new script from nothing with given script text.
override Vector3 AbsolutePosition
The absolute position of this scene object in the scene
OpenSim.Framework.PermissionMask PermissionMask
void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
UUID FullID
Asset UUID
Definition: AssetBase.cs:168
void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item, uint cost)
delegate void RemoveInventoryFolder(IClientAPI remoteClient, List< UUID > folderIDs)
SceneObjectPart RezScriptFromAgentInventory(UUID agentID, UUID fromItemID, uint localID)
Rez a script into a prim from an agent inventory.
override string Name
The name of an object grouping is always the same as its root part
This maintains the relationship between a UUID and a user name.
virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId)
void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, string description, uint flags, uint callbackID, UUID assetID, sbyte assetType, sbyte invType, uint nextOwnerMask, int creationDate)
Create a new inventory item.
OpenSim.Region.Framework.Scenes.Animation.AnimationSet AnimationSet
AsyncInventorySender m_asyncInventorySender
Allows inventory details to be sent to clients asynchronously
Used to serialize a whole inventory for transfer over the network.
bool IsAttachment
Is this scene object acting as an attachment?
virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId, out string message)
Give an inventory item from one user to another
delegate void CreateNewInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask, int creationDate)