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.4.1
Justin Clark-Casey (justincc) 2012-04-24 00:03:57 +01:00
parent b798b32b19
commit 40e37d8b78
6 changed files with 127 additions and 49 deletions

View File

@ -29,22 +29,21 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
namespace OpenSim.Region.ScriptEngine.Shared.Api namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
public class ApiManager public class ApiManager
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<string,Type> m_Apis = new Dictionary<string,Type>(); private Dictionary<string,Type> m_Apis = new Dictionary<string,Type>();
public string[] GetApis() 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();
@ -62,9 +61,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_Apis[name] = t; m_Apis[name] = t;
} }
} }
}
List<string> ret = new List<string>(m_Apis.Keys); // m_log.DebugFormat("[API MANAGER]: Found {0} apis", m_Apis.Keys.Count);
return ret.ToArray();
return new List<string>(m_Apis.Keys).ToArray();
} }
public IScriptApi CreateApi(string api) public IScriptApi CreateApi(string api)

View File

@ -2994,7 +2994,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_UrlModule.ReleaseURL(url); 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); m_host.AddScriptLPS(1);
@ -3007,15 +3049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return; return;
if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
{ AttachToAvatar(attachmentPoint);
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);
}
} }
public void llDetachFromAvatar() public void llDetachFromAvatar()
@ -3031,24 +3065,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return; return;
if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
{ DetachFromAvatar();
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);
} }
public void llTakeCamera(string avatar) public void llTakeCamera(string avatar)

View File

@ -209,6 +209,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
throw new Exception("OSSL Runtime Error: " + msg); 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() private void InitLSL()
{ {
if (m_LSL_Api != null) if (m_LSL_Api != null)
@ -3093,5 +3101,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
estate.setEstateTerrainTextureHeights(corner, (float)low, (float)high); estate.setEstateTerrainTextureHeights(corner, (float)low, (float)high);
} }
} }
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 osAvatarPlayAnimation(string avatar, string animation);
void osAvatarStopAnimation(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 //texture draw functions
string osMovePen(string drawList, int x, int y); string osMovePen(string drawList, int x, int y);
string osDrawLine(string drawList, int startX, int startY, int endX, int endY); 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); 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) 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) public IScriptApi GetApi(string name)
{ {
if (m_Apis.ContainsKey(name)) if (m_Apis.ContainsKey(name))
{
// m_log.DebugFormat("[SCRIPT INSTANCE]: Found api {0} in {1}@{2}", name, ScriptName, PrimName);
return m_Apis[name]; return m_Apis[name];
}
// m_log.DebugFormat("[SCRIPT INSTANCE]: Did not find api {0} in {1}@{2}", name, ScriptName, PrimName);
return null; return null;
} }