diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 5f01788b62..c9d977008c 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.7.4"; + private const string VERSION_NUMBER = "0.7.5"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5bf69ad64e..1222ac6bcf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3418,13 +3418,16 @@ namespace OpenSim.Region.Framework.Scenes public List GetAttachments(uint attachmentPoint) { List attachments = new List(); - - lock (m_attachments) + + if (attachmentPoint >= 0) { - foreach (SceneObjectGroup so in m_attachments) + lock (m_attachments) { - if (attachmentPoint == so.AttachmentPoint) - attachments.Add(so); + foreach (SceneObjectGroup so in m_attachments) + { + if (attachmentPoint == so.AttachmentPoint) + attachments.Add(so); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e245684a43..2e1e5b669d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1673,6 +1673,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } + MessageObject(objUUID, message); + } + + private void MessageObject(UUID objUUID, string message) + { object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) }; SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID); @@ -3224,6 +3229,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + #region Attachment commands + public void osForceAttachToAvatar(int attachmentPoint) { CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar"); @@ -3313,6 +3320,175 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ((LSL_Api)m_LSL_Api).DetachFromAvatar(); } + public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints) + { + CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments"); + + m_host.AddScriptLPS(1); + + UUID targetUUID; + ScenePresence target; + LSL_List resp = new LSL_List(); + + if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target)) + { + foreach (object point in attachmentPoints.Data) + { + LSL_Integer ipoint = new LSL_Integer( + (point is LSL_Integer || point is int || point is uint) ? + (int)point : + 0 + ); + resp.Add(ipoint); + if (ipoint == 0) + { + // indicates zero attachments + resp.Add(new LSL_Integer(0)); + } + else + { + // gets the number of attachments on the attachment point + resp.Add(new LSL_Integer(target.GetAttachments((uint)ipoint).Count)); + } + } + } + + return resp; + } + + public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options) + { + CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments"); + m_host.AddScriptLPS(1); + + UUID targetUUID; + ScenePresence target; + + if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target)) + { + List aps = new List(); + foreach (object point in attachmentPoints.Data) + { + int ipoint; + if (int.TryParse(point.ToString(), out ipoint)) + { + aps.Add(ipoint); + } + } + + List attachments = new List(); + + bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL); + bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0; + + if (msgAll && invertPoints) + { + return; + } + else if (msgAll || invertPoints) + { + attachments = target.GetAttachments(); + } + else + { + foreach (int point in aps) + { + if (point > 0) + { + attachments.AddRange(target.GetAttachments((uint)point)); + } + } + } + + // if we have no attachments at this point, exit now + if (attachments.Count == 0) + { + return; + } + + List ignoreThese = new List(); + + if (invertPoints) + { + foreach (SceneObjectGroup attachment in attachments) + { + if (aps.Contains((int)attachment.AttachmentPoint)) + { + ignoreThese.Add(attachment); + } + } + } + + foreach (SceneObjectGroup attachment in ignoreThese) + { + attachments.Remove(attachment); + } + ignoreThese.Clear(); + + // if inverting removed all attachments to check, exit now + if (attachments.Count < 1) + { + return; + } + + if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0) + { + foreach (SceneObjectGroup attachment in attachments) + { + if (attachment.RootPart.CreatorID != m_host.CreatorID) + { + ignoreThese.Add(attachment); + } + } + + foreach (SceneObjectGroup attachment in ignoreThese) + { + attachments.Remove(attachment); + } + ignoreThese.Clear(); + + // if filtering by same object creator removed all + // attachments to check, exit now + if (attachments.Count == 0) + { + return; + } + } + + if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0) + { + foreach (SceneObjectGroup attachment in attachments) + { + if (attachment.RootPart.CreatorID != m_item.CreatorID) + { + ignoreThese.Add(attachment); + } + } + + foreach (SceneObjectGroup attachment in ignoreThese) + { + attachments.Remove(attachment); + } + ignoreThese.Clear(); + + // if filtering by object creator must match originating + // script creator removed all attachments to check, + // exit now + if (attachments.Count == 0) + { + return; + } + } + + foreach (SceneObjectGroup attachment in attachments) + { + MessageObject(attachment.RootPart.UUID, message); + } + } + } + + #endregion + /// /// Checks if thing is a UUID. /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 06729abe36..3985e6629c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -157,7 +157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osAvatarPlayAnimation(string avatar, string animation); void osAvatarStopAnimation(string avatar, string animation); - // Attachment commands + #region Attachment commands /// /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH @@ -192,6 +192,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces /// Nothing happens if the object is not attached. void osForceDetachFromAvatar(); + /// + /// Returns a strided list of the specified attachment points and the number of attachments on those points. + /// + /// avatar UUID + /// list of ATTACH_* constants + /// + LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints); + + /// + /// Sends a specified message to the specified avatar's attachments on + /// the specified attachment points. + /// + /// + /// Behaves as osMessageObject(), without the sending script needing to know the attachment keys in advance. + /// + /// avatar UUID + /// message string + /// list of ATTACH_* constants, or -1 for all attachments. If -1 is specified and OS_ATTACH_MSG_INVERT_POINTS is present in flags, no action is taken. + /// flags further constraining the attachments to deliver the message to. + void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags); + + #endregion + //texture draw functions string osMovePen(string drawList, int x, int y); string osDrawLine(string drawList, int startX, int startY, int endX, int endY); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index cad8518473..60a7e1433f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -237,6 +237,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int ATTACH_HUD_BOTTOM = 37; public const int ATTACH_HUD_BOTTOM_RIGHT = 38; + #region osMessageAttachments constants + + /// + /// Instructs osMessageAttachements to send the message to attachments + /// on every point. + /// + /// + /// One might expect this to be named OS_ATTACH_ALL, but then one might + /// also expect functions designed to attach or detach or get + /// attachments to work with it too. Attaching a no-copy item to + /// many attachments could be dangerous. + /// when combined with OS_ATTACH_MSG_INVERT_POINTS, will prevent the + /// message from being sent. + /// if combined with OS_ATTACH_MSG_OBJECT_CREATOR or + /// OS_ATTACH_MSG_SCRIPT_CREATOR, could result in no message being + /// sent- this is expected behaviour. + /// + public const int OS_ATTACH_MSG_ALL = -65535; + + /// + /// Instructs osMessageAttachements to invert how the attachment points + /// list should be treated (e.g. go from inclusive operation to + /// exclusive operation). + /// + /// + /// This might be used if you want to deliver a message to one set of + /// attachments and a different message to everything else. With + /// this flag, you only need to build one explicit list for both calls. + /// + public const int OS_ATTACH_MSG_INVERT_POINTS = 1; + + /// + /// Instructs osMessageAttachments to only send the message to + /// attachments with a CreatorID that matches the host object CreatorID + /// + /// + /// This would be used if distributed in an object vendor/updater server. + /// + public const int OS_ATTACH_MSG_OBJECT_CREATOR = 2; + + /// + /// Instructs osMessageAttachments to only send the message to + /// attachments with a CreatorID that matches the sending script CreatorID + /// + /// + /// This might be used if the script is distributed independently of a + /// containing object. + /// + public const int OS_ATTACH_MSG_SCRIPT_CREATOR = 4; + + #endregion + public const int LAND_LEVEL = 0; public const int LAND_RAISE = 1; public const int LAND_LOWER = 2; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index ba1ade2285..52ca3da154 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -289,7 +289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osAvatarStopAnimation(avatar, animation); } - // Avatar functions + #region Attachment commands public void osForceAttachToAvatar(int attachmentPoint) { @@ -311,6 +311,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osForceDetachFromAvatar(); } + public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints) + { + return m_OSSL_Functions.osGetNumberOfAttachments(avatar, attachmentPoints); + } + + public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags) + { + m_OSSL_Functions.osMessageAttachments(avatar, message, attachmentPoints, flags); + } + + #endregion + // Texture Draw functions public string osMovePen(string drawList, int x, int y)