Merge branch 'moap'

prebuild-update
Justin Clark-Casey (justincc) 2010-08-06 18:28:53 +01:00
commit 1270727c96
32 changed files with 28949 additions and 24337 deletions

View File

@ -327,7 +327,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
LinkNumber = @LinkNumber LinkNumber = @LinkNumber, MediaURL = @MediaURL
WHERE UUID = @UUID WHERE UUID = @UUID
END END
ELSE ELSE
@ -342,7 +342,7 @@ ELSE
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL
) VALUES ( ) VALUES (
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
@ -352,7 +352,7 @@ ELSE
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
@ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL
) )
END"; END";
@ -385,7 +385,7 @@ IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID)
PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions,
PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin,
ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow,
Texture = @Texture, ExtraParams = @ExtraParams, State = @State Texture = @Texture, ExtraParams = @ExtraParams, State = @State, Media = @Media
WHERE UUID = @UUID WHERE UUID = @UUID
END END
ELSE ELSE
@ -394,11 +394,11 @@ ELSE
primshapes ( primshapes (
UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY,
PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin,
ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State, Media
) VALUES ( ) VALUES (
@UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY,
@PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin,
@ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State, @Media
) )
END"; END";
@ -1128,6 +1128,9 @@ VALUES
prim.PassTouches = true; prim.PassTouches = true;
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
if (!(primRow["MediaURL"] is System.DBNull))
prim.MediaUrl = (string)primRow["MediaURL"];
return prim; return prim;
} }
@ -1180,6 +1183,9 @@ VALUES
{ {
} }
if (!(shapeRow["Media"] is System.DBNull))
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
return baseShape; return baseShape;
} }
@ -1510,6 +1516,7 @@ VALUES
else else
parameters.Add(_Database.CreateParameter("PassTouches", 0)); parameters.Add(_Database.CreateParameter("PassTouches", 0));
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
return parameters.ToArray(); return parameters.ToArray();
} }
@ -1557,6 +1564,7 @@ VALUES
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
parameters.Add(_Database.CreateParameter("State", s.State)); parameters.Add(_Database.CreateParameter("State", s.State));
parameters.Add(_Database.CreateParameter("Media", null == s.Media ? null : s.Media.ToXml()));
return parameters.ToArray(); return parameters.ToArray();
} }

View File

@ -1,4 +1,4 @@

:VERSION 1 :VERSION 1
CREATE TABLE [dbo].[prims]( CREATE TABLE [dbo].[prims](
@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
COMMIT COMMIT
:VERSION 24
-- Added post 0.7
BEGIN TRANSACTION
ALTER TABLE prims ADD COLUMN MediaURL varchar(255)
ALTER TABLE primshapes ADD COLUMN Media TEXT
COMMIT

View File

@ -174,7 +174,7 @@ namespace OpenSim.Data.MySQL
"ParticleSystem, ClickAction, Material, " + "ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " + "CollisionSound, CollisionSoundVolume, " +
"PassTouches, " + "PassTouches, " +
"LinkNumber) values (" + "?UUID, " + "LinkNumber, MediaURL) values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " + "?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " + "?Description, ?SitName, ?TouchName, " +
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
@ -205,7 +205,7 @@ namespace OpenSim.Data.MySQL
"?SaleType, ?ColorR, ?ColorG, " + "?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " + "?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " + "?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber)"; "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID); FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
@ -222,7 +222,7 @@ namespace OpenSim.Data.MySQL
"PathTaperX, PathTaperY, PathTwist, " + "PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " + "PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " + "ProfileCurve, ProfileHollow, Texture, " +
"ExtraParams, State) values (?UUID, " + "ExtraParams, State, Media) values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " + "?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " + "?PathScaleX, ?PathScaleY, " +
@ -233,7 +233,7 @@ namespace OpenSim.Data.MySQL
"?PathTwistBegin, ?ProfileBegin, " + "?PathTwistBegin, ?ProfileBegin, " +
"?ProfileEnd, ?ProfileCurve, " + "?ProfileEnd, ?ProfileCurve, " +
"?ProfileHollow, ?Texture, ?ExtraParams, " + "?ProfileHollow, ?Texture, ?ExtraParams, " +
"?State)"; "?State, ?Media)";
FillShapeCommand(cmd, prim); FillShapeCommand(cmd, prim);
@ -1185,6 +1185,9 @@ namespace OpenSim.Data.MySQL
prim.PassTouches = ((sbyte)row["PassTouches"] != 0); prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
prim.LinkNum = (int)row["LinkNumber"]; prim.LinkNum = (int)row["LinkNumber"];
if (!(row["MediaURL"] is System.DBNull))
prim.MediaUrl = (string)row["MediaURL"];
return prim; return prim;
} }
@ -1521,6 +1524,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("PassTouches", 0); cmd.Parameters.AddWithValue("PassTouches", 0);
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
} }
/// <summary> /// <summary>
@ -1701,6 +1705,9 @@ namespace OpenSim.Data.MySQL
s.State = (byte)(int)row["State"]; s.State = (byte)(int)row["State"];
if (!(row["Media"] is System.DBNull))
s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
return s; return s;
} }
@ -1743,6 +1750,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Texture", s.TextureEntry); cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
cmd.Parameters.AddWithValue("State", s.State); cmd.Parameters.AddWithValue("State", s.State);
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
} }
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)

View File

@ -1,4 +1,4 @@

:VERSION 1 #--------------------- :VERSION 1 #---------------------
BEGIN; BEGIN;
@ -800,3 +800,10 @@ BEGIN;
ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`; ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`;
COMMIT; COMMIT;
:VERSION 35 #---------------------
-- Added post 0.7
BEGIN;
ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
ALTER TABLE primshapes ADD COLUMN Media TEXT;
COMMIT;

View File

@ -0,0 +1,6 @@
BEGIN;
ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
ALTER TABLE primshapes ADD COLUMN Media TEXT;
COMMIT;

View File

