Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
commit
f9f776e407
|
@ -327,7 +327,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
|
|||
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
|
||||
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
|
||||
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
|
||||
LinkNumber = @LinkNumber
|
||||
LinkNumber = @LinkNumber, MediaURL = @MediaURL
|
||||
WHERE UUID = @UUID
|
||||
END
|
||||
ELSE
|
||||
|
@ -342,7 +342,7 @@ ELSE
|
|||
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
|
||||
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
|
||||
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 (
|
||||
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
|
||||
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
|
||||
|
@ -352,7 +352,7 @@ ELSE
|
|||
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
|
||||
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
|
||||
@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";
|
||||
|
||||
|
@ -385,7 +385,7 @@ IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID)
|
|||
PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions,
|
||||
PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin,
|
||||
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
|
||||
END
|
||||
ELSE
|
||||
|
@ -394,11 +394,11 @@ ELSE
|
|||
primshapes (
|
||||
UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY,
|
||||
PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin,
|
||||
ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State
|
||||
ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State, Media
|
||||
) VALUES (
|
||||
@UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY,
|
||||
@PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin,
|
||||
@ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State
|
||||
@ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State, @Media
|
||||
)
|
||||
END";
|
||||
|
||||
|
@ -1128,6 +1128,9 @@ VALUES
|
|||
prim.PassTouches = true;
|
||||
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
||||
|
||||
if (!(primRow["MediaURL"] is System.DBNull))
|
||||
prim.MediaUrl = (string)primRow["MediaURL"];
|
||||
|
||||
return prim;
|
||||
}
|
||||
|
||||
|
@ -1180,6 +1183,9 @@ VALUES
|
|||
{
|
||||
}
|
||||
|
||||
if (!(shapeRow["Media"] is System.DBNull))
|
||||
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
||||
|
||||
return baseShape;
|
||||
}
|
||||
|
||||
|
@ -1510,6 +1516,7 @@ VALUES
|
|||
else
|
||||
parameters.Add(_Database.CreateParameter("PassTouches", 0));
|
||||
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
|
||||
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
|
@ -1557,6 +1564,7 @@ VALUES
|
|||
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
|
||||
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
||||
parameters.Add(_Database.CreateParameter("State", s.State));
|
||||
parameters.Add(_Database.CreateParameter("Media", null == s.Media ? null : s.Media.ToXml()));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
:VERSION 1
|
||||
|
||||
CREATE TABLE [dbo].[prims](
|
||||
|
@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
|
|||
|
||||
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
|
|
@ -174,7 +174,7 @@ namespace OpenSim.Data.MySQL
|
|||
"ParticleSystem, ClickAction, Material, " +
|
||||
"CollisionSound, CollisionSoundVolume, " +
|
||||
"PassTouches, " +
|
||||
"LinkNumber) values (" + "?UUID, " +
|
||||
"LinkNumber, MediaURL) values (" + "?UUID, " +
|
||||
"?CreationDate, ?Name, ?Text, " +
|
||||
"?Description, ?SitName, ?TouchName, " +
|
||||
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
|
||||
|
@ -205,7 +205,7 @@ namespace OpenSim.Data.MySQL
|
|||
"?SaleType, ?ColorR, ?ColorG, " +
|
||||
"?ColorB, ?ColorA, ?ParticleSystem, " +
|
||||
"?ClickAction, ?Material, ?CollisionSound, " +
|
||||
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber)";
|
||||
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
|
||||
|
||||
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
||||
|
||||
|
@ -222,7 +222,7 @@ namespace OpenSim.Data.MySQL
|
|||
"PathTaperX, PathTaperY, PathTwist, " +
|
||||
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
|
||||
"ProfileCurve, ProfileHollow, Texture, " +
|
||||
"ExtraParams, State) values (?UUID, " +
|
||||
"ExtraParams, State, Media) values (?UUID, " +
|
||||
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
|
||||
"?PCode, ?PathBegin, ?PathEnd, " +
|
||||
"?PathScaleX, ?PathScaleY, " +
|
||||
|
@ -233,7 +233,7 @@ namespace OpenSim.Data.MySQL
|
|||
"?PathTwistBegin, ?ProfileBegin, " +
|
||||
"?ProfileEnd, ?ProfileCurve, " +
|
||||
"?ProfileHollow, ?Texture, ?ExtraParams, " +
|
||||
"?State)";
|
||||
"?State, ?Media)";
|
||||
|
||||
FillShapeCommand(cmd, prim);
|
||||
|
||||
|
@ -1185,6 +1185,9 @@ namespace OpenSim.Data.MySQL
|
|||
prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
|
||||
prim.LinkNum = (int)row["LinkNumber"];
|
||||
|
||||
if (!(row["MediaURL"] is System.DBNull))
|
||||
prim.MediaUrl = (string)row["MediaURL"];
|
||||
|
||||
return prim;
|
||||
}
|
||||
|
||||
|
@ -1521,6 +1524,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("PassTouches", 0);
|
||||
|
||||
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
|
||||
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1701,6 +1705,9 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
s.State = (byte)(int)row["State"];
|
||||
|
||||
if (!(row["Media"] is System.DBNull))
|
||||
s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -1743,6 +1750,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
|
||||
cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
|
||||
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)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
:VERSION 1 #---------------------
|
||||
|
||||
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`;
|
||||
COMMIT;
|
||||
|
||||
:VERSION 35 #---------------------
|
||||
-- Added post 0.7
|
||||
|
||||
BEGIN;
|
||||
ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
|
||||
ALTER TABLE primshapes ADD COLUMN Media TEXT;
|
||||
COMMIT;
|
|
@ -0,0 +1,6 @@
|
|||
BEGIN;
|
||||
|
||||
ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
|
||||
ALTER TABLE primshapes ADD COLUMN Media TEXT;
|
||||
|
||||
COMMIT;
|
|
@ -34,6 +34,7 @@ using System.Reflection;
|
|||
using log4net;
|
||||
using Mono.Data.Sqlite;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
@ -975,6 +976,8 @@ namespace OpenSim.Data.SQLite
|
|||
|
||||
createCol(prims, "VolumeDetect", typeof(Int16));
|
||||
|
||||
createCol(prims, "MediaURL", typeof(String));
|
||||
|
||||
// Add in contraints
|
||||
prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
|
||||
|
||||
|
@ -1021,6 +1024,7 @@ namespace OpenSim.Data.SQLite
|
|||
// way to specify this as a blob atm
|
||||
createCol(shapes, "Texture", typeof (Byte[]));
|
||||
createCol(shapes, "ExtraParams", typeof (Byte[]));
|
||||
createCol(shapes, "Media", typeof(String));
|
||||
|
||||
shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
|
||||
|
||||
|
@ -1340,6 +1344,12 @@ namespace OpenSim.Data.SQLite
|
|||
if (Convert.ToInt16(row["VolumeDetect"]) != 0)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1614,7 +1624,6 @@ namespace OpenSim.Data.SQLite
|
|||
row["PayButton3"] = prim.PayPrice[3];
|
||||
row["PayButton4"] = prim.PayPrice[4];
|
||||
|
||||
|
||||
row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
|
||||
row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
|
||||
|
||||
|
@ -1675,6 +1684,7 @@ namespace OpenSim.Data.SQLite
|
|||
else
|
||||
row["VolumeDetect"] = 0;
|
||||
|
||||
row["MediaURL"] = prim.MediaUrl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1849,6 +1859,10 @@ namespace OpenSim.Data.SQLite
|
|||
s.TextureEntry = textureEntry;
|
||||
|
||||
s.ExtraParams = (byte[]) row["ExtraParams"];
|
||||
|
||||
if (!(row["Media"] is System.DBNull))
|
||||
s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -1892,17 +1906,19 @@ namespace OpenSim.Data.SQLite
|
|||
|
||||
row["Texture"] = s.TextureEntry;
|
||||
row["ExtraParams"] = s.ExtraParams;
|
||||
|
||||
if (s.Media != null)
|
||||
row["Media"] = s.Media.ToXml();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Persistently store a prim.
|
||||
/// </summary>
|
||||
/// <param name="prim"></param>
|
||||
/// <param name="sceneGroupID"></param>
|
||||
/// <param name="regionUUID"></param>
|
||||
private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
|
||||
{
|
||||
|
||||
DataTable prims = ds.Tables["prims"];
|
||||
DataTable shapes = ds.Tables["primshapes"];
|
||||
|
||||
|
|
|
@ -26,12 +26,17 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
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()
|
||||
{
|
||||
PCode = (byte) PCodeEnum.Primitive;
|
||||
|
@ -1207,5 +1219,104 @@ namespace OpenSim.Framework
|
|||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Serialization
|
||||
|
@ -172,5 +173,29 @@ namespace OpenSim.Framework.Serialization
|
|||
{
|
||||
return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract a plain path from an IAR path
|
||||
/// </summary>
|
||||
/// <param name="iarPath"></param>
|
||||
/// <returns></returns>
|
||||
public static string ExtractPlainPathFromIarPath(string iarPath)
|
||||
{
|
||||
List<string> plainDirs = new List<string>();
|
||||
|
||||
string[] iarDirs = iarPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (string iarDir in iarDirs)
|
||||
{
|
||||
if (!iarDir.Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR))
|
||||
plainDirs.Add(iarDir);
|
||||
|
||||
int i = iarDir.LastIndexOf(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
|
||||
|
||||
plainDirs.Add(iarDir.Remove(i));
|
||||
}
|
||||
|
||||
return string.Join("/", plainDirs.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -362,7 +362,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
string path = request.RawUrl;
|
||||
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))
|
||||
{
|
||||
|
|
|
@ -4328,8 +4328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
|
||||
{
|
||||
|
||||
|
||||
int notifyCount = ownersAndCount.Count;
|
||||
ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
|
||||
|
||||
|
@ -4601,6 +4599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
|
||||
update.Scale = data.Shape.Scale;
|
||||
update.Text = Util.StringToBytes256(data.Text);
|
||||
update.MediaURL = Util.StringToBytes256(data.MediaUrl);
|
||||
|
||||
#region PrimFlags
|
||||
|
||||
|
|
|
@ -55,6 +55,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
private UserAccount m_userInfo;
|
||||
private string m_invPath;
|
||||
|
||||
/// <summary>
|
||||
/// Do we want to merge this load with existing inventory?
|
||||
/// </summary>
|
||||
protected bool m_merge;
|
||||
|
||||
/// <value>
|
||||
/// We only use this to request modules
|
||||
/// </value>
|
||||
|
@ -66,19 +71,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
private Stream m_loadStream;
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
Scene scene, UserAccount userInfo, string invPath, string loadPath)
|
||||
Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
|
||||
: this(
|
||||
scene,
|
||||
userInfo,
|
||||
invPath,
|
||||
new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress))
|
||||
new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress),
|
||||
merge)
|
||||
{
|
||||
}
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
Scene scene, UserAccount userInfo, string invPath, Stream loadStream)
|
||||
Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_merge = merge;
|
||||
m_userInfo = userInfo;
|
||||
m_invPath = invPath;
|
||||
m_loadStream = loadStream;
|
||||
|
@ -91,7 +98,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
/// A list of the inventory nodes loaded. If folders were loaded then only the root folders are
|
||||
/// returned
|
||||
/// </returns>
|
||||
public List<InventoryNodeBase> Execute()
|
||||
public HashSet<InventoryNodeBase> Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -100,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
int failedAssetRestores = 0;
|
||||
int successfulItemRestores = 0;
|
||||
|
||||
List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>();
|
||||
HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
|
||||
|
||||
List<InventoryFolderBase> folderCandidates
|
||||
= InventoryArchiveUtils.FindFolderByPath(
|
||||
|
@ -158,9 +165,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
{
|
||||
successfulItemRestores++;
|
||||
|
||||
// If we're loading an item directly into the given destination folder then we need to record
|
||||
// it separately from any loaded root folders
|
||||
if (rootDestinationFolder == foundFolder)
|
||||
// If we aren't loading the folder containing the item then well need to update the
|
||||
// viewer separately for that item.
|
||||
if (!loadedNodes.Contains(foundFolder))
|
||||
loadedNodes.Add(item);
|
||||
}
|
||||
}
|
||||
|
@ -205,14 +212,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
string iarPath,
|
||||
InventoryFolderBase rootDestFolder,
|
||||
Dictionary <string, InventoryFolderBase> resolvedFolders,
|
||||
List<InventoryNodeBase> loadedNodes)
|
||||
HashSet<InventoryNodeBase> loadedNodes)
|
||||
{
|
||||
string iarPathExisting = iarPath;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
|
||||
|
||||
InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
|
||||
InventoryFolderBase destFolder
|
||||
= ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
|
||||
|
@ -251,46 +259,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
{
|
||||
// string originalArchivePath = archivePath;
|
||||
|
||||
InventoryFolderBase destFolder = null;
|
||||
|
||||
if (archivePath.Length > 0)
|
||||
while (archivePath.Length > 0)
|
||||
{
|
||||
while (null == destFolder && archivePath.Length > 0)
|
||||
{
|
||||
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath);
|
||||
m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath);
|
||||
|
||||
if (resolvedFolders.ContainsKey(archivePath))
|
||||
if (resolvedFolders.ContainsKey(archivePath))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
|
||||
return resolvedFolders[archivePath];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_merge)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
|
||||
destFolder = resolvedFolders[archivePath];
|
||||
// TODO: Using m_invPath is totally wrong - what we need to do is strip the uuid from the
|
||||
// iar name and try to find that instead.
|
||||
string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath);
|
||||
List<InventoryFolderBase> folderCandidates
|
||||
= InventoryArchiveUtils.FindFolderByPath(
|
||||
m_scene.InventoryService, m_userInfo.PrincipalID, plainPath);
|
||||
|
||||
if (folderCandidates.Count != 0)
|
||||
{
|
||||
InventoryFolderBase destFolder = folderCandidates[0];
|
||||
resolvedFolders[archivePath] = destFolder;
|
||||
return destFolder;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't include the last slash so find the penultimate one
|
||||
int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
|
||||
|
||||
if (penultimateSlashIndex >= 0)
|
||||
{
|
||||
// Remove the last section of path so that we can see if we've already resolved the parent
|
||||
archivePath = archivePath.Remove(penultimateSlashIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't include the last slash so find the penultimate one
|
||||
int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
|
||||
|
||||
if (penultimateSlashIndex >= 0)
|
||||
{
|
||||
// Remove the last section of path so that we can see if we've already resolved the parent
|
||||
archivePath = archivePath.Remove(penultimateSlashIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
|
||||
// originalArchivePath);
|
||||
archivePath = string.Empty;
|
||||
destFolder = rootDestFolder;
|
||||
}
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
|
||||
// originalArchivePath);
|
||||
archivePath = string.Empty;
|
||||
return rootDestFolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null == destFolder)
|
||||
destFolder = rootDestFolder;
|
||||
|
||||
return destFolder;
|
||||
return rootDestFolder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -316,24 +333,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
string iarPathExisting,
|
||||
string iarPathToReplicate,
|
||||
Dictionary <string, InventoryFolderBase> resolvedFolders,
|
||||
List<InventoryNodeBase> loadedNodes)
|
||||
HashSet<InventoryNodeBase> loadedNodes)
|
||||
{
|
||||
string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int i = 0;
|
||||
|
||||
while (i < rawDirsToCreate.Length)
|
||||
for (int i = 0; i < rawDirsToCreate.Length; i++)
|
||||
{
|
||||
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]);
|
||||
|
||||
if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR))
|
||||
continue;
|
||||
|
||||
int identicalNameIdentifierIndex
|
||||
= rawDirsToCreate[i].LastIndexOf(
|
||||
ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
|
||||
|
||||
if (identicalNameIdentifierIndex < 0)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
|
||||
|
||||
newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
|
||||
|
@ -356,8 +370,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
|
||||
if (0 == i)
|
||||
loadedNodes.Add(destFolder);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,10 +91,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
|
||||
scene.AddCommand(
|
||||
this, "load iar",
|
||||
"load iar <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
"load iar <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
//"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
"Load user inventory archive (IAR).",
|
||||
//"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
|
||||
//"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
|
||||
//+ "<first> is user's first name." + Environment.NewLine
|
||||
"<first> is user's first name." + Environment.NewLine
|
||||
+ "<last> is user's last name." + Environment.NewLine
|
||||
|
@ -138,14 +138,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
}
|
||||
|
||||
public bool ArchiveInventory(
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
|
||||
{
|
||||
return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
|
||||
}
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
|
||||
{
|
||||
return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
public bool ArchiveInventory(
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
|
||||
Dictionary<string, object> options)
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
{
|
||||
|
@ -184,8 +184,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
}
|
||||
|
||||
public bool ArchiveInventory(
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
|
||||
Dictionary<string, object> options)
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
{
|
||||
|
@ -224,13 +224,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
}
|
||||
|
||||
public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream)
|
||||
{
|
||||
return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
|
||||
}
|
||||
{
|
||||
return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
public bool DearchiveInventory(
|
||||
string firstName, string lastName, string invPath, string pass, Stream loadStream,
|
||||
Dictionary<string, object> options)
|
||||
string firstName, string lastName, string invPath, string pass, Stream loadStream,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
{
|
||||
|
@ -241,10 +241,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
if (CheckPresence(userInfo.PrincipalID))
|
||||
{
|
||||
InventoryArchiveReadRequest request;
|
||||
bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream);
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
|
@ -273,8 +274,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
}
|
||||
|
||||
public bool DearchiveInventory(
|
||||
string firstName, string lastName, string invPath, string pass, string loadPath,
|
||||
Dictionary<string, object> options)
|
||||
string firstName, string lastName, string invPath, string pass, string loadPath,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
{
|
||||
|
@ -285,10 +286,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
if (CheckPresence(userInfo.PrincipalID))
|
||||
{
|
||||
InventoryArchiveReadRequest request;
|
||||
bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath);
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
|
@ -334,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
if (mainParams.Count < 6)
|
||||
{
|
||||
m_log.Error(
|
||||
"[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]");
|
||||
"[INVENTORY ARCHIVER]: usage is load iar [--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -469,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
/// Notify the client of loaded nodes if they are logged in
|
||||
/// </summary>
|
||||
/// <param name="loadedNodes">Can be empty. In which case, nothing happens</param>
|
||||
private void UpdateClientWithLoadedNodes(UserAccount userInfo, List<InventoryNodeBase> loadedNodes)
|
||||
private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet<InventoryNodeBase> loadedNodes)
|
||||
{
|
||||
if (loadedNodes.Count == 0)
|
||||
return;
|
||||
|
|
|
@ -629,7 +629,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
|
||||
|
||||
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
|
||||
List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>();
|
||||
HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>();
|
||||
|
||||
string folder1Name = "1";
|
||||
string folder2aName = "2a";
|
||||
|
@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
|
||||
{
|
||||
// Test replication of path1
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
foldersCreated, nodesLoaded);
|
||||
|
@ -661,7 +661,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
|
||||
{
|
||||
// Test replication of path2
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
foldersCreated, nodesLoaded);
|
||||
|
@ -707,10 +707,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
|
||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
new Dictionary<string, InventoryFolderBase>(), new List<InventoryNodeBase>());
|
||||
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||
|
||||
List<InventoryFolderBase> folder1PostCandidates
|
||||
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
|
||||
|
@ -732,5 +732,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
|
||||
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test replication of a partly existing archive path to the user's inventory. This should create
|
||||
/// a merged path.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestMergeIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene("inventory");
|
||||
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
string folder2Name = "b";
|
||||
|
||||
InventoryFolderBase folder1
|
||||
= UserInventoryTestUtils.CreateInventoryFolder(
|
||||
scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
|
||||
|
||||
string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
|
||||
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
||||
|
||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||
|
||||
new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||
|
||||
List<InventoryFolderBase> folder1PostCandidates
|
||||
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
|
||||
Assert.That(folder1PostCandidates.Count, Is.EqualTo(1));
|
||||
Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID));
|
||||
|
||||
List<InventoryFolderBase> folder2PostCandidates
|
||||
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b");
|
||||
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
@ -173,16 +173,16 @@ namespace OpenSim.Region.CoreModules.Framework.Library
|
|||
m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
|
||||
simpleName = GetInventoryPathFromName(simpleName);
|
||||
|
||||
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName);
|
||||
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false);
|
||||
try
|
||||
{
|
||||
List<InventoryNodeBase> nodes = archread.Execute();
|
||||
HashSet<InventoryNodeBase> nodes = archread.Execute();
|
||||
if (nodes != null && nodes.Count == 0)
|
||||
{
|
||||
// didn't find the subfolder with the given name; place it on the top
|
||||
m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
|
||||
archread.Close();
|
||||
archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName);
|
||||
archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
|
||||
archread.Execute();
|
||||
}
|
||||
foreach (InventoryNodeBase node in nodes)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>();
|
||||
private IFriendsModule m_friendsModule;
|
||||
private IGroupsModule m_groupsModule;
|
||||
private IMoapModule m_moapModule;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -177,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
|
||||
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"))
|
||||
return;
|
||||
|
@ -250,6 +251,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
|
||||
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
|
||||
|
||||
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
|
||||
m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
|
||||
|
||||
m_scene.AddCommand(this, "bypass permissions",
|
||||
"bypass permissions <true / false>",
|
||||
"Bypass permission checks",
|
||||
|
@ -394,6 +398,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
|
||||
if (m_groupsModule == null)
|
||||
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()
|
||||
|
@ -1894,5 +1904,80 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -336,6 +336,34 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
|
||||
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 event RegionUp OnRegionUp;
|
||||
|
||||
|
@ -2037,5 +2065,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* 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 DeleteUserInventoryHandler(UUID itemID, UUID userID);
|
||||
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
|
||||
|
||||
public class ScenePermissions
|
||||
|
@ -141,6 +143,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public event CopyUserInventoryHandler OnCopyUserInventory;
|
||||
public event DeleteUserInventoryHandler OnDeleteUserInventory;
|
||||
public event TeleportHandler OnTeleport;
|
||||
public event ControlPrimMediaHandler OnControlPrimMedia;
|
||||
public event InteractWithPrimMediaHandler OnInteractWithPrimMedia;
|
||||
#endregion
|
||||
|
||||
#region Object Permission Checks
|
||||
|
@ -964,5 +968,35 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1918,9 +1918,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
foreach (SceneObjectGroup group in PrimsFromDB)
|
||||
{
|
||||
EventManager.TriggerOnSceneObjectLoaded(group);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1745,6 +1745,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
|
||||
HasGroupChanged = false;
|
||||
|
||||
m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
|
||||
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
|
||||
|
||||
backup_group.ForEachPart(delegate(SceneObjectPart part)
|
||||
|
@ -1795,6 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <summary>
|
||||
/// Duplicates this object, including operations such as physics set up and attaching to the backup event.
|
||||
/// </summary>
|
||||
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
|
||||
/// <returns></returns>
|
||||
public SceneObjectGroup Copy(bool userExposed)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
REGION = 256,
|
||||
TELEPORT = 512,
|
||||
REGION_RESTART = 1024,
|
||||
MEDIA = 2048,
|
||||
ANIMATION = 16384
|
||||
}
|
||||
|
||||
|
@ -331,6 +332,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
protected Vector3 m_lastAngularVelocity;
|
||||
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,
|
||||
// or sit-camera on vehicles will break on sim-crossing.
|
||||
private Vector3 m_cameraEyeOffset;
|
||||
|
@ -984,12 +990,33 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
TriggerScriptChangedEvent(Changed.SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
public byte UpdateFlag
|
||||
{
|
||||
get { return m_updateFlag; }
|
||||
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]
|
||||
public bool CreateSelected
|
||||
{
|
||||
|
@ -1553,6 +1580,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <summary>
|
||||
/// Duplicates this part.
|
||||
/// </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>
|
||||
public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
|
||||
{
|
||||
|
@ -1616,6 +1648,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1059,7 +1059,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public void MakeChildAgent()
|
||||
{
|
||||
Animator.ResetAnimations();
|
||||
// It looks like m_animator is set to null somewhere, and MakeChild
|
||||
// is called after that. Probably in aborted teleports.
|
||||
if (m_animator == null)
|
||||
m_animator = new ScenePresenceAnimator(this);
|
||||
else
|
||||
Animator.ResetAnimations();
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
|
||||
|
|
|
@ -2111,7 +2111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return;
|
||||
|
||||
// Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
|
||||
LSL_Vector currentPos = llGetLocalPos();
|
||||
LSL_Vector currentPos = GetPartLocalPos(part);
|
||||
|
||||
float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
|
||||
bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
|
||||
|
@ -2144,33 +2144,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
public LSL_Vector llGetLocalPos()
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
if (m_host.IsAttachment == true) {
|
||||
if (m_host.IsRoot == true)
|
||||
{
|
||||
return new LSL_Vector(m_host.AbsolutePosition.X,
|
||||
m_host.AbsolutePosition.Y,
|
||||
m_host.AbsolutePosition.Z);
|
||||
return GetPartLocalPos(m_host);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LSL_Vector(m_host.OffsetPosition.X,
|
||||
m_host.OffsetPosition.Y,
|
||||
m_host.OffsetPosition.Z);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_host.ParentID != 0)
|
||||
protected LSL_Vector GetPartLocalPos(SceneObjectPart part)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
if (part.ParentID != 0)
|
||||
{
|
||||
return new LSL_Vector(m_host.OffsetPosition.X,
|
||||
m_host.OffsetPosition.Y,
|
||||
m_host.OffsetPosition.Z);
|
||||
return new LSL_Vector(part.OffsetPosition.X,
|
||||
part.OffsetPosition.Y,
|
||||
part.OffsetPosition.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LSL_Vector(m_host.AbsolutePosition.X,
|
||||
m_host.AbsolutePosition.Y,
|
||||
m_host.AbsolutePosition.Z);
|
||||
return new LSL_Vector(part.AbsolutePosition.X,
|
||||
part.AbsolutePosition.Y,
|
||||
part.AbsolutePosition.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8300,6 +8290,241 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
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>
|
||||
// <para>
|
||||
// The .NET definition of base 64 is:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
void llBreakLink(int linknum);
|
||||
LSL_Integer llCeil(double f);
|
||||
void llClearCameraParams();
|
||||
LSL_Integer llClearPrimMedia(LSL_Integer face);
|
||||
void llCloseRemoteDataChannel(string channel);
|
||||
LSL_Float llCloud(LSL_Vector offset);
|
||||
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_Integer llGetPermissions();
|
||||
LSL_Key llGetPermissionsKey();
|
||||
LSL_List llGetPrimMediaParams(int face, LSL_List rules);
|
||||
LSL_Vector llGetPos();
|
||||
LSL_List llGetPrimitiveParams(LSL_List rules);
|
||||
LSL_Integer llGetRegionAgentCount();
|
||||
|
@ -332,6 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
void llSetParcelMusicURL(string url);
|
||||
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
|
||||
void llSetPos(LSL_Vector pos);
|
||||
LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
|
||||
void llSetPrimitiveParams(LSL_List rules);
|
||||
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
|
||||
void llSetPrimURL(string url);
|
||||
|
|
|
@ -277,6 +277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
public const int CHANGED_TELEPORT = 512;
|
||||
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_MEDIA = 2048;
|
||||
public const int CHANGED_ANIMATION = 16384;
|
||||
public const int TYPE_INVALID = 0;
|
||||
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_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
|
||||
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
|
||||
public const string TEXTURE_DEFAULT = "89556747-24cb-43ed-920b-47caed15465f";
|
||||
|
|
|
@ -1834,5 +1834,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
|||
|
||||
private bool GetBoolResponse(XmlRpcRequest request, out string reason)
|
||||
{
|
||||
//m_log.Debug("[HGrid]: Linking to " + uri);
|
||||
//m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL);
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
|
@ -366,14 +366,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server ");
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
|
||||
reason = "Exception: " + e.Message;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
|
||||
m_log.ErrorFormat("[HGrid]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
reason = "XMLRPC Fault";
|
||||
return false;
|
||||
}
|
||||
|
@ -383,15 +383,29 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
|||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
reason = "Internal error 1";
|
||||
return false;
|
||||
}
|
||||
bool success = false;
|
||||
reason = string.Empty;
|
||||
Boolean.TryParse((string)hash["result"], out success);
|
||||
if (hash.ContainsKey("result"))
|
||||
Boolean.TryParse((string)hash["result"], out success);
|
||||
else
|
||||
{
|
||||
reason = "Internal error 2";
|
||||
m_log.WarnFormat("[USER AGENT CONNECTOR]: response from {0} does not have expected key 'result'", m_ServerURL);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace);
|
||||
m_log.ErrorFormat("[HGrid]: Got exception on GetBoolResponse response.");
|
||||
if (hash.ContainsKey("result") && hash["result"] != null)
|
||||
m_log.ErrorFormat("Reply was ", (string)hash["result"]);
|
||||
reason = "Exception: " + e.Message;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace OpenSim.Services.HypergridService
|
|||
throw new Exception(String.Format("No section GatekeeperService in config file"));
|
||||
|
||||
string accountService = serverConfig.GetString("UserAccountService", String.Empty);
|
||||
string homeUsersService = serverConfig.GetString("HomeUsersSecurityService", string.Empty);
|
||||
string homeUsersService = serverConfig.GetString("UserAgentService", string.Empty);
|
||||
string gridService = serverConfig.GetString("GridService", String.Empty);
|
||||
string presenceService = serverConfig.GetString("PresenceService", String.Empty);
|
||||
string simulationService = serverConfig.GetString("SimulationService", String.Empty);
|
||||
|
@ -283,18 +283,23 @@ namespace OpenSim.Services.HypergridService
|
|||
return false;
|
||||
}
|
||||
|
||||
Object[] args = new Object[] { userURL };
|
||||
IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); //ServerUtils.LoadPlugin<IUserAgentService>(m_AuthDll, args);
|
||||
if (userAgentService != null)
|
||||
if (userURL == m_ExternalName)
|
||||
return m_UserAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
|
||||
else
|
||||
{
|
||||
try
|
||||
Object[] args = new Object[] { userURL };
|
||||
IUserAgentService userAgentService = new UserAgentServiceConnector(userURL);
|
||||
if (userAgentService != null)
|
||||
{
|
||||
return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL);
|
||||
return false;
|
||||
try
|
||||
{
|
||||
return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,9 +61,11 @@ namespace OpenSim.Services.HypergridService
|
|||
|
||||
protected static IGridUserService m_GridUserService;
|
||||
protected static IGridService m_GridService;
|
||||
//protected static GatekeeperServiceConnector m_GatekeeperConnector;
|
||||
protected static GatekeeperServiceConnector m_GatekeeperConnector;
|
||||
protected static IGatekeeperService m_GatekeeperService;
|
||||
|
||||
protected static string m_GridName;
|
||||
|
||||
protected static bool m_BypassClientVerification;
|
||||
|
||||
public UserAgentService(IConfigSource config)
|
||||
|
@ -90,8 +92,15 @@ namespace OpenSim.Services.HypergridService
|
|||
Object[] args = new Object[] { config };
|
||||
m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
|
||||
m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
|
||||
//m_GatekeeperConnector = new GatekeeperServiceConnector();
|
||||
m_GatekeeperConnector = new GatekeeperServiceConnector();
|
||||
m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args);
|
||||
|
||||
m_GridName = serverConfig.GetString("ExternalName", string.Empty);
|
||||
if (m_GridName == string.Empty)
|
||||
{
|
||||
serverConfig = config.Configs["GatekeeperService"];
|
||||
m_GridName = serverConfig.GetString("ExternalName", string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +148,12 @@ namespace OpenSim.Services.HypergridService
|
|||
TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region);
|
||||
|
||||
//bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
|
||||
bool success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
|
||||
bool success = false;
|
||||
string gridName = "http://" + gatekeeper.ExternalHostName + ":" + gatekeeper.HttpPort;
|
||||
if (m_GridName == gridName)
|
||||
success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
|
||||
else
|
||||
success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
@ -179,7 +193,7 @@ namespace OpenSim.Services.HypergridService
|
|||
m_TravelingAgents[agentCircuit.SessionID] = travel;
|
||||
}
|
||||
travel.UserID = agentCircuit.AgentID;
|
||||
travel.GridExternalName = region.ExternalHostName + ":" + region.HttpPort;
|
||||
travel.GridExternalName = "http://" + region.ExternalHostName + ":" + region.HttpPort;
|
||||
travel.ServiceToken = agentCircuit.ServiceSessionID;
|
||||
if (old != null)
|
||||
travel.ClientToken = old.ClientToken;
|
||||
|
@ -215,6 +229,7 @@ namespace OpenSim.Services.HypergridService
|
|||
return false;
|
||||
|
||||
TravelingAgentInfo travel = m_TravelingAgents[sessionID];
|
||||
|
||||
return travel.GridExternalName == thisGridExternalName;
|
||||
}
|
||||
|
||||
|
|
|
@ -241,21 +241,6 @@ namespace OpenSim.Tools.Configger
|
|||
config.Set("EventQueue", true);
|
||||
}
|
||||
|
||||
{
|
||||
IConfig config = defaultConfig.Configs["Network"];
|
||||
|
||||
if (null == config)
|
||||
config = defaultConfig.AddConfig("Network");
|
||||
|
||||
config.Set("default_location_x", 1000);
|
||||
config.Set("default_location_y", 1000);
|
||||
config.Set("grid_send_key", "null");
|
||||
config.Set("grid_recv_key", "null");
|
||||
config.Set("user_send_key", "null");
|
||||
config.Set("user_recv_key", "null");
|
||||
config.Set("secure_inventory_server", "true");
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,67 @@
|
|||
|
||||
</summary>
|
||||
</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[])">
|
||||
<summary>
|
||||
|
||||
|
@ -151,67 +212,6 @@
|
|||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</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">
|
||||
<summary>
|
||||
|
||||
|
|
Binary file not shown.
|
@ -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.
31037
bin/OpenMetaverse.XML
31037
bin/OpenMetaverse.XML
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.
|
@ -1267,6 +1267,11 @@ UseSafetyCommit = true
|
|||
; DefaultAdministratorGroupUUID = "";
|
||||
; DefaultAdministratorParcelName = "";
|
||||
|
||||
[MediaOnAPrim]
|
||||
; Enable media on a prim facilities
|
||||
Enabled = true;
|
||||
|
||||
|
||||
;;
|
||||
;; These are defaults that are overwritten below in [Architecture].
|
||||
;; These defaults allow OpenSim to work out of the box with
|
||||
|
|
|
@ -2245,6 +2245,7 @@
|
|||
<Reference name="OpenSim.Region.Framework"/>
|
||||
<Reference name="OpenMetaverseTypes.dll"/>
|
||||
<Reference name="OpenMetaverse.dll"/>
|
||||
<Reference name="OpenMetaverse.StructuredData.dll"/>
|
||||
<Reference name="Mono.Data.Sqlite"/>
|
||||
<Reference name="Mono.Addins.dll" />
|
||||
<Reference name="log4net.dll"/>
|
||||
|
|
Loading…
Reference in New Issue