Add osForceAttachToAvatar() and osForceDetachFromAvatar()

These behave identically to llAttachToAvatar() and llDetachFromAvatar() except that they do not enforce the PERMISSION_ATTACH check
Intended for use in completely controlled dedicated environments where these checks are more a UI hinderance than a help.
Threat level high.
0.7.3-extended
Justin Clark-Casey (justincc) 2012-04-24 00:03:57 +01:00
parent 2657aa6987
commit a666cd9e1f
6 changed files with 127 additions and 49 deletions

View File

@ -29,42 +29,43 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using OpenSim.Region.ScriptEngine.Interfaces;
namespace OpenSim.Region.ScriptEngine.Shared.Api
{
public class ApiManager
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<string,Type> m_Apis = new Dictionary<string,Type>();
public string[] GetApis()
{
if (m_Apis.Count > 0)
if (m_Apis.Count <= 0)
{
List<string> l = new List<string>(m_Apis.Keys);
return l.ToArray();
}
Assembly a = Assembly.GetExecutingAssembly();
Assembly a = Assembly.GetExecutingAssembly();
Type[] types = a.GetExportedTypes();
Type[] types = a.GetExportedTypes();
foreach (Type t in types)
{
string name = t.ToString();
int idx = name.LastIndexOf('.');
if (idx != -1)
name = name.Substring(idx+1);
if (name.EndsWith("_Api"))
foreach (Type t in types)
{
name = name.Substring(0, name.Length - 4);
m_Apis[name] = t;
string name = t.ToString();
int idx = name.LastIndexOf('.');
if (idx != -1)
name = name.Substring(idx+1);
if (name.EndsWith("_Api"))
{
name = name.Substring(0, name.Length - 4);
m_Apis[name] = t;
}
}
}
List<string> ret = new List<string>(m_Apis.Keys);
return ret.ToArray();
// m_log.DebugFormat("[API MANAGER]: Found {0} apis", m_Apis.Keys.Count);
return new List<string>(m_Apis.Keys).ToArray();
}
public IScriptApi CreateApi(string api)
@ -76,4 +77,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return ret;
}
}
}
}

View File

@ -2965,7 +2965,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_UrlModule.ReleaseURL(url);
}
public void llAttachToAvatar(int attachment)
/// <summary>
/// Attach the object containing this script to the avatar that owns it.
/// </summary>
/// <param name='attachment'>The attachment point (e.g. ATTACH_CHEST)</param>
/// <returns>true if the attach suceeded, false if it did not</returns>
public bool AttachToAvatar(int attachmentPoint)
{
SceneObjectGroup grp = m_host.ParentGroup;
ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false);
else
return false;
}
/// <summary>
/// Detach the object containing this script from the avatar it is attached to.
/// </summary>
/// <remarks>
/// Nothing happens if the object is not attached.
/// </remarks>
public void DetachFromAvatar()
{
Util.FireAndForget(DetachWrapper, m_host);
}
private void DetachWrapper(object o)
{
SceneObjectPart host = (SceneObjectPart)o;
SceneObjectGroup grp = host.ParentGroup;
UUID itemID = grp.FromItemID;
ScenePresence presence = World.GetScenePresence(host.OwnerID);
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
}
public void llAttachToAvatar(int attachmentPoint)
{
m_host.AddScriptLPS(1);
@ -2978,15 +3020,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
{
SceneObjectGroup grp = m_host.ParentGroup;
ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
attachmentsModule.AttachObject(presence, grp, (uint)attachment, false);
}
AttachToAvatar(attachmentPoint);
}
public void llDetachFromAvatar()
@ -3002,24 +3036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
{
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
Util.FireAndForget(DetachWrapper, m_host);
}
}
private void DetachWrapper(object o)
{
SceneObjectPart host = (SceneObjectPart)o;
SceneObjectGroup grp = host.ParentGroup;
UUID itemID = grp.FromItemID;
ScenePresence presence = World.GetScenePresence(host.OwnerID);
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
DetachFromAvatar();
}
public void llTakeCamera(string avatar)

View File

@ -209,6 +209,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
throw new Exception("OSSL Runtime Error: " + msg);
}
/// <summary>
/// Initialize the LSL interface.
/// </summary>
/// <remarks>
/// FIXME: This is an abomination. We should be able to set this up earlier but currently we have no
/// guarantee the interface is present on Initialize(). There needs to be another post initialize call from
/// ScriptInstance.
/// </remarks>
private void InitLSL()
{
if (m_LSL_Api != null)
@ -2918,5 +2926,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
}
public void osForceAttachToAvatar(int attachmentPoint)
{
CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
m_host.AddScriptLPS(1);
InitLSL();
((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint);
}
public void osForceDetachFromAvatar()
{
CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar");
m_host.AddScriptLPS(1);
InitLSL();
((LSL_Api)m_LSL_Api).DetachFromAvatar();
}
}
}

View File

@ -98,6 +98,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void osAvatarPlayAnimation(string avatar, string animation);
void osAvatarStopAnimation(string avatar, string animation);
// Attachment commands
/// <summary>
/// Attach the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH
/// </summary>
/// <param name='attachment'>The attachment point. For example, ATTACH_CHEST</param>
void osForceAttachToAvatar(int attachment);
/// <summary>
/// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH
/// </summary>
/// <remarks>Nothing happens if the object is not attached.</remarks>
void osForceDetachFromAvatar();
//texture draw functions
string osMovePen(string drawList, int x, int y);
string osDrawLine(string drawList, int startX, int startY, int endX, int endY);

View File

@ -289,8 +289,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_OSSL_Functions.osAvatarStopAnimation(avatar, animation);
}
// Avatar functions
//Texture Draw functions
public void osForceAttachToAvatar(int attachmentPoint)
{
m_OSSL_Functions.osForceAttachToAvatar(attachmentPoint);
}
public void osForceDetachFromAvatar()
{
m_OSSL_Functions.osForceDetachFromAvatar();
}
// Texture Draw functions
public string osMovePen(string drawList, int x, int y)
{

View File

@ -964,7 +964,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public IScriptApi GetApi(string name)
{
if (m_Apis.ContainsKey(name))
{
// m_log.DebugFormat("[SCRIPT INSTANCE]: Found api {0} in {1}@{2}", name, ScriptName, PrimName);
return m_Apis[name];
}
// m_log.DebugFormat("[SCRIPT INSTANCE]: Did not find api {0} in {1}@{2}", name, ScriptName, PrimName);
return null;
}