@ -34,6 +34,7 @@ using System.Reflection;
using log4net; using log4net;
using Mono.Data.Sqlite; using Mono.Data.Sqlite;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -975,6 +976,8 @@ namespace OpenSim.Data.SQLite
createCol(prims, "VolumeDetect", typeof(Int16)); createCol(prims, "VolumeDetect", typeof(Int16));
createCol(prims, "MediaURL", typeof(String));
// Add in contraints // Add in contraints
prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]}; prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
@ -1021,6 +1024,7 @@ namespace OpenSim.Data.SQLite
// way to specify this as a blob atm // way to specify this as a blob atm
createCol(shapes, "Texture", typeof (Byte[])); createCol(shapes, "Texture", typeof (Byte[]));
createCol(shapes, "ExtraParams", typeof (Byte[])); createCol(shapes, "ExtraParams", typeof (Byte[]));
createCol(shapes, "Media", typeof(String));
shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]}; shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
@ -1340,6 +1344,12 @@ namespace OpenSim.Data.SQLite
if (Convert.ToInt16(row["VolumeDetect"]) != 0) if (Convert.ToInt16(row["VolumeDetect"]) != 0)
prim.VolumeDetectActive = true; prim.VolumeDetectActive = true;
if (!(row["MediaURL"] is System.DBNull))
{
//m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType());
prim.MediaUrl = (string)row["MediaURL"];
}
return prim; return prim;
} }
@ -1614,7 +1624,6 @@ namespace OpenSim.Data.SQLite
row["PayButton3"] = prim.PayPrice[3]; row["PayButton3"] = prim.PayPrice[3];
row["PayButton4"] = prim.PayPrice[4]; row["PayButton4"] = prim.PayPrice[4];
row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation); row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem); row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
@ -1675,6 +1684,7 @@ namespace OpenSim.Data.SQLite
else else
row["VolumeDetect"] = 0; row["VolumeDetect"] = 0;
row["MediaURL"] = prim.MediaUrl;
} }
/// <summary> /// <summary>
@ -1849,6 +1859,10 @@ namespace OpenSim.Data.SQLite
s.TextureEntry = textureEntry; s.TextureEntry = textureEntry;
s.ExtraParams = (byte[]) row["ExtraParams"]; s.ExtraParams = (byte[]) row["ExtraParams"];
if (!(row["Media"] is System.DBNull))
s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
return s; return s;
} }
@ -1892,17 +1906,19 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry; row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams; row["ExtraParams"] = s.ExtraParams;
if (s.Media != null)
row["Media"] = s.Media.ToXml();
} }
/// <summary> /// <summary>
/// /// Persistently store a prim.
/// </summary> /// </summary>
/// <param name="prim"></param> /// <param name="prim"></param>
/// <param name="sceneGroupID"></param> /// <param name="sceneGroupID"></param>
/// <param name="regionUUID"></param> /// <param name="regionUUID"></param>
private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
{ {
DataTable prims = ds.Tables["prims"]; DataTable prims = ds.Tables["prims"];
DataTable shapes = ds.Tables["primshapes"]; DataTable shapes = ds.Tables["primshapes"];

View File

@ -26,12 +26,17 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO;
using System.Reflection; using System.Reflection;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization; using System.Xml.Serialization;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
@ -171,6 +176,13 @@ namespace OpenSim.Framework
} }
} }
/// <summary>
/// Entries to store media textures on each face
/// </summary>
/// Do not change this value directly - always do it through an IMoapModule.
/// Lock before manipulating.
public MediaList Media { get; set; }
public PrimitiveBaseShape() public PrimitiveBaseShape()
{ {
PCode = (byte) PCodeEnum.Primitive; PCode = (byte) PCodeEnum.Primitive;
@ -1207,5 +1219,104 @@ namespace OpenSim.Framework
return prim; return prim;
} }
/// <summary>
/// Encapsulates a list of media entries.
/// </summary>
/// This class is necessary because we want to replace auto-serialization of MediaEntry with something more
/// OSD like and less vulnerable to change.
public class MediaList : List<MediaEntry>, IXmlSerializable
{
public const string MEDIA_TEXTURE_TYPE = "sl";
public MediaList() : base() {}
public MediaList(IEnumerable<MediaEntry> collection) : base(collection) {}
public MediaList(int capacity) : base(capacity) {}
public XmlSchema GetSchema()
{
return null;
}
public string ToXml()
{
lock (this)
{
using (StringWriter sw = new StringWriter())
{
using (XmlTextWriter xtw = new XmlTextWriter(sw))
{
xtw.WriteStartElement("OSMedia");
xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE);
xtw.WriteAttributeString("version", "0.1");
OSDArray meArray = new OSDArray();
foreach (MediaEntry me in this)
{
OSD osd = (null == me ? new OSD() : me.GetOSD());
meArray.Add(osd);
}
xtw.WriteStartElement("OSData");
xtw.WriteRaw(OSDParser.SerializeLLSDXmlString(meArray));
xtw.WriteEndElement();
xtw.WriteEndElement();
xtw.Flush();
return sw.ToString();
}
}
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteRaw(ToXml());
}
public static MediaList FromXml(string rawXml)
{
MediaList ml = new MediaList();
ml.ReadXml(rawXml);
return ml;
}
public void ReadXml(string rawXml)
{
using (StringReader sr = new StringReader(rawXml))
{
using (XmlTextReader xtr = new XmlTextReader(sr))
{
xtr.MoveToContent();
string type = xtr.GetAttribute("type");
//m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type);
if (type != MEDIA_TEXTURE_TYPE)
return;
xtr.ReadStartElement("OSMedia");
OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
foreach (OSD osdMe in osdMeArray)
{
MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
Add(me);
}
xtr.ReadEndElement();
}
}
}
public void ReadXml(XmlReader reader)
{
if (reader.IsEmptyElement)
return;
ReadXml(reader.ReadInnerXml());
}
}
} }
} }

View File

