From ff867b59cf59fdab19413cd46f3dd04058fbf3c7 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sat, 1 Sep 2012 02:44:11 +0100 Subject: Implementing functing to send messages directly to attachments --- .../Shared/Api/Implementation/OSSL_Api.cs | 131 +++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 13 ++ .../Shared/Api/Runtime/LSL_Constants.cs | 52 ++++++++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 + 4 files changed, 201 insertions(+) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 82114b3..8e80b4c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3354,6 +3354,137 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api 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 /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 6db6443..bde7a8e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -200,6 +200,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces /// 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 diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index cad8518..60a7e14 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 230c378..08ebfd6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -316,6 +316,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 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 -- cgit v1.1