2007-10-19 20:28:18 +00:00
/ *
2008-03-18 05:16:43 +00:00
* Copyright ( c ) Contributors , http : //opensimulator.org/
* See CONTRIBUTORS . TXT for a full list of copyright holders .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
2009-06-01 06:37:14 +00:00
* * Neither the name of the OpenSimulator Project nor the
2008-03-18 05:16:43 +00:00
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
2007-10-19 20:28:18 +00:00
2008-02-05 19:44:27 +00:00
using System ;
2007-12-27 21:41:48 +00:00
using System.Collections.Generic ;
2009-12-22 05:25:32 +00:00
using System.Collections ;
2008-04-21 07:09:17 +00:00
using System.Reflection ;
using System.Text ;
2008-07-06 02:27:10 +00:00
using System.Timers ;
2008-09-06 07:52:41 +00:00
using OpenMetaverse ;
2009-04-07 17:46:23 +00:00
using OpenMetaverse.Packets ;
2008-04-21 07:09:17 +00:00
using log4net ;
2007-10-29 21:46:25 +00:00
using OpenSim.Framework ;
2009-02-06 16:55:34 +00:00
using OpenSim.Region.Framework ;
2012-04-06 18:52:05 +00:00
using OpenSim.Framework.Client ;
2009-02-06 16:55:34 +00:00
using OpenSim.Region.Framework.Interfaces ;
2009-05-08 15:47:59 +00:00
using OpenSim.Region.Framework.Scenes.Serialization ;
2013-03-26 03:40:06 +00:00
using PermissionMask = OpenSim . Framework . PermissionMask ;
2008-02-10 22:23:11 +00:00
2009-02-06 16:55:34 +00:00
namespace OpenSim.Region.Framework.Scenes
2007-10-19 20:28:18 +00:00
{
public partial class Scene
{
2008-05-16 01:22:11 +00:00
private static readonly ILog m_log
2009-02-04 00:01:36 +00:00
= LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2008-09-29 19:09:49 +00:00
/// <summary>
/// Allows asynchronous derezzing of objects from the scene into a client's inventory.
/// </summary>
2009-02-04 00:01:36 +00:00
protected AsyncSceneObjectGroupDeleter m_asyncSceneObjectDeleter ;
2008-02-05 19:44:27 +00:00
2011-07-01 20:25:40 +00:00
/// <summary>
/// Allows inventory details to be sent to clients asynchronously
/// </summary>
protected AsyncInventorySender m_asyncInventorySender ;
2008-01-07 02:12:06 +00:00
/// <summary>
2011-09-05 09:45:02 +00:00
/// Creates all the scripts in the scene which should be started.
2008-01-07 02:12:06 +00:00
/// </summary>
2012-06-19 23:10:19 +00:00
/// <returns>
/// Number of scripts that were valid for starting. This does not guarantee that all these scripts
/// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found)
/// </returns>
public int CreateScriptInstances ( )
2008-01-07 02:12:06 +00:00
{
2012-06-19 23:10:19 +00:00
m_log . InfoFormat ( "[SCENE]: Initializing script instances in {0}" , RegionInfo . RegionName ) ;
int scriptsValidForStarting = 0 ;
2008-05-16 01:22:11 +00:00
2010-09-10 19:04:12 +00:00
EntityBase [ ] entities = Entities . GetEntities ( ) ;
foreach ( EntityBase group in entities )
2008-01-07 02:12:06 +00:00
{
2008-05-11 04:32:43 +00:00
if ( group is SceneObjectGroup )
{
2012-06-19 23:10:19 +00:00
scriptsValidForStarting
+ = ( ( SceneObjectGroup ) group ) . CreateScriptInstances ( 0 , false , DefaultScriptEngine , 0 ) ;
2010-04-19 05:29:26 +00:00
( ( SceneObjectGroup ) group ) . ResumeScripts ( ) ;
2008-05-11 04:32:43 +00:00
}
2008-05-16 01:22:11 +00:00
}
2012-06-19 23:10:19 +00:00
m_log . InfoFormat (
"[SCENE]: Initialized {0} script instances in {1}" ,
scriptsValidForStarting , RegionInfo . RegionName ) ;
return scriptsValidForStarting ;
2008-01-07 02:12:06 +00:00
}
2007-12-27 21:41:48 +00:00
2011-09-05 09:45:02 +00:00
/// <summary>
/// Lets the script engines start processing scripts.
/// </summary>
public void StartScripts ( )
{
2012-08-24 23:42:32 +00:00
// m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
2011-09-05 09:45:02 +00:00
IScriptModule [ ] engines = RequestModuleInterfaces < IScriptModule > ( ) ;
2011-11-22 22:13:57 +00:00
foreach ( IScriptModule engine in engines )
engine . StartProcessing ( ) ;
2011-09-05 09:45:02 +00:00
}
2008-09-06 07:52:41 +00:00
public void AddUploadedInventoryItem ( UUID agentID , InventoryItemBase item )
2008-05-23 01:38:20 +00:00
{
2010-09-04 00:36:26 +00:00
IMoneyModule money = RequestModuleInterface < IMoneyModule > ( ) ;
2008-05-28 03:44:49 +00:00
if ( money ! = null )
2008-05-23 01:38:20 +00:00
{
2010-07-02 04:20:36 +00:00
money . ApplyUploadCharge ( agentID , money . UploadCharge , "Asset upload" ) ;
2008-05-23 01:38:20 +00:00
}
2010-09-04 00:36:26 +00:00
AddInventoryItem ( item ) ;
2008-05-23 01:38:20 +00:00
}
2008-09-06 07:52:41 +00:00
public bool AddInventoryItemReturned ( UUID AgentId , InventoryItemBase item )
2008-05-24 09:40:14 +00:00
{
2010-09-04 00:36:26 +00:00
if ( AddInventoryItem ( item ) )
2008-05-24 09:40:14 +00:00
return true ;
else
{
2009-08-13 03:39:48 +00:00
m_log . WarnFormat (
"[AGENT INVENTORY]: Unable to add item {1} to agent {2} inventory" , item . Name , AgentId ) ;
2008-05-24 09:40:14 +00:00
return false ;
}
}
2010-09-03 23:09:53 +00:00
/// <summary>
/// Add the given inventory item to a user's inventory.
/// </summary>
/// <param name="item"></param>
2010-09-04 00:36:26 +00:00
public bool AddInventoryItem ( InventoryItemBase item )
2007-10-19 20:28:18 +00:00
{
2012-04-06 18:52:05 +00:00
if ( item . Folder ! = UUID . Zero & & InventoryService . AddItem ( item ) )
2010-09-04 00:36:26 +00:00
{
2012-04-06 18:52:05 +00:00
int userlevel = 0 ;
if ( Permissions . IsGod ( item . Owner ) )
2010-09-04 00:36:26 +00:00
{
2012-04-06 18:52:05 +00:00
userlevel = 1 ;
}
2013-07-21 22:46:00 +00:00
EventManager . TriggerOnNewInventoryItemUploadComplete ( item . Owner , ( AssetType ) item . AssetType , item . AssetID , item . Name , userlevel ) ;
2012-04-06 18:52:05 +00:00
return true ;
}
// OK so either the viewer didn't send a folderID or AddItem failed
UUID originalFolder = item . Folder ;
InventoryFolderBase f = InventoryService . GetFolderForType ( item . Owner , ( AssetType ) item . AssetType ) ;
if ( f ! = null )
{
m_log . DebugFormat (
"[AGENT INVENTORY]: Found folder {0} type {1} for item {2}" ,
f . Name , ( AssetType ) f . Type , item . Name ) ;
2010-09-04 00:36:26 +00:00
2012-04-06 18:52:05 +00:00
item . Folder = f . ID ;
}
else
{
f = InventoryService . GetRootFolder ( item . Owner ) ;
if ( f ! = null )
{
2010-09-04 00:36:26 +00:00
item . Folder = f . ID ;
}
else
{
2012-04-06 18:52:05 +00:00
m_log . WarnFormat (
"[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified" ,
item . Owner , item . Name ) ;
return false ;
2010-09-04 00:36:26 +00:00
}
}
2009-08-13 03:39:48 +00:00
if ( InventoryService . AddItem ( item ) )
2007-10-19 20:28:18 +00:00
{
2008-04-10 09:36:55 +00:00
int userlevel = 0 ;
2010-09-03 23:09:53 +00:00
if ( Permissions . IsGod ( item . Owner ) )
2008-04-10 09:36:55 +00:00
{
userlevel = 1 ;
}
2013-07-21 22:46:00 +00:00
EventManager . TriggerOnNewInventoryItemUploadComplete ( item . Owner , ( AssetType ) item . AssetType , item . AssetID , item . Name , userlevel ) ;
2012-04-06 18:52:05 +00:00
if ( originalFolder ! = UUID . Zero )
{
// Tell the viewer that the item didn't go there
ChangePlacement ( item , f ) ;
}
2010-09-04 00:36:26 +00:00
return true ;
2007-10-19 20:28:18 +00:00
}
2008-04-26 20:31:01 +00:00
else
{
2009-08-13 03:39:48 +00:00
m_log . WarnFormat (
2010-08-24 15:50:31 +00:00
"[AGENT INVENTORY]: Agent {0} could not add item {1} {2}" ,
2010-09-03 23:09:53 +00:00
item . Owner , item . Name , item . ID ) ;
2008-05-16 01:22:11 +00:00
2010-09-04 00:36:26 +00:00
return false ;
2010-09-12 17:43:49 +00:00
}
2010-09-03 23:09:53 +00:00
}
2012-04-06 18:52:05 +00:00
private void ChangePlacement ( InventoryItemBase item , InventoryFolderBase f )
{
ScenePresence sp = GetScenePresence ( item . Owner ) ;
if ( sp ! = null )
{
if ( sp . ControllingClient is IClientCore )
{
IClientCore core = ( IClientCore ) sp . ControllingClient ;
IClientInventory inv ;
if ( core . TryGet < IClientInventory > ( out inv ) )
{
InventoryFolderBase parent = new InventoryFolderBase ( f . ParentID , f . Owner ) ;
parent = InventoryService . GetFolder ( parent ) ;
inv . SendRemoveInventoryItems ( new UUID [ ] { item . ID } ) ;
inv . SendBulkUpdateInventory ( new InventoryFolderBase [ 0 ] , new InventoryItemBase [ ] { item } ) ;
string message = "The item was placed in folder " + f . Name ;
if ( parent ! = null )
message + = " under " + parent . Name ;
sp . ControllingClient . SendAgentAlertMessage ( message , false ) ;
}
}
}
}
2010-09-03 23:09:53 +00:00
/// <summary>
/// Add the given inventory item to a user's inventory.
/// </summary>
/// <param name="AgentID">
/// A <see cref="UUID"/>
/// </param>
/// <param name="item">
/// A <see cref="InventoryItemBase"/>
/// </param>
[Obsolete("Use AddInventoryItem(InventoryItemBase item) instead. This was deprecated in OpenSim 0.7.1")]
public void AddInventoryItem ( UUID AgentID , InventoryItemBase item )
{
AddInventoryItem ( item ) ;
2007-10-19 20:28:18 +00:00
}
2007-12-27 21:41:48 +00:00
2008-05-16 01:22:11 +00:00
/// <summary>
2008-06-26 02:46:29 +00:00
/// Add an inventory item to an avatar's inventory.
2007-12-25 18:11:56 +00:00
/// </summary>
2008-06-26 02:46:29 +00:00
/// <param name="remoteClient">The remote client controlling the avatar</param>
2007-12-25 18:11:56 +00:00
/// <param name="item">The item. This structure contains all the item metadata, including the folder
2008-05-16 01:22:11 +00:00
/// in which the item is to be placed.</param>
2008-06-26 02:46:29 +00:00
public void AddInventoryItem ( IClientAPI remoteClient , InventoryItemBase item )
2007-10-19 20:28:18 +00:00
{
2010-09-03 23:09:53 +00:00
AddInventoryItem ( item ) ;
2009-08-13 03:39:48 +00:00
remoteClient . SendInventoryItemCreateUpdate ( item , 0 ) ;
2007-10-19 20:28:18 +00:00
}
2007-12-25 18:11:56 +00:00
/// <summary>
2008-09-06 07:52:41 +00:00
/// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see>
2007-12-25 18:11:56 +00:00
/// </summary>
2009-01-21 21:14:17 +00:00
public UUID CapsUpdateInventoryItemAsset ( UUID avatarId , UUID itemID , byte [ ] data )
2007-12-25 18:11:56 +00:00
{
ScenePresence avatar ;
2010-03-19 12:58:34 +00:00
if ( TryGetScenePresence ( avatarId , out avatar ) )
2007-12-25 18:11:56 +00:00
{
2010-01-30 17:23:07 +00:00
IInventoryAccessModule invAccess = RequestModuleInterface < IInventoryAccessModule > ( ) ;
if ( invAccess ! = null )
return invAccess . CapsUpdateInventoryItemAsset ( avatar . ControllingClient , itemID , data ) ;
2007-12-25 18:11:56 +00:00
}
else
{
2008-02-10 01:57:59 +00:00
m_log . ErrorFormat (
2008-02-20 23:21:51 +00:00
"[AGENT INVENTORY]: " +
2008-02-10 01:57:59 +00:00
"Avatar {0} cannot be found to update its inventory item asset" ,
avatarId ) ;
2007-12-25 18:11:56 +00:00
}
2008-09-06 07:52:41 +00:00
return UUID . Zero ;
2007-12-27 21:41:48 +00:00
}
2007-12-24 22:35:01 +00:00
/// <summary>
/// Capability originating call to update the asset of a script in a prim's (task's) inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="primID">The prim which contains the item to update</param>
/// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
2008-05-16 01:22:11 +00:00
/// <param name="data"></param>
2009-12-22 05:25:32 +00:00
public ArrayList CapsUpdateTaskInventoryScriptAsset ( IClientAPI remoteClient , UUID itemId ,
2008-09-06 07:52:41 +00:00
UUID primId , bool isScriptRunning , byte [ ] data )
2007-12-24 22:35:01 +00:00
{
2008-11-21 22:14:57 +00:00
if ( ! Permissions . CanEditScript ( itemId , primId , remoteClient . AgentId ) )
2008-09-23 03:36:16 +00:00
{
remoteClient . SendAgentAlertMessage ( "Insufficient permissions to edit script" , false ) ;
2009-12-22 05:25:32 +00:00
return new ArrayList ( ) ;
2008-09-23 03:36:16 +00:00
}
2008-01-09 15:46:45 +00:00
// Retrieve group
SceneObjectPart part = GetSceneObjectPart ( primId ) ;
2011-08-27 03:16:46 +00:00
if ( part = = null )
return new ArrayList ( ) ;
2007-12-27 21:41:48 +00:00
2011-09-01 00:22:28 +00:00
SceneObjectGroup group = part . ParentGroup ;
2008-05-16 01:22:11 +00:00
2007-12-24 22:35:01 +00:00
// Retrieve item
2008-03-05 18:57:13 +00:00
TaskInventoryItem item = group . GetInventoryItem ( part . LocalId , itemId ) ;
2008-08-18 00:39:10 +00:00
2008-01-09 15:46:45 +00:00
if ( null = = item )
2008-08-18 00:39:10 +00:00
{
2008-07-06 12:35:00 +00:00
m_log . ErrorFormat (
"[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update "
+ " but the item does not exist in this inventory" ,
itemId , part . Name , part . UUID ) ;
2009-12-22 05:25:32 +00:00
return new ArrayList ( ) ;
2008-01-09 15:46:45 +00:00
}
2008-05-16 01:22:11 +00:00
2010-02-22 21:27:17 +00:00
AssetBase asset = CreateAsset ( item . Name , item . Description , ( sbyte ) AssetType . LSLText , data , remoteClient . AgentId ) ;
2009-05-15 05:00:25 +00:00
AssetService . Store ( asset ) ;
2008-05-16 01:22:11 +00:00
2012-05-09 22:12:30 +00:00
// m_log.DebugFormat(
// "[PRIM INVENTORY]: Stored asset {0} when updating item {1} in prim {2} for {3}",
// asset.ID, item.Name, part.Name, remoteClient.Name);
2008-09-21 00:05:33 +00:00
if ( isScriptRunning )
2008-06-28 16:08:12 +00:00
{
2010-01-25 21:51:58 +00:00
part . Inventory . RemoveScriptInstance ( item . ItemID , false ) ;
2008-06-28 16:08:12 +00:00
}
2009-02-04 00:01:36 +00:00
2007-12-24 22:35:01 +00:00
// Update item with new asset
2009-02-17 01:36:44 +00:00
item . AssetID = asset . FullID ;
2010-04-19 20:25:59 +00:00
if ( group . UpdateInventoryItem ( item ) )
2013-06-18 20:21:59 +00:00
remoteClient . SendAlertMessage ( "Script saved" ) ;
2010-04-19 20:25:59 +00:00
2011-09-15 17:58:58 +00:00
part . SendPropertiesToClient ( remoteClient ) ;
2008-05-16 01:22:11 +00:00
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
2009-12-22 05:25:32 +00:00
ArrayList errors = new ArrayList ( ) ;
2008-09-21 00:05:33 +00:00
if ( isScriptRunning )
2008-01-09 15:46:45 +00:00
{
2008-09-21 21:47:00 +00:00
// Needs to determine which engine was running it and use that
/ /
2008-11-21 21:16:42 +00:00
part . Inventory . CreateScriptInstance ( item . ItemID , 0 , false , DefaultScriptEngine , 0 ) ;
2009-12-22 05:25:32 +00:00
errors = part . Inventory . GetScriptErrors ( item . ItemID ) ;
2008-01-09 15:46:45 +00:00
}
2008-09-25 17:26:32 +00:00
else
{
2013-06-18 20:21:59 +00:00
remoteClient . SendAlertMessage ( "Script saved" ) ;
2008-09-25 17:26:32 +00:00
}
2012-02-17 17:12:41 +00:00
// Tell anyone managing scripts that a script has been reloaded/changed
EventManager . TriggerUpdateScript ( remoteClient . AgentId , itemId , primId , isScriptRunning , item . AssetID ) ;
2010-04-19 05:29:26 +00:00
part . ParentGroup . ResumeScripts ( ) ;
2009-12-22 05:25:32 +00:00
return errors ;
2007-12-25 18:11:56 +00:00
}
2007-12-27 21:41:48 +00:00
2007-12-25 18:11:56 +00:00
/// <summary>
2008-09-06 07:52:41 +00:00
/// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])</see>
2008-05-16 01:22:11 +00:00
/// </summary>
2009-12-22 05:25:32 +00:00
public ArrayList CapsUpdateTaskInventoryScriptAsset ( UUID avatarId , UUID itemId ,
2008-09-06 07:52:41 +00:00
UUID primId , bool isScriptRunning , byte [ ] data )
2007-12-27 21:41:48 +00:00
{
2007-12-25 18:11:56 +00:00
ScenePresence avatar ;
2010-03-19 12:58:34 +00:00
if ( TryGetScenePresence ( avatarId , out avatar ) )
2007-12-25 18:11:56 +00:00
{
2009-12-22 05:25:32 +00:00
return CapsUpdateTaskInventoryScriptAsset (
2007-12-25 18:11:56 +00:00
avatar . ControllingClient , itemId , primId , isScriptRunning , data ) ;
}
else
{
2008-02-10 01:57:59 +00:00
m_log . ErrorFormat (
2008-02-20 23:21:51 +00:00
"[PRIM INVENTORY]: " +
2008-02-10 01:57:59 +00:00
"Avatar {0} cannot be found to update its prim item asset" ,
avatarId ) ;
2009-12-22 05:25:32 +00:00
return new ArrayList ( ) ;
2007-12-27 21:41:48 +00:00
}
2007-12-24 22:35:01 +00:00
}
2007-10-19 20:28:18 +00:00
2007-12-03 20:06:01 +00:00
/// <summary>
/// Update an item which is either already in the client's inventory or is within
/// a transaction
/// </summary>
/// <param name="remoteClient"></param>
2008-09-06 07:52:41 +00:00
/// <param name="transactionID">The transaction ID. If this is UUID.Zero we will
2007-12-03 20:06:01 +00:00
/// assume that we are not in a transaction</param>
/// <param name="itemID">The ID of the updated item</param>
/// <param name="name">The name of the updated item</param>
/// <param name="description">The description of the updated item</param>
/// <param name="nextOwnerMask">The permissions of the updated item</param>
2009-01-19 17:11:57 +00:00
/ * public void UpdateInventoryItemAsset ( IClientAPI remoteClient , UUID transactionID ,
UUID itemID , string name , string description ,
uint nextOwnerMask ) * /
2008-09-06 07:52:41 +00:00
public void UpdateInventoryItemAsset ( IClientAPI remoteClient , UUID transactionID ,
UUID itemID , InventoryItemBase itemUpd )
2007-12-27 21:41:48 +00:00
{
2011-09-23 01:59:33 +00:00
// m_log.DebugFormat(
// "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}",
// itemID, itemUpd.Name, transactionID, remoteClient.Name);
2010-07-13 19:45:16 +00:00
// This one will let people set next perms on items in agent
// inventory. Rut-Roh. Whatever. Make this secure. Yeah.
/ /
// Passing something to another avatar or a an object will already
2009-08-19 05:17:47 +00:00
InventoryItemBase item = new InventoryItemBase ( itemID , remoteClient . AgentId ) ;
item = InventoryService . GetItem ( item ) ;
2007-12-27 21:41:48 +00:00
2009-08-13 03:39:48 +00:00
if ( item ! = null )
2007-10-19 20:28:18 +00:00
{
2011-12-09 22:36:51 +00:00
if ( item . Owner ! = remoteClient . AgentId )
return ;
2013-01-27 01:07:37 +00:00
item . Name = itemUpd . Name ;
item . Description = itemUpd . Description ;
2012-02-10 02:13:15 +00:00
// m_log.DebugFormat(
// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
2013-08-18 01:59:10 +00:00
bool sendUpdate = false ;
2013-01-27 01:07:37 +00:00
if ( itemUpd . NextPermissions ! = 0 ) // Use this to determine validity. Can never be 0 if valid
{
2013-03-31 20:59:44 +00:00
// Create a set of base permissions that will not include export if the user
// is not allowed to change the export flag.
bool denyExportChange = false ;
2013-05-14 18:44:41 +00:00
// m_log.DebugFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions);
2013-03-31 20:59:44 +00:00
// If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export
if ( ( item . BasePermissions & ( uint ) ( PermissionMask . All | PermissionMask . Export ) ) ! = ( uint ) ( PermissionMask . All | PermissionMask . Export ) | | ( item . CurrentPermissions & ( uint ) PermissionMask . Export ) = = 0 | | item . CreatorIdAsUuid ! = item . Owner )
denyExportChange = true ;
2013-05-14 18:44:41 +00:00
// m_log.DebugFormat("[XXX]: Deny Export Update {0}", denyExportChange);
2013-03-31 20:59:44 +00:00
// If it is already set, force it set and also force full perm
// else prevent setting it. It can and should never be set unless
// set in base, so the condition above is valid
if ( denyExportChange )
{
// If we are not allowed to change it, then force it to the
// original item's setting and if it was on, also force full perm
if ( ( item . EveryOnePermissions & ( uint ) PermissionMask . Export ) ! = 0 )
{
itemUpd . NextPermissions = ( uint ) ( PermissionMask . All ) ;
itemUpd . EveryOnePermissions | = ( uint ) PermissionMask . Export ;
}
else
{
itemUpd . EveryOnePermissions & = ~ ( uint ) PermissionMask . Export ;
}
}
else
{
// If the new state is exportable, force full perm
if ( ( itemUpd . EveryOnePermissions & ( uint ) PermissionMask . Export ) ! = 0 )
{
2013-05-14 18:44:41 +00:00
// m_log.DebugFormat("[XXX]: Force full perm");
2013-03-31 20:59:44 +00:00
itemUpd . NextPermissions = ( uint ) ( PermissionMask . All ) ;
}
}
2011-01-12 21:39:13 +00:00
if ( item . NextPermissions ! = ( itemUpd . NextPermissions & item . BasePermissions ) )
item . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteNextOwner ;
2010-07-13 19:45:16 +00:00
item . NextPermissions = itemUpd . NextPermissions & item . BasePermissions ;
2013-03-31 20:59:44 +00:00
2011-01-12 21:39:13 +00:00
if ( item . EveryOnePermissions ! = ( itemUpd . EveryOnePermissions & item . BasePermissions ) )
item . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteEveryone ;
2010-07-13 19:45:16 +00:00
item . EveryOnePermissions = itemUpd . EveryOnePermissions & item . BasePermissions ;
2013-03-31 20:59:44 +00:00
2011-01-12 21:39:13 +00:00
if ( item . GroupPermissions ! = ( itemUpd . GroupPermissions & item . BasePermissions ) )
item . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteGroup ;
2010-07-13 19:45:16 +00:00
item . GroupPermissions = itemUpd . GroupPermissions & item . BasePermissions ;
2013-03-31 20:59:44 +00:00
2009-08-13 03:39:48 +00:00
item . GroupID = itemUpd . GroupID ;
item . GroupOwned = itemUpd . GroupOwned ;
item . CreationDate = itemUpd . CreationDate ;
// The client sends zero if its newly created?
2007-12-27 21:41:48 +00:00
2009-08-13 03:39:48 +00:00
if ( itemUpd . CreationDate = = 0 )
item . CreationDate = Util . UnixTimeSinceEpoch ( ) ;
2007-12-27 21:41:48 +00:00
else
2009-08-13 03:39:48 +00:00
item . CreationDate = itemUpd . CreationDate ;
// TODO: Check if folder changed and move item
//item.NextPermissions = itemUpd.Folder;
item . InvType = itemUpd . InvType ;
2011-01-12 21:39:13 +00:00
if ( item . SalePrice ! = itemUpd . SalePrice | |
item . SaleType ! = itemUpd . SaleType )
item . Flags | = ( uint ) InventoryItemFlags . ObjectSlamSale ;
2009-08-13 03:39:48 +00:00
item . SalePrice = itemUpd . SalePrice ;
item . SaleType = itemUpd . SaleType ;
2013-08-18 01:59:10 +00:00
if ( item . InvType = = ( int ) InventoryType . Wearable & & ( item . Flags & 0xf ) = = 0 & & ( itemUpd . Flags & 0xf ) ! = 0 )
{
item . Flags = ( uint ) ( item . Flags & 0xfffffff0 ) | ( itemUpd . Flags & 0xf ) ;
sendUpdate = true ;
}
2013-05-09 21:43:16 +00:00
2013-08-18 01:59:10 +00:00
InventoryService . UpdateItem ( item ) ;
2007-12-03 20:06:01 +00:00
}
2013-01-27 01:07:37 +00:00
if ( UUID . Zero ! = transactionID )
2007-12-27 21:41:48 +00:00
{
2012-06-07 22:51:04 +00:00
if ( AgentTransactionsModule ! = null )
2009-08-13 03:39:48 +00:00
{
2012-06-07 22:51:04 +00:00
AgentTransactionsModule . HandleItemUpdateFromTransaction ( remoteClient , transactionID , item ) ;
2009-08-13 03:39:48 +00:00
}
2007-10-19 20:28:18 +00:00
}
2013-08-18 01:59:10 +00:00
else
{
// This MAY be problematic, if it is, another solution
// needs to be found. If inventory item flags are updated
// the viewer's notion of the item needs to be refreshed.
2013-09-16 22:26:13 +00:00
/ /
// In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start
// failing frequently. Possibly this is a race with a separate transaction that uploads the asset.
2013-08-18 01:59:10 +00:00
if ( sendUpdate )
remoteClient . SendBulkUpdateInventory ( item ) ;
}
2007-10-19 20:28:18 +00:00
}
2007-12-03 20:06:01 +00:00
else
{
2011-12-09 22:36:51 +00:00
m_log . ErrorFormat (
"[AGENTINVENTORY]: Item id {0} not found for an inventory item update for {1}." ,
itemID , remoteClient . Name ) ;
2007-12-03 20:06:01 +00:00
}
2007-10-19 20:28:18 +00:00
}
2008-05-16 01:22:11 +00:00
2008-04-07 01:46:00 +00:00
/// <summary>
2008-12-04 19:57:36 +00:00
/// Give an inventory item from one user to another
2008-04-07 01:46:00 +00:00
/// </summary>
/// <param name="recipientClient"></param>
2008-04-07 21:03:03 +00:00
/// <param name="senderId">ID of the sender of the item</param>
2009-02-04 00:01:36 +00:00
/// <param name="itemId"></param>
2008-11-11 15:18:16 +00:00
public virtual void GiveInventoryItem ( IClientAPI recipientClient , UUID senderId , UUID itemId )
2008-11-12 06:22:31 +00:00
{
InventoryItemBase itemCopy = GiveInventoryItem ( recipientClient . AgentId , senderId , itemId ) ;
if ( itemCopy ! = null )
recipientClient . SendBulkUpdateInventory ( itemCopy ) ;
}
2008-12-04 19:57:36 +00:00
/// <summary>
/// Give an inventory item from one user to another
/// </summary>
/// <param name="recipient"></param>
/// <param name="senderId">ID of the sender of the item</param>
2009-02-04 00:01:36 +00:00
/// <param name="itemId"></param>
2008-12-04 19:57:36 +00:00
/// <returns>The inventory item copy given, null if the give was unsuccessful</returns>
2008-11-12 06:22:31 +00:00
public virtual InventoryItemBase GiveInventoryItem ( UUID recipient , UUID senderId , UUID itemId )
2008-12-04 19:57:36 +00:00
{
return GiveInventoryItem ( recipient , senderId , itemId , UUID . Zero ) ;
}
2009-02-04 00:01:36 +00:00
2008-12-04 19:57:36 +00:00
/// <summary>
/// Give an inventory item from one user to another
/// </summary>
/// <param name="recipient"></param>
/// <param name="senderId">ID of the sender of the item</param>
2009-02-04 00:01:36 +00:00
/// <param name="itemId"></param>
2008-12-04 19:57:36 +00:00
/// <param name="recipientFolderId">
/// The id of the folder in which the copy item should go. If UUID.Zero then the item is placed in the most
/// appropriate default folder.
/// </param>
/// <returns>
/// The inventory item copy given, null if the give was unsuccessful
/// </returns>
public virtual InventoryItemBase GiveInventoryItem (
UUID recipient , UUID senderId , UUID itemId , UUID recipientFolderId )
2008-04-07 01:46:00 +00:00
{
2009-10-13 00:00:01 +00:00
//Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem");
2009-06-29 15:05:12 +00:00
2013-08-04 03:36:30 +00:00
if ( ! Permissions . CanTransferUserInventory ( itemId , senderId , recipient ) )
return null ;
2009-08-19 05:17:47 +00:00
InventoryItemBase item = new InventoryItemBase ( itemId , senderId ) ;
item = InventoryService . GetItem ( item ) ;
2008-04-07 01:46:00 +00:00
2011-06-04 01:39:26 +00:00
if ( item = = null )
2008-04-07 01:46:00 +00:00
{
2011-06-04 01:39:26 +00:00
m_log . WarnFormat (
"[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}" , itemId , senderId , recipient ) ;
return null ;
}
2010-11-25 19:14:16 +00:00
2011-06-04 01:39:26 +00:00
if ( item . Owner ! = senderId )
{
m_log . WarnFormat (
"[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}" ,
item . Name , item . ID , recipient , senderId , item . Owner ) ;
return null ;
}
IUserManagement uman = RequestModuleInterface < IUserManagement > ( ) ;
if ( uman ! = null )
uman . AddUser ( item . CreatorIdAsUuid , item . CreatorData ) ;
if ( ! Permissions . BypassPermissions ( ) )
{
if ( ( item . CurrentPermissions & ( uint ) PermissionMask . Transfer ) = = 0 )
return null ;
}
2008-05-15 19:28:10 +00:00
2011-06-04 01:39:26 +00:00
// Insert a copy of the item into the recipient
InventoryItemBase itemCopy = new InventoryItemBase ( ) ;
itemCopy . Owner = recipient ;
itemCopy . CreatorId = item . CreatorId ;
itemCopy . CreatorData = item . CreatorData ;
itemCopy . ID = UUID . Random ( ) ;
itemCopy . AssetID = item . AssetID ;
itemCopy . Description = item . Description ;
itemCopy . Name = item . Name ;
itemCopy . AssetType = item . AssetType ;
itemCopy . InvType = item . InvType ;
itemCopy . Folder = recipientFolderId ;
if ( Permissions . PropagatePermissions ( ) & & recipient ! = senderId )
{
// Trying to do this right this time. This is evil. If
// you believe in Good, go elsewhere. Vampires and other
// evil creatores only beyond this point. You have been
// warned.
// We're going to mask a lot of things by the next perms
// Tweak the next perms to be nicer to our data
/ /
// In this mask, all the bits we do NOT want to mess
// with are set. These are:
/ /
// Transfer
// Copy
// Modufy
uint permsMask = ~ ( ( uint ) PermissionMask . Copy |
( uint ) PermissionMask . Transfer |
( uint ) PermissionMask . Modify ) ;
// Now, reduce the next perms to the mask bits
// relevant to the operation
uint nextPerms = permsMask | ( item . NextPermissions &
( ( uint ) PermissionMask . Copy |
( uint ) PermissionMask . Transfer |
( uint ) PermissionMask . Modify ) ) ;
// nextPerms now has all bits set, except for the actual
// next permission bits.
// This checks for no mod, no copy, no trans.
// This indicates an error or messed up item. Do it like
// SL and assume trans
if ( nextPerms = = permsMask )
nextPerms | = ( uint ) PermissionMask . Transfer ;
// Inventory owner perms are the logical AND of the
// folded perms and the root prim perms, however, if
// the root prim is mod, the inventory perms will be
// mod. This happens on "take" and is of little concern
// here, save for preventing escalation
// This hack ensures that items previously permalocked
// get unlocked when they're passed or rezzed
uint basePerms = item . BasePermissions |
( uint ) PermissionMask . Move ;
uint ownerPerms = item . CurrentPermissions ;
// If this is an object, root prim perms may be more
// permissive than folded perms. Use folded perms as
// a mask
if ( item . InvType = = ( int ) InventoryType . Object )
2009-08-13 03:39:48 +00:00
{
2011-06-04 01:39:26 +00:00
// Create a safe mask for the current perms
uint foldedPerms = ( item . CurrentPermissions & 7 ) < < 13 ;
foldedPerms | = permsMask ;
bool isRootMod = ( item . CurrentPermissions &
( uint ) PermissionMask . Modify ) ! = 0 ?
true : false ;
// Mask the owner perms to the folded perms
ownerPerms & = foldedPerms ;
basePerms & = foldedPerms ;
// If the root was mod, let the mask reflect that
// We also need to adjust the base here, because
// we should be able to edit in-inventory perms
// for the root prim, if it's mod.
if ( isRootMod )
2008-04-07 01:46:00 +00:00
{
2011-06-04 01:39:26 +00:00
ownerPerms | = ( uint ) PermissionMask . Modify ;
basePerms | = ( uint ) PermissionMask . Modify ;
2008-04-07 01:46:00 +00:00
}
2011-06-04 01:39:26 +00:00
}
2009-08-13 03:39:48 +00:00
2011-06-04 01:39:26 +00:00
// These will be applied to the root prim at next rez.
// The slam bit (bit 3) and folded permission (bits 0-2)
// are preserved due to the above mangling
ownerPerms & = nextPerms ;
2010-05-21 01:31:14 +00:00
2011-06-04 01:39:26 +00:00
// Mask the base permissions. This is a conservative
// approach altering only the three main perms
basePerms & = nextPerms ;
2010-07-14 14:21:55 +00:00
2011-06-04 01:39:26 +00:00
// Assign to the actual item. Make sure the slam bit is
// set, if it wasn't set before.
itemCopy . BasePermissions = basePerms ;
itemCopy . CurrentPermissions = ownerPerms ;
itemCopy . Flags | = ( uint ) InventoryItemFlags . ObjectSlamPerm ;
2009-08-13 03:39:48 +00:00
2011-06-04 01:39:26 +00:00
itemCopy . NextPermissions = item . NextPermissions ;
2010-05-21 01:31:14 +00:00
2011-06-04 01:39:26 +00:00
// This preserves "everyone can move"
itemCopy . EveryOnePermissions = item . EveryOnePermissions &
nextPerms ;
2010-07-13 19:45:16 +00:00
2011-06-04 01:39:26 +00:00
// Intentionally killing "share with group" here, as
// the recipient will not have the group this is
// set to
itemCopy . GroupPermissions = 0 ;
}
else
{
itemCopy . CurrentPermissions = item . CurrentPermissions ;
itemCopy . NextPermissions = item . NextPermissions ;
itemCopy . EveryOnePermissions = item . EveryOnePermissions & item . NextPermissions ;
itemCopy . GroupPermissions = item . GroupPermissions & item . NextPermissions ;
itemCopy . BasePermissions = item . BasePermissions ;
}
if ( itemCopy . Folder = = UUID . Zero )
{
InventoryFolderBase folder = InventoryService . GetFolderForType ( recipient , ( AssetType ) itemCopy . AssetType ) ;
if ( folder ! = null )
2008-04-07 01:46:00 +00:00
{
2011-06-04 01:39:26 +00:00
itemCopy . Folder = folder . ID ;
2009-08-13 03:39:48 +00:00
}
2011-06-04 01:39:26 +00:00
else
2010-05-03 21:44:23 +00:00
{
2011-06-04 01:39:26 +00:00
InventoryFolderBase root = InventoryService . GetRootFolder ( recipient ) ;
2010-05-03 21:44:23 +00:00
2011-06-04 01:39:26 +00:00
if ( root ! = null )
itemCopy . Folder = root . ID ;
2010-05-03 21:44:23 +00:00
else
2011-06-04 01:39:26 +00:00
return null ; // No destination
2010-05-03 21:44:23 +00:00
}
2011-06-04 01:39:26 +00:00
}
2010-05-03 21:44:23 +00:00
2011-06-04 01:39:26 +00:00
itemCopy . GroupID = UUID . Zero ;
itemCopy . GroupOwned = false ;
itemCopy . Flags = item . Flags ;
itemCopy . SalePrice = item . SalePrice ;
itemCopy . SaleType = item . SaleType ;
2008-05-16 01:22:11 +00:00
2012-12-10 06:03:21 +00:00
IInventoryAccessModule invAccess = RequestModuleInterface < IInventoryAccessModule > ( ) ;
if ( invAccess ! = null )
invAccess . TransferInventoryAssets ( itemCopy , senderId , recipient ) ;
AddInventoryItem ( itemCopy ) ;
2009-08-13 03:39:48 +00:00
2011-06-04 01:39:26 +00:00
if ( ! Permissions . BypassPermissions ( ) )
{
if ( ( item . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
2009-08-13 03:39:48 +00:00
{
2011-06-04 01:39:26 +00:00
List < UUID > items = new List < UUID > ( ) ;
items . Add ( itemId ) ;
InventoryService . DeleteItems ( senderId , items ) ;
2008-04-07 01:46:00 +00:00
}
2008-05-16 01:22:11 +00:00
}
2009-02-04 00:01:36 +00:00
2011-06-04 01:39:26 +00:00
return itemCopy ;
2008-04-07 01:46:00 +00:00
}
2009-02-04 00:01:36 +00:00
2008-12-04 19:57:36 +00:00
/// <summary>
2009-02-04 00:01:36 +00:00
/// Give an entire inventory folder from one user to another. The entire contents (including all descendent
2008-12-04 19:57:36 +00:00
/// folders) is given.
/// </summary>
/// <param name="recipientId"></param>
/// <param name="senderId">ID of the sender of the item</param>
/// <param name="folderId"></param>
/// <param name="recipientParentFolderId">
2009-02-04 00:01:36 +00:00
/// The id of the receipient folder in which the send folder should be placed. If UUID.Zero then the
2008-12-04 19:57:36 +00:00
/// recipient folder is the root folder
/// </param>
/// <returns>
/// The inventory folder copy given, null if the copy was unsuccessful
/// </returns>
2009-08-13 03:39:48 +00:00
public virtual InventoryFolderBase GiveInventoryFolder (
2008-12-04 19:57:36 +00:00
UUID recipientId , UUID senderId , UUID folderId , UUID recipientParentFolderId )
{
2009-08-13 03:39:48 +00:00
//// Retrieve the folder from the sender
2009-08-13 21:10:12 +00:00
InventoryFolderBase folder = InventoryService . GetFolder ( new InventoryFolderBase ( folderId ) ) ;
2008-12-04 19:57:36 +00:00
if ( null = = folder )
{
m_log . ErrorFormat (
"[AGENT INVENTORY]: Could not find inventory folder {0} to give" , folderId ) ;
2009-02-04 00:01:36 +00:00
return null ;
2008-12-04 19:57:36 +00:00
}
2009-08-13 03:39:48 +00:00
if ( recipientParentFolderId = = UUID . Zero )
2009-03-23 00:11:34 +00:00
{
2009-08-13 03:39:48 +00:00
InventoryFolderBase recipientRootFolder = InventoryService . GetRootFolder ( recipientId ) ;
if ( recipientRootFolder ! = null )
recipientParentFolderId = recipientRootFolder . ID ;
else
{
m_log . WarnFormat ( "[AGENT INVENTORY]: Unable to find root folder for receiving agent" ) ;
2009-03-23 00:11:34 +00:00
return null ;
2009-08-13 03:39:48 +00:00
}
2009-03-23 00:11:34 +00:00
}
2008-12-04 19:57:36 +00:00
UUID newFolderId = UUID . Random ( ) ;
2009-08-28 11:52:40 +00:00
InventoryFolderBase newFolder
= new InventoryFolderBase (
newFolderId , folder . Name , recipientId , folder . Type , recipientParentFolderId , folder . Version ) ;
2009-08-13 03:39:48 +00:00
InventoryService . AddFolder ( newFolder ) ;
2009-02-04 00:01:36 +00:00
2008-12-04 19:57:36 +00:00
// Give all the subfolders
2009-08-13 03:39:48 +00:00
InventoryCollection contents = InventoryService . GetFolderContent ( senderId , folderId ) ;
foreach ( InventoryFolderBase childFolder in contents . Folders )
2008-12-04 19:57:36 +00:00
{
2009-08-13 03:39:48 +00:00
GiveInventoryFolder ( recipientId , senderId , childFolder . ID , newFolder . ID ) ;
2009-02-04 00:01:36 +00:00
}
2008-12-04 19:57:36 +00:00
// Give all the items
2009-08-13 03:39:48 +00:00
foreach ( InventoryItemBase item in contents . Items )
2008-12-04 19:57:36 +00:00
{
2009-08-13 03:39:48 +00:00
GiveInventoryItem ( recipientId , senderId , item . ID , newFolder . ID ) ;
2008-12-04 19:57:36 +00:00
}
2009-02-04 00:01:36 +00:00
2009-08-13 03:39:48 +00:00
return newFolder ;
2008-12-04 19:57:36 +00:00
}
2007-10-19 20:28:18 +00:00
2008-09-06 07:52:41 +00:00
public void CopyInventoryItem ( IClientAPI remoteClient , uint callbackID , UUID oldAgentID , UUID oldItemID ,
UUID newFolderID , string newName )
2007-11-18 13:50:46 +00:00
{
2008-04-07 01:46:00 +00:00
m_log . DebugFormat (
"[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}" ,
remoteClient . AgentId , oldAgentID , oldItemID , newFolderID , newName ) ;
2008-05-16 01:22:11 +00:00
2010-01-02 05:12:46 +00:00
InventoryItemBase item = null ;
if ( LibraryService ! = null & & LibraryService . LibraryRootFolder ! = null )
item = LibraryService . LibraryRootFolder . FindItem ( oldItemID ) ;
2008-05-16 01:22:11 +00:00
2007-11-18 13:50:46 +00:00
if ( item = = null )
{
2009-08-19 05:17:47 +00:00
item = new InventoryItemBase ( oldItemID , remoteClient . AgentId ) ;
item = InventoryService . GetItem ( item ) ;
2008-05-16 01:22:11 +00:00
2009-08-13 18:30:29 +00:00
if ( item = = null )
2007-11-18 13:50:46 +00:00
{
2008-05-01 18:04:42 +00:00
m_log . Error ( "[AGENT INVENTORY]: Failed to find item " + oldItemID . ToString ( ) ) ;
2007-11-18 13:50:46 +00:00
return ;
}
2010-02-14 23:58:54 +00:00
if ( ( item . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
return ;
2007-11-18 13:50:46 +00:00
}
2008-05-16 01:22:11 +00:00
2009-05-15 05:00:25 +00:00
AssetBase asset = AssetService . Get ( item . AssetID . ToString ( ) ) ;
2007-11-18 13:50:46 +00:00
2008-02-20 23:31:33 +00:00
if ( asset ! = null )
{
2008-05-31 20:47:14 +00:00
if ( newName ! = String . Empty )
{
2009-02-17 01:36:44 +00:00
asset . Name = newName ;
2008-05-31 20:47:14 +00:00
}
2008-08-29 11:03:58 +00:00
else
{
newName = item . Name ;
}
2008-05-31 20:47:14 +00:00
2011-07-23 01:13:11 +00:00
if ( remoteClient . AgentId = = oldAgentID
| | ( LibraryService ! = null
& & LibraryService . LibraryRootFolder ! = null
& & oldAgentID = = LibraryService . LibraryRootFolder . Owner ) )
2008-05-16 01:22:11 +00:00
{
CreateNewInventoryItem (
2012-07-26 22:44:29 +00:00
remoteClient , item . CreatorId , item . CreatorData , newFolderID ,
newName , item . Description , item . Flags , callbackID , asset , ( sbyte ) item . InvType ,
item . BasePermissions , item . CurrentPermissions , item . EveryOnePermissions ,
item . NextPermissions , item . GroupPermissions , Util . UnixTimeSinceEpoch ( ) ) ;
2008-05-16 01:22:11 +00:00
}
else
2010-12-23 18:17:33 +00:00
{
// If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
2012-07-26 22:44:29 +00:00
if ( ( ( item . CurrentPermissions & ( uint ) PermissionMask . Transfer ) ! = 0 )
& & ( m_permissions . BypassPermissions ( )
| | m_permissions . CanCopyUserInventory ( remoteClient . AgentId , oldItemID ) ) )
2010-12-23 18:17:33 +00:00
{
CreateNewInventoryItem (
2012-07-26 22:44:29 +00:00
remoteClient , item . CreatorId , item . CreatorData , newFolderID , newName , item . Description , item . Flags , callbackID ,
2010-12-23 18:17:33 +00:00
asset , ( sbyte ) item . InvType ,
item . NextPermissions , item . NextPermissions , item . EveryOnePermissions & item . NextPermissions ,
item . NextPermissions , item . GroupPermissions , Util . UnixTimeSinceEpoch ( ) ) ;
}
2008-05-16 01:22:11 +00:00
}
2008-02-20 23:31:33 +00:00
}
else
{
m_log . ErrorFormat (
"[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found" ,
2008-05-16 01:22:11 +00:00
item . Name , item . AssetID ) ;
2008-02-20 23:31:33 +00:00
}
2007-11-18 13:50:46 +00:00
}
2008-06-23 18:01:58 +00:00
/// <summary>
/// Create a new asset data structure.
/// </summary>
2010-08-13 21:29:42 +00:00
public AssetBase CreateAsset ( string name , string description , sbyte assetType , byte [ ] data , UUID creatorID )
2007-11-18 13:50:46 +00:00
{
2010-02-22 22:18:59 +00:00
AssetBase asset = new AssetBase ( UUID . Random ( ) , name , assetType , creatorID . ToString ( ) ) ;
2009-02-17 01:36:44 +00:00
asset . Description = description ;
2007-11-18 13:50:46 +00:00
asset . Data = ( data = = null ) ? new byte [ 1 ] : data ;
2008-08-18 00:39:10 +00:00
2007-11-18 13:50:46 +00:00
return asset ;
}
2008-05-03 23:23:46 +00:00
/// <summary>
/// Move an item within the agent's inventory.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="folderID"></param>
/// <param name="itemID"></param>
/// <param name="length"></param>
/// <param name="newName"></param>
2009-08-19 17:56:08 +00:00
public void MoveInventoryItem ( IClientAPI remoteClient , List < InventoryItemBase > items )
2007-12-08 19:13:10 +00:00
{
2008-04-07 01:46:00 +00:00
m_log . DebugFormat (
2009-08-19 17:56:08 +00:00
"[AGENT INVENTORY]: Moving {0} items for user {1}" , items . Count , remoteClient . AgentId ) ;
2007-12-27 21:41:48 +00:00
2009-08-19 17:56:08 +00:00
if ( ! InventoryService . MoveItems ( remoteClient . AgentId , items ) )
m_log . Warn ( "[AGENT INVENTORY]: Failed to move items for user " + remoteClient . AgentId ) ;
2007-12-08 19:13:10 +00:00
}
2008-06-23 18:01:58 +00:00
/// <summary>
/// Create a new inventory item.
/// </summary>
2012-07-26 22:44:29 +00:00
/// <param name="remoteClient">Client creating this inventory item.</param>
/// <param name="creatorID"></param>
/// <param name="creatorData"></param>
/// <param name="folderID">UUID of folder in which this item should be placed.</param>
/// <param name="name">Item name.</para>
/// <param name="description">Item description.</param>
/// <param name="flags">Item flags</param>
/// <param name="callbackID">Generated by the client.</para>
/// <param name="asset">Asset to which this item refers.</param>
/// <param name="invType">Type of inventory item.</param>
/// <param name="nextOwnerMask">Next owner pemrissions mask.</param>
/// <param name="creationDate">Unix timestamp at which this item was created.</param>
public void CreateNewInventoryItem (
IClientAPI remoteClient , string creatorID , string creatorData , UUID folderID ,
string name , string description , uint flags , uint callbackID ,
AssetBase asset , sbyte invType , uint nextOwnerMask , int creationDate )
2008-05-16 01:22:11 +00:00
{
2008-06-23 18:01:58 +00:00
CreateNewInventoryItem (
2012-07-26 22:44:29 +00:00
remoteClient , creatorID , creatorData , folderID , name , description , flags , callbackID , asset , invType ,
2013-03-26 03:40:06 +00:00
( uint ) PermissionMask . All | ( uint ) PermissionMask . Export , ( uint ) PermissionMask . All | ( uint ) PermissionMask . Export , 0 , nextOwnerMask , 0 , creationDate ) ;
2008-05-16 01:22:11 +00:00
}
2008-05-15 19:28:10 +00:00
2008-02-11 21:58:58 +00:00
/// <summary>
2008-07-13 18:57:13 +00:00
/// Create a new Inventory Item
2008-02-11 21:58:58 +00:00
/// </summary>
2012-07-26 22:44:29 +00:00
/// <param name="remoteClient">Client creating this inventory item.</param>
/// <param name="creatorID"></param>
/// <param name="creatorData"></param>
/// <param name="folderID">UUID of folder in which this item should be placed.</param>
/// <param name="name">Item name.</para>
/// <param name="description">Item description.</param>
/// <param name="flags">Item flags</param>
/// <param name="callbackID">Generated by the client.</para>
/// <param name="asset">Asset to which this item refers.</param>
/// <param name="invType">Type of inventory item.</param>
/// <param name="baseMask">Base permissions mask.</param>
/// <param name="currentMask">Current permissions mask.</param>
/// <param name="everyoneMask">Everyone permissions mask.</param>
/// <param name="nextOwnerMask">Next owner pemrissions mask.</param>
/// <param name="groupMask">Group permissions mask.</param>
/// <param name="creationDate">Unix timestamp at which this item was created.</param>
2008-06-23 18:01:58 +00:00
private void CreateNewInventoryItem (
2012-07-26 22:44:29 +00:00
IClientAPI remoteClient , string creatorID , string creatorData , UUID folderID ,
string name , string description , uint flags , uint callbackID , AssetBase asset , sbyte invType ,
2008-11-14 18:54:38 +00:00
uint baseMask , uint currentMask , uint everyoneMask , uint nextOwnerMask , uint groupMask , int creationDate )
2007-11-18 13:50:46 +00:00
{
2009-08-13 03:39:48 +00:00
InventoryItemBase item = new InventoryItemBase ( ) ;
item . Owner = remoteClient . AgentId ;
item . CreatorId = creatorID ;
2010-11-22 01:19:24 +00:00
item . CreatorData = creatorData ;
2009-08-13 03:39:48 +00:00
item . ID = UUID . Random ( ) ;
item . AssetID = asset . FullID ;
item . Name = name ;
2012-07-26 22:44:29 +00:00
item . Description = description ;
2009-08-13 03:39:48 +00:00
item . Flags = flags ;
item . AssetType = asset . Type ;
item . InvType = invType ;
item . Folder = folderID ;
item . CurrentPermissions = currentMask ;
item . NextPermissions = nextOwnerMask ;
item . EveryOnePermissions = everyoneMask ;
item . GroupPermissions = groupMask ;
item . BasePermissions = baseMask ;
item . CreationDate = creationDate ;
2010-09-04 00:36:26 +00:00
if ( AddInventoryItem ( item ) )
{
2009-02-19 03:09:56 +00:00
remoteClient . SendInventoryItemCreateUpdate ( item , callbackID ) ;
2010-09-04 00:36:26 +00:00
}
2008-02-11 21:58:58 +00:00
else
{
2009-08-13 03:39:48 +00:00
m_dialogModule . SendAlertToUser ( remoteClient , "Failed to create item" ) ;
2008-02-11 21:58:58 +00:00
m_log . WarnFormat (
2009-08-13 03:39:48 +00:00
"Failed to add item for {0} in CreateNewInventoryItem!" ,
remoteClient . Name ) ;
2008-02-11 21:58:58 +00:00
}
2007-11-18 13:50:46 +00:00
}
2011-05-12 01:46:13 +00:00
/// <summary>
/// Link an inventory item to an existing item.
/// </summary>
2011-05-12 02:18:53 +00:00
/// <remarks>
/// The linkee item id is placed in the asset id slot. This appears to be what the viewer expects when
/// it receives inventory information.
/// </remarks>
2011-05-12 01:46:13 +00:00
/// <param name="remoteClient"></param>
/// <param name="transActionID"></param>
/// <param name="folderID"></param>
/// <param name="callbackID"></param>
/// <param name="description"></param>
/// <param name="name"></param>
/// <param name="invType"></param>
/// <param name="type">/param>
/// <param name="olditemID"></param>
2010-04-13 00:10:51 +00:00
private void HandleLinkInventoryItem ( IClientAPI remoteClient , UUID transActionID , UUID folderID ,
uint callbackID , string description , string name ,
sbyte invType , sbyte type , UUID olditemID )
{
2011-05-13 23:10:27 +00:00
// m_log.DebugFormat(
2012-05-21 20:00:22 +00:00
// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}, assetType {4}, inventoryType {5}",
// remoteClient.Name, name, folderID, olditemID, (AssetType)type, (InventoryType)invType);
2010-04-13 00:10:51 +00:00
if ( ! Permissions . CanCreateUserInventory ( invType , remoteClient . AgentId ) )
return ;
ScenePresence presence ;
if ( TryGetScenePresence ( remoteClient . AgentId , out presence ) )
{
2011-05-13 23:10:27 +00:00
// Disabled the check for duplicate links.
/ /
// When outfits are being adjusted, the viewer rapidly sends delete link messages followed by
// create links. However, since these are handled asynchronously, the deletes do not complete before
// the creates are handled. Therefore, we cannot enforce a duplicate link check.
// InventoryItemBase existingLink = null;
// List<InventoryItemBase> existingItems = InventoryService.GetFolderItems(remoteClient.AgentId, folderID);
// foreach (InventoryItemBase item in existingItems)
// if (item.AssetID == olditemID)
// existingLink = item;
/ /
// if (existingLink != null)
// {
// m_log.WarnFormat(
// "[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",
// remoteClient.Name, name, folderID, olditemID, existingLink.Name, existingLink.ID);
/ /
// return;
// }
2010-04-13 00:10:51 +00:00
AssetBase asset = new AssetBase ( ) ;
asset . FullID = olditemID ;
asset . Type = type ;
asset . Name = name ;
asset . Description = description ;
2012-05-21 20:00:22 +00:00
2010-08-13 22:15:11 +00:00
CreateNewInventoryItem (
2012-07-26 22:44:29 +00:00
remoteClient , remoteClient . AgentId . ToString ( ) , string . Empty , folderID ,
name , description , 0 , callbackID , asset , invType ,
2013-03-26 03:40:06 +00:00
( uint ) PermissionMask . All | ( uint ) PermissionMask . Export , ( uint ) PermissionMask . All | ( uint ) PermissionMask . Export , ( uint ) PermissionMask . All ,
( uint ) PermissionMask . All | ( uint ) PermissionMask . Export , ( uint ) PermissionMask . All | ( uint ) PermissionMask . Export , Util . UnixTimeSinceEpoch ( ) ) ;
2010-04-13 00:10:51 +00:00
}
else
{
m_log . ErrorFormat (
"ScenePresence for agent uuid {0} unexpectedly not found in HandleLinkInventoryItem" ,
remoteClient . AgentId ) ;
}
}
2008-05-03 23:23:46 +00:00
/// <summary>
/// Remove an inventory item for the client's inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
2009-08-19 07:13:51 +00:00
private void RemoveInventoryItem ( IClientAPI remoteClient , List < UUID > itemIDs )
2008-02-18 03:25:14 +00:00
{
2011-05-13 23:10:27 +00:00
// m_log.DebugFormat(
// "[AGENT INVENTORY]: Removing inventory items {0} for {1}",
// string.Join(",", itemIDs.ConvertAll<string>(uuid => uuid.ToString()).ToArray()),
// remoteClient.Name);
2009-08-19 07:13:51 +00:00
InventoryService . DeleteItems ( remoteClient . AgentId , itemIDs ) ;
2008-02-18 03:25:14 +00:00
}
2008-05-03 18:13:32 +00:00
/// <summary>
2009-08-22 17:24:26 +00:00
/// Removes an inventory folder. This packet is sent when the user
/// right-clicks a folder that's already in trash and chooses "purge"
2008-05-03 18:13:32 +00:00
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="folderID"></param>
2009-08-22 17:24:26 +00:00
private void RemoveInventoryFolder ( IClientAPI remoteClient , List < UUID > folderIDs )
2008-02-18 03:25:14 +00:00
{
2009-08-22 17:24:26 +00:00
m_log . DebugFormat ( "[SCENE INVENTORY]: RemoveInventoryFolders count {0}" , folderIDs . Count ) ;
InventoryService . DeleteFolders ( remoteClient . AgentId , folderIDs ) ;
2008-02-18 03:25:14 +00:00
}
2007-10-19 20:28:18 +00:00
/// <summary>
2008-04-02 17:34:53 +00:00
/// Send the details of a prim's inventory to the client.
2007-10-19 20:28:18 +00:00
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="primLocalID"></param>
public void RequestTaskInventory ( IClientAPI remoteClient , uint primLocalID )
2008-05-16 01:22:11 +00:00
{
2010-12-21 20:47:00 +00:00
SceneObjectPart part = GetSceneObjectPart ( primLocalID ) ;
if ( part = = null )
return ;
if ( XferManager ! = null )
part . Inventory . RequestInventoryFile ( remoteClient , XferManager ) ;
2007-10-19 20:28:18 +00:00
}
2007-12-22 02:52:35 +00:00
/// <summary>
/// Remove an item from a prim (task) inventory
/// </summary>
2008-01-09 15:46:45 +00:00
/// <param name="remoteClient">Unused at the moment but retained since the avatar ID might
/// be necessary for a permissions check at some stage.</param>
2007-12-22 02:52:35 +00:00
/// <param name="itemID"></param>
/// <param name="localID"></param>
2008-09-06 07:52:41 +00:00
public void RemoveTaskInventory ( IClientAPI remoteClient , UUID itemID , uint localID )
2007-10-19 20:28:18 +00:00
{
2008-05-16 23:11:00 +00:00
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
2012-01-06 17:43:35 +00:00
SceneObjectGroup group = null ;
if ( part ! = null )
{
group = part . ParentGroup ;
}
if ( part ! = null & & group ! = null )
{
if ( ! Permissions . CanEditObjectInventory ( part . UUID , remoteClient . AgentId ) )
return ;
2011-09-01 00:22:28 +00:00
2012-01-06 17:43:35 +00:00
TaskInventoryItem item = group . GetInventoryItem ( localID , itemID ) ;
if ( item = = null )
return ;
2008-09-25 05:13:44 +00:00
2012-01-06 17:43:35 +00:00
InventoryFolderBase destFolder = InventoryService . GetFolderForType ( remoteClient . AgentId , AssetType . TrashFolder ) ;
// Move the item to trash. If this is a copiable item, only
// a copy will be moved and we will still need to delete
// the item from the prim. If it was no copy, is will be
// deleted by this method.
MoveTaskInventoryItem ( remoteClient , destFolder . ID , part , itemID ) ;
if ( group . GetInventoryItem ( localID , itemID ) ! = null )
{
if ( item . Type = = 10 )
{
part . RemoveScriptEvents ( itemID ) ;
EventManager . TriggerRemoveScript ( localID , itemID ) ;
}
group . RemoveInventoryItem ( localID , itemID ) ;
}
part . SendPropertiesToClient ( remoteClient ) ;
2007-12-27 21:41:48 +00:00
}
2007-12-22 02:52:35 +00:00
}
2008-05-16 01:22:11 +00:00
2008-09-06 07:52:41 +00:00
private InventoryItemBase CreateAgentInventoryItemFromTask ( UUID destAgent , SceneObjectPart part , UUID itemId )
2008-04-26 20:31:01 +00:00
{
2008-11-21 21:16:42 +00:00
TaskInventoryItem taskItem = part . Inventory . GetInventoryItem ( itemId ) ;
2008-05-16 01:22:11 +00:00
2008-04-26 20:31:01 +00:00
if ( null = = taskItem )
{
2008-07-06 12:35:00 +00:00
m_log . ErrorFormat (
"[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for creating an avatar"
+ " inventory item from a prim's inventory item "
+ " but the required item does not exist in the prim's inventory" ,
itemId , part . Name , part . UUID ) ;
2008-06-26 02:46:29 +00:00
return null ;
2008-04-26 20:31:01 +00:00
}
2008-05-16 01:22:11 +00:00
2008-10-08 02:45:23 +00:00
if ( ( destAgent ! = taskItem . OwnerID ) & & ( ( taskItem . CurrentPermissions & ( uint ) PermissionMask . Transfer ) = = 0 ) )
{
return null ;
}
2008-04-26 20:31:01 +00:00
InventoryItemBase agentItem = new InventoryItemBase ( ) ;
2008-05-16 01:22:11 +00:00
2008-09-06 07:52:41 +00:00
agentItem . ID = UUID . Random ( ) ;
2009-04-08 17:50:57 +00:00
agentItem . CreatorId = taskItem . CreatorID . ToString ( ) ;
2010-11-22 01:19:24 +00:00
agentItem . CreatorData = taskItem . CreatorData ;
2008-06-26 02:46:29 +00:00
agentItem . Owner = destAgent ;
2008-04-26 20:31:01 +00:00
agentItem . AssetID = taskItem . AssetID ;
agentItem . Description = taskItem . Description ;
agentItem . Name = taskItem . Name ;
agentItem . AssetType = taskItem . Type ;
agentItem . InvType = taskItem . InvType ;
2008-06-25 01:37:11 +00:00
agentItem . Flags = taskItem . Flags ;
2008-05-16 01:22:11 +00:00
2008-11-28 01:07:22 +00:00
if ( ( part . OwnerID ! = destAgent ) & & Permissions . PropagatePermissions ( ) )
2008-05-14 05:33:32 +00:00
{
2010-06-27 19:04:39 +00:00
agentItem . BasePermissions = taskItem . BasePermissions & ( taskItem . NextPermissions | ( uint ) PermissionMask . Move ) ;
2009-05-09 21:11:12 +00:00
if ( taskItem . InvType = = ( int ) InventoryType . Object )
2010-06-27 19:20:08 +00:00
agentItem . CurrentPermissions = agentItem . BasePermissions & ( ( ( taskItem . CurrentPermissions & 7 ) < < 13 ) | ( taskItem . CurrentPermissions & ( uint ) PermissionMask . Move ) ) ;
else
agentItem . CurrentPermissions = agentItem . BasePermissions & taskItem . CurrentPermissions ;
2010-05-21 01:31:14 +00:00
2011-01-12 21:39:13 +00:00
agentItem . Flags | = ( uint ) InventoryItemFlags . ObjectSlamPerm ;
2008-07-23 22:14:29 +00:00
agentItem . NextPermissions = taskItem . NextPermissions ;
2010-06-27 19:20:08 +00:00
agentItem . EveryOnePermissions = taskItem . EveryonePermissions & ( taskItem . NextPermissions | ( uint ) PermissionMask . Move ) ;
2008-11-14 18:54:38 +00:00
agentItem . GroupPermissions = taskItem . GroupPermissions & taskItem . NextPermissions ;
2008-04-26 20:31:01 +00:00
}
else
{
2008-07-23 22:14:29 +00:00
agentItem . BasePermissions = taskItem . BasePermissions ;
agentItem . CurrentPermissions = taskItem . CurrentPermissions ;
agentItem . NextPermissions = taskItem . NextPermissions ;
agentItem . EveryOnePermissions = taskItem . EveryonePermissions ;
2008-11-14 18:54:38 +00:00
agentItem . GroupPermissions = taskItem . GroupPermissions ;
2008-04-26 20:31:01 +00:00
}
2008-05-16 01:22:11 +00:00
2008-11-21 22:14:57 +00:00
if ( ! Permissions . BypassPermissions ( ) )
2008-05-16 01:22:11 +00:00
{
2008-07-23 22:14:29 +00:00
if ( ( taskItem . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
2012-01-06 17:43:35 +00:00
{
if ( taskItem . Type = = 10 )
{
part . RemoveScriptEvents ( itemId ) ;
EventManager . TriggerRemoveScript ( part . LocalId , itemId ) ;
}
2008-11-21 21:16:42 +00:00
part . Inventory . RemoveInventoryItem ( itemId ) ;
2012-01-06 17:43:35 +00:00
}
2008-05-16 01:22:11 +00:00
}
2008-06-26 02:46:29 +00:00
return agentItem ;
}
/// <summary>
/// Move the given item in the given prim to a folder in the client's inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="folderID"></param>
/// <param name="part"></param>
/// <param name="itemID"></param>
2008-12-14 22:27:40 +00:00
public InventoryItemBase MoveTaskInventoryItem ( IClientAPI remoteClient , UUID folderId , SceneObjectPart part , UUID itemId )
2008-06-26 02:46:29 +00:00
{
2010-08-23 21:24:23 +00:00
m_log . DebugFormat (
"[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}" ,
itemId , part . Name , folderId , remoteClient . Name ) ;
2008-06-26 02:46:29 +00:00
InventoryItemBase agentItem = CreateAgentInventoryItemFromTask ( remoteClient . AgentId , part , itemId ) ;
2008-10-08 02:45:23 +00:00
if ( agentItem = = null )
2008-12-14 22:27:40 +00:00
return null ;
2008-10-08 02:45:23 +00:00
2008-06-26 02:46:29 +00:00
agentItem . Folder = folderId ;
AddInventoryItem ( remoteClient , agentItem ) ;
2008-12-14 22:27:40 +00:00
return agentItem ;
2008-04-26 20:31:01 +00:00
}
2008-08-18 00:39:10 +00:00
2008-06-24 21:23:28 +00:00
/// <summary>
2008-06-24 23:55:33 +00:00
/// <see>ClientMoveTaskInventoryItem</see>
2008-06-24 21:23:28 +00:00
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="folderID"></param>
/// <param name="primLocalID"></param>
/// <param name="itemID"></param>
2008-09-06 07:52:41 +00:00
public void ClientMoveTaskInventoryItem ( IClientAPI remoteClient , UUID folderId , uint primLocalId , UUID itemId )
2008-06-25 14:30:28 +00:00
{
2008-06-24 21:23:28 +00:00
SceneObjectPart part = GetSceneObjectPart ( primLocalId ) ;
if ( null = = part )
{
m_log . WarnFormat (
"[PRIM INVENTORY]: " +
"Move of inventory item {0} from prim with local id {1} failed because the prim could not be found" ,
itemId , primLocalId ) ;
return ;
}
2008-06-24 23:55:33 +00:00
2008-11-21 21:16:42 +00:00
TaskInventoryItem taskItem = part . Inventory . GetInventoryItem ( itemId ) ;
2008-08-18 00:39:10 +00:00
2012-02-21 23:41:48 +00:00
if ( null = = taskItem )
{
m_log . WarnFormat ( "[PRIM INVENTORY]: Move of inventory item {0} from prim with local id {1} failed"
+ " because the inventory item could not be found" ,
itemId , primLocalId ) ;
return ;
}
2012-02-21 22:54:30 +00:00
if ( ( taskItem . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
2010-07-15 18:28:18 +00:00
{
// If the item to be moved is no copy, we need to be able to
// edit the prim.
2012-02-21 22:49:06 +00:00
if ( ! Permissions . CanEditObjectInventory ( part . UUID , remoteClient . AgentId ) )
2010-07-15 18:28:18 +00:00
return ;
}
else
{
// If the item is copiable, then we just need to have perms
// on it. The delete check is a pure rights check
2012-02-21 22:49:06 +00:00
if ( ! Permissions . CanDeleteObject ( part . UUID , remoteClient . AgentId ) )
2010-07-15 18:28:18 +00:00
return ;
}
2008-06-24 23:55:33 +00:00
2008-06-25 14:30:28 +00:00
MoveTaskInventoryItem ( remoteClient , folderId , part , itemId ) ;
}
2008-08-18 00:39:10 +00:00
2008-06-25 14:30:28 +00:00
/// <summary>
/// <see>MoveTaskInventoryItem</see>
/// </summary>
2008-06-24 21:23:28 +00:00
/// <param name="remoteClient"></param>
2010-08-23 22:21:44 +00:00
/// <param name="folderID">
/// The user inventory folder to move (or copy) the item to. If null, then the most
/// suitable system folder is used (e.g. the Objects folder for objects). If there is no suitable folder, then
/// the item is placed in the user's root inventory folder
/// </param>
2008-06-24 21:23:28 +00:00
/// <param name="part"></param>
/// <param name="itemID"></param>
2008-12-14 22:27:40 +00:00
public InventoryItemBase MoveTaskInventoryItem ( UUID avatarId , UUID folderId , SceneObjectPart part , UUID itemId )
2008-06-25 14:30:28 +00:00
{
ScenePresence avatar ;
2007-12-27 21:41:48 +00:00
2010-03-19 12:58:34 +00:00
if ( TryGetScenePresence ( avatarId , out avatar ) )
2008-06-24 21:23:28 +00:00
{
2008-12-14 22:27:40 +00:00
return MoveTaskInventoryItem ( avatar . ControllingClient , folderId , part , itemId ) ;
2008-06-24 21:23:28 +00:00
}
else
2009-09-30 16:00:09 +00:00
{
2008-06-26 02:46:29 +00:00
InventoryItemBase agentItem = CreateAgentInventoryItemFromTask ( avatarId , part , itemId ) ;
2008-10-08 02:45:23 +00:00
if ( agentItem = = null )
2008-12-14 22:27:40 +00:00
return null ;
2008-10-08 02:45:23 +00:00
2008-06-26 02:46:29 +00:00
agentItem . Folder = folderId ;
2010-09-03 23:09:53 +00:00
AddInventoryItem ( agentItem ) ;
2008-12-14 22:27:40 +00:00
return agentItem ;
2008-06-24 21:23:28 +00:00
}
2008-06-25 14:30:28 +00:00
}
2008-08-18 00:39:10 +00:00
2008-06-25 14:30:28 +00:00
/// <summary>
/// Copy a task (prim) inventory item to another task (prim)
/// </summary>
2012-03-22 22:33:37 +00:00
/// <param name="destId">ID of destination part</param>
/// <param name="part">Source part</param>
/// <param name="itemId">Source item id to transfer</param>
2008-09-06 07:52:41 +00:00
public void MoveTaskInventoryItem ( UUID destId , SceneObjectPart part , UUID itemId )
2008-06-25 14:30:28 +00:00
{
2008-11-21 21:16:42 +00:00
TaskInventoryItem srcTaskItem = part . Inventory . GetInventoryItem ( itemId ) ;
2008-06-25 14:30:28 +00:00
if ( srcTaskItem = = null )
{
2008-07-06 12:35:00 +00:00
m_log . ErrorFormat (
"[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for moving"
+ " but the item does not exist in this inventory" ,
itemId , part . Name , part . UUID ) ;
2008-06-25 14:30:28 +00:00
return ;
}
2008-08-18 00:39:10 +00:00
2008-06-25 14:30:28 +00:00
SceneObjectPart destPart = GetSceneObjectPart ( destId ) ;
if ( destPart = = null )
{
m_log . ErrorFormat (
"[PRIM INVENTORY]: " +
"Could not find prim for ID {0}" ,
destId ) ;
return ;
}
2008-08-18 00:39:10 +00:00
2012-03-22 22:40:38 +00:00
if ( part . OwnerID ! = destPart . OwnerID )
2008-06-26 20:52:05 +00:00
{
2012-03-22 22:40:38 +00:00
// Source must have transfer permissions
if ( ( srcTaskItem . CurrentPermissions & ( uint ) PermissionMask . Transfer ) = = 0 )
return ;
2008-06-26 20:52:05 +00:00
2012-03-22 22:40:38 +00:00
// Object cannot copy items to an object owned by a different owner
// unless llAllowInventoryDrop has been called on the destination
if ( ( destPart . GetEffectiveObjectFlags ( ) & ( uint ) PrimFlags . AllowInventoryDrop ) = = 0 )
return ;
2008-06-26 20:52:05 +00:00
}
// must have both move and modify permission to put an item in an object
2008-07-06 14:02:22 +00:00
if ( ( part . OwnerMask & ( ( uint ) PermissionMask . Move | ( uint ) PermissionMask . Modify ) ) = = 0 )
2008-06-26 20:52:05 +00:00
return ;
2008-06-25 14:30:28 +00:00
TaskInventoryItem destTaskItem = new TaskInventoryItem ( ) ;
2008-08-18 00:39:10 +00:00
2008-09-06 07:52:41 +00:00
destTaskItem . ItemID = UUID . Random ( ) ;
2008-06-25 14:30:28 +00:00
destTaskItem . CreatorID = srcTaskItem . CreatorID ;
2010-11-22 01:19:24 +00:00
destTaskItem . CreatorData = srcTaskItem . CreatorData ;
2008-06-25 14:30:28 +00:00
destTaskItem . AssetID = srcTaskItem . AssetID ;
2008-06-24 23:55:33 +00:00
destTaskItem . GroupID = destPart . GroupID ;
destTaskItem . OwnerID = destPart . OwnerID ;
destTaskItem . ParentID = destPart . UUID ;
destTaskItem . ParentPartID = destPart . UUID ;
2008-06-24 21:23:28 +00:00
2008-07-23 22:14:29 +00:00
destTaskItem . BasePermissions = srcTaskItem . BasePermissions ;
destTaskItem . EveryonePermissions = srcTaskItem . EveryonePermissions ;
destTaskItem . GroupPermissions = srcTaskItem . GroupPermissions ;
destTaskItem . CurrentPermissions = srcTaskItem . CurrentPermissions ;
destTaskItem . NextPermissions = srcTaskItem . NextPermissions ;
2008-06-25 14:30:28 +00:00
destTaskItem . Flags = srcTaskItem . Flags ;
2008-08-18 00:39:10 +00:00
2008-06-25 14:30:28 +00:00
if ( destPart . OwnerID ! = part . OwnerID )
2008-06-24 23:55:33 +00:00
{
2008-11-21 22:14:57 +00:00
if ( Permissions . PropagatePermissions ( ) )
2008-06-24 23:55:33 +00:00
{
2008-07-23 22:14:29 +00:00
destTaskItem . CurrentPermissions = srcTaskItem . CurrentPermissions &
2010-06-27 19:20:08 +00:00
( srcTaskItem . NextPermissions | ( uint ) PermissionMask . Move ) ;
2008-07-23 22:14:29 +00:00
destTaskItem . GroupPermissions = srcTaskItem . GroupPermissions &
2010-06-27 19:20:08 +00:00
( srcTaskItem . NextPermissions | ( uint ) PermissionMask . Move ) ;
2008-07-23 22:14:29 +00:00
destTaskItem . EveryonePermissions = srcTaskItem . EveryonePermissions &
2010-06-27 19:20:08 +00:00
( srcTaskItem . NextPermissions | ( uint ) PermissionMask . Move ) ;
2008-07-23 22:14:29 +00:00
destTaskItem . BasePermissions = srcTaskItem . BasePermissions &
2010-06-27 19:04:39 +00:00
( srcTaskItem . NextPermissions | ( uint ) PermissionMask . Move ) ;
2011-01-12 21:39:13 +00:00
destTaskItem . Flags | = ( uint ) InventoryItemFlags . ObjectSlamPerm ;
2008-06-24 23:55:33 +00:00
}
}
2008-06-25 14:30:28 +00:00
destTaskItem . Description = srcTaskItem . Description ;
destTaskItem . Name = srcTaskItem . Name ;
destTaskItem . InvType = srcTaskItem . InvType ;
destTaskItem . Type = srcTaskItem . Type ;
2008-08-18 00:39:10 +00:00
2008-11-21 21:16:42 +00:00
destPart . Inventory . AddInventoryItem ( destTaskItem , part . OwnerID ! = destPart . OwnerID ) ;
2008-06-24 23:55:33 +00:00
2008-07-23 22:14:29 +00:00
if ( ( srcTaskItem . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
2008-11-21 21:16:42 +00:00
part . Inventory . RemoveInventoryItem ( itemId ) ;
2008-06-26 20:52:05 +00:00
ScenePresence avatar ;
2008-08-18 00:39:10 +00:00
2010-03-19 12:58:34 +00:00
if ( TryGetScenePresence ( srcTaskItem . OwnerID , out avatar ) )
2008-06-26 20:52:05 +00:00
{
2011-09-15 17:58:58 +00:00
destPart . SendPropertiesToClient ( avatar . ControllingClient ) ;
2008-06-26 20:52:05 +00:00
}
2008-06-25 14:30:28 +00:00
}
2008-08-18 00:39:10 +00:00
2008-12-14 22:27:40 +00:00
public UUID MoveTaskInventoryItems ( UUID destID , string category , SceneObjectPart host , List < UUID > items )
2008-06-26 02:46:29 +00:00
{
2009-08-13 03:39:48 +00:00
InventoryFolderBase rootFolder = InventoryService . GetRootFolder ( destID ) ;
2008-06-26 02:46:29 +00:00
2008-09-06 07:52:41 +00:00
UUID newFolderID = UUID . Random ( ) ;
2008-08-18 00:39:10 +00:00
2009-09-13 17:24:00 +00:00
InventoryFolderBase newFolder = new InventoryFolderBase ( newFolderID , category , destID , - 1 , rootFolder . ID , rootFolder . Version ) ;
2009-08-13 03:39:48 +00:00
InventoryService . AddFolder ( newFolder ) ;
2008-06-26 02:46:29 +00:00
2008-09-06 07:52:41 +00:00
foreach ( UUID itemID in items )
2008-06-26 02:46:29 +00:00
{
InventoryItemBase agentItem = CreateAgentInventoryItemFromTask ( destID , host , itemID ) ;
2008-10-08 02:45:23 +00:00
if ( agentItem ! = null )
{
agentItem . Folder = newFolderID ;
2010-09-03 23:09:53 +00:00
AddInventoryItem ( agentItem ) ;
2008-10-08 02:45:23 +00:00
}
2008-06-26 02:46:29 +00:00
}
2009-08-13 03:39:48 +00:00
ScenePresence avatar = null ;
2010-03-19 12:58:34 +00:00
if ( TryGetScenePresence ( destID , out avatar ) )
2008-06-26 02:46:29 +00:00
{
2009-08-13 03:39:48 +00:00
//profile.SendInventoryDecendents(avatar.ControllingClient,
// profile.RootFolder.ID, true, false);
//profile.SendInventoryDecendents(avatar.ControllingClient,
// newFolderID, false, true);
SendInventoryUpdate ( avatar . ControllingClient , rootFolder , true , false ) ;
SendInventoryUpdate ( avatar . ControllingClient , newFolder , false , true ) ;
2008-06-26 02:46:29 +00:00
}
2008-12-14 22:27:40 +00:00
return newFolderID ;
2008-06-26 02:46:29 +00:00
}
2012-10-06 01:34:49 +00:00
public void SendInventoryUpdate ( IClientAPI client , InventoryFolderBase folder , bool fetchFolders , bool fetchItems )
2009-08-13 03:39:48 +00:00
{
2010-01-07 23:53:55 +00:00
if ( folder = = null )
return ;
2010-05-06 04:12:13 +00:00
// TODO: This code for looking in the folder for the library should be folded somewhere else
// so that this class doesn't have to know the details (and so that multiple libraries, etc.
// can be handled transparently).
InventoryFolderImpl fold = null ;
if ( LibraryService ! = null & & LibraryService . LibraryRootFolder ! = null )
{
if ( ( fold = LibraryService . LibraryRootFolder . FindFolder ( folder . ID ) ) ! = null )
{
client . SendInventoryFolderDetails (
fold . Owner , folder . ID , fold . RequestListOfItems ( ) ,
fold . RequestListOfFolders ( ) , fold . Version , fetchFolders , fetchItems ) ;
return ;
}
}
2010-03-10 22:05:49 +00:00
// Fetch the folder contents
2009-08-13 03:39:48 +00:00
InventoryCollection contents = InventoryService . GetFolderContent ( client . AgentId , folder . ID ) ;
2010-03-10 22:05:49 +00:00
// Fetch the folder itself to get its current version
InventoryFolderBase containingFolder = new InventoryFolderBase ( folder . ID , client . AgentId ) ;
2009-11-04 01:56:19 +00:00
containingFolder = InventoryService . GetFolder ( containingFolder ) ;
2011-05-13 02:24:19 +00:00
// m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
// contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
2010-03-10 22:05:49 +00:00
2011-06-28 23:56:35 +00:00
if ( containingFolder ! = null )
2011-05-13 02:24:19 +00:00
{
// If the folder requested contains links, then we need to send those folders first, otherwise the links
// will be broken in the viewer.
HashSet < UUID > linkedItemFolderIdsToSend = new HashSet < UUID > ( ) ;
foreach ( InventoryItemBase item in contents . Items )
{
if ( item . AssetType = = ( int ) AssetType . Link )
{
InventoryItemBase linkedItem = InventoryService . GetItem ( new InventoryItemBase ( item . AssetID ) ) ;
2011-05-17 01:25:05 +00:00
// Take care of genuinely broken links where the target doesn't exist
2011-06-29 00:33:41 +00:00
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
// rather than having to keep track of every folder requested in the recursion.
if ( linkedItem ! = null & & linkedItem . AssetType ! = ( int ) AssetType . Link )
2011-06-28 23:54:31 +00:00
{
// We don't need to send the folder if source and destination of the link are in the same
// folder.
if ( linkedItem . Folder ! = containingFolder . ID )
linkedItemFolderIdsToSend . Add ( linkedItem . Folder ) ;
}
2011-05-13 02:24:19 +00:00
}
}
foreach ( UUID linkedItemFolderId in linkedItemFolderIdsToSend )
SendInventoryUpdate ( client , new InventoryFolderBase ( linkedItemFolderId ) , false , true ) ;
2011-06-28 23:56:35 +00:00
client . SendInventoryFolderDetails (
client . AgentId , folder . ID , contents . Items , contents . Folders ,
containingFolder . Version , fetchFolders , fetchItems ) ;
2011-05-13 02:24:19 +00:00
}
2009-08-13 03:39:48 +00:00
}
2007-12-22 02:52:35 +00:00
/// <summary>
2008-05-16 01:22:11 +00:00
/// Update an item in a prim (task) inventory.
2008-09-06 07:52:41 +00:00
/// This method does not handle scripts, <see>RezScript(IClientAPI, UUID, unit)</see>
2007-12-22 02:52:35 +00:00
/// </summary>
/// <param name="remoteClient"></param>
2008-05-23 02:45:52 +00:00
/// <param name="transactionID"></param>
/// <param name="itemInfo"></param>
2007-12-22 02:52:35 +00:00
/// <param name="primLocalID"></param>
2008-09-06 07:52:41 +00:00
public void UpdateTaskInventory ( IClientAPI remoteClient , UUID transactionID , TaskInventoryItem itemInfo ,
2007-12-22 02:52:35 +00:00
uint primLocalID )
{
2008-09-06 07:52:41 +00:00
UUID itemID = itemInfo . ItemID ;
2008-05-23 02:45:52 +00:00
// Find the prim we're dealing with
2008-05-15 19:28:10 +00:00
SceneObjectPart part = GetSceneObjectPart ( primLocalID ) ;
2008-03-03 16:52:25 +00:00
2008-05-15 19:28:10 +00:00
if ( part ! = null )
2007-12-22 02:52:35 +00:00
{
2008-11-21 21:16:42 +00:00
TaskInventoryItem currentItem = part . Inventory . GetInventoryItem ( itemID ) ;
2008-11-14 17:24:56 +00:00
bool allowInventoryDrop = ( part . GetEffectiveObjectFlags ( )
2008-11-15 02:21:52 +00:00
& ( uint ) PrimFlags . AllowInventoryDrop ) ! = 0 ;
2008-11-14 17:24:56 +00:00
// Explicity allow anyone to add to the inventory if the
// AllowInventoryDrop flag has been set. Don't however let
// them update an item unless they pass the external checks
/ /
2008-11-21 22:14:57 +00:00
if ( ! Permissions . CanEditObjectInventory ( part . UUID , remoteClient . AgentId )
2008-11-15 02:21:52 +00:00
& & ( currentItem ! = null | | ! allowInventoryDrop ) )
2008-11-14 17:24:56 +00:00
return ;
2008-11-14 13:03:18 +00:00
2008-05-28 03:44:49 +00:00
if ( currentItem = = null )
2008-03-03 16:52:25 +00:00
{
2008-09-06 07:52:41 +00:00
UUID copyID = UUID . Random ( ) ;
if ( itemID ! = UUID . Zero )
2008-03-03 16:52:25 +00:00
{
2009-08-19 05:17:47 +00:00
InventoryItemBase item = new InventoryItemBase ( itemID , remoteClient . AgentId ) ;
item = InventoryService . GetItem ( item ) ;
2008-03-03 16:52:25 +00:00
2009-08-13 18:30:29 +00:00
// Try library
2010-01-02 05:12:46 +00:00
if ( null = = item & & LibraryService ! = null & & LibraryService . LibraryRootFolder ! = null )
2008-03-03 16:52:25 +00:00
{
2010-01-02 05:12:46 +00:00
item = LibraryService . LibraryRootFolder . FindItem ( itemID ) ;
2009-08-13 18:30:29 +00:00
}
2008-05-23 02:45:52 +00:00
2010-04-05 18:37:02 +00:00
// If we've found the item in the user's inventory or in the library
2009-08-13 18:30:29 +00:00
if ( item ! = null )
{
2012-01-26 00:10:37 +00:00
part . ParentGroup . AddInventoryItem ( remoteClient . AgentId , primLocalID , item , copyID ) ;
2009-08-13 18:30:29 +00:00
m_log . InfoFormat (
"[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}" ,
item . Name , primLocalID , remoteClient . Name ) ;
2011-09-15 17:58:58 +00:00
part . SendPropertiesToClient ( remoteClient ) ;
2009-08-13 18:30:29 +00:00
if ( ! Permissions . BypassPermissions ( ) )
2008-05-23 02:45:52 +00:00
{
2009-08-13 18:30:29 +00:00
if ( ( item . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
2009-08-19 07:13:51 +00:00
{
List < UUID > uuids = new List < UUID > ( ) ;
uuids . Add ( itemID ) ;
RemoveInventoryItem ( remoteClient , uuids ) ;
}
2008-05-16 01:22:11 +00:00
}
2008-03-03 16:52:25 +00:00
}
2009-08-13 18:30:29 +00:00
else
{
m_log . ErrorFormat (
"[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!" ,
itemID , remoteClient . Name ) ;
}
2008-03-03 16:52:25 +00:00
}
}
2008-05-23 02:45:52 +00:00
else // Updating existing item with new perms etc
2009-02-04 00:01:36 +00:00
{
2011-04-28 21:59:12 +00:00
// m_log.DebugFormat(
// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
// currentItem.Name, part.Name);
2010-07-15 18:03:08 +00:00
2012-02-04 00:20:27 +00:00
// Only look for an uploaded updated asset if we are passed a transaction ID. This is only the
// case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update)
// will not pass in a transaction ID in the update message.
2012-06-07 22:51:04 +00:00
if ( transactionID ! = UUID . Zero & & AgentTransactionsModule ! = null )
2012-02-04 00:20:27 +00:00
{
2012-06-07 22:51:04 +00:00
AgentTransactionsModule . HandleTaskItemUpdateFromTransaction (
remoteClient , part , transactionID , currentItem ) ;
if ( ( InventoryType ) itemInfo . InvType = = InventoryType . Notecard )
2013-06-18 20:21:59 +00:00
remoteClient . SendAlertMessage ( "Notecard saved" ) ;
2012-06-07 22:51:04 +00:00
else if ( ( InventoryType ) itemInfo . InvType = = InventoryType . LSL )
2013-06-18 20:21:59 +00:00
remoteClient . SendAlertMessage ( "Script saved" ) ;
2012-06-07 22:51:04 +00:00
else
2013-06-18 20:21:59 +00:00
remoteClient . SendAlertMessage ( "Item saved" ) ;
2012-02-04 00:20:27 +00:00
}
2010-07-14 18:02:41 +00:00
2010-07-20 12:45:46 +00:00
// Base ALWAYS has move
currentItem . BasePermissions | = ( uint ) PermissionMask . Move ;
2011-01-12 21:39:13 +00:00
itemInfo . Flags = currentItem . Flags ;
2010-07-15 18:03:08 +00:00
// Check if we're allowed to mess with permissions
if ( ! Permissions . IsGod ( remoteClient . AgentId ) ) // Not a god
{
if ( remoteClient . AgentId ! = part . OwnerID ) // Not owner
{
// Friends and group members can't change any perms
itemInfo . BasePermissions = currentItem . BasePermissions ;
itemInfo . EveryonePermissions = currentItem . EveryonePermissions ;
itemInfo . GroupPermissions = currentItem . GroupPermissions ;
itemInfo . NextPermissions = currentItem . NextPermissions ;
itemInfo . CurrentPermissions = currentItem . CurrentPermissions ;
}
else
{
// Owner can't change base, and can change other
// only up to base
itemInfo . BasePermissions = currentItem . BasePermissions ;
2011-01-12 21:39:13 +00:00
if ( itemInfo . EveryonePermissions ! = currentItem . EveryonePermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteEveryone ;
if ( itemInfo . GroupPermissions ! = currentItem . GroupPermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteGroup ;
if ( itemInfo . CurrentPermissions ! = currentItem . CurrentPermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteOwner ;
if ( itemInfo . NextPermissions ! = currentItem . NextPermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteNextOwner ;
2010-07-15 18:03:08 +00:00
itemInfo . EveryonePermissions & = currentItem . BasePermissions ;
itemInfo . GroupPermissions & = currentItem . BasePermissions ;
itemInfo . CurrentPermissions & = currentItem . BasePermissions ;
itemInfo . NextPermissions & = currentItem . BasePermissions ;
}
}
2011-01-12 21:39:13 +00:00
else
{
if ( itemInfo . BasePermissions ! = currentItem . BasePermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteBase ;
if ( itemInfo . EveryonePermissions ! = currentItem . EveryonePermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteEveryone ;
if ( itemInfo . GroupPermissions ! = currentItem . GroupPermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteGroup ;
if ( itemInfo . CurrentPermissions ! = currentItem . CurrentPermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteOwner ;
if ( itemInfo . NextPermissions ! = currentItem . NextPermissions )
itemInfo . Flags | = ( uint ) InventoryItemFlags . ObjectOverwriteNextOwner ;
}
2010-07-20 12:45:46 +00:00
// Next ALWAYS has move
itemInfo . NextPermissions | = ( uint ) PermissionMask . Move ;
2010-07-15 18:03:08 +00:00
if ( part . Inventory . UpdateInventoryItem ( itemInfo ) )
{
2011-09-15 17:58:58 +00:00
part . SendPropertiesToClient ( remoteClient ) ;
2010-04-19 20:25:59 +00:00
}
2008-05-23 02:45:52 +00:00
}
2007-12-27 21:41:48 +00:00
}
2007-12-22 02:52:35 +00:00
else
{
2008-02-10 01:57:59 +00:00
m_log . WarnFormat (
2008-02-20 23:21:51 +00:00
"[PRIM INVENTORY]: " +
2008-02-10 01:57:59 +00:00
"Update with item {0} requested of prim {1} for {2} but this prim does not exist" ,
itemID , primLocalID , remoteClient . Name ) ;
2007-12-27 21:41:48 +00:00
}
2007-10-19 20:28:18 +00:00
}
2007-12-22 14:34:05 +00:00
/// <summary>
2008-11-13 18:52:16 +00:00
/// Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory
2007-12-22 14:34:05 +00:00
/// </summary>
/// <param name="remoteClient"></param>
2012-01-25 23:22:07 +00:00
/// <param name="itemBase"> </param>
/// <param name="transactionID"></param>
2007-12-22 14:34:05 +00:00
/// <param name="localID"></param>
2008-09-06 07:52:41 +00:00
public void RezScript ( IClientAPI remoteClient , InventoryItemBase itemBase , UUID transactionID , uint localID )
2007-10-19 20:28:18 +00:00
{
2012-01-26 00:10:37 +00:00
SceneObjectPart partWhereRezzed ;
2012-01-25 23:22:07 +00:00
if ( itemBase . ID ! = UUID . Zero )
2012-01-26 00:10:37 +00:00
partWhereRezzed = RezScriptFromAgentInventory ( remoteClient . AgentId , itemBase . ID , localID ) ;
2012-01-25 23:22:07 +00:00
else
2012-01-26 00:10:37 +00:00
partWhereRezzed = RezNewScript ( remoteClient . AgentId , itemBase ) ;
if ( partWhereRezzed ! = null )
partWhereRezzed . SendPropertiesToClient ( remoteClient ) ;
2012-01-25 23:22:07 +00:00
}
/// <summary>
/// Rez a script into a prim from an agent inventory.
/// </summary>
2012-01-26 00:10:37 +00:00
/// <param name="agentID"></param>
2012-01-25 23:22:07 +00:00
/// <param name="fromItemID"></param>
/// <param name="localID"></param>
2012-01-26 00:10:37 +00:00
/// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
public SceneObjectPart RezScriptFromAgentInventory ( UUID agentID , UUID fromItemID , uint localID )
2012-01-25 23:22:07 +00:00
{
2008-09-06 07:52:41 +00:00
UUID copyID = UUID . Random ( ) ;
2012-01-26 00:10:37 +00:00
InventoryItemBase item = new InventoryItemBase ( fromItemID , agentID ) ;
2012-01-25 23:22:07 +00:00
item = InventoryService . GetItem ( item ) ;
2008-05-16 01:22:11 +00:00
2012-01-25 23:22:07 +00:00
// Try library
// XXX clumsy, possibly should be one call
if ( null = = item & & LibraryService ! = null & & LibraryService . LibraryRootFolder ! = null )
2007-10-19 20:28:18 +00:00
{
2012-01-25 23:22:07 +00:00
item = LibraryService . LibraryRootFolder . FindItem ( fromItemID ) ;
}
2008-05-16 01:22:11 +00:00
2012-01-25 23:22:07 +00:00
if ( item ! = null )
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part ! = null )
2009-08-13 18:30:29 +00:00
{
2012-01-26 00:10:37 +00:00
if ( ! Permissions . CanEditObjectInventory ( part . UUID , agentID ) )
return null ;
2012-01-25 23:22:07 +00:00
2012-01-26 00:10:37 +00:00
part . ParentGroup . AddInventoryItem ( agentID , localID , item , copyID ) ;
2012-01-25 23:22:07 +00:00
// TODO: switch to posting on_rez here when scripts
// have state in inventory
part . Inventory . CreateScriptInstance ( copyID , 0 , false , DefaultScriptEngine , 0 ) ;
2012-02-17 17:12:41 +00:00
// tell anyone watching that there is a new script in town
EventManager . TriggerNewScript ( agentID , part , copyID ) ;
2012-01-25 23:22:07 +00:00
// m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name);
2012-02-17 17:12:41 +00:00
2012-01-25 23:22:07 +00:00
part . ParentGroup . ResumeScripts ( ) ;
2012-01-26 00:10:37 +00:00
return part ;
2007-10-19 20:28:18 +00:00
}
2009-08-13 18:30:29 +00:00
else
{
m_log . ErrorFormat (
2012-01-25 23:22:07 +00:00
"[PRIM INVENTORY]: " +
"Could not rez script {0} into prim local ID {1} for user {2}"
+ " because the prim could not be found in the region!" ,
2012-01-26 00:10:37 +00:00
item . Name , localID , agentID ) ;
2009-08-13 18:30:29 +00:00
}
2007-10-19 20:28:18 +00:00
}
2012-01-25 23:22:07 +00:00
else
2009-02-04 00:01:36 +00:00
{
2012-01-25 23:22:07 +00:00
m_log . ErrorFormat (
"[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!" ,
2012-01-26 00:10:37 +00:00
fromItemID , agentID ) ;
2012-01-25 23:22:07 +00:00
}
2012-01-26 00:10:37 +00:00
return null ;
2012-01-25 23:22:07 +00:00
}
2008-05-16 23:11:00 +00:00
2012-01-25 23:22:07 +00:00
/// <summary>
/// Rez a new script from nothing.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemBase"></param>
2012-01-26 00:10:37 +00:00
/// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
public SceneObjectPart RezNewScript ( UUID agentID , InventoryItemBase itemBase )
2013-01-16 02:07:43 +00:00
{
return RezNewScript (
agentID ,
itemBase ,
"default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}" ) ;
}
/// <summary>
/// Rez a new script from nothing with given script text.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemBase">Template item.</param>
/// <param name="scriptText"></param>
/// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
public SceneObjectPart RezNewScript ( UUID agentID , InventoryItemBase itemBase , string scriptText )
2012-01-25 23:22:07 +00:00
{
2012-01-26 00:10:37 +00:00
// The part ID is the folder ID!
2012-01-25 23:22:07 +00:00
SceneObjectPart part = GetSceneObjectPart ( itemBase . Folder ) ;
if ( part = = null )
2012-01-26 01:16:03 +00:00
{
// m_log.DebugFormat(
// "[SCENE INVENTORY]: Could not find part with id {0} for {1} to rez new script",
// itemBase.Folder, agentID);
2012-01-26 00:10:37 +00:00
return null ;
2012-01-26 01:16:03 +00:00
}
2008-07-09 19:53:22 +00:00
2012-01-26 00:10:37 +00:00
if ( ! Permissions . CanCreateObjectInventory ( itemBase . InvType , part . UUID , agentID ) )
2012-01-26 01:16:03 +00:00
{
// m_log.DebugFormat(
// "[SCENE INVENTORY]: No permission to create new script in {0} for {1}", part.Name, agentID);
2012-01-26 00:10:37 +00:00
return null ;
2012-01-26 01:16:03 +00:00
}
2008-08-18 00:39:10 +00:00
2013-01-16 02:07:43 +00:00
AssetBase asset
= CreateAsset (
itemBase . Name ,
itemBase . Description ,
( sbyte ) itemBase . AssetType ,
Encoding . ASCII . GetBytes ( scriptText ) ,
agentID ) ;
2012-01-25 23:22:07 +00:00
AssetService . Store ( asset ) ;
TaskInventoryItem taskItem = new TaskInventoryItem ( ) ;
taskItem . ResetIDs ( itemBase . Folder ) ;
taskItem . ParentID = itemBase . Folder ;
taskItem . CreationDate = ( uint ) itemBase . CreationDate ;
taskItem . Name = itemBase . Name ;
taskItem . Description = itemBase . Description ;
taskItem . Type = itemBase . AssetType ;
taskItem . InvType = itemBase . InvType ;
taskItem . OwnerID = itemBase . Owner ;
taskItem . CreatorID = itemBase . CreatorIdAsUuid ;
taskItem . BasePermissions = itemBase . BasePermissions ;
taskItem . CurrentPermissions = itemBase . CurrentPermissions ;
taskItem . EveryonePermissions = itemBase . EveryOnePermissions ;
taskItem . GroupPermissions = itemBase . GroupPermissions ;
taskItem . NextPermissions = itemBase . NextPermissions ;
taskItem . GroupID = itemBase . GroupID ;
taskItem . GroupPermissions = 0 ;
taskItem . Flags = itemBase . Flags ;
taskItem . PermsGranter = UUID . Zero ;
taskItem . PermsMask = 0 ;
taskItem . AssetID = asset . FullID ;
part . Inventory . AddInventoryItem ( taskItem , false ) ;
part . Inventory . CreateScriptInstance ( taskItem , 0 , false , DefaultScriptEngine , 0 ) ;
2012-02-17 17:12:41 +00:00
// tell anyone managing scripts that a new script exists
EventManager . TriggerNewScript ( agentID , part , taskItem . ItemID ) ;
2012-01-25 23:22:07 +00:00
part . ParentGroup . ResumeScripts ( ) ;
2012-01-26 00:10:37 +00:00
return part ;
2007-10-19 20:28:18 +00:00
}
2008-06-27 02:22:33 +00:00
/// <summary>
/// Rez a script into a prim's inventory from another prim
/// </summary>
/// <param name="remoteClient"></param>
2014-11-11 17:27:30 +00:00
/// <param name="srcPart"> </param>
/// <param name="destId"> </param>
/// <param name="pin"></param>
/// <param name="running"></param>
/// <param name="start_param"></param>
2012-01-25 23:22:07 +00:00
public void RezScriptFromPrim ( UUID srcId , SceneObjectPart srcPart , UUID destId , int pin , int running , int start_param )
2008-07-06 14:02:22 +00:00
{
2008-11-21 21:16:42 +00:00
TaskInventoryItem srcTaskItem = srcPart . Inventory . GetInventoryItem ( srcId ) ;
2008-06-27 02:22:33 +00:00
if ( srcTaskItem = = null )
{
2008-07-06 12:35:00 +00:00
m_log . ErrorFormat (
"[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for rezzing a script but the "
+ " item does not exist in this inventory" ,
srcId , srcPart . Name , srcPart . UUID ) ;
2008-06-27 02:22:33 +00:00
return ;
}
2008-08-18 00:39:10 +00:00
2008-06-27 02:22:33 +00:00
SceneObjectPart destPart = GetSceneObjectPart ( destId ) ;
if ( destPart = = null )
{
m_log . ErrorFormat (
2014-11-11 17:27:30 +00:00
"[PRIM INVENTORY]: Could not find part {0} to insert script item {1} from {2} {3} in {4}" ,
destId , srcId , srcPart . Name , srcPart . UUID , Name ) ;
2008-06-27 02:22:33 +00:00
return ;
}
2014-11-11 17:27:30 +00:00
2008-06-28 16:08:12 +00:00
// Must own the object, and have modify rights
2008-07-06 14:02:22 +00:00
if ( srcPart . OwnerID ! = destPart . OwnerID )
2009-06-09 18:07:35 +00:00
{
// Group permissions
if ( ( destPart . GroupID = = UUID . Zero ) | | ( destPart . GroupID ! = srcPart . GroupID ) | |
( ( destPart . GroupMask & ( uint ) PermissionMask . Modify ) = = 0 ) )
return ;
2014-11-11 17:27:30 +00:00
}
else
{
2009-06-09 18:07:35 +00:00
if ( ( destPart . OwnerMask & ( uint ) PermissionMask . Modify ) = = 0 )
return ;
}
2008-06-28 16:08:12 +00:00
2014-11-11 17:27:30 +00:00
if ( destPart . ScriptAccessPin = = 0 | | destPart . ScriptAccessPin ! = pin )
2008-07-06 14:02:22 +00:00
{
m_log . WarnFormat (
"[PRIM INVENTORY]: " +
"Script in object {0} : {1}, attempted to load script {2} : {3} into object {4} : {5} with invalid pin {6}" ,
srcPart . Name , srcId , srcTaskItem . Name , srcTaskItem . ItemID , destPart . Name , destId , pin ) ;
2008-08-18 00:39:10 +00:00
// the LSL Wiki says we are supposed to shout on the DEBUG_CHANNEL -
2008-07-06 14:02:22 +00:00
// "Object: Task Object trying to illegally load script onto task Other_Object!"
// How do we shout from in here?
return ;
}
2008-08-18 00:39:10 +00:00
2008-07-06 14:02:22 +00:00
TaskInventoryItem destTaskItem = new TaskInventoryItem ( ) ;
2008-08-18 00:39:10 +00:00
2008-09-06 07:52:41 +00:00
destTaskItem . ItemID = UUID . Random ( ) ;
2008-06-27 02:22:33 +00:00
destTaskItem . CreatorID = srcTaskItem . CreatorID ;
2010-11-22 01:19:24 +00:00
destTaskItem . CreatorData = srcTaskItem . CreatorData ;
2008-06-27 02:22:33 +00:00
destTaskItem . AssetID = srcTaskItem . AssetID ;
destTaskItem . GroupID = destPart . GroupID ;
destTaskItem . OwnerID = destPart . OwnerID ;
destTaskItem . ParentID = destPart . UUID ;
destTaskItem . ParentPartID = destPart . UUID ;
2008-07-23 22:14:29 +00:00
destTaskItem . BasePermissions = srcTaskItem . BasePermissions ;
destTaskItem . EveryonePermissions = srcTaskItem . EveryonePermissions ;
destTaskItem . GroupPermissions = srcTaskItem . GroupPermissions ;
destTaskItem . CurrentPermissions = srcTaskItem . CurrentPermissions ;
destTaskItem . NextPermissions = srcTaskItem . NextPermissions ;
2008-06-27 02:22:33 +00:00
destTaskItem . Flags = srcTaskItem . Flags ;
2008-08-18 00:39:10 +00:00
2008-06-27 02:22:33 +00:00
if ( destPart . OwnerID ! = srcPart . OwnerID )
{
2008-11-21 22:14:57 +00:00
if ( Permissions . PropagatePermissions ( ) )
2008-06-27 02:22:33 +00:00
{
2008-07-23 22:14:29 +00:00
destTaskItem . CurrentPermissions = srcTaskItem . CurrentPermissions &
srcTaskItem . NextPermissions ;
destTaskItem . GroupPermissions = srcTaskItem . GroupPermissions &
srcTaskItem . NextPermissions ;
destTaskItem . EveryonePermissions = srcTaskItem . EveryonePermissions &
srcTaskItem . NextPermissions ;
destTaskItem . BasePermissions = srcTaskItem . BasePermissions &
srcTaskItem . NextPermissions ;
2011-01-12 21:39:13 +00:00
destTaskItem . Flags | = ( uint ) InventoryItemFlags . ObjectSlamPerm ;
2008-06-27 02:22:33 +00:00
}
}
2008-05-25 23:27:38 +00:00
2008-06-27 02:22:33 +00:00
destTaskItem . Description = srcTaskItem . Description ;
destTaskItem . Name = srcTaskItem . Name ;
destTaskItem . InvType = srcTaskItem . InvType ;
destTaskItem . Type = srcTaskItem . Type ;
2008-08-18 00:39:10 +00:00
2008-11-21 21:16:42 +00:00
destPart . Inventory . AddInventoryItemExclusive ( destTaskItem , false ) ;
2008-06-27 02:22:33 +00:00
2008-07-06 14:02:22 +00:00
if ( running > 0 )
{
2009-03-25 11:05:01 +00:00
destPart . Inventory . CreateScriptInstance ( destTaskItem , start_param , false , DefaultScriptEngine , 0 ) ;
2008-07-06 14:02:22 +00:00
}
2008-08-18 00:39:10 +00:00
2010-04-19 09:43:25 +00:00
destPart . ParentGroup . ResumeScripts ( ) ;
2008-07-06 14:02:22 +00:00
ScenePresence avatar ;
2008-08-18 00:39:10 +00:00
2010-03-19 12:58:34 +00:00
if ( TryGetScenePresence ( srcTaskItem . OwnerID , out avatar ) )
2008-06-27 02:22:33 +00:00
{
2011-09-15 17:58:58 +00:00
destPart . SendPropertiesToClient ( avatar . ControllingClient ) ;
2008-06-27 02:22:33 +00:00
}
2008-07-06 14:02:22 +00:00
}
2008-08-18 00:39:10 +00:00
2012-11-10 05:43:57 +00:00
/// <summary>
/// Derez one or more objects from the scene.
/// </summary>
/// <remarks>
/// Won't actually remove the scene object in the case where the object is being copied to a user inventory.
/// </remarks>
/// <param name='remoteClient'>Client requesting derez</param>
/// <param name='localIDs'>Local ids of root parts of objects to delete.</param>
/// <param name='groupID'>Not currently used. Here because the client passes this to us.</param>
/// <param name='action'>DeRezAction</param>
/// <param name='destinationID'>User folder ID to place derezzed object</param>
public virtual void DeRezObjects (
IClientAPI remoteClient , List < uint > localIDs , UUID groupID , DeRezAction action , UUID destinationID )
2010-06-01 00:27:30 +00:00
{
// First, see of we can perform the requested action and
// build a list of eligible objects
List < uint > deleteIDs = new List < uint > ( ) ;
List < SceneObjectGroup > deleteGroups = new List < SceneObjectGroup > ( ) ;
2007-10-19 20:28:18 +00:00
2010-06-01 00:27:30 +00:00
// Start with true for both, then remove the flags if objects
// that we can't derez are part of the selection
bool permissionToTake = true ;
bool permissionToTakeCopy = true ;
bool permissionToDelete = true ;
foreach ( uint localID in localIDs )
{
// Invalid id
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part = = null )
continue ;
2008-05-16 01:22:11 +00:00
2010-06-01 00:27:30 +00:00
// Already deleted by someone else
2011-09-01 00:22:28 +00:00
if ( part . ParentGroup . IsDeleted )
2010-06-01 00:27:30 +00:00
continue ;
2007-12-17 16:41:28 +00:00
2010-06-01 00:27:30 +00:00
// Can't delete child prims
if ( part ! = part . ParentGroup . RootPart )
continue ;
2009-02-04 16:00:39 +00:00
2010-06-01 00:27:30 +00:00
SceneObjectGroup grp = part . ParentGroup ;
2007-12-17 16:41:28 +00:00
2010-06-01 00:27:30 +00:00
deleteIDs . Add ( localID ) ;
deleteGroups . Add ( grp ) ;
2012-08-23 23:15:30 +00:00
// If child prims have invalid perms, fix them
grp . AdjustChildPrimPermissions ( ) ;
2010-06-29 19:36:17 +00:00
if ( remoteClient = = null )
{
// Autoreturn has a null client. Nothing else does. So
// allow only returns
if ( action ! = DeRezAction . Return )
2010-11-22 22:51:26 +00:00
{
m_log . WarnFormat (
"[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client" ,
action , grp . Name , grp . UUID ) ;
2010-06-29 19:36:17 +00:00
return ;
2010-11-22 22:51:26 +00:00
}
2010-06-29 19:36:17 +00:00
2010-06-01 00:27:30 +00:00
permissionToTakeCopy = false ;
2010-06-29 19:36:17 +00:00
}
else
{
if ( ! Permissions . CanTakeCopyObject ( grp . UUID , remoteClient . AgentId ) )
permissionToTakeCopy = false ;
2010-11-22 22:51:26 +00:00
2010-06-29 19:36:17 +00:00
if ( ! Permissions . CanTakeObject ( grp . UUID , remoteClient . AgentId ) )
permissionToTake = false ;
2010-11-22 22:51:26 +00:00
2010-06-29 19:36:17 +00:00
if ( ! Permissions . CanDeleteObject ( grp . UUID , remoteClient . AgentId ) )
permissionToDelete = false ;
}
2008-10-18 05:51:36 +00:00
}
2010-06-01 00:27:30 +00:00
// Handle god perms
2010-07-05 10:36:26 +00:00
if ( ( remoteClient ! = null ) & & Permissions . IsGod ( remoteClient . AgentId ) )
2008-10-18 05:51:36 +00:00
{
2010-06-01 00:27:30 +00:00
permissionToTake = true ;
permissionToTakeCopy = true ;
permissionToDelete = true ;
2008-10-18 05:51:36 +00:00
}
2010-06-01 00:27:30 +00:00
// If we're re-saving, we don't even want to delete
if ( action = = DeRezAction . SaveToExistingUserInventoryItem )
permissionToDelete = false ;
2010-07-04 09:59:38 +00:00
// if we want to take a copy, we also don't want to delete
2010-06-01 00:27:30 +00:00
// Note: after this point, the permissionToTakeCopy flag
// becomes irrelevant. It already includes the permissionToTake
// permission and after excluding no copy items here, we can
// just use that.
if ( action = = DeRezAction . TakeCopy )
2008-10-18 05:51:36 +00:00
{
2010-06-01 00:27:30 +00:00
// If we don't have permission, stop right here
if ( ! permissionToTakeCopy )
2013-08-04 03:13:44 +00:00
{
remoteClient . SendAlertMessage ( "You don't have permission to take the object" ) ;
2010-06-01 00:27:30 +00:00
return ;
2013-08-04 03:13:44 +00:00
}
2010-06-01 00:27:30 +00:00
2010-07-04 09:59:38 +00:00
permissionToTake = true ;
2010-06-01 00:27:30 +00:00
// Don't delete
permissionToDelete = false ;
2008-10-18 05:51:36 +00:00
}
2010-06-01 00:27:30 +00:00
if ( action = = DeRezAction . Return )
2008-10-18 05:51:36 +00:00
{
if ( remoteClient ! = null )
2008-05-24 09:40:14 +00:00
{
2010-06-01 00:27:30 +00:00
if ( Permissions . CanReturnObjects (
2010-03-18 18:57:29 +00:00
null ,
remoteClient . AgentId ,
2010-06-01 00:27:30 +00:00
deleteGroups ) )
2008-11-21 07:33:13 +00:00
{
2010-06-01 01:04:49 +00:00
permissionToTake = true ;
permissionToDelete = true ;
foreach ( SceneObjectGroup g in deleteGroups )
{
2012-02-15 23:07:12 +00:00
AddReturn ( g . OwnerID = = g . GroupID ? g . LastOwnerID : g . OwnerID , g . Name , g . AbsolutePosition , "parcel owner return" ) ;
2010-06-01 01:04:49 +00:00
}
2008-11-21 07:33:13 +00:00
}
2008-05-24 09:40:14 +00:00
}
2008-10-18 05:51:36 +00:00
else // Auto return passes through here with null agent
2008-05-24 09:40:14 +00:00
{
2008-10-18 05:51:36 +00:00
permissionToTake = true ;
permissionToDelete = true ;
2008-07-06 02:27:10 +00:00
}
}
2008-10-18 05:51:36 +00:00
2012-04-25 18:54:57 +00:00
if ( permissionToTake & & ( action ! = DeRezAction . Delete | | this . m_useTrashOnDelete ) )
2008-10-18 05:51:36 +00:00
{
m_asyncSceneObjectDeleter . DeleteToInventory (
2010-06-01 00:27:30 +00:00
action , destinationID , deleteGroups , remoteClient ,
2008-10-18 05:51:36 +00:00
permissionToDelete ) ;
}
else if ( permissionToDelete )
{
2010-06-01 00:27:30 +00:00
foreach ( SceneObjectGroup g in deleteGroups )
DeleteSceneObject ( g , false ) ;
2008-10-18 05:51:36 +00:00
}
2008-07-06 02:27:10 +00:00
}
2008-04-07 21:33:25 +00:00
/// <summary>
2008-04-27 14:37:51 +00:00
/// Event Handler Rez an object into a scene
/// Calls the non-void event handler
2008-04-07 21:33:25 +00:00
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="RayEnd"></param>
/// <param name="RayStart"></param>
/// <param name="RayTargetID"></param>
/// <param name="BypassRayCast"></param>
/// <param name="RayEndIsIntersection"></param>
/// <param name="EveryoneMask"></param>
/// <param name="GroupMask"></param>
/// <param name="RezSelected"></param>
/// <param name="RemoveItem"></param>
/// <param name="fromTaskID"></param>
2008-09-06 07:52:41 +00:00
public virtual void RezObject ( IClientAPI remoteClient , UUID itemID , Vector3 RayEnd , Vector3 RayStart ,
UUID RayTargetID , byte BypassRayCast , bool RayEndIsIntersection ,
bool RezSelected , bool RemoveItem , UUID fromTaskID )
2008-04-27 14:37:51 +00:00
{
2011-04-12 17:31:41 +00:00
// m_log.DebugFormat(
// "[PRIM INVENTORY]: RezObject from {0} for item {1} from task id {2}",
// remoteClient.Name, itemID, fromTaskID);
if ( fromTaskID = = UUID . Zero )
{
IInventoryAccessModule invAccess = RequestModuleInterface < IInventoryAccessModule > ( ) ;
if ( invAccess ! = null )
invAccess . RezObject (
remoteClient , itemID , RayEnd , RayStart , RayTargetID , BypassRayCast , RayEndIsIntersection ,
RezSelected , RemoveItem , fromTaskID , false ) ;
}
else
{
SceneObjectPart part = GetSceneObjectPart ( fromTaskID ) ;
if ( part = = null )
{
m_log . ErrorFormat (
"[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such scene object" ,
remoteClient . Name , itemID , fromTaskID ) ;
return ;
}
TaskInventoryItem item = part . Inventory . GetInventoryItem ( itemID ) ;
if ( item = = null )
{
m_log . ErrorFormat (
"[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such item" ,
remoteClient . Name , itemID , fromTaskID ) ;
return ;
}
2011-04-12 21:30:43 +00:00
byte bRayEndIsIntersection = ( byte ) ( RayEndIsIntersection ? 1 : 0 ) ;
2011-04-12 17:31:41 +00:00
Vector3 scale = new Vector3 ( 0.5f , 0.5f , 0.5f ) ;
Vector3 pos
= GetNewRezLocation (
RayStart , RayEnd , RayTargetID , Quaternion . Identity ,
BypassRayCast , bRayEndIsIntersection , true , scale , false ) ;
2011-04-12 21:21:46 +00:00
RezObject ( part , item , pos , null , Vector3 . Zero , 0 ) ;
2011-04-12 17:31:41 +00:00
}
2007-10-19 20:28:18 +00:00
}
2010-08-24 19:53:25 +00:00
2008-06-12 17:49:08 +00:00
/// <summary>
2008-12-15 20:32:49 +00:00
/// Rez an object into the scene from a prim's inventory.
2008-06-12 17:49:08 +00:00
/// </summary>
2008-12-15 20:32:49 +00:00
/// <param name="sourcePart"></param>
2008-06-12 17:49:08 +00:00
/// <param name="item"></param>
2011-04-12 21:15:40 +00:00
/// <param name="pos">The position of the rezzed object.</param>
/// <param name="rot">The rotation of the rezzed object. If null, then the rotation stored with the object
/// will be used if it exists.</param>
/// <param name="vel">The velocity of the rezzed object.</param>
2008-06-12 17:49:08 +00:00
/// <param name="param"></param>
2008-12-15 20:32:49 +00:00
/// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns>
2008-07-21 21:10:15 +00:00
public virtual SceneObjectGroup RezObject (
2011-04-12 21:15:40 +00:00
SceneObjectPart sourcePart , TaskInventoryItem item , Vector3 pos , Quaternion ? rot , Vector3 vel , int param )
2008-05-05 00:03:30 +00:00
{
2010-08-24 19:53:25 +00:00
if ( null = = item )
return null ;
2010-08-25 21:46:49 +00:00
SceneObjectGroup group = sourcePart . Inventory . GetRezReadySceneObject ( item ) ;
if ( null = = group )
2010-08-24 19:53:25 +00:00
return null ;
2010-08-25 23:08:53 +00:00
if ( ! Permissions . CanRezObject ( group . PrimCount , item . OwnerID , pos ) )
2010-09-12 17:43:49 +00:00
return null ;
2008-08-18 00:39:10 +00:00
2010-08-24 19:53:25 +00:00
if ( ! Permissions . BypassPermissions ( ) )
{
if ( ( item . CurrentPermissions & ( uint ) PermissionMask . Copy ) = = 0 )
sourcePart . Inventory . RemoveInventoryItem ( item . ItemID ) ;
}
2012-08-02 10:19:33 +00:00
2012-08-03 01:26:54 +00:00
group . FromPartID = sourcePart . UUID ;
2011-05-20 23:02:53 +00:00
AddNewSceneObject ( group , true , pos , rot , vel ) ;
2011-04-27 23:59:21 +00:00
2010-08-24 22:25:19 +00:00
// We can only call this after adding the scene object, since the scene object references the scene
// to find out if scripts should be activated at all.
2010-08-31 20:24:11 +00:00
group . CreateScriptInstances ( param , true , DefaultScriptEngine , 3 ) ;
2010-08-24 22:25:19 +00:00
group . ScheduleGroupForFullUpdate ( ) ;
2010-08-24 19:53:25 +00:00
2010-08-25 21:46:49 +00:00
return group ;
2008-05-05 00:03:30 +00:00
}
2008-08-18 00:39:10 +00:00
2010-10-06 17:59:30 +00:00
public virtual bool returnObjects ( SceneObjectGroup [ ] returnobjects ,
UUID AgentId )
2008-05-24 09:40:14 +00:00
{
2010-10-06 17:59:30 +00:00
List < uint > localIDs = new List < uint > ( ) ;
2008-11-21 07:33:13 +00:00
foreach ( SceneObjectGroup grp in returnobjects )
2008-05-24 21:13:44 +00:00
{
2010-10-06 17:59:30 +00:00
AddReturn ( grp . OwnerID , grp . Name , grp . AbsolutePosition ,
"parcel owner return" ) ;
localIDs . Add ( grp . RootPart . LocalId ) ;
2008-05-25 23:27:38 +00:00
}
2010-10-06 17:59:30 +00:00
DeRezObjects ( null , localIDs , UUID . Zero , DeRezAction . Return ,
UUID . Zero ) ;
2009-02-04 00:01:36 +00:00
2008-05-24 21:13:44 +00:00
return true ;
2008-05-24 09:40:14 +00:00
}
2008-05-16 01:22:11 +00:00
2008-09-06 07:52:41 +00:00
public void SetScriptRunning ( IClientAPI controllingClient , UUID objectID , UUID itemID , bool running )
2008-06-28 16:08:12 +00:00
{
SceneObjectPart part = GetSceneObjectPart ( objectID ) ;
2008-07-06 14:02:22 +00:00
if ( part = = null )
2008-06-28 16:08:12 +00:00
return ;
2008-07-06 14:02:22 +00:00
if ( running )
2008-06-28 16:08:12 +00:00
EventManager . TriggerStartScript ( part . LocalId , itemID ) ;
else
EventManager . TriggerStopScript ( part . LocalId , itemID ) ;
}
2008-08-17 18:41:13 +00:00
2008-09-25 05:13:44 +00:00
public void GetScriptRunning ( IClientAPI controllingClient , UUID objectID , UUID itemID )
{
EventManager . TriggerGetScriptRunning ( controllingClient , objectID , itemID ) ;
}
2008-10-06 00:09:49 +00:00
void ObjectOwner ( IClientAPI remoteClient , UUID ownerID , UUID groupID , List < uint > localIDs )
{
2008-11-21 22:14:57 +00:00
if ( ! Permissions . IsGod ( remoteClient . AgentId ) )
2009-06-14 21:44:34 +00:00
{
if ( ownerID ! = UUID . Zero )
return ;
if ( ! Permissions . CanDeedObject ( remoteClient . AgentId , groupID ) )
return ;
}
List < SceneObjectGroup > groups = new List < SceneObjectGroup > ( ) ;
2008-10-06 00:09:49 +00:00
foreach ( uint localID in localIDs )
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
2011-08-27 03:16:46 +00:00
if ( part = = null )
continue ;
2011-09-01 00:22:28 +00:00
2009-06-14 21:44:34 +00:00
if ( ! groups . Contains ( part . ParentGroup ) )
groups . Add ( part . ParentGroup ) ;
}
foreach ( SceneObjectGroup sog in groups )
{
2009-06-21 19:49:11 +00:00
if ( ownerID ! = UUID . Zero )
2008-10-06 00:09:49 +00:00
{
2009-06-14 21:44:34 +00:00
sog . SetOwnerId ( ownerID ) ;
sog . SetGroup ( groupID , remoteClient ) ;
2010-03-03 22:14:06 +00:00
sog . ScheduleGroupForFullUpdate ( ) ;
2009-06-14 21:44:34 +00:00
2010-09-17 00:30:46 +00:00
SceneObjectPart [ ] partList = sog . Parts ;
2010-08-27 23:40:33 +00:00
foreach ( SceneObjectPart child in partList )
2011-04-03 11:50:19 +00:00
{
2010-08-27 23:40:33 +00:00
child . Inventory . ChangeInventoryOwner ( ownerID ) ;
2011-04-03 11:50:19 +00:00
child . TriggerScriptChangedEvent ( Changed . OWNER ) ;
}
2009-06-14 21:44:34 +00:00
}
else
{
if ( ! Permissions . CanEditObject ( sog . UUID , remoteClient . AgentId ) )
continue ;
if ( sog . GroupID ! = groupID )
continue ;
2010-08-27 23:40:33 +00:00
2010-09-17 00:30:46 +00:00
SceneObjectPart [ ] partList = sog . Parts ;
2010-08-27 23:40:33 +00:00
foreach ( SceneObjectPart child in partList )
2009-06-14 21:44:34 +00:00
{
2010-08-27 23:40:33 +00:00
child . LastOwnerID = child . OwnerID ;
child . Inventory . ChangeInventoryOwner ( groupID ) ;
2011-04-03 11:50:19 +00:00
child . TriggerScriptChangedEvent ( Changed . OWNER ) ;
2009-06-14 21:44:34 +00:00
}
sog . SetOwnerId ( groupID ) ;
2009-06-21 18:38:12 +00:00
sog . ApplyNextOwnerPermissions ( ) ;
2010-09-12 17:43:49 +00:00
}
2008-10-06 00:09:49 +00:00
}
2009-06-21 19:49:11 +00:00
foreach ( uint localID in localIDs )
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
2011-08-27 03:16:46 +00:00
if ( part = = null )
continue ;
2011-09-15 17:58:58 +00:00
part . SendPropertiesToClient ( remoteClient ) ;
2009-06-21 19:49:11 +00:00
}
2008-10-06 00:09:49 +00:00
}
2010-04-30 10:46:50 +00:00
public void DelinkObjects ( List < uint > primIds , IClientAPI client )
{
List < SceneObjectPart > parts = new List < SceneObjectPart > ( ) ;
foreach ( uint localID in primIds )
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part = = null )
continue ;
if ( Permissions . CanDelinkObject ( client . AgentId , part . ParentGroup . RootPart . UUID ) )
parts . Add ( part ) ;
}
m_sceneGraph . DelinkObjects ( parts ) ;
}
2012-02-08 21:58:59 +00:00
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="client"></param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
2010-04-30 10:46:50 +00:00
public void LinkObjects ( IClientAPI client , uint parentPrimId , List < uint > childPrimIds )
2012-02-08 21:58:59 +00:00
{
LinkObjects ( client . AgentId , parentPrimId , childPrimIds ) ;
}
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="agentId">The ID of the user linking.</param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects ( UUID agentId , uint parentPrimId , List < uint > childPrimIds )
2010-04-30 10:46:50 +00:00
{
List < UUID > owners = new List < UUID > ( ) ;
List < SceneObjectPart > children = new List < SceneObjectPart > ( ) ;
SceneObjectPart root = GetSceneObjectPart ( parentPrimId ) ;
2010-04-30 20:35:07 +00:00
if ( root = = null )
{
2010-08-18 23:54:09 +00:00
m_log . DebugFormat ( "[LINK]: Can't find linkset root prim {0}" , parentPrimId ) ;
2010-04-30 20:35:07 +00:00
return ;
}
2012-02-08 21:58:59 +00:00
if ( ! Permissions . CanLinkObject ( agentId , root . ParentGroup . RootPart . UUID ) )
2010-04-30 20:35:07 +00:00
{
m_log . DebugFormat ( "[LINK]: Refusing link. No permissions on root prim" ) ;
2010-04-30 10:46:50 +00:00
return ;
2010-04-30 20:35:07 +00:00
}
2010-04-30 10:46:50 +00:00
foreach ( uint localID in childPrimIds )
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part = = null )
continue ;
if ( ! owners . Contains ( part . OwnerID ) )
owners . Add ( part . OwnerID ) ;
2012-02-08 21:58:59 +00:00
if ( Permissions . CanLinkObject ( agentId , part . ParentGroup . RootPart . UUID ) )
2010-04-30 10:46:50 +00:00
children . Add ( part ) ;
}
// Must be all one owner
/ /
if ( owners . Count > 1 )
2010-04-30 20:35:07 +00:00
{
m_log . DebugFormat ( "[LINK]: Refusing link. Too many owners" ) ;
return ;
}
if ( children . Count = = 0 )
{
m_log . DebugFormat ( "[LINK]: Refusing link. No permissions to link any of the children" ) ;
2010-04-30 10:46:50 +00:00
return ;
2010-04-30 20:35:07 +00:00
}
2010-04-30 10:46:50 +00:00
m_sceneGraph . LinkObjects ( root , children ) ;
}
2011-01-12 21:25:38 +00:00
private string PermissionString ( uint permissions )
{
PermissionMask perms = ( PermissionMask ) permissions &
( PermissionMask . Move |
PermissionMask . Copy |
PermissionMask . Transfer |
PermissionMask . Modify ) ;
return perms . ToString ( ) ;
}
2007-10-19 20:28:18 +00:00
}
2008-05-01 18:04:42 +00:00
}