@ -362,7 +362,7 @@ namespace OpenSim.Framework.Servers.HttpServer
string path = request.RawUrl; string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path); string handlerKey = GetHandlerKey(request.HttpMethod, path);
//m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); // m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
if (TryGetStreamHandler(handlerKey, out requestHandler)) if (TryGetStreamHandler(handlerKey, out requestHandler))
{ {

View File

@ -4288,8 +4288,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
{ {
int notifyCount = ownersAndCount.Count; int notifyCount = ownersAndCount.Count;
ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
@ -4561,6 +4559,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
update.Scale = data.Shape.Scale; update.Scale = data.Shape.Scale;
update.Text = Util.StringToBytes256(data.Text); update.Text = Util.StringToBytes256(data.Text);
update.MediaURL = Util.StringToBytes256(data.MediaUrl);
#region PrimFlags #region PrimFlags

View File

@ -0,0 +1,596 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
using System.Xml;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Media.Moap
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
public class MoapModule : INonSharedRegionModule, IMoapModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
/// <summary>
/// Is this module enabled?
/// </summary>
protected bool m_isEnabled = true;
/// <summary>
/// The scene to which this module is attached
/// </summary>
protected Scene m_scene;
/// <summary>
/// Track the ObjectMedia capabilities given to users keyed by path
/// </summary>
protected Dictionary<string, UUID> m_omCapUsers = new Dictionary<string, UUID>();
/// <summary>
/// Track the ObjectMedia capabilities given to users keyed by agent. Lock m_omCapUsers to manipulate.
/// </summary>
protected Dictionary<UUID, string> m_omCapUrls = new Dictionary<UUID, string>();
/// <summary>
/// Track the ObjectMediaUpdate capabilities given to users keyed by path
/// </summary>
protected Dictionary<string, UUID> m_omuCapUsers = new Dictionary<string, UUID>();
/// <summary>
/// Track the ObjectMediaUpdate capabilities given to users keyed by agent. Lock m_omuCapUsers to manipulate
/// </summary>
protected Dictionary<UUID, string> m_omuCapUrls = new Dictionary<UUID, string>();
public void Initialise(IConfigSource configSource)
{
IConfig config = configSource.Configs["MediaOnAPrim"];
if (config != null && !config.GetBoolean("Enabled", false))
m_isEnabled = false;
// else
// m_log.Debug("[MOAP]: Initialised module.")l
}
public void AddRegion(Scene scene)
{
if (!m_isEnabled)
return;
m_scene = scene;
m_scene.RegisterModuleInterface<IMoapModule>(this);
}
public void RemoveRegion(Scene scene) {}
public void RegionLoaded(Scene scene)
{
if (!m_isEnabled)
return;
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectPartCopy += OnSceneObjectPartCopy;
}
public void Close()
{
if (!m_isEnabled)
return;
m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectPartCopy -= OnSceneObjectPartCopy;
}
public void OnRegisterCaps(UUID agentID, Caps caps)
{
// m_log.DebugFormat(
// "[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
string omCapUrl = "/CAPS/" + UUID.Random();
lock (m_omCapUsers)
{
m_omCapUsers[omCapUrl] = agentID;
m_omCapUrls[agentID] = omCapUrl;
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
"ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage));
}
string omuCapUrl = "/CAPS/" + UUID.Random();
lock (m_omuCapUsers)
{
m_omuCapUsers[omuCapUrl] = agentID;
m_omuCapUrls[agentID] = omuCapUrl;
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
"ObjectMediaNavigate", new RestStreamHandler("POST", omuCapUrl, HandleObjectMediaNavigateMessage));
}
}
public void OnDeregisterCaps(UUID agentID, Caps caps)
{
lock (m_omCapUsers)
{
string path = m_omCapUrls[agentID];
m_omCapUrls.Remove(agentID);
m_omCapUsers.Remove(path);
}
lock (m_omuCapUsers)
{
string path = m_omuCapUrls[agentID];
m_omuCapUrls.Remove(agentID);
m_omuCapUsers.Remove(path);
}
}
protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed)
{
if (original.Shape.Media != null)
{
PrimitiveBaseShape.MediaList dupeMedia = new PrimitiveBaseShape.MediaList();
lock (original.Shape.Media)
{
foreach (MediaEntry me in original.Shape.Media)
{
if (me != null)
dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD()));
else
dupeMedia.Add(null);
}
}
copy.Shape.Media = dupeMedia;
}
}
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
MediaEntry me = null;
CheckFaceParam(part, face);
List<MediaEntry> media = part.Shape.Media;
if (null == media)
{
me = null;
}
else
{
lock (media)
me = media[face];
// TODO: Really need a proper copy constructor down in libopenmetaverse
if (me != null)
me = MediaEntry.FromOSD(me.GetOSD());
}
// m_log.DebugFormat("[MOAP]: GetMediaEntry for {0} face {1} found {2}", part.Name, face, me);
return me;
}
public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
{
CheckFaceParam(part, face);
if (null == part.Shape.Media)
part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]);
lock (part.Shape.Media)
part.Shape.Media[face] = me;
UpdateMediaUrl(part, UUID.Zero);
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
}
public void ClearMediaEntry(SceneObjectPart part, int face)
{
SetMediaEntry(part, face, null);
}
/// <summary>
/// Sets or gets per face media textures.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <param name="httpRequest"></param>
/// <param name="httpResponse"></param>
/// <returns></returns>
protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
// m_log.DebugFormat("[MOAP]: Got ObjectMedia path [{0}], raw request [{1}]", path, request);
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
ObjectMediaMessage omm = new ObjectMediaMessage();
omm.Deserialize(osd);
if (omm.Request is ObjectMediaRequest)
return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest);
else if (omm.Request is ObjectMediaUpdate)
return HandleObjectMediaUpdate(path, omm.Request as ObjectMediaUpdate);
throw new Exception(
string.Format(
"[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}",
omm.Request.GetType()));
}
/// <summary>
/// Handle a fetch request for media textures
/// </summary>
/// <param name="omr"></param>
/// <returns></returns>
protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
{
UUID primId = omr.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
if (null == part)
{
m_log.WarnFormat(
"[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
if (null == part.Shape.Media)
return string.Empty;
ObjectMediaResponse resp = new ObjectMediaResponse();
resp.PrimID = primId;
lock (part.Shape.Media)
resp.FaceMedia = part.Shape.Media.ToArray();
resp.Version = part.MediaUrl;
string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
// m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp);
return rawResp;
}
/// <summary>
/// Handle an update of media textures.
/// </summary>
/// <param name="path">Path on which this request was made</param>
/// <param name="omu">/param>
/// <returns></returns>
protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu)
{
UUID primId = omu.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
if (null == part)
{
m_log.WarnFormat(
"[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
// m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
// for (int i = 0; i < omu.FaceMedia.Length; i++)
// {
// MediaEntry me = omu.FaceMedia[i];
// string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD()));
// m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v);
// }
if (omu.FaceMedia.Length > part.GetNumberOfSides())
{
m_log.WarnFormat(
"[MOAP]: Received {0} media entries from client for prim {1} {2} but this prim has only {3} faces. Dropping request.",
omu.FaceMedia.Length, part.Name, part.UUID, part.GetNumberOfSides());
return string.Empty;
}
UUID agentId = default(UUID);
lock (m_omCapUsers)
agentId = m_omCapUsers[path];
List<MediaEntry> media = part.Shape.Media;
if (null == media)
{
// m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name);
part.Shape.Media = new PrimitiveBaseShape.MediaList(omu.FaceMedia);
for (int i = 0; i < omu.FaceMedia.Length; i++)
{
if (omu.FaceMedia[i] != null)
{
// FIXME: Race condition here since some other texture entry manipulator may overwrite/get
// overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry
// directly.
Primitive.TextureEntry te = part.Shape.Textures;
Primitive.TextureEntryFace face = te.CreateFace((uint)i);
face.MediaFlags = true;
part.Shape.Textures = te;
// m_log.DebugFormat(
// "[MOAP]: Media flags for face {0} is {1}",
// i, part.Shape.Textures.FaceTextures[i].MediaFlags);
}
}
}
else
{
// We need to go through the media textures one at a time to make sure that we have permission
// to change them
// FIXME: Race condition here since some other texture entry manipulator may overwrite/get
// overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry
// directly.
Primitive.TextureEntry te = part.Shape.Textures;
lock (media)
{
for (int i = 0; i < media.Count; i++)
{
if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
{
media[i] = omu.FaceMedia[i];
// When a face is cleared this is done by setting the MediaFlags in the TextureEntry via a normal
// texture update, so we don't need to worry about clearing MediaFlags here.
if (null == media[i])
continue;
Primitive.TextureEntryFace face = te.CreateFace((uint)i);
face.MediaFlags = true;
// m_log.DebugFormat(
// "[MOAP]: Media flags for face {0} is {1}",
// i, face.MediaFlags);
// m_log.DebugFormat("[MOAP]: Set media entry for face {0} on {1}", i, part.Name);
}
}
}
part.Shape.Textures = te;
// for (int i2 = 0; i2 < part.Shape.Textures.FaceTextures.Length; i2++)
// m_log.DebugFormat("[MOAP]: FaceTexture[{0}] is {1}", i2, part.Shape.Textures.FaceTextures[i2]);
}
UpdateMediaUrl(part, agentId);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
return string.Empty;
}
/// <summary>
/// Received from the viewer if a user has changed the url of a media texture.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <param name="httpRequest">/param>
/// <param name="httpResponse">/param>
/// <returns></returns>
protected string HandleObjectMediaNavigateMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
// m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request [{0}]", request);
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
ObjectMediaNavigateMessage omn = new ObjectMediaNavigateMessage();
omn.Deserialize(osd);
UUID primId = omn.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
if (null == part)
{
m_log.WarnFormat(
"[MOAP]: Received an ObjectMediaNavigateMessage for prim {0} but this doesn't exist in region {1}",
primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
UUID agentId = default(UUID);
lock (m_omuCapUsers)
agentId = m_omuCapUsers[path];
if (!m_scene.Permissions.CanInteractWithPrimMedia(agentId, part.UUID, omn.Face))
return string.Empty;
// m_log.DebugFormat(
// "[MOAP]: Received request to update media entry for face {0} on prim {1} {2} to {3}",
// omn.Face, part.Name, part.UUID, omn.URL);
// If media has never been set for this prim, then just return.
if (null == part.Shape.Media)
return string.Empty;
MediaEntry me = null;
lock (part.Shape.Media)
me = part.Shape.Media[omn.Face];
// Do the same if media has not been set up for a specific face
if (null == me)
return string.Empty;
if (me.EnableWhiteList)
{
if (!CheckUrlAgainstWhitelist(omn.URL, me.WhiteList))
{
// m_log.DebugFormat(
// "[MOAP]: Blocking change of face {0} on prim {1} {2} to {3} since it's not on the enabled whitelist",
// omn.Face, part.Name, part.UUID, omn.URL);
return string.Empty;
}
}
me.CurrentURL = omn.URL;
UpdateMediaUrl(part, agentId);
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
return OSDParser.SerializeLLSDXmlString(new OSD());
}
/// <summary>
/// Check that the face number is valid for the given prim.
/// </summary>
/// <param name="part"></param>
/// <param name="face"></param>
protected void CheckFaceParam(SceneObjectPart part, int face)
{
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));
}
/// <summary>
/// Update the media url of the given part
/// </summary>
/// <param name="part"></param>
/// <param name="updateId">
/// The id to attach to this update. Normally, this is the user that changed the
/// texture
/// </param>
protected void UpdateMediaUrl(SceneObjectPart part, UUID updateId)
{
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/" + updateId;
}
else
{
string rawVersion = part.MediaUrl.Substring(5, 10);
int version = int.Parse(rawVersion);
part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, updateId);
}
// m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
}
/// <summary>
/// Check the given url against the given whitelist.
/// </summary>
/// <param name="rawUrl"></param>
/// <param name="whitelist"></param>
/// <returns>true if the url matches an entry on the whitelist, false otherwise</returns>
protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist)
{
Uri url = new Uri(rawUrl);
foreach (string origWlUrl in whitelist)
{
string wlUrl = origWlUrl;
// Deal with a line-ending wildcard
if (wlUrl.EndsWith("*"))
wlUrl = wlUrl.Remove(wlUrl.Length - 1);
// m_log.DebugFormat("[MOAP]: Checking whitelist URL pattern {0}", origWlUrl);
// Handle a line starting wildcard slightly differently since this can only match the domain, not the path
if (wlUrl.StartsWith("*"))
{
wlUrl = wlUrl.Substring(1);
if (url.Host.Contains(wlUrl))
{
// m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl);
return true;
}
}
else
{
string urlToMatch = url.Authority + url.AbsolutePath;
if (urlToMatch.StartsWith(wlUrl))
{
// m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl);
return true;
}
}
}
return false;
}
}
}

