Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
commit
7477d7a036
|
@ -593,6 +593,7 @@ namespace OpenSim.Client.MXP.ClientStack
|
||||||
public event DisconnectUser OnDisconnectUser;
|
public event DisconnectUser OnDisconnectUser;
|
||||||
public event RequestAvatarProperties OnRequestAvatarProperties;
|
public event RequestAvatarProperties OnRequestAvatarProperties;
|
||||||
public event SetAlwaysRun OnSetAlwaysRun;
|
public event SetAlwaysRun OnSetAlwaysRun;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
|
public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
|
||||||
public event DeRezObject OnDeRezObject;
|
public event DeRezObject OnDeRezObject;
|
||||||
public event Action<IClientAPI> OnRegionHandShakeReply;
|
public event Action<IClientAPI> OnRegionHandShakeReply;
|
||||||
|
|
|
@ -253,6 +253,7 @@ namespace OpenSim.Client.Sirikata.ClientStack
|
||||||
public event AddNewPrim OnAddPrim;
|
public event AddNewPrim OnAddPrim;
|
||||||
public event FetchInventory OnAgentDataUpdateRequest;
|
public event FetchInventory OnAgentDataUpdateRequest;
|
||||||
public event TeleportLocationRequest OnSetStartLocationRequest;
|
public event TeleportLocationRequest OnSetStartLocationRequest;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event RequestGodlikePowers OnRequestGodlikePowers;
|
public event RequestGodlikePowers OnRequestGodlikePowers;
|
||||||
public event GodKickUser OnGodKickUser;
|
public event GodKickUser OnGodKickUser;
|
||||||
public event ObjectDuplicate OnObjectDuplicate;
|
public event ObjectDuplicate OnObjectDuplicate;
|
||||||
|
|
|
@ -290,6 +290,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
|
||||||
public event GenericCall2 OnStopMovement = delegate { };
|
public event GenericCall2 OnStopMovement = delegate { };
|
||||||
public event Action<UUID> OnRemoveAvatar = delegate { };
|
public event Action<UUID> OnRemoveAvatar = delegate { };
|
||||||
public event ObjectPermissions OnObjectPermissions = delegate { };
|
public event ObjectPermissions OnObjectPermissions = delegate { };
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy = delegate { };
|
||||||
public event CreateNewInventoryItem OnCreateNewInventoryItem = delegate { };
|
public event CreateNewInventoryItem OnCreateNewInventoryItem = delegate { };
|
||||||
public event LinkInventoryItem OnLinkInventoryItem = delegate { };
|
public event LinkInventoryItem OnLinkInventoryItem = delegate { };
|
||||||
public event CreateInventoryFolder OnCreateNewInventoryFolder = delegate { };
|
public event CreateInventoryFolder OnCreateNewInventoryFolder = delegate { };
|
||||||
|
|
|
@ -327,7 +327,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
|
||||||
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
|
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
|
||||||
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
|
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
|
||||||
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
|
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
|
||||||
LinkNumber = @LinkNumber
|
LinkNumber = @LinkNumber, MediaURL = @MediaURL
|
||||||
WHERE UUID = @UUID
|
WHERE UUID = @UUID
|
||||||
END
|
END
|
||||||
ELSE
|
ELSE
|
||||||
|
@ -342,7 +342,7 @@ ELSE
|
||||||
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
|
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
|
||||||
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
|
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
|
||||||
ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
|
ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
|
||||||
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber
|
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL
|
||||||
) VALUES (
|
) VALUES (
|
||||||
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
|
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
|
||||||
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
|
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
|
||||||
|
@ -352,7 +352,7 @@ ELSE
|
||||||
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
|
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
|
||||||
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
|
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
|
||||||
@ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
|
@ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
|
||||||
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber
|
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL
|
||||||
)
|
)
|
||||||
END";
|
END";
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID)
|
||||||
PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions,
|
PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions,
|
||||||
PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin,
|
PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin,
|
||||||
ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow,
|
ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow,
|
||||||
Texture = @Texture, ExtraParams = @ExtraParams, State = @State
|
Texture = @Texture, ExtraParams = @ExtraParams, State = @State, Media = @Media
|
||||||
WHERE UUID = @UUID
|
WHERE UUID = @UUID
|
||||||
END
|
END
|
||||||
ELSE
|
ELSE
|
||||||
|
@ -394,11 +394,11 @@ ELSE
|
||||||
primshapes (
|
primshapes (
|
||||||
UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY,
|
UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY,
|
||||||
PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin,
|
PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin,
|
||||||
ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State
|
ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State, Media
|
||||||
) VALUES (
|
) VALUES (
|
||||||
@UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY,
|
@UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY,
|
||||||
@PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin,
|
@PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin,
|
||||||
@ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State
|
@ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State, @Media
|
||||||
)
|
)
|
||||||
END";
|
END";
|
||||||
|
|
||||||
|
@ -1128,6 +1128,9 @@ VALUES
|
||||||
prim.PassTouches = true;
|
prim.PassTouches = true;
|
||||||
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
||||||
|
|
||||||
|
if (!(primRow["MediaURL"] is System.DBNull))
|
||||||
|
prim.MediaUrl = (string)primRow["MediaURL"];
|
||||||
|
|
||||||
return prim;
|
return prim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,6 +1183,9 @@ VALUES
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(shapeRow["Media"] is System.DBNull))
|
||||||
|
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
||||||
|
|
||||||
return baseShape;
|
return baseShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1510,6 +1516,7 @@ VALUES
|
||||||
else
|
else
|
||||||
parameters.Add(_Database.CreateParameter("PassTouches", 0));
|
parameters.Add(_Database.CreateParameter("PassTouches", 0));
|
||||||
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
|
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
|
||||||
|
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
|
||||||
|
|
||||||
return parameters.ToArray();
|
return parameters.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -1557,6 +1564,7 @@ VALUES
|
||||||
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
|
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
|
||||||
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
||||||
parameters.Add(_Database.CreateParameter("State", s.State));
|
parameters.Add(_Database.CreateParameter("State", s.State));
|
||||||
|
parameters.Add(_Database.CreateParameter("Media", null == s.Media ? null : s.Media.ToXml()));
|
||||||
|
|
||||||
return parameters.ToArray();
|
return parameters.ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
:VERSION 1
|
:VERSION 1
|
||||||
|
|
||||||
CREATE TABLE [dbo].[prims](
|
CREATE TABLE [dbo].[prims](
|
||||||
|
@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 24
|
||||||
|
-- Added post 0.7
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE prims ADD COLUMN MediaURL varchar(255)
|
||||||
|
ALTER TABLE primshapes ADD COLUMN Media TEXT
|
||||||
|
|
||||||
|
COMMIT
|
|
@ -174,7 +174,7 @@ namespace OpenSim.Data.MySQL
|
||||||
"ParticleSystem, ClickAction, Material, " +
|
"ParticleSystem, ClickAction, Material, " +
|
||||||
"CollisionSound, CollisionSoundVolume, " +
|
"CollisionSound, CollisionSoundVolume, " +
|
||||||
"PassTouches, " +
|
"PassTouches, " +
|
||||||
"LinkNumber) values (" + "?UUID, " +
|
"LinkNumber, MediaURL) values (" + "?UUID, " +
|
||||||
"?CreationDate, ?Name, ?Text, " +
|
"?CreationDate, ?Name, ?Text, " +
|
||||||
"?Description, ?SitName, ?TouchName, " +
|
"?Description, ?SitName, ?TouchName, " +
|
||||||
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
|
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
|
||||||
|
@ -205,7 +205,7 @@ namespace OpenSim.Data.MySQL
|
||||||
"?SaleType, ?ColorR, ?ColorG, " +
|
"?SaleType, ?ColorR, ?ColorG, " +
|
||||||
"?ColorB, ?ColorA, ?ParticleSystem, " +
|
"?ColorB, ?ColorA, ?ParticleSystem, " +
|
||||||
"?ClickAction, ?Material, ?CollisionSound, " +
|
"?ClickAction, ?Material, ?CollisionSound, " +
|
||||||
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber)";
|
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
|
||||||
|
|
||||||
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ namespace OpenSim.Data.MySQL
|
||||||
"PathTaperX, PathTaperY, PathTwist, " +
|
"PathTaperX, PathTaperY, PathTwist, " +
|
||||||
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
|
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
|
||||||
"ProfileCurve, ProfileHollow, Texture, " +
|
"ProfileCurve, ProfileHollow, Texture, " +
|
||||||
"ExtraParams, State) values (?UUID, " +
|
"ExtraParams, State, Media) values (?UUID, " +
|
||||||
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
|
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
|
||||||
"?PCode, ?PathBegin, ?PathEnd, " +
|
"?PCode, ?PathBegin, ?PathEnd, " +
|
||||||
"?PathScaleX, ?PathScaleY, " +
|
"?PathScaleX, ?PathScaleY, " +
|
||||||
|
@ -233,7 +233,7 @@ namespace OpenSim.Data.MySQL
|
||||||
"?PathTwistBegin, ?ProfileBegin, " +
|
"?PathTwistBegin, ?ProfileBegin, " +
|
||||||
"?ProfileEnd, ?ProfileCurve, " +
|
"?ProfileEnd, ?ProfileCurve, " +
|
||||||
"?ProfileHollow, ?Texture, ?ExtraParams, " +
|
"?ProfileHollow, ?Texture, ?ExtraParams, " +
|
||||||
"?State)";
|
"?State, ?Media)";
|
||||||
|
|
||||||
FillShapeCommand(cmd, prim);
|
FillShapeCommand(cmd, prim);
|
||||||
|
|
||||||
|
@ -1185,6 +1185,9 @@ namespace OpenSim.Data.MySQL
|
||||||
prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
|
prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
|
||||||
prim.LinkNum = (int)row["LinkNumber"];
|
prim.LinkNum = (int)row["LinkNumber"];
|
||||||
|
|
||||||
|
if (!(row["MediaURL"] is System.DBNull))
|
||||||
|
prim.MediaUrl = (string)row["MediaURL"];
|
||||||
|
|
||||||
return prim;
|
return prim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1521,6 +1524,7 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.AddWithValue("PassTouches", 0);
|
cmd.Parameters.AddWithValue("PassTouches", 0);
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
|
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
|
||||||
|
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1701,6 +1705,9 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
s.State = (byte)(int)row["State"];
|
s.State = (byte)(int)row["State"];
|
||||||
|
|
||||||
|
if (!(row["Media"] is System.DBNull))
|
||||||
|
s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1743,6 +1750,7 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
|
cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
|
||||||
cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
|
cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
|
||||||
cmd.Parameters.AddWithValue("State", s.State);
|
cmd.Parameters.AddWithValue("State", s.State);
|
||||||
|
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
:VERSION 1 #---------------------
|
:VERSION 1 #---------------------
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -800,3 +800,10 @@ BEGIN;
|
||||||
ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`;
|
ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 35 #---------------------
|
||||||
|
-- Added post 0.7
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
|
||||||
|
ALTER TABLE primshapes ADD COLUMN Media TEXT;
|
||||||
|
COMMIT;
|
|
@ -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 log4net;
|
||||||
using Mono.Data.Sqlite;
|
using Mono.Data.Sqlite;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
@ -975,6 +976,8 @@ namespace OpenSim.Data.SQLite
|
||||||
|
|
||||||
createCol(prims, "VolumeDetect", typeof(Int16));
|
createCol(prims, "VolumeDetect", typeof(Int16));
|
||||||
|
|
||||||
|
createCol(prims, "MediaURL", typeof(String));
|
||||||
|
|
||||||
// Add in contraints
|
// Add in contraints
|
||||||
prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
|
prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
|
||||||
|
|
||||||
|
@ -1021,6 +1024,7 @@ namespace OpenSim.Data.SQLite
|
||||||
// way to specify this as a blob atm
|
// way to specify this as a blob atm
|
||||||
createCol(shapes, "Texture", typeof (Byte[]));
|
createCol(shapes, "Texture", typeof (Byte[]));
|
||||||
createCol(shapes, "ExtraParams", typeof (Byte[]));
|
createCol(shapes, "ExtraParams", typeof (Byte[]));
|
||||||
|
createCol(shapes, "Media", typeof(String));
|
||||||
|
|
||||||
shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
|
shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
|
||||||
|
|
||||||
|
@ -1340,6 +1344,12 @@ namespace OpenSim.Data.SQLite
|
||||||
if (Convert.ToInt16(row["VolumeDetect"]) != 0)
|
if (Convert.ToInt16(row["VolumeDetect"]) != 0)
|
||||||
prim.VolumeDetectActive = true;
|
prim.VolumeDetectActive = true;
|
||||||
|
|
||||||
|
if (!(row["MediaURL"] is System.DBNull))
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType());
|
||||||
|
prim.MediaUrl = (string)row["MediaURL"];
|
||||||
|
}
|
||||||
|
|
||||||
return prim;
|
return prim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1614,7 +1624,6 @@ namespace OpenSim.Data.SQLite
|
||||||
row["PayButton3"] = prim.PayPrice[3];
|
row["PayButton3"] = prim.PayPrice[3];
|
||||||
row["PayButton4"] = prim.PayPrice[4];
|
row["PayButton4"] = prim.PayPrice[4];
|
||||||
|
|
||||||
|
|
||||||
row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
|
row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
|
||||||
row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
|
row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
|
||||||
|
|
||||||
|
@ -1675,6 +1684,7 @@ namespace OpenSim.Data.SQLite
|
||||||
else
|
else
|
||||||
row["VolumeDetect"] = 0;
|
row["VolumeDetect"] = 0;
|
||||||
|
|
||||||
|
row["MediaURL"] = prim.MediaUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1849,6 +1859,10 @@ namespace OpenSim.Data.SQLite
|
||||||
s.TextureEntry = textureEntry;
|
s.TextureEntry = textureEntry;
|
||||||
|
|
||||||
s.ExtraParams = (byte[]) row["ExtraParams"];
|
s.ExtraParams = (byte[]) row["ExtraParams"];
|
||||||
|
|
||||||
|
if (!(row["Media"] is System.DBNull))
|
||||||
|
s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1892,17 +1906,19 @@ namespace OpenSim.Data.SQLite
|
||||||
|
|
||||||
row["Texture"] = s.TextureEntry;
|
row["Texture"] = s.TextureEntry;
|
||||||
row["ExtraParams"] = s.ExtraParams;
|
row["ExtraParams"] = s.ExtraParams;
|
||||||
|
|
||||||
|
if (s.Media != null)
|
||||||
|
row["Media"] = s.Media.ToXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Persistently store a prim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prim"></param>
|
/// <param name="prim"></param>
|
||||||
/// <param name="sceneGroupID"></param>
|
/// <param name="sceneGroupID"></param>
|
||||||
/// <param name="regionUUID"></param>
|
/// <param name="regionUUID"></param>
|
||||||
private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
|
private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
|
||||||
{
|
{
|
||||||
|
|
||||||
DataTable prims = ds.Tables["prims"];
|
DataTable prims = ds.Tables["prims"];
|
||||||
DataTable shapes = ds.Tables["primshapes"];
|
DataTable shapes = ds.Tables["primshapes"];
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,9 @@ namespace OpenSim.Framework
|
||||||
public delegate void MoveInventoryItem(
|
public delegate void MoveInventoryItem(
|
||||||
IClientAPI remoteClient, List<InventoryItemBase> items);
|
IClientAPI remoteClient, List<InventoryItemBase> items);
|
||||||
|
|
||||||
|
public delegate void MoveItemsAndLeaveCopy(
|
||||||
|
IClientAPI remoteClient, List<InventoryItemBase> items, UUID destFolder);
|
||||||
|
|
||||||
public delegate void RemoveInventoryItem(
|
public delegate void RemoveInventoryItem(
|
||||||
IClientAPI remoteClient, List<UUID> itemIDs);
|
IClientAPI remoteClient, List<UUID> itemIDs);
|
||||||
|
|
||||||
|
@ -772,6 +775,7 @@ namespace OpenSim.Framework
|
||||||
event RequestTaskInventory OnRequestTaskInventory;
|
event RequestTaskInventory OnRequestTaskInventory;
|
||||||
event UpdateInventoryItem OnUpdateInventoryItem;
|
event UpdateInventoryItem OnUpdateInventoryItem;
|
||||||
event CopyInventoryItem OnCopyInventoryItem;
|
event CopyInventoryItem OnCopyInventoryItem;
|
||||||
|
event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
event MoveInventoryItem OnMoveInventoryItem;
|
event MoveInventoryItem OnMoveInventoryItem;
|
||||||
event RemoveInventoryFolder OnRemoveInventoryFolder;
|
event RemoveInventoryFolder OnRemoveInventoryFolder;
|
||||||
event RemoveInventoryItem OnRemoveInventoryItem;
|
event RemoveInventoryItem OnRemoveInventoryItem;
|
||||||
|
|
|
@ -26,12 +26,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Schema;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -171,6 +176,13 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entries to store media textures on each face
|
||||||
|
/// </summary>
|
||||||
|
/// Do not change this value directly - always do it through an IMoapModule.
|
||||||
|
/// Lock before manipulating.
|
||||||
|
public MediaList Media { get; set; }
|
||||||
|
|
||||||
public PrimitiveBaseShape()
|
public PrimitiveBaseShape()
|
||||||
{
|
{
|
||||||
PCode = (byte) PCodeEnum.Primitive;
|
PCode = (byte) PCodeEnum.Primitive;
|
||||||
|
@ -1207,5 +1219,104 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
return prim;
|
return prim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encapsulates a list of media entries.
|
||||||
|
/// </summary>
|
||||||
|
/// This class is necessary because we want to replace auto-serialization of MediaEntry with something more
|
||||||
|
/// OSD like and less vulnerable to change.
|
||||||
|
public class MediaList : List<MediaEntry>, IXmlSerializable
|
||||||
|
{
|
||||||
|
public const string MEDIA_TEXTURE_TYPE = "sl";
|
||||||
|
|
||||||
|
public MediaList() : base() {}
|
||||||
|
public MediaList(IEnumerable<MediaEntry> collection) : base(collection) {}
|
||||||
|
public MediaList(int capacity) : base(capacity) {}
|
||||||
|
|
||||||
|
public XmlSchema GetSchema()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToXml()
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
using (StringWriter sw = new StringWriter())
|
||||||
|
{
|
||||||
|
using (XmlTextWriter xtw = new XmlTextWriter(sw))
|
||||||
|
{
|
||||||
|
xtw.WriteStartElement("OSMedia");
|
||||||
|
xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE);
|
||||||
|
xtw.WriteAttributeString("version", "0.1");
|
||||||
|
|
||||||
|
OSDArray meArray = new OSDArray();
|
||||||
|
foreach (MediaEntry me in this)
|
||||||
|
{
|
||||||
|
OSD osd = (null == me ? new OSD() : me.GetOSD());
|
||||||
|
meArray.Add(osd);
|
||||||
|
}
|
||||||
|
|
||||||
|
xtw.WriteStartElement("OSData");
|
||||||
|
xtw.WriteRaw(OSDParser.SerializeLLSDXmlString(meArray));
|
||||||
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
|
xtw.Flush();
|
||||||
|
return sw.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteXml(XmlWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteRaw(ToXml());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MediaList FromXml(string rawXml)
|
||||||
|
{
|
||||||
|
MediaList ml = new MediaList();
|
||||||
|
ml.ReadXml(rawXml);
|
||||||
|
return ml;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadXml(string rawXml)
|
||||||
|
{
|
||||||
|
using (StringReader sr = new StringReader(rawXml))
|
||||||
|
{
|
||||||
|
using (XmlTextReader xtr = new XmlTextReader(sr))
|
||||||
|
{
|
||||||
|
xtr.MoveToContent();
|
||||||
|
|
||||||
|
string type = xtr.GetAttribute("type");
|
||||||
|
//m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type);
|
||||||
|
|
||||||
|
if (type != MEDIA_TEXTURE_TYPE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xtr.ReadStartElement("OSMedia");
|
||||||
|
|
||||||
|
OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
|
||||||
|
foreach (OSD osdMe in osdMeArray)
|
||||||
|
{
|
||||||
|
MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
|
||||||
|
Add(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
xtr.ReadEndElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadXml(XmlReader reader)
|
||||||
|
{
|
||||||
|
if (reader.IsEmptyElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ReadXml(reader.ReadInnerXml());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Serialization
|
namespace OpenSim.Framework.Serialization
|
||||||
|
@ -172,5 +173,29 @@ namespace OpenSim.Framework.Serialization
|
||||||
{
|
{
|
||||||
return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -154,6 +154,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public event RequestTaskInventory OnRequestTaskInventory;
|
public event RequestTaskInventory OnRequestTaskInventory;
|
||||||
public event UpdateInventoryItem OnUpdateInventoryItem;
|
public event UpdateInventoryItem OnUpdateInventoryItem;
|
||||||
public event CopyInventoryItem OnCopyInventoryItem;
|
public event CopyInventoryItem OnCopyInventoryItem;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event MoveInventoryItem OnMoveInventoryItem;
|
public event MoveInventoryItem OnMoveInventoryItem;
|
||||||
public event RemoveInventoryItem OnRemoveInventoryItem;
|
public event RemoveInventoryItem OnRemoveInventoryItem;
|
||||||
public event RemoveInventoryFolder OnRemoveInventoryFolder;
|
public event RemoveInventoryFolder OnRemoveInventoryFolder;
|
||||||
|
@ -4327,8 +4328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
|
public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int notifyCount = ownersAndCount.Count;
|
int notifyCount = ownersAndCount.Count;
|
||||||
ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
|
ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
|
||||||
|
|
||||||
|
@ -4600,6 +4599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
|
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
|
||||||
update.Scale = data.Shape.Scale;
|
update.Scale = data.Shape.Scale;
|
||||||
update.Text = Util.StringToBytes256(data.Text);
|
update.Text = Util.StringToBytes256(data.Text);
|
||||||
|
update.MediaURL = Util.StringToBytes256(data.MediaUrl);
|
||||||
|
|
||||||
#region PrimFlags
|
#region PrimFlags
|
||||||
|
|
||||||
|
@ -4840,6 +4840,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
|
AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
|
||||||
AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
|
AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
|
||||||
AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
|
AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
|
||||||
|
AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
|
||||||
AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
|
AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
|
||||||
AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
|
AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
|
||||||
AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
|
AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
|
||||||
|
@ -9350,6 +9351,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
|
||||||
|
{
|
||||||
|
CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
|
||||||
|
|
||||||
|
#region Packet Session and User Check
|
||||||
|
if (m_checkPackets)
|
||||||
|
{
|
||||||
|
if (packet.AgentData.SessionID != SessionId ||
|
||||||
|
packet.AgentData.AgentID != AgentId)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
|
||||||
|
List<InventoryItemBase> items = new List<InventoryItemBase>();
|
||||||
|
foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
|
||||||
|
{
|
||||||
|
InventoryItemBase b = new InventoryItemBase();
|
||||||
|
b.ID = n.OldItemID;
|
||||||
|
b.Folder = n.OldFolderID;
|
||||||
|
items.Add(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
|
||||||
|
if (handlerMoveItemsAndLeaveCopy != null)
|
||||||
|
{
|
||||||
|
handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
|
private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -55,6 +55,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
private UserAccount m_userInfo;
|
private UserAccount m_userInfo;
|
||||||
private string m_invPath;
|
private string m_invPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do we want to merge this load with existing inventory?
|
||||||
|
/// </summary>
|
||||||
|
protected bool m_merge;
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// We only use this to request modules
|
/// We only use this to request modules
|
||||||
/// </value>
|
/// </value>
|
||||||
|
@ -66,19 +71,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
private Stream m_loadStream;
|
private Stream m_loadStream;
|
||||||
|
|
||||||
public InventoryArchiveReadRequest(
|
public InventoryArchiveReadRequest(
|
||||||
Scene scene, UserAccount userInfo, string invPath, string loadPath)
|
Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
|
||||||
: this(
|
: this(
|
||||||
scene,
|
scene,
|
||||||
userInfo,
|
userInfo,
|
||||||
invPath,
|
invPath,
|
||||||
new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress))
|
new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress),
|
||||||
|
merge)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryArchiveReadRequest(
|
public InventoryArchiveReadRequest(
|
||||||
Scene scene, UserAccount userInfo, string invPath, Stream loadStream)
|
Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
m_merge = merge;
|
||||||
m_userInfo = userInfo;
|
m_userInfo = userInfo;
|
||||||
m_invPath = invPath;
|
m_invPath = invPath;
|
||||||
m_loadStream = loadStream;
|
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
|
/// A list of the inventory nodes loaded. If folders were loaded then only the root folders are
|
||||||
/// returned
|
/// returned
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public List<InventoryNodeBase> Execute()
|
public HashSet<InventoryNodeBase> Execute()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -100,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
int failedAssetRestores = 0;
|
int failedAssetRestores = 0;
|
||||||
int successfulItemRestores = 0;
|
int successfulItemRestores = 0;
|
||||||
|
|
||||||
List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>();
|
HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
|
||||||
|
|
||||||
List<InventoryFolderBase> folderCandidates
|
List<InventoryFolderBase> folderCandidates
|
||||||
= InventoryArchiveUtils.FindFolderByPath(
|
= InventoryArchiveUtils.FindFolderByPath(
|
||||||
|
@ -158,9 +165,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
{
|
{
|
||||||
successfulItemRestores++;
|
successfulItemRestores++;
|
||||||
|
|
||||||
// If we're loading an item directly into the given destination folder then we need to record
|
// If we aren't loading the folder containing the item then well need to update the
|
||||||
// it separately from any loaded root folders
|
// viewer separately for that item.
|
||||||
if (rootDestinationFolder == foundFolder)
|
if (!loadedNodes.Contains(foundFolder))
|
||||||
loadedNodes.Add(item);
|
loadedNodes.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,14 +212,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
string iarPath,
|
string iarPath,
|
||||||
InventoryFolderBase rootDestFolder,
|
InventoryFolderBase rootDestFolder,
|
||||||
Dictionary <string, InventoryFolderBase> resolvedFolders,
|
Dictionary <string, InventoryFolderBase> resolvedFolders,
|
||||||
List<InventoryNodeBase> loadedNodes)
|
HashSet<InventoryNodeBase> loadedNodes)
|
||||||
{
|
{
|
||||||
string iarPathExisting = iarPath;
|
string iarPathExisting = iarPath;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
|
// "[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(
|
// m_log.DebugFormat(
|
||||||
// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
|
// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
|
||||||
|
@ -251,22 +259,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
{
|
{
|
||||||
// string originalArchivePath = archivePath;
|
// string originalArchivePath = archivePath;
|
||||||
|
|
||||||
InventoryFolderBase destFolder = null;
|
while (archivePath.Length > 0)
|
||||||
|
|
||||||
if (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(
|
// m_log.DebugFormat(
|
||||||
// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
|
// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
|
||||||
destFolder = resolvedFolders[archivePath];
|
return resolvedFolders[archivePath];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (m_merge)
|
||||||
|
{
|
||||||
|
// 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
|
// Don't include the last slash so find the penultimate one
|
||||||
int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
|
int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
|
||||||
|
|
||||||
|
@ -281,16 +302,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
|
// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
|
||||||
// originalArchivePath);
|
// originalArchivePath);
|
||||||
archivePath = string.Empty;
|
archivePath = string.Empty;
|
||||||
destFolder = rootDestFolder;
|
return rootDestFolder;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null == destFolder)
|
return rootDestFolder;
|
||||||
destFolder = rootDestFolder;
|
|
||||||
|
|
||||||
return destFolder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -316,24 +333,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
string iarPathExisting,
|
string iarPathExisting,
|
||||||
string iarPathToReplicate,
|
string iarPathToReplicate,
|
||||||
Dictionary <string, InventoryFolderBase> resolvedFolders,
|
Dictionary <string, InventoryFolderBase> resolvedFolders,
|
||||||
List<InventoryNodeBase> loadedNodes)
|
HashSet<InventoryNodeBase> loadedNodes)
|
||||||
{
|
{
|
||||||
string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
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]);
|
// 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
|
int identicalNameIdentifierIndex
|
||||||
= rawDirsToCreate[i].LastIndexOf(
|
= rawDirsToCreate[i].LastIndexOf(
|
||||||
ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
|
ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
|
||||||
|
|
||||||
if (identicalNameIdentifierIndex < 0)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
|
string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
|
||||||
|
|
||||||
newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
|
newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
|
||||||
|
@ -356,8 +370,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
|
|
||||||
if (0 == i)
|
if (0 == i)
|
||||||
loadedNodes.Add(destFolder);
|
loadedNodes.Add(destFolder);
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,10 +241,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
if (CheckPresence(userInfo.PrincipalID))
|
if (CheckPresence(userInfo.PrincipalID))
|
||||||
{
|
{
|
||||||
InventoryArchiveReadRequest request;
|
InventoryArchiveReadRequest request;
|
||||||
|
bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream);
|
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
|
||||||
}
|
}
|
||||||
catch (EntryPointNotFoundException e)
|
catch (EntryPointNotFoundException e)
|
||||||
{
|
{
|
||||||
|
@ -285,10 +286,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
if (CheckPresence(userInfo.PrincipalID))
|
if (CheckPresence(userInfo.PrincipalID))
|
||||||
{
|
{
|
||||||
InventoryArchiveReadRequest request;
|
InventoryArchiveReadRequest request;
|
||||||
|
bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath);
|
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
|
||||||
}
|
}
|
||||||
catch (EntryPointNotFoundException e)
|
catch (EntryPointNotFoundException e)
|
||||||
{
|
{
|
||||||
|
@ -334,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
if (mainParams.Count < 6)
|
if (mainParams.Count < 6)
|
||||||
{
|
{
|
||||||
m_log.Error(
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
/// Notify the client of loaded nodes if they are logged in
|
/// Notify the client of loaded nodes if they are logged in
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="loadedNodes">Can be empty. In which case, nothing happens</param>
|
/// <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)
|
if (loadedNodes.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -629,7 +629,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
|
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
|
||||||
|
|
||||||
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
|
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
|
||||||
List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>();
|
HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>();
|
||||||
|
|
||||||
string folder1Name = "1";
|
string folder1Name = "1";
|
||||||
string folder2aName = "2a";
|
string folder2aName = "2a";
|
||||||
|
@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
|
|
||||||
{
|
{
|
||||||
// Test replication of path1
|
// Test replication of path1
|
||||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
|
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||||
.ReplicateArchivePathToUserInventory(
|
.ReplicateArchivePathToUserInventory(
|
||||||
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||||
foldersCreated, nodesLoaded);
|
foldersCreated, nodesLoaded);
|
||||||
|
@ -661,7 +661,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
|
|
||||||
{
|
{
|
||||||
// Test replication of path2
|
// Test replication of path2
|
||||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
|
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||||
.ReplicateArchivePathToUserInventory(
|
.ReplicateArchivePathToUserInventory(
|
||||||
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||||
foldersCreated, nodesLoaded);
|
foldersCreated, nodesLoaded);
|
||||||
|
@ -707,10 +707,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
|
|
||||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||||
|
|
||||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
|
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||||
.ReplicateArchivePathToUserInventory(
|
.ReplicateArchivePathToUserInventory(
|
||||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||||
new Dictionary<string, InventoryFolderBase>(), new List<InventoryNodeBase>());
|
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||||
|
|
||||||
List<InventoryFolderBase> folder1PostCandidates
|
List<InventoryFolderBase> folder1PostCandidates
|
||||||
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
|
= 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");
|
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
|
||||||
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
|
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/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -173,16 +173,16 @@ namespace OpenSim.Region.CoreModules.Framework.Library
|
||||||
m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
|
m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
|
||||||
simpleName = GetInventoryPathFromName(simpleName);
|
simpleName = GetInventoryPathFromName(simpleName);
|
||||||
|
|
||||||
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName);
|
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<InventoryNodeBase> nodes = archread.Execute();
|
HashSet<InventoryNodeBase> nodes = archread.Execute();
|
||||||
if (nodes != null && nodes.Count == 0)
|
if (nodes != null && nodes.Count == 0)
|
||||||
{
|
{
|
||||||
// didn't find the subfolder with the given name; place it on the top
|
// 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);
|
m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
|
||||||
archread.Close();
|
archread.Close();
|
||||||
archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName);
|
archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
|
||||||
archread.Execute();
|
archread.Execute();
|
||||||
}
|
}
|
||||||
foreach (InventoryNodeBase node in nodes)
|
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 Dictionary<string, bool> GrantYP = new Dictionary<string, bool>();
|
||||||
private IFriendsModule m_friendsModule;
|
private IFriendsModule m_friendsModule;
|
||||||
private IGroupsModule m_groupsModule;
|
private IGroupsModule m_groupsModule;
|
||||||
|
private IMoapModule m_moapModule;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -250,6 +251,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
|
|
||||||
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
|
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
|
||||||
|
|
||||||
|
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
|
||||||
|
m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
|
||||||
|
|
||||||
m_scene.AddCommand(this, "bypass permissions",
|
m_scene.AddCommand(this, "bypass permissions",
|
||||||
"bypass permissions <true / false>",
|
"bypass permissions <true / false>",
|
||||||
"Bypass permission checks",
|
"Bypass permission checks",
|
||||||
|
@ -394,6 +398,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
|
|
||||||
if (m_groupsModule == null)
|
if (m_groupsModule == null)
|
||||||
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
|
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
|
||||||
|
|
||||||
|
m_moapModule = m_scene.RequestModuleInterface<IMoapModule>();
|
||||||
|
|
||||||
|
// This log line will be commented out when no longer required for debugging
|
||||||
|
// if (m_moapModule == null)
|
||||||
|
// m_log.Warn("[PERMISSIONS]: Media on a prim module not found, media on a prim permissions will not work");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@ -1894,5 +1904,80 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||||
}
|
}
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CanControlPrimMedia(UUID agentID, UUID primID, int face)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PERMISSONS]: Performing CanControlPrimMedia check with agentID {0}, primID {1}, face {2}",
|
||||||
|
// agentID, primID, face);
|
||||||
|
|
||||||
|
if (null == m_moapModule)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
|
||||||
|
if (null == part)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MediaEntry me = m_moapModule.GetMediaEntry(part, face);
|
||||||
|
|
||||||
|
// If there is no existing media entry then it can be controlled (in this context, created).
|
||||||
|
if (null == me)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}",
|
||||||
|
// agentID, primID, face, me.ControlPermissions);
|
||||||
|
|
||||||
|
return GenericPrimMediaPermission(part, agentID, me.ControlPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PERMISSONS]: Performing CanInteractWithPrimMedia check with agentID {0}, primID {1}, face {2}",
|
||||||
|
// agentID, primID, face);
|
||||||
|
|
||||||
|
if (null == m_moapModule)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
|
||||||
|
if (null == part)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MediaEntry me = m_moapModule.GetMediaEntry(part, face);
|
||||||
|
|
||||||
|
// If there is no existing media entry then it can be controlled (in this context, created).
|
||||||
|
if (null == me)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PERMISSIONS]: Checking CanInteractWithPrimMedia for {0} on {1} face {2} with interact permissions {3}",
|
||||||
|
// agentID, primID, face, me.InteractPermissions);
|
||||||
|
|
||||||
|
return GenericPrimMediaPermission(part, agentID, me.InteractPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms)
|
||||||
|
{
|
||||||
|
// if (IsAdministrator(agentID))
|
||||||
|
// return true;
|
||||||
|
|
||||||
|
if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ((perms & MediaPermission.Owner) == MediaPermission.Owner)
|
||||||
|
{
|
||||||
|
if (agentID == part.OwnerID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((perms & MediaPermission.Group) == MediaPermission.Group)
|
||||||
|
{
|
||||||
|
if (IsGroupMember(part.GroupID, agentID, 0))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -79,7 +79,7 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
public event DisconnectUser OnDisconnectUser;
|
public event DisconnectUser OnDisconnectUser;
|
||||||
public event RequestAvatarProperties OnRequestAvatarProperties;
|
public event RequestAvatarProperties OnRequestAvatarProperties;
|
||||||
public event SetAlwaysRun OnSetAlwaysRun;
|
public event SetAlwaysRun OnSetAlwaysRun;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event DeRezObject OnDeRezObject;
|
public event DeRezObject OnDeRezObject;
|
||||||
public event Action<IClientAPI> OnRegionHandShakeReply;
|
public event Action<IClientAPI> OnRegionHandShakeReply;
|
||||||
public event GenericCall2 OnRequestWearables;
|
public event GenericCall2 OnRequestWearables;
|
||||||
|
|
|
@ -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 delegate void Attach(uint localID, UUID itemID, UUID avatarID);
|
||||||
public event Attach OnAttach;
|
public event Attach OnAttach;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called immediately after an object is loaded from storage.
|
||||||
|
/// </summary>
|
||||||
|
public event SceneObjectDelegate OnSceneObjectLoaded;
|
||||||
|
public delegate void SceneObjectDelegate(SceneObjectGroup so);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called immediately before an object is saved to storage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="persistingSo">
|
||||||
|
/// The scene object being persisted.
|
||||||
|
/// This is actually a copy of the original scene object so changes made here will be saved to storage but will not be kept in memory.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="originalSo">
|
||||||
|
/// The original scene object being persisted. Changes here will stay in memory but will not be saved to storage on this save.
|
||||||
|
/// </param>
|
||||||
|
public event SceneObjectPreSaveDelegate OnSceneObjectPreSave;
|
||||||
|
public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a scene object part is cloned within the region.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="copy"></param>
|
||||||
|
/// <param name="original"></param>
|
||||||
|
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
|
||||||
|
public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
|
||||||
|
public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
|
||||||
|
|
||||||
public delegate void RegionUp(GridRegion region);
|
public delegate void RegionUp(GridRegion region);
|
||||||
public event RegionUp OnRegionUp;
|
public event RegionUp OnRegionUp;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -648,6 +648,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newName == null) newName = item.Name;
|
||||||
|
|
||||||
AssetBase asset = AssetService.Get(item.AssetID.ToString());
|
AssetBase asset = AssetService.Get(item.AssetID.ToString());
|
||||||
|
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
|
@ -694,6 +696,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move an item within the agent's inventory, and leave a copy (used in making a new outfit)
|
||||||
|
/// </summary>
|
||||||
|
public void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List<InventoryItemBase> items, UUID destfolder)
|
||||||
|
{
|
||||||
|
List<InventoryItemBase> moveitems = new List<InventoryItemBase>();
|
||||||
|
foreach (InventoryItemBase b in items)
|
||||||
|
{
|
||||||
|
CopyInventoryItem(remoteClient, 0, remoteClient.AgentId, b.ID, b.Folder, null);
|
||||||
|
InventoryItemBase n = InventoryService.GetItem(b);
|
||||||
|
n.Folder = destfolder;
|
||||||
|
moveitems.Add(n);
|
||||||
|
remoteClient.SendInventoryItemCreateUpdate(n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveInventoryItem(remoteClient, moveitems);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Move an item within the agent's inventory.
|
/// Move an item within the agent's inventory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -82,6 +82,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
|
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
|
||||||
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
|
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
|
||||||
public delegate bool TeleportHandler(UUID userID, Scene scene);
|
public delegate bool TeleportHandler(UUID userID, Scene scene);
|
||||||
|
public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
|
||||||
|
public delegate bool InteractWithPrimMediaHandler(UUID userID, UUID primID, int face);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public class ScenePermissions
|
public class ScenePermissions
|
||||||
|
@ -141,6 +143,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public event CopyUserInventoryHandler OnCopyUserInventory;
|
public event CopyUserInventoryHandler OnCopyUserInventory;
|
||||||
public event DeleteUserInventoryHandler OnDeleteUserInventory;
|
public event DeleteUserInventoryHandler OnDeleteUserInventory;
|
||||||
public event TeleportHandler OnTeleport;
|
public event TeleportHandler OnTeleport;
|
||||||
|
public event ControlPrimMediaHandler OnControlPrimMedia;
|
||||||
|
public event InteractWithPrimMediaHandler OnInteractWithPrimMedia;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Object Permission Checks
|
#region Object Permission Checks
|
||||||
|
@ -964,5 +968,35 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CanControlPrimMedia(UUID userID, UUID primID, int face)
|
||||||
|
{
|
||||||
|
ControlPrimMediaHandler handler = OnControlPrimMedia;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
Delegate[] list = handler.GetInvocationList();
|
||||||
|
foreach (ControlPrimMediaHandler h in list)
|
||||||
|
{
|
||||||
|
if (h(userID, primID, face) == false)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanInteractWithPrimMedia(UUID userID, UUID primID, int face)
|
||||||
|
{
|
||||||
|
InteractWithPrimMediaHandler handler = OnInteractWithPrimMedia;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
Delegate[] list = handler.GetInvocationList();
|
||||||
|
foreach (InteractWithPrimMediaHandler h in list)
|
||||||
|
{
|
||||||
|
if (h(userID, primID, face) == false)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1918,9 +1918,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
foreach (SceneObjectGroup group in PrimsFromDB)
|
foreach (SceneObjectGroup group in PrimsFromDB)
|
||||||
{
|
{
|
||||||
|
EventManager.TriggerOnSceneObjectLoaded(group);
|
||||||
|
|
||||||
if (group.RootPart == null)
|
if (group.RootPart == null)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
||||||
group.Children == null ? 0 : group.Children.Count);
|
group.Children == null ? 0 : group.Children.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2922,6 +2924,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
client.OnFetchInventory += HandleFetchInventory;
|
client.OnFetchInventory += HandleFetchInventory;
|
||||||
client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
|
client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
|
||||||
client.OnCopyInventoryItem += CopyInventoryItem;
|
client.OnCopyInventoryItem += CopyInventoryItem;
|
||||||
|
client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
|
||||||
client.OnMoveInventoryItem += MoveInventoryItem;
|
client.OnMoveInventoryItem += MoveInventoryItem;
|
||||||
client.OnRemoveInventoryItem += RemoveInventoryItem;
|
client.OnRemoveInventoryItem += RemoveInventoryItem;
|
||||||
client.OnRemoveInventoryFolder += RemoveInventoryFolder;
|
client.OnRemoveInventoryFolder += RemoveInventoryFolder;
|
||||||
|
|
|
@ -1745,6 +1745,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
|
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
|
||||||
HasGroupChanged = false;
|
HasGroupChanged = false;
|
||||||
|
|
||||||
|
m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
|
||||||
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
|
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
|
||||||
|
|
||||||
backup_group.ForEachPart(delegate(SceneObjectPart part)
|
backup_group.ForEachPart(delegate(SceneObjectPart part)
|
||||||
|
@ -1795,6 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Duplicates this object, including operations such as physics set up and attaching to the backup event.
|
/// Duplicates this object, including operations such as physics set up and attaching to the backup event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public SceneObjectGroup Copy(bool userExposed)
|
public SceneObjectGroup Copy(bool userExposed)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
REGION = 256,
|
REGION = 256,
|
||||||
TELEPORT = 512,
|
TELEPORT = 512,
|
||||||
REGION_RESTART = 1024,
|
REGION_RESTART = 1024,
|
||||||
|
MEDIA = 2048,
|
||||||
ANIMATION = 16384
|
ANIMATION = 16384
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +332,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected Vector3 m_lastAngularVelocity;
|
protected Vector3 m_lastAngularVelocity;
|
||||||
protected int m_lastTerseSent;
|
protected int m_lastTerseSent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores media texture data
|
||||||
|
/// </summary>
|
||||||
|
protected string m_mediaUrl;
|
||||||
|
|
||||||
// TODO: Those have to be changed into persistent properties at some later point,
|
// TODO: Those have to be changed into persistent properties at some later point,
|
||||||
// or sit-camera on vehicles will break on sim-crossing.
|
// or sit-camera on vehicles will break on sim-crossing.
|
||||||
private Vector3 m_cameraEyeOffset;
|
private Vector3 m_cameraEyeOffset;
|
||||||
|
@ -984,12 +990,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
TriggerScriptChangedEvent(Changed.SCALE);
|
TriggerScriptChangedEvent(Changed.SCALE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte UpdateFlag
|
public byte UpdateFlag
|
||||||
{
|
{
|
||||||
get { return m_updateFlag; }
|
get { return m_updateFlag; }
|
||||||
set { m_updateFlag = value; }
|
set { m_updateFlag = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used for media on a prim.
|
||||||
|
/// </summary>
|
||||||
|
/// Do not change this value directly - always do it through an IMoapModule.
|
||||||
|
public string MediaUrl
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_mediaUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_mediaUrl = value;
|
||||||
|
|
||||||
|
if (ParentGroup != null)
|
||||||
|
ParentGroup.HasGroupChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public bool CreateSelected
|
public bool CreateSelected
|
||||||
{
|
{
|
||||||
|
@ -1553,6 +1580,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Duplicates this part.
|
/// Duplicates this part.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="localID"></param>
|
||||||
|
/// <param name="AgentID"></param>
|
||||||
|
/// <param name="GroupID"></param>
|
||||||
|
/// <param name="linkNum"></param>
|
||||||
|
/// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
|
public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
|
||||||
{
|
{
|
||||||
|
@ -1616,6 +1648,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
|
dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
|
||||||
|
|
||||||
return dupe;
|
return dupe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1059,6 +1059,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MakeChildAgent()
|
public void MakeChildAgent()
|
||||||
{
|
{
|
||||||
|
// 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();
|
Animator.ResetAnimations();
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
|
|
|
@ -815,6 +815,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
public event ObjectOwner OnObjectOwner;
|
public event ObjectOwner OnObjectOwner;
|
||||||
public event DirPlacesQuery OnDirPlacesQuery;
|
public event DirPlacesQuery OnDirPlacesQuery;
|
||||||
public event DirFindQuery OnDirFindQuery;
|
public event DirFindQuery OnDirFindQuery;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event DirLandQuery OnDirLandQuery;
|
public event DirLandQuery OnDirLandQuery;
|
||||||
public event DirPopularQuery OnDirPopularQuery;
|
public event DirPopularQuery OnDirPopularQuery;
|
||||||
public event DirClassifiedQuery OnDirClassifiedQuery;
|
public event DirClassifiedQuery OnDirClassifiedQuery;
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
#pragma warning disable 67
|
#pragma warning disable 67
|
||||||
public event Action<IClientAPI> OnLogout;
|
public event Action<IClientAPI> OnLogout;
|
||||||
public event ObjectPermissions OnObjectPermissions;
|
public event ObjectPermissions OnObjectPermissions;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event MoneyTransferRequest OnMoneyTransferRequest;
|
public event MoneyTransferRequest OnMoneyTransferRequest;
|
||||||
public event ParcelBuy OnParcelBuy;
|
public event ParcelBuy OnParcelBuy;
|
||||||
public event Action<IClientAPI> OnConnectionClosed;
|
public event Action<IClientAPI> OnConnectionClosed;
|
||||||
|
|
|
@ -2111,7 +2111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
|
// 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);
|
float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
|
||||||
bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
|
bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
|
||||||
|
@ -2144,33 +2144,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public LSL_Vector llGetLocalPos()
|
public LSL_Vector llGetLocalPos()
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
if (m_host.IsAttachment == true) {
|
return GetPartLocalPos(m_host);
|
||||||
if (m_host.IsRoot == true)
|
}
|
||||||
{
|
|
||||||
return new LSL_Vector(m_host.AbsolutePosition.X,
|
|
||||||
m_host.AbsolutePosition.Y,
|
|
||||||
m_host.AbsolutePosition.Z);
|
|
||||||
|
|
||||||
|
protected LSL_Vector GetPartLocalPos(SceneObjectPart part)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
if (part.ParentID != 0)
|
||||||
|
{
|
||||||
|
return new LSL_Vector(part.OffsetPosition.X,
|
||||||
|
part.OffsetPosition.Y,
|
||||||
|
part.OffsetPosition.Z);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new LSL_Vector(m_host.OffsetPosition.X,
|
return new LSL_Vector(part.AbsolutePosition.X,
|
||||||
m_host.OffsetPosition.Y,
|
part.AbsolutePosition.Y,
|
||||||
m_host.OffsetPosition.Z);
|
part.AbsolutePosition.Z);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_host.ParentID != 0)
|
|
||||||
{
|
|
||||||
return new LSL_Vector(m_host.OffsetPosition.X,
|
|
||||||
m_host.OffsetPosition.Y,
|
|
||||||
m_host.OffsetPosition.Z);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new LSL_Vector(m_host.AbsolutePosition.X,
|
|
||||||
m_host.AbsolutePosition.Y,
|
|
||||||
m_host.AbsolutePosition.Z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8300,6 +8290,241 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
ScriptSleep(1000);
|
||||||
|
|
||||||
|
// LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
|
||||||
|
// TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
|
||||||
|
// Assuming silently fail means give back an empty list. Ideally, need to check this.
|
||||||
|
if (face < 0 || face > m_host.GetNumberOfSides() - 1)
|
||||||
|
return new LSL_List();
|
||||||
|
|
||||||
|
return GetPrimMediaParams(face, rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LSL_List GetPrimMediaParams(int face, LSL_List rules)
|
||||||
|
{
|
||||||
|
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
|
||||||
|
if (null == module)
|
||||||
|
throw new Exception("Media on a prim functions not available");
|
||||||
|
|
||||||
|
MediaEntry me = module.GetMediaEntry(m_host, face);
|
||||||
|
|
||||||
|
// As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
|
||||||
|
if (null == me)
|
||||||
|
return new LSL_List();
|
||||||
|
|
||||||
|
LSL_List res = new LSL_List();
|
||||||
|
|
||||||
|
for (int i = 0; i < rules.Length; i++)
|
||||||
|
{
|
||||||
|
int code = (int)rules.GetLSLIntegerItem(i);
|
||||||
|
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
|
||||||
|
// Not implemented
|
||||||
|
res.Add(new LSL_Integer(0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
|
||||||
|
if (me.Controls == MediaControls.Standard)
|
||||||
|
res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD));
|
||||||
|
else
|
||||||
|
res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
|
||||||
|
res.Add(new LSL_String(me.CurrentURL));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
|
||||||
|
res.Add(new LSL_String(me.HomeURL));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
|
||||||
|
res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
|
||||||
|
res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
|
||||||
|
res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
|
||||||
|
res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
|
||||||
|
res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
|
||||||
|
res.Add(new LSL_Integer(me.Width));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
|
||||||
|
res.Add(new LSL_Integer(me.Height));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
|
||||||
|
res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
|
||||||
|
string[] urls = (string[])me.WhiteList.Clone();
|
||||||
|
|
||||||
|
for (int j = 0; j < urls.Length; j++)
|
||||||
|
urls[j] = Uri.EscapeDataString(urls[j]);
|
||||||
|
|
||||||
|
res.Add(new LSL_String(string.Join(", ", urls)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
|
||||||
|
res.Add(new LSL_Integer((int)me.InteractPermissions));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
|
||||||
|
res.Add(new LSL_Integer((int)me.ControlPermissions));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
ScriptSleep(1000);
|
||||||
|
|
||||||
|
// LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
|
||||||
|
// Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
|
||||||
|
// Don't perform the media check directly
|
||||||
|
if (face < 0 || face > m_host.GetNumberOfSides() - 1)
|
||||||
|
return ScriptBaseClass.LSL_STATUS_OK;
|
||||||
|
|
||||||
|
return SetPrimMediaParams(face, rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
|
||||||
|
{
|
||||||
|
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
|
||||||
|
if (null == module)
|
||||||
|
throw new Exception("Media on a prim functions not available");
|
||||||
|
|
||||||
|
MediaEntry me = module.GetMediaEntry(m_host, face);
|
||||||
|
if (null == me)
|
||||||
|
me = new MediaEntry();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < rules.Length - 1)
|
||||||
|
{
|
||||||
|
int code = rules.GetLSLIntegerItem(i++);
|
||||||
|
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
|
||||||
|
me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
|
||||||
|
int v = rules.GetLSLIntegerItem(i++);
|
||||||
|
if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
|
||||||
|
me.Controls = MediaControls.Standard;
|
||||||
|
else
|
||||||
|
me.Controls = MediaControls.Mini;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
|
||||||
|
me.CurrentURL = rules.GetLSLStringItem(i++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
|
||||||
|
me.HomeURL = rules.GetLSLStringItem(i++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
|
||||||
|
me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
|
||||||
|
me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
|
||||||
|
me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
|
||||||
|
me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
|
||||||
|
me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
|
||||||
|
me.Width = (int)rules.GetLSLIntegerItem(i++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
|
||||||
|
me.Height = (int)rules.GetLSLIntegerItem(i++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
|
||||||
|
me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
|
||||||
|
string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
|
||||||
|
List<string> whiteListUrls = new List<string>();
|
||||||
|
Array.ForEach(
|
||||||
|
rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
|
||||||
|
me.WhiteList = whiteListUrls.ToArray();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
|
||||||
|
me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
|
||||||
|
me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.SetMediaEntry(m_host, face, me);
|
||||||
|
|
||||||
|
return ScriptBaseClass.LSL_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Integer llClearPrimMedia(LSL_Integer face)
|
||||||
|
{
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
ScriptSleep(1000);
|
||||||
|
|
||||||
|
// LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid
|
||||||
|
// Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
|
||||||
|
// FIXME: Don't perform the media check directly
|
||||||
|
if (face < 0 || face > m_host.GetNumberOfSides() - 1)
|
||||||
|
return ScriptBaseClass.LSL_STATUS_OK;
|
||||||
|
|
||||||
|
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
|
||||||
|
if (null == module)
|
||||||
|
throw new Exception("Media on a prim functions not available");
|
||||||
|
|
||||||
|
module.ClearMediaEntry(m_host, face);
|
||||||
|
|
||||||
|
return ScriptBaseClass.LSL_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// <remarks>
|
// <remarks>
|
||||||
// <para>
|
// <para>
|
||||||
// The .NET definition of base 64 is:
|
// The .NET definition of base 64 is:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
void llBreakLink(int linknum);
|
void llBreakLink(int linknum);
|
||||||
LSL_Integer llCeil(double f);
|
LSL_Integer llCeil(double f);
|
||||||
void llClearCameraParams();
|
void llClearCameraParams();
|
||||||
|
LSL_Integer llClearPrimMedia(LSL_Integer face);
|
||||||
void llCloseRemoteDataChannel(string channel);
|
void llCloseRemoteDataChannel(string channel);
|
||||||
LSL_Float llCloud(LSL_Vector offset);
|
LSL_Float llCloud(LSL_Vector offset);
|
||||||
void llCollisionFilter(string name, string id, int accept);
|
void llCollisionFilter(string name, string id, int accept);
|
||||||
|
@ -162,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
LSL_List llGetParcelPrimOwners(LSL_Vector pos);
|
LSL_List llGetParcelPrimOwners(LSL_Vector pos);
|
||||||
LSL_Integer llGetPermissions();
|
LSL_Integer llGetPermissions();
|
||||||
LSL_Key llGetPermissionsKey();
|
LSL_Key llGetPermissionsKey();
|
||||||
|
LSL_List llGetPrimMediaParams(int face, LSL_List rules);
|
||||||
LSL_Vector llGetPos();
|
LSL_Vector llGetPos();
|
||||||
LSL_List llGetPrimitiveParams(LSL_List rules);
|
LSL_List llGetPrimitiveParams(LSL_List rules);
|
||||||
LSL_Integer llGetRegionAgentCount();
|
LSL_Integer llGetRegionAgentCount();
|
||||||
|
@ -332,6 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
void llSetParcelMusicURL(string url);
|
void llSetParcelMusicURL(string url);
|
||||||
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
|
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
|
||||||
void llSetPos(LSL_Vector pos);
|
void llSetPos(LSL_Vector pos);
|
||||||
|
LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
|
||||||
void llSetPrimitiveParams(LSL_List rules);
|
void llSetPrimitiveParams(LSL_List rules);
|
||||||
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
|
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
|
||||||
void llSetPrimURL(string url);
|
void llSetPrimURL(string url);
|
||||||
|
|
|
@ -277,6 +277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
public const int CHANGED_TELEPORT = 512;
|
public const int CHANGED_TELEPORT = 512;
|
||||||
public const int CHANGED_REGION_RESTART = 1024;
|
public const int CHANGED_REGION_RESTART = 1024;
|
||||||
public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
|
public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
|
||||||
|
public const int CHANGED_MEDIA = 2048;
|
||||||
public const int CHANGED_ANIMATION = 16384;
|
public const int CHANGED_ANIMATION = 16384;
|
||||||
public const int TYPE_INVALID = 0;
|
public const int TYPE_INVALID = 0;
|
||||||
public const int TYPE_INTEGER = 1;
|
public const int TYPE_INTEGER = 1;
|
||||||
|
@ -519,6 +520,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
|
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
|
||||||
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
|
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
|
||||||
|
|
||||||
|
// constants for llGetPrimMediaParams/llSetPrimMediaParams
|
||||||
|
public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
|
||||||
|
public const int PRIM_MEDIA_CONTROLS = 1;
|
||||||
|
public const int PRIM_MEDIA_CURRENT_URL = 2;
|
||||||
|
public const int PRIM_MEDIA_HOME_URL = 3;
|
||||||
|
public const int PRIM_MEDIA_AUTO_LOOP = 4;
|
||||||
|
public const int PRIM_MEDIA_AUTO_PLAY = 5;
|
||||||
|
public const int PRIM_MEDIA_AUTO_SCALE = 6;
|
||||||
|
public const int PRIM_MEDIA_AUTO_ZOOM = 7;
|
||||||
|
public const int PRIM_MEDIA_FIRST_CLICK_INTERACT = 8;
|
||||||
|
public const int PRIM_MEDIA_WIDTH_PIXELS = 9;
|
||||||
|
public const int PRIM_MEDIA_HEIGHT_PIXELS = 10;
|
||||||
|
public const int PRIM_MEDIA_WHITELIST_ENABLE = 11;
|
||||||
|
public const int PRIM_MEDIA_WHITELIST = 12;
|
||||||
|
public const int PRIM_MEDIA_PERMS_INTERACT = 13;
|
||||||
|
public const int PRIM_MEDIA_PERMS_CONTROL = 14;
|
||||||
|
|
||||||
|
public const int PRIM_MEDIA_CONTROLS_STANDARD = 0;
|
||||||
|
public const int PRIM_MEDIA_CONTROLS_MINI = 1;
|
||||||
|
|
||||||
|
public const int PRIM_MEDIA_PERM_NONE = 0;
|
||||||
|
public const int PRIM_MEDIA_PERM_OWNER = 1;
|
||||||
|
public const int PRIM_MEDIA_PERM_GROUP = 2;
|
||||||
|
public const int PRIM_MEDIA_PERM_ANYONE = 4;
|
||||||
|
|
||||||
|
// extra constants for llSetPrimMediaParams
|
||||||
|
public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_TYPE_MISMATCH = new LSLInteger(1001);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_BOUNDS_ERROR = new LSLInteger(1002);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_NOT_FOUND = new LSLInteger(1003);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_NOT_SUPPORTED = new LSLInteger(1004);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_INTERNAL_ERROR = new LSLInteger(1999);
|
||||||
|
public static readonly LSLInteger LSL_STATUS_WHITELIST_FAILED = new LSLInteger(2001);
|
||||||
|
|
||||||
// Constants for default textures
|
// Constants for default textures
|
||||||
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
|
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
|
||||||
public const string TEXTURE_DEFAULT = "89556747-24cb-43ed-920b-47caed15465f";
|
public const string TEXTURE_DEFAULT = "89556747-24cb-43ed-920b-47caed15465f";
|
||||||
|
|
|
@ -1834,5 +1834,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
{
|
{
|
||||||
return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
|
return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
|
||||||
|
{
|
||||||
|
return m_LSL_Functions.llGetPrimMediaParams(face, rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
|
||||||
|
{
|
||||||
|
return m_LSL_Functions.llSetPrimMediaParams(face, rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LSL_Integer llClearPrimMedia(LSL_Integer face)
|
||||||
|
{
|
||||||
|
return m_LSL_Functions.llClearPrimMedia(face);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,7 +358,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
||||||
|
|
||||||
private bool GetBoolResponse(XmlRpcRequest request, out string reason)
|
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;
|
XmlRpcResponse response = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -366,14 +366,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
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;
|
reason = "Exception: " + e.Message;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.IsFault)
|
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";
|
reason = "XMLRPC Fault";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -383,15 +383,29 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
||||||
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
|
||||||
try
|
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;
|
bool success = false;
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
|
if (hash.ContainsKey("result"))
|
||||||
Boolean.TryParse((string)hash["result"], out success);
|
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;
|
return success;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
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;
|
reason = "Exception: " + e.Message;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace OpenSim.Services.HypergridService
|
||||||
throw new Exception(String.Format("No section GatekeeperService in config file"));
|
throw new Exception(String.Format("No section GatekeeperService in config file"));
|
||||||
|
|
||||||
string accountService = serverConfig.GetString("UserAccountService", String.Empty);
|
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 gridService = serverConfig.GetString("GridService", String.Empty);
|
||||||
string presenceService = serverConfig.GetString("PresenceService", String.Empty);
|
string presenceService = serverConfig.GetString("PresenceService", String.Empty);
|
||||||
string simulationService = serverConfig.GetString("SimulationService", String.Empty);
|
string simulationService = serverConfig.GetString("SimulationService", String.Empty);
|
||||||
|
@ -283,8 +283,12 @@ namespace OpenSim.Services.HypergridService
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userURL == m_ExternalName)
|
||||||
|
return m_UserAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
|
||||||
|
else
|
||||||
|
{
|
||||||
Object[] args = new Object[] { userURL };
|
Object[] args = new Object[] { userURL };
|
||||||
IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); //ServerUtils.LoadPlugin<IUserAgentService>(m_AuthDll, args);
|
IUserAgentService userAgentService = new UserAgentServiceConnector(userURL);
|
||||||
if (userAgentService != null)
|
if (userAgentService != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -297,6 +301,7 @@ namespace OpenSim.Services.HypergridService
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,11 @@ namespace OpenSim.Services.HypergridService
|
||||||
|
|
||||||
protected static IGridUserService m_GridUserService;
|
protected static IGridUserService m_GridUserService;
|
||||||
protected static IGridService m_GridService;
|
protected static IGridService m_GridService;
|
||||||
//protected static GatekeeperServiceConnector m_GatekeeperConnector;
|
protected static GatekeeperServiceConnector m_GatekeeperConnector;
|
||||||
protected static IGatekeeperService m_GatekeeperService;
|
protected static IGatekeeperService m_GatekeeperService;
|
||||||
|
|
||||||
|
protected static string m_GridName;
|
||||||
|
|
||||||
protected static bool m_BypassClientVerification;
|
protected static bool m_BypassClientVerification;
|
||||||
|
|
||||||
public UserAgentService(IConfigSource config)
|
public UserAgentService(IConfigSource config)
|
||||||
|
@ -90,8 +92,15 @@ namespace OpenSim.Services.HypergridService
|
||||||
Object[] args = new Object[] { config };
|
Object[] args = new Object[] { config };
|
||||||
m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
|
m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
|
||||||
m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
|
m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
|
||||||
//m_GatekeeperConnector = new GatekeeperServiceConnector();
|
m_GatekeeperConnector = new GatekeeperServiceConnector();
|
||||||
m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args);
|
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);
|
TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region);
|
||||||
|
|
||||||
//bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
|
//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)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
@ -179,7 +193,7 @@ namespace OpenSim.Services.HypergridService
|
||||||
m_TravelingAgents[agentCircuit.SessionID] = travel;
|
m_TravelingAgents[agentCircuit.SessionID] = travel;
|
||||||
}
|
}
|
||||||
travel.UserID = agentCircuit.AgentID;
|
travel.UserID = agentCircuit.AgentID;
|
||||||
travel.GridExternalName = region.ExternalHostName + ":" + region.HttpPort;
|
travel.GridExternalName = "http://" + region.ExternalHostName + ":" + region.HttpPort;
|
||||||
travel.ServiceToken = agentCircuit.ServiceSessionID;
|
travel.ServiceToken = agentCircuit.ServiceSessionID;
|
||||||
if (old != null)
|
if (old != null)
|
||||||
travel.ClientToken = old.ClientToken;
|
travel.ClientToken = old.ClientToken;
|
||||||
|
@ -215,6 +229,7 @@ namespace OpenSim.Services.HypergridService
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TravelingAgentInfo travel = m_TravelingAgents[sessionID];
|
TravelingAgentInfo travel = m_TravelingAgents[sessionID];
|
||||||
|
|
||||||
return travel.GridExternalName == thisGridExternalName;
|
return travel.GridExternalName == thisGridExternalName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
public event MoneyTransferRequest OnMoneyTransferRequest;
|
public event MoneyTransferRequest OnMoneyTransferRequest;
|
||||||
public event ParcelBuy OnParcelBuy;
|
public event ParcelBuy OnParcelBuy;
|
||||||
public event Action<IClientAPI> OnConnectionClosed;
|
public event Action<IClientAPI> OnConnectionClosed;
|
||||||
|
public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||||
public event ImprovedInstantMessage OnInstantMessage;
|
public event ImprovedInstantMessage OnInstantMessage;
|
||||||
public event ChatMessage OnChatFromClient;
|
public event ChatMessage OnChatFromClient;
|
||||||
public event TextureRequest OnRequestTexture;
|
public event TextureRequest OnRequestTexture;
|
||||||
|
|
|
@ -241,21 +241,6 @@ namespace OpenSim.Tools.Configger
|
||||||
config.Set("EventQueue", true);
|
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;
|
return defaultConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,67 @@
|
||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<param name="delimiter"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<param name="buffer"></param>
|
||||||
|
<param name="offset"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="s"></param>
|
||||||
|
<param name="c"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="s"></param>
|
||||||
|
<param name="c"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])">
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])">
|
||||||
<summary>
|
<summary>
|
||||||
|
|
||||||
|
@ -151,67 +212,6 @@
|
||||||
<param name="reader"></param>
|
<param name="reader"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<param name="delimiter"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<param name="buffer"></param>
|
|
||||||
<param name="offset"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="s"></param>
|
|
||||||
<param name="c"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="s"></param>
|
|
||||||
<param name="c"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="T:OpenMetaverse.StructuredData.OSDType">
|
<member name="T:OpenMetaverse.StructuredData.OSDType">
|
||||||
<summary>
|
<summary>
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -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.
31063
bin/OpenMetaverse.XML
31063
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 = "";
|
; DefaultAdministratorGroupUUID = "";
|
||||||
; DefaultAdministratorParcelName = "";
|
; DefaultAdministratorParcelName = "";
|
||||||
|
|
||||||
|
[MediaOnAPrim]
|
||||||
|
; Enable media on a prim facilities
|
||||||
|
Enabled = true;
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; These are defaults that are overwritten below in [Architecture].
|
;; These are defaults that are overwritten below in [Architecture].
|
||||||
;; These defaults allow OpenSim to work out of the box with
|
;; These defaults allow OpenSim to work out of the box with
|
||||||
|
|
|
@ -2245,6 +2245,7 @@
|
||||||
<Reference name="OpenSim.Region.Framework"/>
|
<Reference name="OpenSim.Region.Framework"/>
|
||||||
<Reference name="OpenMetaverseTypes.dll"/>
|
<Reference name="OpenMetaverseTypes.dll"/>
|
||||||
<Reference name="OpenMetaverse.dll"/>
|
<Reference name="OpenMetaverse.dll"/>
|
||||||
|
<Reference name="OpenMetaverse.StructuredData.dll"/>
|
||||||
<Reference name="Mono.Data.Sqlite"/>
|
<Reference name="Mono.Data.Sqlite"/>
|
||||||
<Reference name="Mono.Addins.dll" />
|
<Reference name="Mono.Addins.dll" />
|
||||||
<Reference name="log4net.dll"/>
|
<Reference name="log4net.dll"/>
|
||||||
|
|
Loading…
Reference in New Issue