diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index a0ff151a92..22c89370a7 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -110,7 +110,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // client.OnAvatarNowWearing -= AvatarIsWearing; } - public void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) { IInventoryService invService = m_scene.InventoryService; @@ -134,7 +133,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } else { - m_log.ErrorFormat("[APPEARANCE]: Can't find inventory item {0}, setting to default", appearance.Wearables[i].ItemID); + m_log.ErrorFormat( + "[APPEARANCE]: Can't find inventory item {0} for {1}, setting to default", + appearance.Wearables[i].ItemID, (WearableType)i); + appearance.Wearables[i].AssetID = def.Wearables[i].AssetID; } } diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs index abcaf917bb..c289cdbaf6 100644 --- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs +++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs @@ -43,10 +43,67 @@ namespace OpenSim.Region.Framework.Interfaces int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face); UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer); + + /// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the + /// asset service. + /// + /// The simulator in which the texture is being generated + /// The prim to which to apply the texture. + /// The content type to create. Current choices are "vector" to create a vector + /// based texture or "image" to create a texture from an image at a particular URL + /// The data for the generator + /// Parameters for the generator that don't form part of the main data. + /// If zero, the image is never updated after the first generation. If positive + /// the image is updated at the given interval. Not implemented for + /// + /// If true, the newly generated texture is blended with the appropriate existing ones on the prim + /// + /// + /// The alpha value of the generated texture. + /// + /// + /// The UUID of the texture updater, not the texture UUID. If you need the texture UUID then you will need + /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture + /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID + /// UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer, bool SetBlending, byte AlphaValue); - UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, - int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face); + + /// + /// Apply a dynamically generated texture to the given prim. + /// + /// The simulator in which the texture is being generated + /// The prim to which to apply the texture. + /// The content type to create. Current choices are "vector" to create a vector + /// based texture or "image" to create a texture from an image at a particular URL + /// The data for the generator + /// Parameters for the generator that don't form part of the main data. + /// If zero, the image is never updated after the first generation. If positive + /// the image is updated at the given interval. Not implemented for + /// + /// If true, the newly generated texture is blended with the appropriate existing ones on the prim + /// + /// + /// Display flags. If DISP_EXPIRE then the old texture is deleted if it is replaced by a + /// newer generated texture (may not currently be implemented). If DISP_TEMP then the asset is flagged as + /// temporary, which often means that it is not persisted to the database. + /// + /// + /// The alpha value of the generated texture. + /// + /// + /// The face of the prim on which to put the generated texture. If ALL_SIDES then all sides of the prim are + /// set + /// + /// + /// The UUID of the texture updater, not the texture UUID. If you need the texture UUID then you will need + /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture + /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID + /// + UUID AddDynamicTextureData( + UUID simID, UUID primID, string contentType, string data, string extraParams, + int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face); + void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, out double xSize, out double ySize); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 473920ee88..9f74b2a14c 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -205,6 +205,12 @@ namespace OpenSim.Region.Framework.Scenes public delegate void OnMakeRootAgentDelegate(ScenePresence presence); public event OnMakeRootAgentDelegate OnMakeRootAgent; + /// + /// Triggered when an object or attachment enters a scene + /// + public event OnIncomingSceneObjectDelegate OnIncomingSceneObject; + public delegate void OnIncomingSceneObjectDelegate(SceneObjectGroup so); + public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); public event NewInventoryItemUploadComplete OnNewInventoryItemUploadComplete; @@ -407,7 +413,7 @@ namespace OpenSim.Region.Framework.Scenes } } } - } + } public void TriggerGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) { @@ -1206,6 +1212,27 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerOnIncomingSceneObject(SceneObjectGroup so) + { + OnIncomingSceneObjectDelegate handlerIncomingSceneObject = OnIncomingSceneObject; + if (handlerIncomingSceneObject != null) + { + foreach (OnIncomingSceneObjectDelegate d in handlerIncomingSceneObject.GetInvocationList()) + { + try + { + d(so); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerOnIncomingSceneObject failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerOnRegisterCaps(UUID agentID, Caps caps) { RegisterCapsEvent handlerRegisterCaps = OnRegisterCaps; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f109589542..669720a464 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2239,9 +2239,14 @@ namespace OpenSim.Region.Framework.Scenes } + /// + /// Called when objects or attachments cross the border between regions. + /// + /// + /// public bool IncomingCreateObject(ISceneObject sog) { - //m_log.Debug(" >>> IncomingCreateObject <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); + //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); SceneObjectGroup newObject; try { @@ -2258,7 +2263,12 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); return false; } + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1); + + // Do this as late as possible so that listeners have full access to the incoming object + EventManager.TriggerOnIncomingSceneObject(newObject); + return true; } @@ -2270,6 +2280,8 @@ namespace OpenSim.Region.Framework.Scenes /// False public virtual bool IncomingCreateObject(UUID userID, UUID itemID) { + //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); + ScenePresence sp = GetScenePresence(userID); if (sp != null) { @@ -2307,7 +2319,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart p in sceneObject.Children.Values) p.LocalId = 0; - if ((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0)) // Attachment + if (sceneObject.IsAttachmentCheckFull()) // Attachment { sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); @@ -2332,29 +2344,23 @@ namespace OpenSim.Region.Framework.Scenes //RootPrim.SetParentLocalId(parentLocalID); - m_log.DebugFormat("[ATTACHMENT]: Received " + - "attachment {0}, inworld asset id {1}", - //grp.RootPart.LastOwnerID.ToString(), - grp.GetFromItemID(), - grp.UUID.ToString()); + m_log.DebugFormat( + "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.GetFromItemID(), grp.UUID); //grp.SetFromAssetID(grp.RootPart.LastOwnerID); - m_log.DebugFormat("[ATTACHMENT]: Attach " + - "to avatar {0} at position {1}", - sp.UUID.ToString(), grp.AbsolutePosition); - AttachObject(sp.ControllingClient, - grp.LocalId, (uint)0, - grp.GroupRotation, - grp.AbsolutePosition, false); + m_log.DebugFormat( + "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); + + AttachObject( + sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); - grp.SendGroupFullUpdate(); + grp.SendGroupFullUpdate(); } else { RootPrim.RemFlag(PrimFlags.TemporaryOnRez); RootPrim.AddFlag(PrimFlags.TemporaryOnRez); } - } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8c568707aa..af466593bc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -268,7 +268,16 @@ namespace OpenSim.Region.Framework.Scenes } } - private bool IsAttachmentCheckFull() + /// + /// Check both the attachment property and the relevant properties of the underlying root part. + /// + /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't + /// have the IsAttachment property yet checked. + /// + /// FIXME: However, this should be fixed so that this property + /// propertly reflects the underlying status. + /// + public bool IsAttachmentCheckFull() { return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 29f607bd9b..b8a937a303 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -104,6 +104,14 @@ namespace OpenSim.Region.Framework.Scenes } protected ScenePresenceAnimator m_animator; + /// + /// The scene objects attached to this avatar. Do not change this list directly - use methods such as + /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. + /// + public List Attachments + { + get { return m_attachments; } + } protected List m_attachments = new List(); private Dictionary scriptedcontrols = new Dictionary(); @@ -219,11 +227,6 @@ namespace OpenSim.Region.Framework.Scenes protected AvatarAppearance m_appearance; - public List Attachments - { - get { return m_attachments; } - } - // neighbouring regions we have enabled a child agent in // holds the seed cap for the child agent in that region private Dictionary m_knownChildRegions = new Dictionary(); @@ -3210,8 +3213,7 @@ namespace OpenSim.Region.Framework.Scenes m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong m_physicsActor.SubscribeEvents(500); - m_physicsActor.LocalID = LocalId; - + m_physicsActor.LocalID = LocalId; } private void OutOfBoundsCall(Vector3 pos) @@ -3221,7 +3223,7 @@ namespace OpenSim.Region.Framework.Scenes //AddToPhysicalScene(flying); if (ControllingClient != null) - ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.",true); + ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); } // Event called by the physics plugin to tell the avatar about a collision.