View File

@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>();
private IFriendsModule m_friendsModule; private IFriendsModule m_friendsModule;
private IGroupsModule m_groupsModule; private IGroupsModule m_groupsModule;
private IMoapModule m_moapModule;
#endregion #endregion
@ -177,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule");
List<string> modules=new List<string>(permissionModules.Split(',')); List<string> modules = new List<string>(permissionModules.Split(','));
if (!modules.Contains("DefaultPermissionsModule")) if (!modules.Contains("DefaultPermissionsModule"))
return; return;
@ -250,6 +251,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
m_scene.AddCommand(this, "bypass permissions", m_scene.AddCommand(this, "bypass permissions",
"bypass permissions <true / false>", "bypass permissions <true / false>",
"Bypass permission checks", "Bypass permission checks",
@ -394,6 +398,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_groupsModule == null) if (m_groupsModule == null)
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work"); m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
m_moapModule = m_scene.RequestModuleInterface<IMoapModule>();
// This log line will be commented out when no longer required for debugging
// if (m_moapModule == null)
// m_log.Warn("[PERMISSIONS]: Media on a prim module not found, media on a prim permissions will not work");
} }
public void Close() public void Close()
@ -1894,5 +1904,80 @@ namespace OpenSim.Region.CoreModules.World.Permissions
} }
return(false); return(false);
} }
private bool CanControlPrimMedia(UUID agentID, UUID primID, int face)
{
// m_log.DebugFormat(
// "[PERMISSONS]: Performing CanControlPrimMedia check with agentID {0}, primID {1}, face {2}",
// agentID, primID, face);
if (null == m_moapModule)
return false;
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
if (null == part)
return false;
MediaEntry me = m_moapModule.GetMediaEntry(part, face);
// If there is no existing media entry then it can be controlled (in this context, created).
if (null == me)
return true;
// m_log.DebugFormat(
// "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}",
// agentID, primID, face, me.ControlPermissions);
return GenericPrimMediaPermission(part, agentID, me.ControlPermissions);
}
private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face)
{
// m_log.DebugFormat(
// "[PERMISSONS]: Performing CanInteractWithPrimMedia check with agentID {0}, primID {1}, face {2}",
// agentID, primID, face);
if (null == m_moapModule)
return false;
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
if (null == part)
return false;
MediaEntry me = m_moapModule.GetMediaEntry(part, face);
// If there is no existing media entry then it can be controlled (in this context, created).
if (null == me)
return true;
// m_log.DebugFormat(
// "[PERMISSIONS]: Checking CanInteractWithPrimMedia for {0} on {1} face {2} with interact permissions {3}",
// agentID, primID, face, me.InteractPermissions);
return GenericPrimMediaPermission(part, agentID, me.InteractPermissions);
}
private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms)
{
// if (IsAdministrator(agentID))
// return true;
if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone)
return true;
if ((perms & MediaPermission.Owner) == MediaPermission.Owner)
{
if (agentID == part.OwnerID)
return true;
}
if ((perms & MediaPermission.Group) == MediaPermission.Group)
{
if (IsGroupMember(part.GroupID, agentID, 0))
return true;
}
return false;
}
} }
} }

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces
{
/// <summary>
/// Provides methods from manipulating media-on-a-prim
/// </summary>
public interface IMoapModule
{
/// <summary>
/// Get the media entry for a given prim face.
/// </summary>
/// A copy of the media entry is returned rather than the original, so this can be altered at will without
/// affecting the original settings.
/// <param name="part"></param>
/// <param name="face"></param>
/// <returns></returns>
MediaEntry GetMediaEntry(SceneObjectPart part, int face);
/// <summary>
/// Set the media entry for a given prim face.
/// </summary>
/// <param name="SceneObjectPart"></param>
/// <param name="face"></param>
/// <param name="me"></param>
void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me);
/// <summary>
/// Clear the media entry for a given prim face.
/// </summary>
///
/// This is the equivalent of setting a media entry of null
///
/// <param name="part"></param>
/// <param name="face">/param>
void ClearMediaEntry(SceneObjectPart part, int face);
}
}

