diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 517dbf6e03..85638ca243 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -176,6 +176,7 @@ namespace OpenSim.Framework
///
/// Entries to store media textures on each face
///
+ /// Do not change this value directly - always do it through an IMoapModule.
public List Media { get; set; }
public PrimitiveBaseShape()
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 9f7436714f..064047da25 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -102,16 +102,54 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
+ throw new ArgumentException("Face cannot be less than zero");
- List media = part.Shape.Media;
-
- if (face > media.Count - 1)
+ int maxFaces = part.GetNumberOfSides() - 1;
+ if (face > maxFaces)
throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, media.Count - 1));
+ string.Format("Face argument was {0} but max is {1}", face, maxFaces));
- // TODO: Really need a proper copy constructor down in libopenmetaverse
- return MediaEntry.FromOSD(media[face].GetOSD());
+ List media = part.Shape.Media;
+
+ if (null == media)
+ {
+ return null;
+ }
+ else
+ {
+ // TODO: Really need a proper copy constructor down in libopenmetaverse
+ return MediaEntry.FromOSD(media[face].GetOSD());
+ }
+ }
+
+ public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
+ {
+ if (face < 0)
+ throw new ArgumentException("Face cannot be less than zero");
+
+ int maxFaces = part.GetNumberOfSides() - 1;
+ if (face > maxFaces)
+ throw new ArgumentException(
+ string.Format("Face argument was {0} but max is {1}", face, maxFaces));
+
+ if (null == part.Shape.Media)
+ part.Shape.Media = new List(maxFaces);
+
+ part.Shape.Media[face] = me;
+
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ }
+
+ part.ScheduleFullUpdate();
}
///
@@ -140,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
throw new Exception(
string.Format(
"[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}",
- omm.Request.GetType()));
+ omm.Request.GetType()));
}
///
@@ -233,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
- // Arguably we don't need to send a full update to the avatar that just changed the texture.
+ // Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
return string.Empty;
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
index 4447f3475e..31bb6d87c0 100644
--- a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -39,9 +39,19 @@ namespace OpenSim.Region.Framework.Interfaces
///
/// Get the media entry for a given prim face.
///
+ /// A copy of the media entry is returned rather than the original, so this can be altered at will without
+ /// affecting the original settings.
///
///
///
- MediaEntry GetMediaEntry(SceneObjectPart part, int face);
- }
+ MediaEntry GetMediaEntry(SceneObjectPart part, int face);
+
+ ///
+ /// Set the media entry for a given prim face.
+ ///
+ ///
+ ///
+ ///
+ void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me);
+ }
}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1e5133b34d..8830fb098e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -975,8 +975,9 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Used for media on a prim
+ /// Used for media on a prim.
///
+ /// Do not change this value directly - always do it through an IMoapModule.
public string MediaUrl
{
get
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9290fc37b9..26007901d3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7816,7 +7816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
// TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
// Assuming silently fail means give back an empty list. Ideally, need to check this.
- if (face < 0 || face > m_host.Shape.Media.Count - 1)
+ if (face < 0 || face > m_host.GetNumberOfSides() - 1)
return new LSL_List();
return GetLinkPrimMediaParams(face, rules);
@@ -7830,6 +7830,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
MediaEntry me = module.GetMediaEntry(m_host, face);
+ // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
+ if (null == me)
+ return new LSL_List();
+
LSL_List res = new LSL_List();
for (int i = 0; i < rules.Length; i++)
@@ -7912,6 +7916,113 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return res;
}
+ public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
+ {
+ m_host.AddScriptLPS(1);
+ ScriptSleep(1000);
+
+ // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
+ // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
+ // Don't perform the media check directly
+ if (face < 0 || face > m_host.GetNumberOfSides() - 1)
+ return ScriptBaseClass.LSL_STATUS_OK;
+
+ return SetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
+ {
+ IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ MediaEntry me = module.GetMediaEntry(m_host, face);
+ if (null == me)
+ me = new MediaEntry();
+
+ int i = 0;
+
+ while (i < rules.Length - 1)
+ {
+ int code = rules.GetLSLIntegerItem(i++);
+
+ switch (code)
+ {
+ case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
+ me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
+ int v = rules.GetLSLIntegerItem(i++);
+ if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
+ me.Controls = MediaControls.Standard;
+ else
+ me.Controls = MediaControls.Mini;
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
+ me.CurrentURL = rules.GetLSLStringItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
+ me.HomeURL = rules.GetLSLStringItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
+ me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
+ me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
+ me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
+ me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
+ me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
+ me.Width = (int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
+ me.Height = (int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
+ me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
+ string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
+ List whiteListUrls = new List();
+ Array.ForEach(
+ rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
+ me.WhiteList = whiteListUrls.ToArray();
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
+ me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
+ me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
+ break;
+ }
+ }
+
+ module.SetMediaEntry(m_host, face, me);
+
+ return ScriptBaseClass.LSL_STATUS_OK;
+ }
+
//
//
// The .NET definition of base 64 is:
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9a64f8c40f..6ef786a49a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -518,7 +518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
- // constants for llGetPrimMediaParams
+ // constants for llGetPrimMediaParams/llSetPrimMediaParams
public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
public const int PRIM_MEDIA_CONTROLS = 1;
public const int PRIM_MEDIA_CURRENT_URL = 2;
@@ -542,6 +542,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_MEDIA_PERM_OWNER = 1;
public const int PRIM_MEDIA_PERM_GROUP = 2;
public const int PRIM_MEDIA_PERM_ANYONE = 4;
+
+ // extra constants for llSetPrimMediaParams
+ public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
+ public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
+ public static readonly LSLInteger LSL_STATUS_TYPE_MISMATCH = new LSLInteger(1001);
+ public static readonly LSLInteger LSL_STATUS_BOUNDS_ERROR = new LSLInteger(1002);
+ public static readonly LSLInteger LSL_STATUS_NOT_FOUND = new LSLInteger(1003);
+ public static readonly LSLInteger LSL_STATUS_NOT_SUPPORTED = new LSLInteger(1004);
+ public static readonly LSLInteger LSL_STATUS_INTERNAL_ERROR = new LSLInteger(1999);
+ public static readonly LSLInteger LSL_STATUS_WHITELIST_FAILED = new LSLInteger(2001);
// Constants for default textures
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";