View File

@ -332,6 +332,34 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void Attach(uint localID, UUID itemID, UUID avatarID); public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
public event Attach OnAttach; public event Attach OnAttach;
/// <summary>
/// Called immediately after an object is loaded from storage.
/// </summary>
public event SceneObjectDelegate OnSceneObjectLoaded;
public delegate void SceneObjectDelegate(SceneObjectGroup so);
/// <summary>
/// Called immediately before an object is saved to storage.
/// </summary>
/// <param name="persistingSo">
/// The scene object being persisted.
/// This is actually a copy of the original scene object so changes made here will be saved to storage but will not be kept in memory.
/// </param>
/// <param name="originalSo">
/// The original scene object being persisted. Changes here will stay in memory but will not be saved to storage on this save.
/// </param>
public event SceneObjectPreSaveDelegate OnSceneObjectPreSave;
public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo);
/// <summary>
/// Called when a scene object part is cloned within the region.
/// </summary>
/// <param name="copy"></param>
/// <param name="original"></param>
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
public delegate void RegionUp(GridRegion region); public delegate void RegionUp(GridRegion region);
public event RegionUp OnRegionUp; public event RegionUp OnRegionUp;
@ -2013,5 +2041,68 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
public void TriggerOnSceneObjectLoaded(SceneObjectGroup so)
{
SceneObjectDelegate handler = OnSceneObjectLoaded;
if (handler != null)
{
foreach (SceneObjectDelegate d in handler.GetInvocationList())
{
try
{
d(so);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerOnSceneObjectLoaded failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerOnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo)
{
SceneObjectPreSaveDelegate handler = OnSceneObjectPreSave;
if (handler != null)
{
foreach (SceneObjectPreSaveDelegate d in handler.GetInvocationList())
{
try
{
d(persistingSo, originalSo);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPreSave failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerOnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed)
{
SceneObjectPartCopyDelegate handler = OnSceneObjectPartCopy;
if (handler != null)
{
foreach (SceneObjectPartCopyDelegate d in handler.GetInvocationList())
{
try
{
d(copy, original, userExposed);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPartCopy failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
} }
} }

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -82,6 +82,8 @@ namespace OpenSim.Region.Framework.Scenes
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID); public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID); public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene); public delegate bool TeleportHandler(UUID userID, Scene scene);
public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
public delegate bool InteractWithPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion #endregion
public class ScenePermissions public class ScenePermissions
@ -141,6 +143,8 @@ namespace OpenSim.Region.Framework.Scenes
public event CopyUserInventoryHandler OnCopyUserInventory; public event CopyUserInventoryHandler OnCopyUserInventory;
public event DeleteUserInventoryHandler OnDeleteUserInventory; public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport; public event TeleportHandler OnTeleport;
public event ControlPrimMediaHandler OnControlPrimMedia;
public event InteractWithPrimMediaHandler OnInteractWithPrimMedia;
#endregion #endregion
#region Object Permission Checks #region Object Permission Checks
@ -964,5 +968,35 @@ namespace OpenSim.Region.Framework.Scenes
} }
return true; return true;
} }
public bool CanControlPrimMedia(UUID userID, UUID primID, int face)
{
ControlPrimMediaHandler handler = OnControlPrimMedia;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ControlPrimMediaHandler h in list)
{
if (h(userID, primID, face) == false)
return false;
}
}
return true;
}
public bool CanInteractWithPrimMedia(UUID userID, UUID primID, int face)
{
InteractWithPrimMediaHandler handler = OnInteractWithPrimMedia;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (InteractWithPrimMediaHandler h in list)
{
if (h(userID, primID, face) == false)
return false;
}
}
return true;
}
} }
} }

View File

@ -1887,9 +1887,11 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectGroup group in PrimsFromDB) foreach (SceneObjectGroup group in PrimsFromDB)
{ {
EventManager.TriggerOnSceneObjectLoaded(group);
if (group.RootPart == null) if (group.RootPart == null)
{ {
m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children", m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
group.Children == null ? 0 : group.Children.Count); group.Children == null ? 0 : group.Children.Count);
} }

View File

@ -1479,6 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
HasGroupChanged = false; HasGroupChanged = false;
m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
backup_group.ForEachPart(delegate(SceneObjectPart part) backup_group.ForEachPart(delegate(SceneObjectPart part)
@ -1527,6 +1528,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Duplicates this object, including operations such as physics set up and attaching to the backup event. /// Duplicates this object, including operations such as physics set up and attaching to the backup event.
/// </summary> /// </summary>
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
/// <returns></returns> /// <returns></returns>
public SceneObjectGroup Copy(bool userExposed) public SceneObjectGroup Copy(bool userExposed)
{ {

View File

@ -59,6 +59,7 @@ namespace OpenSim.Region.Framework.Scenes
REGION = 256, REGION = 256,
TELEPORT = 512, TELEPORT = 512,
REGION_RESTART = 1024, REGION_RESTART = 1024,
MEDIA = 2048,
ANIMATION = 16384 ANIMATION = 16384
} }
@ -322,6 +323,11 @@ namespace OpenSim.Region.Framework.Scenes
protected Vector3 m_lastAngularVelocity; protected Vector3 m_lastAngularVelocity;
protected int m_lastTerseSent; protected int m_lastTerseSent;
/// <summary>
/// Stores media texture data
/// </summary>
protected string m_mediaUrl;
// TODO: Those have to be changed into persistent properties at some later point, // TODO: Those have to be changed into persistent properties at some later point,
// or sit-camera on vehicles will break on sim-crossing. // or sit-camera on vehicles will break on sim-crossing.
private Vector3 m_cameraEyeOffset; private Vector3 m_cameraEyeOffset;
@ -965,12 +971,33 @@ namespace OpenSim.Region.Framework.Scenes
TriggerScriptChangedEvent(Changed.SCALE); TriggerScriptChangedEvent(Changed.SCALE);
} }
} }
public byte UpdateFlag public byte UpdateFlag
{ {
get { return m_updateFlag; } get { return m_updateFlag; }
set { m_updateFlag = value; } set { m_updateFlag = value; }
} }
/// <summary>
/// Used for media on a prim.
/// </summary>
/// Do not change this value directly - always do it through an IMoapModule.
public string MediaUrl
{
get
{
return m_mediaUrl;
}
set
{
m_mediaUrl = value;
if (ParentGroup != null)
ParentGroup.HasGroupChanged = true;
}
}
[XmlIgnore] [XmlIgnore]
public bool CreateSelected public bool CreateSelected
{ {
@ -1527,6 +1554,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Duplicates this part. /// Duplicates this part.
/// </summary> /// </summary>
/// <param name="localID"></param>
/// <param name="AgentID"></param>
/// <param name="GroupID"></param>
/// <param name="linkNum"></param>
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
/// <returns></returns> /// <returns></returns>
public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
{ {
@ -1590,6 +1622,10 @@ namespace OpenSim.Region.Framework.Scenes
dupe.DoPhysicsPropertyUpdate(UsePhysics, true); dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
} }
ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
return dupe; return dupe;
} }

View File

@ -7842,6 +7842,241 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return res; return res;
} }
public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
{
m_host.AddScriptLPS(1);
ScriptSleep(1000);
// 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.GetNumberOfSides() - 1)
return new LSL_List();
return GetPrimMediaParams(face, rules);
}
private LSL_List GetPrimMediaParams(int face, LSL_List rules)
{
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
if (null == module)
throw new Exception("Media on a prim functions not available");
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++)
{
int code = (int)rules.GetLSLIntegerItem(i);
switch (code)
{
case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
// Not implemented
res.Add(new LSL_Integer(0));
break;
case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
if (me.Controls == MediaControls.Standard)
res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD));
else
res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI));
break;
case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
res.Add(new LSL_String(me.CurrentURL));
break;
case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
res.Add(new LSL_String(me.HomeURL));
break;
case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
break;
case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
break;
case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
break;
case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
break;
case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
break;
case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
res.Add(new LSL_Integer(me.Width));
break;
case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
res.Add(new LSL_Integer(me.Height));
break;
case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
break;
case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
string[] urls = (string[])me.WhiteList.Clone();
for (int j = 0; j < urls.Length; j++)
urls[j] = Uri.EscapeDataString(urls[j]);
res.Add(new LSL_String(string.Join(", ", urls)));
break;
case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
res.Add(new LSL_Integer((int)me.InteractPermissions));
break;
case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
res.Add(new LSL_Integer((int)me.ControlPermissions));
break;
}
}
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);
}
private LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
{
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
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<string> whiteListUrls = new List<string>();
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;
}
public LSL_Integer llClearPrimMedia(LSL_Integer face)
{
m_host.AddScriptLPS(1);
ScriptSleep(1000);
// LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid
// Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
// FIXME: Don't perform the media check directly
if (face < 0 || face > m_host.GetNumberOfSides() - 1)
return ScriptBaseClass.LSL_STATUS_OK;
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
if (null == module)
throw new Exception("Media on a prim functions not available");
module.ClearMediaEntry(m_host, face);
return ScriptBaseClass.LSL_STATUS_OK;
}
// <remarks> // <remarks>
// <para> // <para>
// The .NET definition of base 64 is: // The .NET definition of base 64 is:

View File

@ -62,6 +62,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llBreakLink(int linknum); void llBreakLink(int linknum);
LSL_Integer llCeil(double f); LSL_Integer llCeil(double f);
void llClearCameraParams(); void llClearCameraParams();
LSL_Integer llClearPrimMedia(LSL_Integer face);
void llCloseRemoteDataChannel(string channel); void llCloseRemoteDataChannel(string channel);
LSL_Float llCloud(LSL_Vector offset); LSL_Float llCloud(LSL_Vector offset);
void llCollisionFilter(string name, string id, int accept); void llCollisionFilter(string name, string id, int accept);
@ -162,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_List llGetParcelPrimOwners(LSL_Vector pos); LSL_List llGetParcelPrimOwners(LSL_Vector pos);
LSL_Integer llGetPermissions(); LSL_Integer llGetPermissions();
LSL_Key llGetPermissionsKey(); LSL_Key llGetPermissionsKey();
LSL_List llGetPrimMediaParams(int face, LSL_List rules);
LSL_Vector llGetPos(); LSL_Vector llGetPos();
LSL_List llGetPrimitiveParams(LSL_List rules); LSL_List llGetPrimitiveParams(LSL_List rules);
LSL_Integer llGetRegionAgentCount(); LSL_Integer llGetRegionAgentCount();
@ -332,6 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetParcelMusicURL(string url); void llSetParcelMusicURL(string url);
void llSetPayPrice(int price, LSL_List quick_pay_buttons); void llSetPayPrice(int price, LSL_List quick_pay_buttons);
void llSetPos(LSL_Vector pos); void llSetPos(LSL_Vector pos);
LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
void llSetPrimitiveParams(LSL_List rules); void llSetPrimitiveParams(LSL_List rules);
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
void llSetPrimURL(string url); void llSetPrimURL(string url);

View File

@ -277,6 +277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int CHANGED_TELEPORT = 512; public const int CHANGED_TELEPORT = 512;
public const int CHANGED_REGION_RESTART = 1024; public const int CHANGED_REGION_RESTART = 1024;
public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
public const int CHANGED_MEDIA = 2048;
public const int CHANGED_ANIMATION = 16384; public const int CHANGED_ANIMATION = 16384;
public const int TYPE_INVALID = 0; public const int TYPE_INVALID = 0;
public const int TYPE_INTEGER = 1; public const int TYPE_INTEGER = 1;
@ -519,6 +520,41 @@ 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_TEXCOORD = new vector(-1.0, -1.0, 0.0);
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
// 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;
public const int PRIM_MEDIA_HOME_URL = 3;
public const int PRIM_MEDIA_AUTO_LOOP = 4;
public const int PRIM_MEDIA_AUTO_PLAY = 5;
public const int PRIM_MEDIA_AUTO_SCALE = 6;
public const int PRIM_MEDIA_AUTO_ZOOM = 7;
public const int PRIM_MEDIA_FIRST_CLICK_INTERACT = 8;
public const int PRIM_MEDIA_WIDTH_PIXELS = 9;
public const int PRIM_MEDIA_HEIGHT_PIXELS = 10;
public const int PRIM_MEDIA_WHITELIST_ENABLE = 11;
public const int PRIM_MEDIA_WHITELIST = 12;
public const int PRIM_MEDIA_PERMS_INTERACT = 13;
public const int PRIM_MEDIA_PERMS_CONTROL = 14;
public const int PRIM_MEDIA_CONTROLS_STANDARD = 0;
public const int PRIM_MEDIA_CONTROLS_MINI = 1;
public const int PRIM_MEDIA_PERM_NONE = 0;
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 // Constants for default textures
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f"; public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
public const string TEXTURE_DEFAULT = "89556747-24cb-43ed-920b-47caed15465f"; public const string TEXTURE_DEFAULT = "89556747-24cb-43ed-920b-47caed15465f";

View File

@ -1832,5 +1832,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2); return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
} }
public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
{
return m_LSL_Functions.llGetPrimMediaParams(face, rules);
}
public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
{
return m_LSL_Functions.llSetPrimMediaParams(face, rules);
}
public LSL_Integer llClearPrimMedia(LSL_Integer face)
{
return m_LSL_Functions.llClearPrimMedia(face);
}
} }
} }

View File

@ -15,6 +15,67 @@
</summary> </summary>
</member> </member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
<summary>
</summary>
<param name="reader"></param>
<param name="delimiter"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
<summary>
</summary>
<param name="reader"></param>
<param name="buffer"></param>
<param name="offset"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
<summary>
</summary>
<param name="s"></param>
<param name="c"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
<summary>
</summary>
<param name="s"></param>
<param name="c"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])"> <member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])">
<summary> <summary>
@ -151,67 +212,6 @@
<param name="reader"></param> <param name="reader"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
<summary>
</summary>
<param name="reader"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
<summary>
</summary>
<param name="reader"></param>
<param name="delimiter"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
<summary>
</summary>
<param name="reader"></param>
<param name="buffer"></param>
<param name="offset"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
<summary>
</summary>
<param name="s"></param>
<param name="c"></param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
<summary>
</summary>
<param name="s"></param>
<param name="c"></param>
<returns></returns>
</member>
<member name="T:OpenMetaverse.StructuredData.OSDType"> <member name="T:OpenMetaverse.StructuredData.OSDType">
<summary> <summary>

Binary file not shown.

View File

@ -1,98 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>OpenMetaverse.Utilities</name>
</assembly>
<members>
<member name="F:OpenMetaverse.Utilities.VoiceManager.BlockingTimeout">
<summary>Amount of time to wait for the voice daemon to respond.
The value needs to stay relatively high because some of the calls
require the voice daemon to make remote queries before replying</summary>
</member>
<member name="M:OpenMetaverse.Utilities.VoiceManager.RequestRenderAudioStart(System.String,System.Boolean)">
<summary>
Does not appear to be working
</summary>
<param name="fileName"></param>
<param name="loop"></param>
</member>
<member name="M:OpenMetaverse.RegistrationApi.CreateUser(OpenMetaverse.RegistrationApi.CreateUserParam)">
<summary>
Returns the new user ID or throws an exception containing the error code
The error codes can be found here: https://wiki.secondlife.com/wiki/RegAPIError
</summary>
<param name="user">New user account to create</param>
<returns>The UUID of the new user account</returns>
</member>
<member name="T:OpenMetaverse.RegistrationApi.CreateUserParam">
<summary>
See https://secure-web6.secondlife.com/developers/third_party_reg/#service_create_user or
https://wiki.secondlife.com/wiki/RegAPIDoc for description
</summary>
</member>
<member name="T:OpenMetaverse.Utilities.WaterType">
<summary>
</summary>
</member>
<member name="F:OpenMetaverse.Utilities.WaterType.Unknown">
<summary></summary>
</member>
<member name="F:OpenMetaverse.Utilities.WaterType.Dry">
<summary></summary>
</member>
<member name="F:OpenMetaverse.Utilities.WaterType.Waterfront">
<summary></summary>
</member>
<member name="F:OpenMetaverse.Utilities.WaterType.Underwater">
<summary></summary>
</member>
<member name="M:OpenMetaverse.Utilities.Realism.Shoot(OpenMetaverse.GridClient,OpenMetaverse.Vector3)">
<summary>
Aims at the specified position, enters mouselook, presses and
releases the left mouse button, and leaves mouselook
</summary>
<param name="client"></param>
<param name="target">Target to shoot at</param>
<returns></returns>
</member>
<member name="M:OpenMetaverse.Utilities.Realism.Shoot(OpenMetaverse.GridClient)">
<summary>
Enters mouselook, presses and releases the left mouse button, and leaves mouselook
</summary>
<returns></returns>
</member>
<member name="M:OpenMetaverse.Utilities.Realism.Chat(OpenMetaverse.GridClient,System.String)">
<summary>
A psuedo-realistic chat function that uses the typing sound and
animation, types at three characters per second, and randomly
pauses. This function will block until the message has been sent
</summary>
<param name="client">A reference to the client that will chat</param>
<param name="message">The chat message to send</param>
</member>
<member name="M:OpenMetaverse.Utilities.Realism.Chat(OpenMetaverse.GridClient,System.String,OpenMetaverse.ChatType,System.Int32)">
<summary>
A psuedo-realistic chat function that uses the typing sound and
animation, types at a given rate, and randomly pauses. This
function will block until the message has been sent
</summary>
<param name="client">A reference to the client that will chat</param>
<param name="message">The chat message to send</param>
<param name="type">The chat type (usually Normal, Whisper or Shout)</param>
<param name="cps">Characters per second rate for chatting</param>
</member>
<member name="F:OpenMetaverse.Utilities.VoiceServiceType.Unknown">
<summary>Unknown voice service level</summary>
</member>
<member name="F:OpenMetaverse.Utilities.VoiceServiceType.TypeA">
<summary>Spatialized local chat</summary>
</member>
<member name="F:OpenMetaverse.Utilities.VoiceServiceType.TypeB">
<summary>Remote multi-party chat</summary>
</member>
<member name="F:OpenMetaverse.Utilities.VoiceServiceType.TypeC">
<summary>One-to-one and small group chat</summary>
</member>
</members>
</doc>

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1245,6 +1245,11 @@
; enabled=false ; enabled=false
[MediaOnAPrim]
; Enable media on a prim facilities
Enabled = true;
;; ;;
;; These are defaults that are overwritten below in [Architecture]. ;; These are defaults that are overwritten below in [Architecture].
;; These defaults allow OpenSim to work out of the box with ;; These defaults allow OpenSim to work out of the box with

View File

@ -2214,6 +2214,7 @@
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenMetaverseTypes.dll"/> <Reference name="OpenMetaverseTypes.dll"/>
<Reference name="OpenMetaverse.dll"/> <Reference name="OpenMetaverse.dll"/>
<Reference name="OpenMetaverse.StructuredData.dll"/>
<Reference name="Mono.Data.Sqlite"/> <Reference name="Mono.Data.Sqlite"/>
<Reference name="Mono.Addins.dll" /> <Reference name="Mono.Addins.dll" />
<Reference name="log4net.dll"/> <Reference name="log4net.dll"/>