From 5925aac859ee493fd7f6b10026c84a6a22626c79 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 30 Jun 2010 00:10:44 +0100
Subject: Add --merge switch to load iar.
When this switch is used, iar folders are merged with existing same-name user inventory folders.
This makes it a little easier to back and restore entire individual user inventories, among other things
Added unit test to check behaviour
---
.../Framework/Serialization/ArchiveConstants.cs | 29 +++++-
.../Archiver/InventoryArchiveReadRequest.cs | 110 ++++++++++++---------
.../Inventory/Archiver/InventoryArchiverModule.cs | 60 +++++------
.../Archiver/Tests/InventoryArchiverTests.cs | 50 +++++++++-
.../CoreModules/Framework/Library/LibraryModule.cs | 8 +-
.../Shared/Api/Implementation/LS_Api.cs | 2 +-
6 files changed, 169 insertions(+), 90 deletions(-)
diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs
index 475a9de..3143e3b 100644
--- a/OpenSim/Framework/Serialization/ArchiveConstants.cs
+++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Text;
using OpenMetaverse;
namespace OpenSim.Framework.Serialization
@@ -171,6 +172,30 @@ namespace OpenSim.Framework.Serialization
public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos)
{
return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos);
- }
+ }
+
+ ///
+ /// Extract a plain path from an IAR path
+ ///
+ ///
+ ///
+ public static string ExtractPlainPathFromIarPath(string iarPath)
+ {
+ List plainDirs = new List();
+
+ 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());
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 9996074..f130b3e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -54,6 +54,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
private UserAccount m_userInfo;
private string m_invPath;
+
+ ///
+ /// Do we want to merge this load with existing inventory?
+ ///
+ protected bool m_merge;
///
/// We only use this to request modules
@@ -66,19 +71,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
private Stream m_loadStream;
public InventoryArchiveReadRequest(
- Scene scene, UserAccount userInfo, string invPath, string loadPath)
+ Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
: this(
scene,
userInfo,
invPath,
- new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress))
+ new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress),
+ merge)
{
}
public InventoryArchiveReadRequest(
- Scene scene, UserAccount userInfo, string invPath, Stream loadStream)
+ Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
{
m_scene = scene;
+ m_merge = merge;
m_userInfo = userInfo;
m_invPath = invPath;
m_loadStream = loadStream;
@@ -91,14 +98,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// A list of the inventory nodes loaded. If folders were loaded then only the root folders are
/// returned
///
- public List Execute()
+ public HashSet Execute()
{
string filePath = "ERROR";
int successfulAssetRestores = 0;
int failedAssetRestores = 0;
int successfulItemRestores = 0;
- List loadedNodes = new List();
+ HashSet loadedNodes = new HashSet();
List folderCandidates
= InventoryArchiveUtils.FindFolderByPath(
@@ -158,9 +165,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
successfulItemRestores++;
- // If we're loading an item directly into the given destination folder then we need to record
- // it separately from any loaded root folders
- if (rootDestinationFolder == foundFolder)
+ // If we aren't loading the folder containing the item then well need to update the
+ // viewer separately for that item.
+ if (!loadedNodes.Contains(foundFolder))
loadedNodes.Add(item);
}
}
@@ -203,14 +210,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string iarPath,
InventoryFolderBase rootDestFolder,
Dictionary resolvedFolders,
- List loadedNodes)
+ HashSet loadedNodes)
{
string iarPathExisting = iarPath;
// m_log.DebugFormat(
// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
- InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
+ InventoryFolderBase destFolder
+ = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
m_log.DebugFormat(
"[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
@@ -249,46 +257,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{
string originalArchivePath = archivePath;
- InventoryFolderBase destFolder = null;
-
- if (archivePath.Length > 0)
+ while (archivePath.Length > 0)
{
- while (null == destFolder && archivePath.Length > 0)
+ m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath);
+
+ if (resolvedFolders.ContainsKey(archivePath))
{
- m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath);
+ m_log.DebugFormat(
+ "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
+ return resolvedFolders[archivePath];
+ }
+ 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 folderCandidates
+ = InventoryArchiveUtils.FindFolderByPath(
+ m_scene.InventoryService, m_userInfo.PrincipalID, plainPath);
+
+ if (folderCandidates.Count != 0)
+ {
+ InventoryFolderBase destFolder = folderCandidates[0];
+ resolvedFolders[archivePath] = destFolder;
+ return destFolder;
+ }
+ }
- if (resolvedFolders.ContainsKey(archivePath))
+ // Don't include the last slash so find the penultimate one
+ int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
+
+ if (penultimateSlashIndex >= 0)
{
- m_log.DebugFormat(
- "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
- destFolder = resolvedFolders[archivePath];
+ // Remove the last section of path so that we can see if we've already resolved the parent
+ archivePath = archivePath.Remove(penultimateSlashIndex + 1);
}
else
{
- // Don't include the last slash so find the penultimate one
- int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
-
- if (penultimateSlashIndex >= 0)
- {
- // Remove the last section of path so that we can see if we've already resolved the parent
- archivePath = archivePath.Remove(penultimateSlashIndex + 1);
- }
- else
- {
- m_log.DebugFormat(
- "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
- originalArchivePath);
- archivePath = string.Empty;
- destFolder = rootDestFolder;
- }
+ m_log.DebugFormat(
+ "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
+ originalArchivePath);
+ archivePath = string.Empty;
+ return rootDestFolder;
}
}
}
- if (null == destFolder)
- destFolder = rootDestFolder;
-
- return destFolder;
+ return rootDestFolder;
}
///
@@ -314,24 +331,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string iarPathExisting,
string iarPathToReplicate,
Dictionary resolvedFolders,
- List loadedNodes)
+ HashSet loadedNodes)
{
string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
- int i = 0;
- while (i < rawDirsToCreate.Length)
+ for (int i = 0; i < rawDirsToCreate.Length; i++)
{
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]);
+ if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR))
+ continue;
+
int identicalNameIdentifierIndex
= rawDirsToCreate[i].LastIndexOf(
ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
- if (identicalNameIdentifierIndex < 0)
- {
- i++;
- continue;
- }
string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
@@ -354,8 +368,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (0 == i)
loadedNodes.Add(destFolder);
-
- i++;
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index cfefbe9..668c344 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -91,12 +91,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
scene.AddCommand(
this, "load iar",
- "load iar []",
+ "load iar []",
//"load iar [--merge] []",
"Load user inventory archive (IAR).",
- //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
+ //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
//+ " is user's first name." + Environment.NewLine
- " is user's first name." + Environment.NewLine
+ " is user's first name." + Environment.NewLine
+ " is user's last name." + Environment.NewLine
+ " is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine
+ " is the user's password." + Environment.NewLine
@@ -136,16 +136,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (handlerInventoryArchiveSaved != null)
handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException);
}
-
+
public bool ArchiveInventory(
- Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
- {
- return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary());
- }
+ Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
+ {
+ return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary());
+ }
public bool ArchiveInventory(
- Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
- Dictionary options)
+ Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
+ Dictionary options)
{
if (m_scenes.Count > 0)
{
@@ -184,8 +184,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
public bool ArchiveInventory(
- Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
- Dictionary options)
+ Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
+ Dictionary options)
{
if (m_scenes.Count > 0)
{
@@ -224,13 +224,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream)
- {
- return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary());
- }
-
+ {
+ return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary());
+ }
+
public bool DearchiveInventory(
- string firstName, string lastName, string invPath, string pass, Stream loadStream,
- Dictionary options)
+ string firstName, string lastName, string invPath, string pass, Stream loadStream,
+ Dictionary options)
{
if (m_scenes.Count > 0)
{
@@ -241,10 +241,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (CheckPresence(userInfo.PrincipalID))
{
InventoryArchiveReadRequest request;
+ bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
try
{
- request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream);
+ request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
}
catch (EntryPointNotFoundException e)
{
@@ -273,8 +274,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
}
public bool DearchiveInventory(
- string firstName, string lastName, string invPath, string pass, string loadPath,
- Dictionary options)
+ string firstName, string lastName, string invPath, string pass, string loadPath,
+ Dictionary options)
{
if (m_scenes.Count > 0)
{
@@ -285,10 +286,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (CheckPresence(userInfo.PrincipalID))
{
InventoryArchiveReadRequest request;
+ bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
try
- {
- request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath);
+ {
+ request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
}
catch (EntryPointNotFoundException e)
{
@@ -322,13 +324,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
///
protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams)
{
- m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
-
- Dictionary options = new Dictionary();
+ m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
+
+ Dictionary options = new Dictionary();
OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
List mainParams = optionSet.Parse(cmdparams);
-
+
if (mainParams.Count < 6)
{
m_log.Error(
@@ -349,7 +351,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
- loadPath, firstName, lastName);
+ loadPath, firstName, lastName);
}
///
@@ -454,7 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Notify the client of loaded nodes if they are logged in
///
/// Can be empty. In which case, nothing happens
- private void UpdateClientWithLoadedNodes(UserAccount userInfo, List loadedNodes)
+ private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet loadedNodes)
{
if (loadedNodes.Count == 0)
return;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 5130fa5..5fad0a9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -514,7 +514,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene);
Dictionary foldersCreated = new Dictionary();
- List nodesLoaded = new List();
+ HashSet nodesLoaded = new HashSet();
string folder1Name = "1";
string folder2aName = "2a";
@@ -529,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
// Test replication of path1
- new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
+ new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
@@ -546,7 +546,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
// Test replication of path2
- new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
+ new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
foldersCreated, nodesLoaded);
@@ -592,10 +592,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
- new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null)
+ new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
.ReplicateArchivePathToUserInventory(
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
- new Dictionary(), new List());
+ new Dictionary(), new HashSet());
List folder1PostCandidates
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
@@ -617,5 +617,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
}
+
+ ///
+ /// Test replication of a partly existing archive path to the user's inventory. This should create
+ /// a merged path.
+ ///
+ [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(), new HashSet());
+
+ List 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 folder2PostCandidates
+ = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b");
+ Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index 36dae6b..9c20d68 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -173,16 +173,16 @@ namespace OpenSim.Region.CoreModules.Framework.Library
m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
simpleName = GetInventoryPathFromName(simpleName);
- InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName);
+ InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false);
try
{
- List nodes = archread.Execute();
+ HashSet nodes = archread.Execute();
if (nodes != null && nodes.Count == 0)
{
// didn't find the subfolder with the given name; place it on the top
m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
archread.Close();
- archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName);
+ archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
archread.Execute();
}
foreach (InventoryNodeBase node in nodes)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index fe71ed5..5ae6439 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
--
cgit v1.1
From 1077a8a3925a4fede6ee0d775550820ec4e541a2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 30 Jun 2010 20:46:35 +0100
Subject: add stub media-on-a-prim (shared media) module
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 56 ++++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
new file mode 100644
index 0000000..1e5c767
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -0,0 +1,56 @@
+/*
+ * 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.Reflection;
+using Nini.Config;
+using log4net;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using Mono.Addins;
+using OpenMetaverse;
+
+namespace OpenSim.Region.CoreModules.Media.Moap
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
+ public class MoapModule : INonSharedRegionModule
+ {
+ public string Name { get { return "MoapModule"; } }
+ public Type ReplaceableInterface { get { return null; } }
+
+ public void Initialise(IConfigSource config) {}
+
+ public void AddRegion(Scene scene) { Console.WriteLine("YEAH I'M HERE, BABY!"); }
+
+ public void RemoveRegion(Scene scene) {}
+
+ public void RegionLoaded(Scene scene) {}
+
+ public void Close() {}
+ }
+}
\ No newline at end of file
--
cgit v1.1
From e098d339293435add487312119d77cb5d18cfe8a Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 30 Jun 2010 22:30:05 +0100
Subject: Register ObjectMedia and ObjectMediaNavigate capabilities from moap
module.
Not sure if these are correct, but just supplying these to the viewer is enough to allow it to put media textures on prims (previously the icons were greyed out).
This is not yet persisted even in-memory, so no other avatars will see it yet.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 58 ++++++++++++++++++++--
1 file changed, 53 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 1e5c767..68b9b43 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -26,31 +26,79 @@
*/
using System;
+using System.Collections;
+using System.Collections.Specialized;
using System.Reflection;
-using Nini.Config;
+using System.IO;
+using System.Web;
using log4net;
+using Mono.Addins;
+using Nini.Config;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
using OpenSim.Framework;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
-using Mono.Addins;
-using OpenMetaverse;
+using OpenSim.Services.Interfaces;
+using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Region.CoreModules.Media.Moap
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
public class MoapModule : INonSharedRegionModule
{
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
+ protected Scene m_scene;
+
public void Initialise(IConfigSource config) {}
- public void AddRegion(Scene scene) { Console.WriteLine("YEAH I'M HERE, BABY!"); }
+ public void AddRegion(Scene scene)
+ {
+ m_scene = scene;
+ }
public void RemoveRegion(Scene scene) {}
- public void RegionLoaded(Scene scene) {}
+ public void RegionLoaded(Scene scene)
+ {
+ m_scene.EventManager.OnRegisterCaps += RegisterCaps;
+ }
public void Close() {}
+
+ public void RegisterCaps(UUID agentID, Caps caps)
+ {
+ m_log.DebugFormat(
+ "[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
+
+ caps.RegisterHandler(
+ "ObjectMedia", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaRequest));
+ caps.RegisterHandler(
+ "ObjectMediaNavigate", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaNavigateRequest));
+ }
+
+ protected string OnObjectMediaRequest(
+ string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia request for {0}", path);
+ //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+
+ return string.Empty;
+ }
+
+ protected string OnObjectMediaNavigateRequest(
+ string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
+ //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+
+ return string.Empty;
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 94646599f09cf8a4cc930a1150195036134c28b5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 00:24:30 +0100
Subject: do a whole load of crappy hacking to get cubes to display google.com
currently, for smoe reason the page only appears when you click a face.
also, actually navigating anywhere always snaps you back to the google search box, for some unknown reason
you can still change the url and normal navigation will work again
---
.../Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +-
.../CoreModules/World/Media/Moap/MoapModule.cs | 95 ++++++++++++++++++++--
2 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 8123f2f..f85cb57 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -362,7 +362,7 @@ namespace OpenSim.Framework.Servers.HttpServer
string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path);
- //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
+ m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
if (TryGetStreamHandler(handlerKey, out requestHandler))
{
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 68b9b43..b6fa53f 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -35,8 +35,10 @@ 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;
@@ -77,28 +79,109 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
+ // We do receive a post to ObjectMedia when a new avatar enters the region - though admittedly this is the
+ // avatar that set the texture in the first place.
+ // Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaRequest));
+ "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaRequest));
+
+ // We do get these posts when the url has been changed.
+ // Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaNavigateRequest));
+ "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateRequest));
}
- protected string OnObjectMediaRequest(
+ ///
+ /// Sets or gets per face media textures.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected string HandleObjectMediaRequest(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMedia request for {0}", path);
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
+
+ Hashtable osdParams = new Hashtable();
+ osdParams = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
+
+ foreach (Object key in osdParams.Keys)
+ m_log.DebugFormat("[MOAP]: Param {0}={1}", key, osdParams[key]);
+
+ string verb = (string)osdParams["verb"];
+
+ if ("GET" == verb)
+ return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
+
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+ // TODO: Persist in memory
+ // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
+ // TODO: Persist in database
+
return string.Empty;
}
- protected string OnObjectMediaNavigateRequest(
+ protected string HandleObjectMediaRequestGet(
+ string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ // Yeah, only for cubes right now. I know it's dumb.
+ int faces = 6;
+
+ MediaEntry[] media = new MediaEntry[faces];
+ for (int i = 0; i < faces; i++)
+ {
+ MediaEntry me = new MediaEntry();
+ me.HomeURL = "google.com";
+ me.CurrentURL = "google.com";
+ me.AutoScale = true;
+ //me.Height = 300;
+ //me.Width = 240;
+ media[i] = me;
+ }
+
+ ObjectMediaResponse resp = new ObjectMediaResponse();
+
+ resp.PrimID = (UUID)osdParams["object_id"];
+ resp.FaceMedia = media;
+
+ // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
+ // to minimally satisfy for now to get something working
+ resp.Version = "x-mv:0000000016/" + UUID.Random();
+
+ //string rawResp = resp.Serialize().ToString();
+ string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
+
+ m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp);
+
+ return rawResp;
+ }
+
+ ///
+ /// Received from the viewer if a user has changed the url of a media texture.
+ ///
+ ///
+ ///
+ ///
+ /// /param>
+ /// /param>
+ ///
+ protected string HandleObjectMediaNavigateRequest(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+ // TODO: Persist in memory
+ // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
+ // TODO: Persist in database
+
return string.Empty;
- }
+ }
+
+
}
}
\ No newline at end of file
--
cgit v1.1
From 92502687538e2f9dd8d473aad9e9ef1c75091dd8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 00:47:12 +0100
Subject: have a stab at sending the correct number of media entries to shapes
actually, this is probably wrong anyway if there's a default texture
it's going to be easier just to gather the object media updates and retain those in-memory now
but what the hell
---
.../Region/CoreModules/World/Media/Moap/MoapModule.cs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index b6fa53f..30507a4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -128,8 +128,20 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected string HandleObjectMediaRequestGet(
string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- // Yeah, only for cubes right now. I know it's dumb.
- int faces = 6;
+ UUID primId = (UUID)osdParams["object_id"];
+
+ 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 the scene",
+ primId);
+ return string.Empty;
+ }
+
+ int faces = part.GetNumberOfSides();
+ m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
MediaEntry[] media = new MediaEntry[faces];
for (int i = 0; i < faces; i++)
--
cgit v1.1
From 214db91503148f0bad42f951965f4acfc3cdd7e1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 02:06:51 +0100
Subject: start storing incoming MediaEntry on a new Media field on
PrimitiveBaseShape
This allows the media texture to persist in memory - logging in and out will redisplay it (after a click) though navigation will be lost
Next need to implement media uri on prim and delegate more incoming llsd parsing to libomv
---
OpenSim/Framework/PrimitiveBaseShape.cs | 7 +++
.../CoreModules/World/Media/Moap/MoapModule.cs | 63 ++++++++++++++++++++--
2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 4d1de22..517dbf6 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -26,12 +26,14 @@
*/
using System;
+using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
@@ -170,6 +172,11 @@ namespace OpenSim.Framework
}
}
}
+
+ ///
+ /// Entries to store media textures on each face
+ ///
+ public List Media { get; set; }
public PrimitiveBaseShape()
{
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 30507a4..90626f4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
@@ -115,6 +116,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if ("GET" == verb)
return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
+ if ("UPDATE" == verb)
+ return HandleObjectMediaRequestUpdate(path, osdParams, httpRequest, httpResponse);
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
@@ -140,6 +143,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
+ /*
int faces = part.GetNumberOfSides();
m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
@@ -154,17 +158,20 @@ namespace OpenSim.Region.CoreModules.Media.Moap
//me.Width = 240;
media[i] = me;
}
+ */
+
+ if (null == part.Shape.Media)
+ return string.Empty;
ObjectMediaResponse resp = new ObjectMediaResponse();
- resp.PrimID = (UUID)osdParams["object_id"];
- resp.FaceMedia = media;
+ resp.PrimID = primId;
+ resp.FaceMedia = part.Shape.Media.ToArray();
// I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
// to minimally satisfy for now to get something working
resp.Version = "x-mv:0000000016/" + UUID.Random();
- //string rawResp = resp.Serialize().ToString();
string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp);
@@ -172,6 +179,56 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return rawResp;
}
+ protected string HandleObjectMediaRequestUpdate(
+ string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ UUID primId = (UUID)osdParams["object_id"];
+
+ SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
+
+ if (null == part)
+ {
+ m_log.WarnFormat(
+ "[MOAP]: Received am UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
+ primId);
+ return string.Empty;
+ }
+
+ List cookedMediaEntries = new List();
+
+ ArrayList rawMediaEntries = (ArrayList)osdParams["object_media_data"];
+ foreach (Object obj in rawMediaEntries)
+ {
+ Hashtable rawMe = (Hashtable)obj;
+
+ // TODO: Yeah, I know this is silly. Very soon use existing better code in libomv to do this.
+ MediaEntry cookedMe = new MediaEntry();
+ cookedMe.EnableAlterntiveImage = (bool)rawMe["alt_image_enable"];
+ cookedMe.AutoLoop = (bool)rawMe["auto_loop"];
+ cookedMe.AutoPlay = (bool)rawMe["auto_play"];
+ cookedMe.AutoScale = (bool)rawMe["auto_scale"];
+ cookedMe.AutoZoom = (bool)rawMe["auto_zoom"];
+ cookedMe.InteractOnFirstClick = (bool)rawMe["first_click_interact"];
+ cookedMe.Controls = (MediaControls)rawMe["controls"];
+ cookedMe.HomeURL = (string)rawMe["home_url"];
+ cookedMe.CurrentURL = (string)rawMe["current_url"];
+ cookedMe.Height = (int)rawMe["height_pixels"];
+ cookedMe.Width = (int)rawMe["width_pixels"];
+ cookedMe.ControlPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_control"].ToString());
+ cookedMe.InteractPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_interact"].ToString());
+ cookedMe.EnableWhiteList = (bool)rawMe["whitelist_enable"];
+ //cookedMe.WhiteList = (string[])rawMe["whitelist"];
+
+ cookedMediaEntries.Add(cookedMe);
+ }
+
+ m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", cookedMediaEntries.Count, primId);
+
+ part.Shape.Media = cookedMediaEntries;
+
+ return string.Empty;
+ }
+
///
/// Received from the viewer if a user has changed the url of a media texture.
///
--
cgit v1.1
From de769d56f5b99f4eb38f62bddebd075385f0e0f4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 18:42:47 +0100
Subject: replace hand parsing of incoming object media messages with parsing
code in libopenmetaverse
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 91 ++++++++--------------
1 file changed, 31 insertions(+), 60 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 90626f4..568170e 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -46,6 +46,7 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
+using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Media.Moap
{
@@ -59,7 +60,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected Scene m_scene;
- public void Initialise(IConfigSource config) {}
+ public void Initialise(IConfigSource config)
+ {
+ // TODO: Add config switches to enable/disable this module
+ }
public void AddRegion(Scene scene)
{
@@ -73,7 +77,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
- public void Close() {}
+ public void Close()
+ {
+ m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
+ }
public void RegisterCaps(UUID agentID, Caps caps)
{
@@ -105,33 +112,26 @@ namespace OpenSim.Region.CoreModules.Media.Moap
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
-
- Hashtable osdParams = new Hashtable();
- osdParams = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
-
- foreach (Object key in osdParams.Keys)
- m_log.DebugFormat("[MOAP]: Param {0}={1}", key, osdParams[key]);
-
- string verb = (string)osdParams["verb"];
-
- if ("GET" == verb)
- return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
- if ("UPDATE" == verb)
- return HandleObjectMediaRequestUpdate(path, osdParams, httpRequest, httpResponse);
-
- //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
-
- // TODO: Persist in memory
- // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
- // TODO: Persist in database
-
- return string.Empty;
+
+ 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(omm.Request as ObjectMediaUpdate);
+
+ throw new Exception(
+ string.Format(
+ "[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}",
+ omm.Request.GetType()));
}
- protected string HandleObjectMediaRequestGet(
- string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
- {
- UUID primId = (UUID)osdParams["object_id"];
+ protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
+ {
+ //UUID primId = (UUID)osdParams["object_id"];
+ UUID primId = omr.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
@@ -179,10 +179,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return rawResp;
}
- protected string HandleObjectMediaRequestUpdate(
- string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
{
- UUID primId = (UUID)osdParams["object_id"];
+ UUID primId = omu.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
@@ -194,37 +193,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- List cookedMediaEntries = new List();
-
- ArrayList rawMediaEntries = (ArrayList)osdParams["object_media_data"];
- foreach (Object obj in rawMediaEntries)
- {
- Hashtable rawMe = (Hashtable)obj;
-
- // TODO: Yeah, I know this is silly. Very soon use existing better code in libomv to do this.
- MediaEntry cookedMe = new MediaEntry();
- cookedMe.EnableAlterntiveImage = (bool)rawMe["alt_image_enable"];
- cookedMe.AutoLoop = (bool)rawMe["auto_loop"];
- cookedMe.AutoPlay = (bool)rawMe["auto_play"];
- cookedMe.AutoScale = (bool)rawMe["auto_scale"];
- cookedMe.AutoZoom = (bool)rawMe["auto_zoom"];
- cookedMe.InteractOnFirstClick = (bool)rawMe["first_click_interact"];
- cookedMe.Controls = (MediaControls)rawMe["controls"];
- cookedMe.HomeURL = (string)rawMe["home_url"];
- cookedMe.CurrentURL = (string)rawMe["current_url"];
- cookedMe.Height = (int)rawMe["height_pixels"];
- cookedMe.Width = (int)rawMe["width_pixels"];
- cookedMe.ControlPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_control"].ToString());
- cookedMe.InteractPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_interact"].ToString());
- cookedMe.EnableWhiteList = (bool)rawMe["whitelist_enable"];
- //cookedMe.WhiteList = (string[])rawMe["whitelist"];
-
- cookedMediaEntries.Add(cookedMe);
- }
-
- m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", cookedMediaEntries.Count, primId);
+ m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
- part.Shape.Media = cookedMediaEntries;
+ part.Shape.Media = new List(omu.FaceMedia);
return string.Empty;
}
--
cgit v1.1
From 18b22e26cbc79bc0fbebc1cc0acbdb4b966038c0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 19:25:46 +0100
Subject: start storing a mediaurl on the scene object part
not yet persisted or sent in the update
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 30 +++++++++++++++++-----
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++-
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 568170e..edd0397 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// avatar that set the texture in the first place.
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaRequest));
+ "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaMessage));
// We do get these posts when the url has been changed.
// Even though we're registering for POST we're going to get GETS and UPDATES too
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
///
///
- protected string HandleObjectMediaRequest(
+ protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
@@ -167,10 +167,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
resp.PrimID = primId;
resp.FaceMedia = part.Shape.Media.ToArray();
-
- // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
- // to minimally satisfy for now to get something working
- resp.Version = "x-mv:0000000016/" + UUID.Random();
+ resp.Version = part.MediaUrl;
string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
@@ -197,6 +194,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media = new List(omu.FaceMedia);
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:10D}/{1}", version, UUID.Zero);
+ }
+
+ m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
+
+ // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
+ // to minimally satisfy for now to get something working
+ //resp.Version = "x-mv:0000000016/" + UUID.Random();
+
+ // TODO: schedule full object update for all other avatars. This will trigger them to send an
+ // ObjectMediaRequest once they see that the MediaUrl is different.
+
return string.Empty;
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 59fd805..f83c4cf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -967,13 +967,18 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_updateFlag; }
set { m_updateFlag = value; }
}
+
+ ///
+ /// Used for media on a prim
+ ///
+ public string MediaUrl { get; set; }
[XmlIgnore]
public bool CreateSelected
{
get { return m_createSelected; }
set { m_createSelected = value; }
- }
+ }
#endregion
--
cgit v1.1
From 81f727416d4e59a3fe4d9e3481a3cbba9af3de3f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 19:33:41 +0100
Subject: start sending media url in object full updates
---
OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index d2824bd..ddc963a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -4314,8 +4314,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendLandObjectOwners(LandData land, List groups, Dictionary ownersAndCount)
{
-
-
int notifyCount = ownersAndCount.Count;
ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
@@ -4587,6 +4585,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
update.Scale = data.Shape.Scale;
update.Text = Util.StringToBytes256(data.Text);
+ update.MediaURL = Util.StringToBytes256(data.MediaUrl);
#region PrimFlags
--
cgit v1.1
From 4fb7c1a9e1a26c3afa850685926944508a469b2e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 19:53:03 +0100
Subject: send a full object update out to avatars when a media texture is
initially set
this allows other avatars to see it, but still only after they've clicked on the face
still not handling navigation yet
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index edd0397..0d31732 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -208,12 +208,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
- // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
- // to minimally satisfy for now to get something working
- //resp.Version = "x-mv:0000000016/" + UUID.Random();
-
- // TODO: schedule full object update for all other avatars. This will trigger them to send an
- // ObjectMediaRequest once they see that the MediaUrl is different.
+ // Arguably we don't need to send a full update to the avatar that just changed the texture.
+ part.ScheduleFullUpdate();
return string.Empty;
}
--
cgit v1.1
From ca5d1411a6eb19408033bfa22c8ed765fcc0de99 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 20:25:35 +0100
Subject: handle ObjectMediaNavigateMessage
Other avatars can now see the webpages that you're navigating to.
The requirement for an initial prim click before the texture displayed has gone away.
Flash (e.g. YouTube) appears to work fine.
Still not persisting any media data so this all disappears on server restart
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 69 +++++++++++++++++-----
1 file changed, 55 insertions(+), 14 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 0d31732..c3ec2a6 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -96,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// We do get these posts when the url has been changed.
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateRequest));
+ "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
}
///
@@ -128,6 +128,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
omm.Request.GetType()));
}
+ ///
+ /// Handle a request for media textures
+ ///
+ ///
+ ///
protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
{
//UUID primId = (UUID)osdParams["object_id"];
@@ -138,8 +143,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == part)
{
m_log.WarnFormat(
- "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
- primId);
+ "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
+ primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
@@ -176,6 +181,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return rawResp;
}
+ ///
+ /// Handle an update of media textures.
+ ///
+ /// /param>
+ ///
protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
{
UUID primId = omu.PrimID;
@@ -185,8 +195,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == part)
{
m_log.WarnFormat(
- "[MOAP]: Received am UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
- primId);
+ "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
+ primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
@@ -203,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
string rawVersion = part.MediaUrl.Substring(5, 10);
int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:10D}/{1}", version, UUID.Zero);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
}
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
@@ -223,19 +233,50 @@ namespace OpenSim.Region.CoreModules.Media.Moap
/// /param>
/// /param>
///
- protected string HandleObjectMediaNavigateRequest(
+ protected string HandleObjectMediaNavigateMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
- //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+ 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;
+ }
+
+ m_log.DebugFormat(
+ "[MOAP]: Updating media entry for face {0} on prim {1} {2} to {3}",
+ omn.Face, part.Name, part.UUID, omn.URL);
+
+ MediaEntry me = part.Shape.Media[omn.Face];
+ me.CurrentURL = omn.URL;
+
+ string oldMediaUrl = part.MediaUrl;
+
+ // TODO: refactor into common method
+ string rawVersion = oldMediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+
+ m_log.DebugFormat(
+ "[MOAP]: Updating media url in prim {0} {1} from [{2}] to [{3}]",
+ part.Name, part.UUID, oldMediaUrl, part.MediaUrl);
+
+ part.ScheduleFullUpdate();
- // TODO: Persist in memory
- // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
// TODO: Persist in database
return string.Empty;
- }
-
-
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 53ddcf6d25b5ff85847f3762b15f22d1dd2f49a5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 22:52:31 +0100
Subject: Implement media texture persistence over server restarts for sqlite
This is currently persisting media as an OSDArray serialized to LLSD XML.
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 36 +++++++++++++++++++---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 22 ++++++++++++-
prebuild.xml | 1 +
3 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 81d0ac4..fc9667b 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -34,6 +34,7 @@ using System.Reflection;
using log4net;
using Mono.Data.Sqlite;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@@ -974,6 +975,8 @@ namespace OpenSim.Data.SQLite
createCol(prims, "CollisionSoundVolume", typeof(Double));
createCol(prims, "VolumeDetect", typeof(Int16));
+
+ createCol(prims, "MediaURL", typeof(String));
// Add in contraints
prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
@@ -1021,6 +1024,7 @@ namespace OpenSim.Data.SQLite
// way to specify this as a blob atm
createCol(shapes, "Texture", typeof (Byte[]));
createCol(shapes, "ExtraParams", typeof (Byte[]));
+ createCol(shapes, "Media", typeof(String));
shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
@@ -1339,6 +1343,12 @@ namespace OpenSim.Data.SQLite
if (Convert.ToInt16(row["VolumeDetect"]) != 0)
prim.VolumeDetectActive = true;
+
+ if (!(row["MediaURL"] is System.DBNull))
+ {
+ m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType());
+ prim.MediaUrl = (string)row["MediaURL"];
+ }
return prim;
}
@@ -1614,7 +1624,6 @@ namespace OpenSim.Data.SQLite
row["PayButton3"] = prim.PayPrice[3];
row["PayButton4"] = prim.PayPrice[4];
-
row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
@@ -1674,7 +1683,8 @@ namespace OpenSim.Data.SQLite
row["VolumeDetect"] = 1;
else
row["VolumeDetect"] = 0;
-
+
+ row["MediaURL"] = prim.MediaUrl;
}
///
@@ -1849,6 +1859,19 @@ namespace OpenSim.Data.SQLite
s.TextureEntry = textureEntry;
s.ExtraParams = (byte[]) row["ExtraParams"];
+
+ if (!(row["Media"] is System.DBNull))
+ {
+ string rawMeArray = (string)row["Media"];
+ OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(rawMeArray);
+
+ List mediaEntries = new List();
+ foreach (OSD osdMe in osdMeArray)
+ mediaEntries.Add(MediaEntry.FromOSD(osdMe));
+
+ s.Media = mediaEntries;
+ }
+
return s;
}
@@ -1892,17 +1915,22 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams;
+
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in s.Media)
+ meArray.Add(me.GetOSD());
+
+ row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
///
- ///
+ /// Persistently store a prim.
///
///
///
///
private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
{
-
DataTable prims = ds.Tables["prims"];
DataTable shapes = ds.Tables["primshapes"];
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index f83c4cf..1e5133b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -317,6 +317,11 @@ namespace OpenSim.Region.Framework.Scenes
protected Vector3 m_lastAcceleration;
protected Vector3 m_lastAngularVelocity;
protected int m_lastTerseSent;
+
+ ///
+ /// Stores media texture data
+ ///
+ protected string m_mediaUrl;
// TODO: Those have to be changed into persistent properties at some later point,
// or sit-camera on vehicles will break on sim-crossing.
@@ -962,6 +967,7 @@ namespace OpenSim.Region.Framework.Scenes
TriggerScriptChangedEvent(Changed.SCALE);
}
}
+
public byte UpdateFlag
{
get { return m_updateFlag; }
@@ -971,7 +977,21 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Used for media on a prim
///
- public string MediaUrl { get; set; }
+ public string MediaUrl
+ {
+ get
+ {
+ return m_mediaUrl;
+ }
+
+ set
+ {
+ m_mediaUrl = value;
+
+ if (ParentGroup != null)
+ ParentGroup.HasGroupChanged = true;
+ }
+ }
[XmlIgnore]
public bool CreateSelected
diff --git a/prebuild.xml b/prebuild.xml
index 1eb8fee..1eabc4b 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -2238,6 +2238,7 @@
+
--
cgit v1.1
From 7e3c54213c115fd8edb0423a352b2393fae60363 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 15:47:56 +0100
Subject: Implement llGetPrimMediaParams()
Exposes method to get media entry via IMoapModule
As yet untested.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 19 +++-
OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 47 ++++++++++
.../Shared/Api/Implementation/LSL_Api.cs | 104 +++++++++++++++++++++
.../Shared/Api/Runtime/LSL_Constants.cs | 25 +++++
4 files changed, 193 insertions(+), 2 deletions(-)
create mode 100644 OpenSim/Region/Framework/Interfaces/IMoapModule.cs
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index c3ec2a6..9f74367 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -51,7 +51,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Media.Moap
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
- public class MoapModule : INonSharedRegionModule
+ public class MoapModule : INonSharedRegionModule, IMoapModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -97,7 +97,22 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
"ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
- }
+ }
+
+ public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
+ {
+ if (face < 0)
+ throw new ArgumentException("Face cannot be less than zero");
+
+ List media = part.Shape.Media;
+
+ if (face > media.Count - 1)
+ throw new ArgumentException(
+ string.Format("Face argument was {0} but max is {1}", face, media.Count - 1));
+
+ // TODO: Really need a proper copy constructor down in libopenmetaverse
+ return MediaEntry.FromOSD(media[face].GetOSD());
+ }
///
/// Sets or gets per face media textures.
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
new file mode 100644
index 0000000..4447f34
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -0,0 +1,47 @@
+/*
+ * 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
+{
+ ///
+ /// Provides methods from manipulating media-on-a-prim
+ ///
+ public interface IMoapModule
+ {
+ ///
+ /// Get the media entry for a given prim face.
+ ///
+ ///
+ ///
+ ///
+ MediaEntry GetMediaEntry(SceneObjectPart part, int face);
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 712bd7d..9290fc3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7808,6 +7808,110 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return res;
}
+ public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
+ {
+ m_host.AddScriptLPS(1);
+ ScriptSleep(1000);
+
+ // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
+ // TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
+ // Assuming silently fail means give back an empty list. Ideally, need to check this.
+ if (face < 0 || face > m_host.Shape.Media.Count - 1)
+ return new LSL_List();
+
+ return GetLinkPrimMediaParams(face, rules);
+ }
+
+ public LSL_List GetLinkPrimMediaParams(int face, LSL_List rules)
+ {
+ IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ MediaEntry me = module.GetMediaEntry(m_host, face);
+
+ 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;
+ }
+
//
//
// The .NET definition of base 64 is:
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index dba6502..9a64f8c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -517,6 +517,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int TOUCH_INVALID_FACE = -1;
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
+
+ // constants for llGetPrimMediaParams
+ 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;
// Constants for default textures
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
--
cgit v1.1
From 4a92046b589a0ced240cbf5b174855daf5504a4f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 19:46:23 +0100
Subject: implement llSetPrimMediaParams()
Untested
---
OpenSim/Framework/PrimitiveBaseShape.cs | 1 +
.../CoreModules/World/Media/Moap/MoapModule.cs | 54 ++++++++--
OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 14 ++-
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +-
.../Shared/Api/Implementation/LSL_Api.cs | 113 ++++++++++++++++++++-
.../Shared/Api/Runtime/LSL_Constants.cs | 12 ++-
6 files changed, 184 insertions(+), 13 deletions(-)
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 517dbf6..85638ca 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -176,6 +176,7 @@ namespace OpenSim.Framework
///
/// Entries to store media textures on each face
///
+ /// Do not change this value directly - always do it through an IMoapModule.
public List Media { get; set; }
public PrimitiveBaseShape()
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 9f74367..064047d 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -102,16 +102,54 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
+ throw new ArgumentException("Face cannot be less than zero");
+
+ int maxFaces = part.GetNumberOfSides() - 1;
+ if (face > maxFaces)
+ throw new ArgumentException(
+ string.Format("Face argument was {0} but max is {1}", face, maxFaces));
- List media = part.Shape.Media;
+ List media = part.Shape.Media;
- if (face > media.Count - 1)
+ if (null == media)
+ {
+ return null;
+ }
+ else
+ {
+ // TODO: Really need a proper copy constructor down in libopenmetaverse
+ return MediaEntry.FromOSD(media[face].GetOSD());
+ }
+ }
+
+ public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
+ {
+ if (face < 0)
+ throw new ArgumentException("Face cannot be less than zero");
+
+ int maxFaces = part.GetNumberOfSides() - 1;
+ if (face > maxFaces)
throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, media.Count - 1));
+ string.Format("Face argument was {0} but max is {1}", face, maxFaces));
- // TODO: Really need a proper copy constructor down in libopenmetaverse
- return MediaEntry.FromOSD(media[face].GetOSD());
+ if (null == part.Shape.Media)
+ part.Shape.Media = new List(maxFaces);
+
+ part.Shape.Media[face] = me;
+
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ }
+
+ part.ScheduleFullUpdate();
}
///
@@ -140,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
throw new Exception(
string.Format(
"[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}",
- omm.Request.GetType()));
+ omm.Request.GetType()));
}
///
@@ -233,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
- // Arguably we don't need to send a full update to the avatar that just changed the texture.
+ // Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
return string.Empty;
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
index 4447f34..31bb6d8 100644
--- a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -39,9 +39,19 @@ namespace OpenSim.Region.Framework.Interfaces
///
/// Get the media entry for a given prim face.
///
+ /// A copy of the media entry is returned rather than the original, so this can be altered at will without
+ /// affecting the original settings.
///
///
///
- MediaEntry GetMediaEntry(SceneObjectPart part, int face);
- }
+ MediaEntry GetMediaEntry(SceneObjectPart part, int face);
+
+ ///
+ /// Set the media entry for a given prim face.
+ ///
+ ///
+ ///
+ ///
+ void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me);
+ }
}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1e5133b..8830fb0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -975,8 +975,9 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Used for media on a prim
+ /// Used for media on a prim.
///
+ /// Do not change this value directly - always do it through an IMoapModule.
public string MediaUrl
{
get
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9290fc3..2600790 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7816,7 +7816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
// TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
// Assuming silently fail means give back an empty list. Ideally, need to check this.
- if (face < 0 || face > m_host.Shape.Media.Count - 1)
+ if (face < 0 || face > m_host.GetNumberOfSides() - 1)
return new LSL_List();
return GetLinkPrimMediaParams(face, rules);
@@ -7830,6 +7830,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
MediaEntry me = module.GetMediaEntry(m_host, face);
+ // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
+ if (null == me)
+ return new LSL_List();
+
LSL_List res = new LSL_List();
for (int i = 0; i < rules.Length; i++)
@@ -7912,6 +7916,113 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return res;
}
+ public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
+ {
+ m_host.AddScriptLPS(1);
+ ScriptSleep(1000);
+
+ // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
+ // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
+ // Don't perform the media check directly
+ if (face < 0 || face > m_host.GetNumberOfSides() - 1)
+ return ScriptBaseClass.LSL_STATUS_OK;
+
+ return SetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
+ {
+ IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ MediaEntry me = module.GetMediaEntry(m_host, face);
+ if (null == me)
+ me = new MediaEntry();
+
+ int i = 0;
+
+ while (i < rules.Length - 1)
+ {
+ int code = rules.GetLSLIntegerItem(i++);
+
+ switch (code)
+ {
+ case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
+ me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
+ int v = rules.GetLSLIntegerItem(i++);
+ if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
+ me.Controls = MediaControls.Standard;
+ else
+ me.Controls = MediaControls.Mini;
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
+ me.CurrentURL = rules.GetLSLStringItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
+ me.HomeURL = rules.GetLSLStringItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
+ me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
+ me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
+ me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
+ me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
+ me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
+ me.Width = (int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
+ me.Height = (int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
+ me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
+ string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
+ List whiteListUrls = new List();
+ Array.ForEach(
+ rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
+ me.WhiteList = whiteListUrls.ToArray();
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
+ me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
+ me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
+ break;
+ }
+ }
+
+ module.SetMediaEntry(m_host, face, me);
+
+ return ScriptBaseClass.LSL_STATUS_OK;
+ }
+
//
//
// The .NET definition of base 64 is:
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9a64f8c..6ef786a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -518,7 +518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
- // constants for llGetPrimMediaParams
+ // constants for llGetPrimMediaParams/llSetPrimMediaParams
public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
public const int PRIM_MEDIA_CONTROLS = 1;
public const int PRIM_MEDIA_CURRENT_URL = 2;
@@ -542,6 +542,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_MEDIA_PERM_OWNER = 1;
public const int PRIM_MEDIA_PERM_GROUP = 2;
public const int PRIM_MEDIA_PERM_ANYONE = 4;
+
+ // extra constants for llSetPrimMediaParams
+ public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
+ public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
+ public static readonly LSLInteger LSL_STATUS_TYPE_MISMATCH = new LSLInteger(1001);
+ public static readonly LSLInteger LSL_STATUS_BOUNDS_ERROR = new LSLInteger(1002);
+ public static readonly LSLInteger LSL_STATUS_NOT_FOUND = new LSLInteger(1003);
+ public static readonly LSLInteger LSL_STATUS_NOT_SUPPORTED = new LSLInteger(1004);
+ public static readonly LSLInteger LSL_STATUS_INTERNAL_ERROR = new LSLInteger(1999);
+ public static readonly LSLInteger LSL_STATUS_WHITELIST_FAILED = new LSLInteger(2001);
// Constants for default textures
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
--
cgit v1.1
From 312eb5e42ee3812f33ced0c2250f908daf23a864 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 19:48:20 +0100
Subject: minor: correct a few method names and change accessability
---
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 2600790..ff2f6a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7819,10 +7819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (face < 0 || face > m_host.GetNumberOfSides() - 1)
return new LSL_List();
- return GetLinkPrimMediaParams(face, rules);
+ return GetPrimMediaParams(face, rules);
}
- public LSL_List GetLinkPrimMediaParams(int face, LSL_List rules)
+ private LSL_List GetPrimMediaParams(int face, LSL_List rules)
{
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
if (null == module)
@@ -7930,7 +7930,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return SetPrimMediaParams(face, rules);
}
- public LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
+ private LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
{
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
if (null == module)
--
cgit v1.1
From 9231fc0f3127f5c6263ce630ee7a5c246d7e823f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 20:15:10 +0100
Subject: factor out common face parameter checking code
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 56 ++++++++--------------
1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 064047d..9dd46eb 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -101,13 +101,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
- if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
-
- int maxFaces = part.GetNumberOfSides() - 1;
- if (face > maxFaces)
- throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, maxFaces));
+ CheckFaceParam(part, face);
List media = part.Shape.Media;
@@ -124,16 +118,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
{
- if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
-
- int maxFaces = part.GetNumberOfSides() - 1;
- if (face > maxFaces)
- throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, maxFaces));
+ CheckFaceParam(part, face);
if (null == part.Shape.Media)
- part.Shape.Media = new List(maxFaces);
+ part.Shape.Media = new List(part.GetNumberOfSides());
part.Shape.Media[face] = me;
@@ -187,8 +175,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
///
protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
- {
- //UUID primId = (UUID)osdParams["object_id"];
+ {
UUID primId = omr.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
@@ -200,23 +187,6 @@ namespace OpenSim.Region.CoreModules.Media.Moap
primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
-
- /*
- int faces = part.GetNumberOfSides();
- m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
-
- MediaEntry[] media = new MediaEntry[faces];
- for (int i = 0; i < faces; i++)
- {
- MediaEntry me = new MediaEntry();
- me.HomeURL = "google.com";
- me.CurrentURL = "google.com";
- me.AutoScale = true;
- //me.Height = 300;
- //me.Width = 240;
- media[i] = me;
- }
- */
if (null == part.Shape.Media)
return string.Empty;
@@ -330,6 +300,22 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// TODO: Persist in database
return string.Empty;
- }
+ }
+
+ ///
+ /// Check that the face number is valid for the given prim.
+ ///
+ ///
+ ///
+ 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));
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 7691a638e316ff9580e348b570c4a0c727587bc6 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 20:18:10 +0100
Subject: factor out common code for updating the media url
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 68 +++++++++-------------
1 file changed, 27 insertions(+), 41 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 9dd46eb..242ff6c 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -124,19 +124,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media = new List(part.GetNumberOfSides());
part.Shape.Media[face] = me;
-
- if (null == part.MediaUrl)
- {
- // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
- part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
- }
- else
- {
- string rawVersion = part.MediaUrl.Substring(5, 10);
- int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
- }
-
+ UpdateMediaUrl(part);
part.ScheduleFullUpdate();
}
@@ -223,23 +211,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
+ m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
part.Shape.Media = new List(omu.FaceMedia);
- if (null == part.MediaUrl)
- {
- // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
- part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
- }
- else
- {
- string rawVersion = part.MediaUrl.Substring(5, 10);
- int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
- }
-
- m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
+ UpdateMediaUrl(part);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
@@ -267,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
UUID primId = omn.PrimID;
- SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
+ SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
if (null == part)
{
@@ -284,20 +260,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
MediaEntry me = part.Shape.Media[omn.Face];
me.CurrentURL = omn.URL;
- string oldMediaUrl = part.MediaUrl;
-
- // TODO: refactor into common method
- string rawVersion = oldMediaUrl.Substring(5, 10);
- int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
-
- m_log.DebugFormat(
- "[MOAP]: Updating media url in prim {0} {1} from [{2}] to [{3}]",
- part.Name, part.UUID, oldMediaUrl, part.MediaUrl);
-
- part.ScheduleFullUpdate();
+ UpdateMediaUrl(part);
- // TODO: Persist in database
+ part.ScheduleFullUpdate();
return string.Empty;
}
@@ -317,5 +282,26 @@ namespace OpenSim.Region.CoreModules.Media.Moap
throw new ArgumentException(
string.Format("Face argument was {0} but max is {1}", face, maxFaces));
}
+
+ ///
+ /// Update the media url of the given part
+ ///
+ ///
+ protected void UpdateMediaUrl(SceneObjectPart part)
+ {
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ }
+
+ m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From d4684da8bd73ff088192da9f06657d32d6672342 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 21:33:27 +0100
Subject: fix problem persisting when only one face had a media texture
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 10 ++++++++--
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 7 +++++++
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index fc9667b..51f4cef 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -1867,7 +1867,10 @@ namespace OpenSim.Data.SQLite
List mediaEntries = new List();
foreach (OSD osdMe in osdMeArray)
- mediaEntries.Add(MediaEntry.FromOSD(osdMe));
+ {
+ MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
+ mediaEntries.Add(me);
+ }
s.Media = mediaEntries;
}
@@ -1918,7 +1921,10 @@ namespace OpenSim.Data.SQLite
OSDArray meArray = new OSDArray();
foreach (MediaEntry me in s.Media)
- meArray.Add(me.GetOSD());
+ {
+ OSD osd = (null == me ? new OSD() : me.GetOSD());
+ meArray.Add(osd);
+ }
row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 242ff6c..93a1ae8 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -212,6 +212,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
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);
+// }
part.Shape.Media = new List(omu.FaceMedia);
--
cgit v1.1
From 01ff3c9f9f7fb223e81164647391e52ec4e975d6 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 21:43:36 +0100
Subject: fix issue with GetMediaEntry if the face requested wasn't set to a
media texture
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 93a1ae8..43953a7 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -112,7 +112,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
else
{
// TODO: Really need a proper copy constructor down in libopenmetaverse
- return MediaEntry.FromOSD(media[face].GetOSD());
+ MediaEntry me = media[face];
+ return (null == me ? null : MediaEntry.FromOSD(me.GetOSD()));
}
}
--
cgit v1.1
From 4b0c5711b5099f3611783e103629deaa9033cd7f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 22:00:45 +0100
Subject: implement llClearPrimMedia()
untested
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 5 +++++
OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 10 ++++++++++
.../Shared/Api/Implementation/LSL_Api.cs | 20 ++++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 43953a7..8699800 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -129,6 +129,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.ScheduleFullUpdate();
}
+ public void ClearMediaEntry(SceneObjectPart part, int face)
+ {
+ SetMediaEntry(part, face, null);
+ }
+
///
/// Sets or gets per face media textures.
///
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
index 31bb6d8..24b6860 100644
--- a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -53,5 +53,15 @@ namespace OpenSim.Region.Framework.Interfaces
///
///
void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me);
+
+ ///
+ /// Clear the media entry for a given prim face.
+ ///
+ ///
+ /// This is the equivalent of setting a media entry of null
+ ///
+ ///
+ /// /param>
+ void ClearMediaEntry(SceneObjectPart part, int face);
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ff2f6a2..4773a50 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -8023,6 +8023,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ module.ClearMediaEntry(m_host, face);
+
+ return ScriptBaseClass.LSL_STATUS_OK;
+ }
+
//
//
// The .NET definition of base 64 is:
--
cgit v1.1
From 55caab1efdf9a397141d6e56193dff4513107d95 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 22:27:11 +0100
Subject: Fire CHANGED_MEDIA event if a media texture is set or cleared
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 5 +++++
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++-
OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 1 +
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 8699800..8bccab4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media[face] = me;
UpdateMediaUrl(part);
part.ScheduleFullUpdate();
+ part.TriggerScriptChangedEvent(Changed.MEDIA);
}
public void ClearMediaEntry(SceneObjectPart part, int face)
@@ -233,6 +234,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// 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;
}
@@ -277,6 +280,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.ScheduleFullUpdate();
+ part.TriggerScriptChangedEvent(Changed.MEDIA);
+
return string.Empty;
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 8830fb0..3165f4d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes
OWNER = 128,
REGION_RESTART = 256,
REGION = 512,
- TELEPORT = 1024
+ TELEPORT = 1024,
+ MEDIA = 2048
}
// I don't really know where to put this except here.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 6ef786a..06f9426 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -276,6 +276,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int CHANGED_REGION_RESTART = 256;
public const int CHANGED_REGION = 512;
public const int CHANGED_TELEPORT = 1024;
+ public const int CHANGED_MEDIA = 2048;
public const int CHANGED_ANIMATION = 16384;
public const int TYPE_INVALID = 0;
public const int TYPE_INTEGER = 1;
--
cgit v1.1
From 1a1d42db8382c806cbb9c00f0c1c2250cab795e9 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 19:28:07 +0100
Subject: discard an object media update message if it tries to set more media
textures than the prim has faces
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 8bccab4..378ff4a 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -227,6 +227,14 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// 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;
+ }
+
part.Shape.Media = new List(omu.FaceMedia);
UpdateMediaUrl(part);
--
cgit v1.1
From 6f644f5322ee0c5ffe6c654387981f1c13f7112d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:19:45 +0100
Subject: implement prim media control permissions serverside in order to stop
bad clients
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 87 ++++++++++++++++------
.../World/Permissions/PermissionsModule.cs | 43 ++++++++++-
.../Region/Framework/Scenes/Scene.Permissions.cs | 21 +++++-
3 files changed, 127 insertions(+), 24 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 378ff4a..d7aede9 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -58,8 +58,21 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
+ ///
+ /// The scene to which this module is attached
+ ///
protected Scene m_scene;
+ ///
+ /// Track the ObjectMedia capabilities given to users
+ ///
+ protected Dictionary m_omCapUsers = new Dictionary();
+
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users
+ ///
+ protected Dictionary m_omuCapUsers = new Dictionary();
+
public void Initialise(IConfigSource config)
{
// TODO: Add config switches to enable/disable this module
@@ -87,16 +100,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
- // We do receive a post to ObjectMedia when a new avatar enters the region - though admittedly this is the
- // avatar that set the texture in the first place.
- // Even though we're registering for POST we're going to get GETS and UPDATES too
- caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaMessage));
+ string omCapUrl = "/CAPS/" + UUID.Random();
+
+ lock (m_omCapUsers)
+ {
+ m_omCapUsers[omCapUrl] = agentID;
+
+ // 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();
- // We do get these posts when the url has been changed.
- // Even though we're registering for POST we're going to get GETS and UPDATES too
- caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
+ lock (m_omuCapUsers)
+ {
+ m_omuCapUsers[omuCapUrl] = agentID;
+
+ // 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 MediaEntry GetMediaEntry(SceneObjectPart part, int face)
@@ -147,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia path [{0}], raw request [{1}]", path, request);
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
ObjectMediaMessage omm = new ObjectMediaMessage();
@@ -156,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (omm.Request is ObjectMediaRequest)
return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest);
else if (omm.Request is ObjectMediaUpdate)
- return HandleObjectMediaUpdate(omm.Request as ObjectMediaUpdate);
+ return HandleObjectMediaUpdate(path, omm.Request as ObjectMediaUpdate);
throw new Exception(
string.Format(
@@ -165,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
///
- /// Handle a request for media textures
+ /// Handle a fetch request for media textures
///
///
///
@@ -202,9 +226,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
/// Handle an update of media textures.
///
+ /// Path on which this request was made
/// /param>
///
- protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
+ protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu)
{
UUID primId = omu.PrimID;
@@ -216,16 +241,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
"[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);
-// }
+ 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())
{
@@ -235,7 +260,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- part.Shape.Media = new List(omu.FaceMedia);
+ List media = part.Shape.Media;
+
+ if (null == media)
+ {
+ part.Shape.Media = new List(omu.FaceMedia);
+ }
+ else
+ {
+ // We need to go through the media textures one at a time to make sure that we have permission
+ // to change them
+ UUID agentId = default(UUID);
+
+ lock (m_omCapUsers)
+ agentId = m_omCapUsers[path];
+
+ for (int i = 0; i < media.Count; i++)
+ {
+ if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
+ media[i] = omu.FaceMedia[i];
+ }
+ }
UpdateMediaUrl(part);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 69b247c..358ea59 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private Dictionary GrantYP = new Dictionary();
private IFriendsModule m_friendsModule;
private IGroupsModule m_groupsModule;
+ private IMoapModule m_moapModule;
#endregion
@@ -248,6 +249,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
+
+ m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.AddCommand(this, "bypass permissions",
"bypass permissions ",
@@ -393,6 +396,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_groupsModule == null)
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
+
+ m_moapModule = m_scene.RequestModuleInterface();
}
public void Close()
@@ -1893,5 +1898,41 @@ namespace OpenSim.Region.CoreModules.World.Permissions
}
return(false);
}
+
+ private bool CanControlPrimMedia(UUID agentID, UUID primID, int 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;
+
+ if (IsAdministrator(agentID))
+ return true;
+
+ if ((me.ControlPermissions & MediaPermission.Anyone) == MediaPermission.Anyone)
+ return true;
+
+ if ((me.ControlPermissions & MediaPermission.Owner) == MediaPermission.Owner)
+ {
+ if (agentID == part.OwnerID)
+ return true;
+ }
+
+ if ((me.ControlPermissions & MediaPermission.Group) == MediaPermission.Group)
+ {
+ if (IsGroupMember(part.GroupID, agentID, 0))
+ return true;
+ }
+
+ return false;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 7dab04f..70af978 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -81,6 +81,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene);
+ public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion
public class ScenePermissions
@@ -139,6 +140,7 @@ namespace OpenSim.Region.Framework.Scenes
public event CopyUserInventoryHandler OnCopyUserInventory;
public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport;
+ public event ControlPrimMediaHandler OnControlPrimMedia;
#endregion
#region Object Permission Checks
@@ -947,5 +949,20 @@ namespace OpenSim.Region.Framework.Scenes
}
return true;
}
+
+ public bool CanControlPrimMedia(UUID userID, UUID primID, int face)
+ {
+ ControlPrimMediaHandler handler = OnControlPrimMedia;
+ if (handler != null)
+ {
+ Delegate[] list = handler.GetInvocationList();
+ foreach (ControlPrimMediaHandler h in list)
+ {
+ if (h(userID, primID, face) == false)
+ return false;
+ }
+ }
+ return true;
+ }
}
-}
+}
\ No newline at end of file
--
cgit v1.1
From 2ad9789b1ca85f64a8fd15be66d62b52bf8363f7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:46:49 +0100
Subject: factor out soon to be common media permissions check code
---
.../CoreModules/World/Permissions/PermissionsModule.cs | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 358ea59..2344e96 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -1914,25 +1914,30 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (null == me)
return true;
+ return GenericPrimMediaPermission(part, agentID, me.ControlPermissions);
+ }
+
+ private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms)
+ {
if (IsAdministrator(agentID))
return true;
- if ((me.ControlPermissions & MediaPermission.Anyone) == MediaPermission.Anyone)
+ if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone)
return true;
- if ((me.ControlPermissions & MediaPermission.Owner) == MediaPermission.Owner)
+ if ((perms & MediaPermission.Owner) == MediaPermission.Owner)
{
if (agentID == part.OwnerID)
return true;
}
- if ((me.ControlPermissions & MediaPermission.Group) == MediaPermission.Group)
+ if ((perms & MediaPermission.Group) == MediaPermission.Group)
{
if (IsGroupMember(part.GroupID, agentID, 0))
return true;
}
- return false;
+ return false;
}
}
}
\ No newline at end of file
--
cgit v1.1
From a4c6c4de9114497de831594e5673788d323d8e65 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:58:19 +0100
Subject: implement serverside checks for media texture navigation in order to
stop naughty clients
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 20 ++++++++++++++------
.../World/Permissions/PermissionsModule.cs | 21 ++++++++++++++++++++-
.../Region/Framework/Scenes/Scene.Permissions.cs | 19 ++++++++++++++++++-
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index d7aede9..09786ec 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -245,12 +245,12 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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);
- }
+// 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())
{
@@ -322,6 +322,14 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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]: Updating media entry for face {0} on prim {1} {2} to {3}",
omn.Face, part.Name, part.UUID, omn.URL);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 2344e96..3a690af 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -251,6 +251,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
+ m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
m_scene.AddCommand(this, "bypass permissions",
"bypass permissions ",
@@ -1915,7 +1916,25 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return true;
return GenericPrimMediaPermission(part, agentID, me.ControlPermissions);
- }
+ }
+
+ private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int 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;
+
+ return GenericPrimMediaPermission(part, agentID, me.InteractPermissions);
+ }
private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms)
{
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 70af978..0033900 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -82,6 +82,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene);
public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
+ public delegate bool InteractWithPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion
public class ScenePermissions
@@ -141,6 +142,7 @@ namespace OpenSim.Region.Framework.Scenes
public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport;
public event ControlPrimMediaHandler OnControlPrimMedia;
+ public event InteractWithPrimMediaHandler OnInteractWithPrimMedia;
#endregion
#region Object Permission Checks
@@ -963,6 +965,21 @@ namespace OpenSim.Region.Framework.Scenes
}
}
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;
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From e44e1ccbd32745e25ecf750a6bd0e212e4dfd535 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Jul 2010 00:16:37 +0100
Subject: implement code to deregister users on DeregisterCaps
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 37 ++++++++++++++++++++--
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 09786ec..ce4e921 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -64,15 +64,25 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected Scene m_scene;
///
- /// Track the ObjectMedia capabilities given to users
+ /// Track the ObjectMedia capabilities given to users keyed by path
///
protected Dictionary m_omCapUsers = new Dictionary();
///
- /// Track the ObjectMediaUpdate capabilities given to users
+ /// Track the ObjectMedia capabilities given to users keyed by agent. Lock m_omCapUsers to manipulate.
+ ///
+ protected Dictionary m_omCapUrls = new Dictionary();
+
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users keyed by path
///
protected Dictionary m_omuCapUsers = new Dictionary();
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users keyed by agent. Lock m_omuCapUsers to manipulate
+ ///
+ protected Dictionary m_omuCapUrls = new Dictionary();
+
public void Initialise(IConfigSource config)
{
// TODO: Add config switches to enable/disable this module
@@ -88,11 +98,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void RegionLoaded(Scene scene)
{
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
}
public void Close()
{
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
}
public void RegisterCaps(UUID agentID, Caps caps)
@@ -105,6 +117,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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(
@@ -116,12 +129,30 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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 DeregisterCaps(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);
+ }
+ }
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
--
cgit v1.1
From c3ee451325893df8f102c52f05f791289b7c61f6 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Jul 2010 23:26:24 +0100
Subject: fix previous media interact serverside checking. perform very basic
serverside url whitelist checks
at the moment, only checking for the exact name prefix is implemented
for some reason, whitelists are not persisting
this commit also fixes a very recent problem where setting any media texture parameters after the initial configuration would not work
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 71 ++++++++++++++++++++--
.../World/Permissions/PermissionsModule.cs | 30 +++++++--
2 files changed, 91 insertions(+), 10 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index ce4e921..3c546c4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -91,6 +91,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void AddRegion(Scene scene)
{
m_scene = scene;
+ m_scene.RegisterModuleInterface(this);
}
public void RemoveRegion(Scene scene) {}
@@ -156,20 +157,28 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
+ MediaEntry me = null;
+
CheckFaceParam(part, face);
List media = part.Shape.Media;
if (null == media)
{
- return null;
+ me = null;
}
else
- {
+ {
+ me = media[face];
+
// TODO: Really need a proper copy constructor down in libopenmetaverse
- MediaEntry me = media[face];
- return (null == me ? null : MediaEntry.FromOSD(me.GetOSD()));
+ 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)
@@ -295,6 +304,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == media)
{
+ m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name);
part.Shape.Media = new List(omu.FaceMedia);
}
else
@@ -309,7 +319,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
for (int i = 0; i < media.Count; i++)
{
if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
+ {
media[i] = omu.FaceMedia[i];
+// m_log.DebugFormat("[MOAP]: Set media entry for face {0} on {1}", i, part.Name);
+ }
}
}
@@ -362,10 +375,31 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
m_log.DebugFormat(
- "[MOAP]: Updating media entry for face {0} on prim {1} {2} to {3}",
+ "[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 = 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);
@@ -413,5 +447,32 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
}
+
+ ///
+ /// Check the given url against the given whitelist.
+ ///
+ ///
+ ///
+ /// true if the url matches an entry on the whitelist, false otherwise
+ protected bool CheckUrlAgainstWhitelist(string url, string[] whitelist)
+ {
+ foreach (string rawWlUrl in whitelist)
+ {
+ string wlUrl = rawWlUrl;
+
+ if (!wlUrl.StartsWith("http://"))
+ wlUrl = "http://" + wlUrl;
+
+ m_log.DebugFormat("[MOAP]: Checking whitelist URL {0}", wlUrl);
+
+ if (url.StartsWith(wlUrl))
+ {
+ m_log.DebugFormat("[MOAP]: Whitelist url {0} matches requested url {1}", wlUrl, url);
+ return true;
+ }
+ }
+
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 3a690af..7f6f851 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule");
- List modules=new List(permissionModules.Split(','));
+ List modules = new List(permissionModules.Split(','));
if (!modules.Contains("DefaultPermissionsModule"))
return;
@@ -399,6 +399,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
m_moapModule = m_scene.RequestModuleInterface();
+
+ // 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()
@@ -1901,7 +1905,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
}
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;
@@ -1909,17 +1917,25 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (null == part)
return false;
- MediaEntry me = m_moapModule.GetMediaEntry(part, face);
+ 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;
@@ -1933,13 +1949,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions
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 (IsAdministrator(agentID))
+// return true;
if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone)
return true;
--
cgit v1.1
From aec3b330119a6c4e799939329bd0748ce1a265be Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Jul 2010 23:48:24 +0100
Subject: fix bug where prim persistence would fail if media had never been set
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 51f4cef..7acbd22 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -1919,14 +1919,17 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams;
- OSDArray meArray = new OSDArray();
- foreach (MediaEntry me in s.Media)
+ if (null != s.Media)
{
- OSD osd = (null == me ? new OSD() : me.GetOSD());
- meArray.Add(osd);
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in s.Media)
+ {
+ OSD osd = (null == me ? new OSD() : me.GetOSD());
+ meArray.Add(osd);
+ }
+
+ row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
-
- row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
///
--
cgit v1.1
From e74e591e0b2196bcf58e17f604e2d8d4819c3917 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 00:15:23 +0100
Subject: properly expose prim media LSL functions to scripts
scripts using these functions should now compile but I don't know how well the methods themselves work yet
llSetPrimMedia(), at least, appears to have problems when a current url is set for a face that doesn't yet have a texture
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 2 +-
.../Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 3 +++
.../Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 15 +++++++++++++++
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 3c546c4..4bbac6e 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -186,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
CheckFaceParam(part, face);
if (null == part.Shape.Media)
- part.Shape.Media = new List(part.GetNumberOfSides());
+ part.Shape.Media = new List(new MediaEntry[part.GetNumberOfSides()]);
part.Shape.Media[face] = me;
UpdateMediaUrl(part);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index cba46a3..561e3b3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -62,6 +62,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llBreakLink(int linknum);
LSL_Integer llCeil(double f);
void llClearCameraParams();
+ LSL_Integer llClearPrimMedia(LSL_Integer face);
void llCloseRemoteDataChannel(string channel);
LSL_Float llCloud(LSL_Vector offset);
void llCollisionFilter(string name, string id, int accept);
@@ -162,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_List llGetParcelPrimOwners(LSL_Vector pos);
LSL_Integer llGetPermissions();
LSL_Key llGetPermissionsKey();
+ LSL_List llGetPrimMediaParams(int face, LSL_List rules);
LSL_Vector llGetPos();
LSL_List llGetPrimitiveParams(LSL_List rules);
LSL_Integer llGetRegionAgentCount();
@@ -332,6 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetParcelMusicURL(string url);
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
void llSetPos(LSL_Vector pos);
+ LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
void llSetPrimitiveParams(LSL_List rules);
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
void llSetPrimURL(string url);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 3339995..451163f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -1832,5 +1832,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
}
+
+ public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
+ {
+ return m_LSL_Functions.llGetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
+ {
+ return m_LSL_Functions.llSetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer llClearPrimMedia(LSL_Integer face)
+ {
+ return m_LSL_Functions.llClearPrimMedia(face);
+ }
}
}
--
cgit v1.1
From 610a2626a5e60cf5c3511ecf4d4187e9da71d336 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 21:14:55 +0100
Subject: Implement * end wildcard for whitelist urls
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 4bbac6e..c24e6d5 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -460,6 +460,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
string wlUrl = rawWlUrl;
+ // Deal with a line-ending wildcard
+ if (wlUrl.EndsWith("*"))
+ wlUrl = wlUrl.Remove(wlUrl.Length - 1);
+
if (!wlUrl.StartsWith("http://"))
wlUrl = "http://" + wlUrl;
@@ -467,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (url.StartsWith(wlUrl))
{
- m_log.DebugFormat("[MOAP]: Whitelist url {0} matches requested url {1}", wlUrl, url);
+ m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, url);
return true;
}
}
--
cgit v1.1
From 2ec6e3b4402ae7acf9e3f0da77c12203c2b44ff9 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 21:40:44 +0100
Subject: refactor: simplify current whitelist url checking by using System.Uri
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index c24e6d5..c8e72ca 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -451,11 +451,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
/// Check the given url against the given whitelist.
///
- ///
+ ///
///
/// true if the url matches an entry on the whitelist, false otherwise
- protected bool CheckUrlAgainstWhitelist(string url, string[] whitelist)
+ protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist)
{
+ Uri url = new Uri(rawUrl);
+
foreach (string rawWlUrl in whitelist)
{
string wlUrl = rawWlUrl;
@@ -464,14 +466,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (wlUrl.EndsWith("*"))
wlUrl = wlUrl.Remove(wlUrl.Length - 1);
- if (!wlUrl.StartsWith("http://"))
- wlUrl = "http://" + wlUrl;
-
m_log.DebugFormat("[MOAP]: Checking whitelist URL {0}", wlUrl);
+
+ string urlToMatch = url.Authority + url.AbsolutePath;
- if (url.StartsWith(wlUrl))
+ if (urlToMatch.StartsWith(wlUrl))
{
- m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, url);
+ m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, urlToMatch);
return true;
}
}
--
cgit v1.1
From 0bec4f5ea5b2586bcc3899ad084e30d42218cb44 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 21:51:57 +0100
Subject: Handle checking of line starting "*" wildcard for whitelist patterns
A line starting * can only be applied to the domain, not the path
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 30 ++++++++++++++++------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index c8e72ca..cbe9af2 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -458,22 +458,36 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
Uri url = new Uri(rawUrl);
- foreach (string rawWlUrl in whitelist)
+ foreach (string origWlUrl in whitelist)
{
- string wlUrl = rawWlUrl;
+ 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 {0}", wlUrl);
+ m_log.DebugFormat("[MOAP]: Checking whitelist URL pattern {0}", origWlUrl);
- string urlToMatch = url.Authority + url.AbsolutePath;
-
- if (urlToMatch.StartsWith(wlUrl))
+ // 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
{
- m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, urlToMatch);
- return true;
+ string urlToMatch = url.Authority + url.AbsolutePath;
+
+ if (urlToMatch.StartsWith(wlUrl))
+ {
+ m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl);
+ return true;
+ }
}
}
--
cgit v1.1
From 2c3207df076b6633c7b8a777adb8583eba6a6d82 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 23:28:36 +0100
Subject: add missing regionstore migration file for new fields. D'oh!
this should enable persistence now
---
OpenSim/Data/SQLite/Resources/020_RegionStore.sql | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 OpenSim/Data/SQLite/Resources/020_RegionStore.sql
diff --git a/OpenSim/Data/SQLite/Resources/020_RegionStore.sql b/OpenSim/Data/SQLite/Resources/020_RegionStore.sql
new file mode 100644
index 0000000..39cb752
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/020_RegionStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
+ALTER TABLE primshapes ADD COLUMN Media TEXT;
+
+COMMIT;
\ No newline at end of file
--
cgit v1.1
From 8e67f6dc44424a53f07cd0c2af0ecf53d7ca30b7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 21 Jul 2010 14:25:21 +0100
Subject: start adding user ids to the media urls
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 28 ++++++++++++----------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index cbe9af2..6755df7 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media = new List(new MediaEntry[part.GetNumberOfSides()]);
part.Shape.Media[face] = me;
- UpdateMediaUrl(part);
+ UpdateMediaUrl(part, UUID.Zero);
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
}
@@ -300,6 +300,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
+ UUID agentId = default(UUID);
+
+ lock (m_omCapUsers)
+ agentId = m_omCapUsers[path];
+
List media = part.Shape.Media;
if (null == media)
@@ -310,12 +315,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
else
{
// We need to go through the media textures one at a time to make sure that we have permission
- // to change them
- UUID agentId = default(UUID);
-
- lock (m_omCapUsers)
- agentId = m_omCapUsers[path];
-
+ // to change them
for (int i = 0; i < media.Count; i++)
{
if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
@@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
- UpdateMediaUrl(part);
+ UpdateMediaUrl(part, agentId);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
@@ -402,13 +402,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
me.CurrentURL = omn.URL;
- UpdateMediaUrl(part);
+ UpdateMediaUrl(part, agentId);
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
- return string.Empty;
+ return OSDParser.SerializeLLSDXmlString(new OSD());
}
///
@@ -431,12 +431,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
/// Update the media url of the given part
///
///
- protected void UpdateMediaUrl(SceneObjectPart part)
+ ///
+ /// The id to attach to this update. Normally, this is the user that changed the
+ /// texture
+ ///
+ 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/" + UUID.Zero;
+ part.MediaUrl = "x-mv:0000000000/" + updateId;
}
else
{
--
cgit v1.1
From 6ef2a72c70882810c1ca1b940d6afdbecdbe78a4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 21 Jul 2010 17:12:43 +0100
Subject: Properly set TextureEntry.MediaFlags when a media texture is set
Media flags is cleared via a direct TextureEntry update from the client. If the clearing leaves no media textures on the prim, then a CAP ObjectMediaUpdate is not received. If there are still media textures present then one is received.
This change fixes drag-and-drop on Windows (and Mac?) clients. It may also fix problems with clearing and then subsequently setting new media textures.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 46 ++++++++++++++++++++--
1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 6755df7..4818546 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -311,19 +311,59 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name);
part.Shape.Media = new List(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;
+
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);
--
cgit v1.1
From 8e8076c947462980d849ac2fac33fc0640ea1a31 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 21 Jul 2010 19:32:05 +0100
Subject: also add avatar id to an updated media url - not just new ones
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 4818546..0130ff9 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -486,7 +486,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
string rawVersion = part.MediaUrl.Substring(5, 10);
int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ part.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);
--
cgit v1.1
From 4736e38e794925946675a8d510f3f9d2fc4e9d8c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 19:56:55 +0100
Subject: Put a wrapper around the media texture region serialization
THIS WILL BREAK EXISTING MEDIA TEXTURE PERSISTENCE. Please delete your existing sqlite databases if you are experimenting with this branch.
This wrapper will make it easier to maintain compatibility if the media texture data evolves.
This will also make it easier to store non-sl media texture data.
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 58 ++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 7acbd22..b564419 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -31,6 +31,7 @@ using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
+using System.Xml;
using log4net;
using Mono.Data.Sqlite;
using OpenMetaverse;
@@ -1862,17 +1863,26 @@ namespace OpenSim.Data.SQLite
if (!(row["Media"] is System.DBNull))
{
- string rawMeArray = (string)row["Media"];
- OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(rawMeArray);
-
- List mediaEntries = new List();
- foreach (OSD osdMe in osdMeArray)
+ using (StringReader sr = new StringReader((string)row["Media"]))
{
- MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
- mediaEntries.Add(me);
+ using (XmlTextReader xtr = new XmlTextReader(sr))
+ {
+ xtr.ReadStartElement("osmedia");
+
+ OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
+
+ List mediaEntries = new List();
+ foreach (OSD osdMe in osdMeArray)
+ {
+ MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
+ mediaEntries.Add(me);
+ }
+
+ s.Media = mediaEntries;
+
+ xtr.ReadEndElement();
+ }
}
-
- s.Media = mediaEntries;
}
return s;
@@ -1921,14 +1931,32 @@ namespace OpenSim.Data.SQLite
if (null != s.Media)
{
- OSDArray meArray = new OSDArray();
- foreach (MediaEntry me in s.Media)
+ using (StringWriter sw = new StringWriter())
{
- OSD osd = (null == me ? new OSD() : me.GetOSD());
- meArray.Add(osd);
+ using (XmlTextWriter xtw = new XmlTextWriter(sw))
+ {
+ xtw.WriteStartElement("osmedia");
+ xtw.WriteAttributeString("type", "sl");
+ xtw.WriteAttributeString("major_version", "0");
+ xtw.WriteAttributeString("minor_version", "1");
+
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in s.Media)
+ {
+ 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();
+ row["Media"] = sw.ToString();
+ }
}
-
- row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
}
--
cgit v1.1
From 491b8181ad4fcb0a8002ee2406703b89c4928219 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 20:13:26 +0100
Subject: Add EventManager.OnSceneObjectLoaded() for future use. This is fired
immediately after a scene object is loaded from storage.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 19 +++++++++----
OpenSim/Region/Framework/Scenes/EventManager.cs | 32 ++++++++++++++++++++--
OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-
3 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 0130ff9..2771492 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -98,17 +98,19 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void RegionLoaded(Scene scene)
{
- m_scene.EventManager.OnRegisterCaps += RegisterCaps;
- m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
+ m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
+ m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded;
}
public void Close()
{
- m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
- m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
+ m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
+ m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded;
}
- public void RegisterCaps(UUID agentID, Caps caps)
+ public void OnRegisterCaps(UUID agentID, Caps caps)
{
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
@@ -138,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
- public void DeregisterCaps(UUID agentID, Caps caps)
+ public void OnDeregisterCaps(UUID agentID, Caps caps)
{
lock (m_omCapUsers)
{
@@ -155,6 +157,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
+ public void OnSceneObjectLoaded(SceneObjectGroup sog)
+ {
+ m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", sog.Name, sog.UUID);
+ }
+
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
MediaEntry me = null;
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index ef125cd..46e17c5 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -331,9 +331,16 @@ namespace OpenSim.Region.Framework.Scenes
/// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
public event Attach OnAttach;
+
+ public delegate void SceneObjectDelegate(SceneObjectGroup so);
+
+ ///
+ /// Called immediately after an object is loaded from storage.
+ ///
+ public event SceneObjectDelegate OnSceneObjectLoaded;
public delegate void RegionUp(GridRegion region);
- public event RegionUp OnRegionUp;
+ public event RegionUp OnRegionUp;
public class MoneyTransferArgs : EventArgs
{
@@ -2013,5 +2020,26 @@ 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);
+ }
+ }
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index e2ab643..5542a0c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1887,9 +1887,11 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectGroup group in PrimsFromDB)
{
+ EventManager.TriggerOnSceneObjectLoaded(group);
+
if (group.RootPart == null)
{
- m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children",
+ m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
group.Children == null ? 0 : group.Children.Count);
}
--
cgit v1.1
From c70d57ff983d42b6898d766eb5536e56868b3213 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 20:36:28 +0100
Subject: Add EventManager.OnSceneObjectPreSave() for future use. This is
triggered immediately before a copy of the group is persisted to storage
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 11 ++++--
OpenSim/Region/Framework/Scenes/EventManager.cs | 39 ++++++++++++++++++++--
.../Region/Framework/Scenes/SceneObjectGroup.cs | 1 +
3 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 2771492..263ee57 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -101,6 +101,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded;
+ m_scene.EventManager.OnSceneObjectPreSave += OnSceneObjectPreSave;
}
public void Close()
@@ -108,6 +109,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded;
+ m_scene.EventManager.OnSceneObjectPreSave -= OnSceneObjectPreSave;
}
public void OnRegisterCaps(UUID agentID, Caps caps)
@@ -157,11 +159,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
- public void OnSceneObjectLoaded(SceneObjectGroup sog)
+ public void OnSceneObjectLoaded(SceneObjectGroup so)
{
- m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", sog.Name, sog.UUID);
+ m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", so.Name, so.UUID);
}
+ public void OnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo)
+ {
+ m_log.DebugFormat("[MOAP]: OnSceneObjectPreSave fired for {0} {1}", persistingSo.Name, persistingSo.UUID);
+ }
+
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
MediaEntry me = null;
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 46e17c5..a4dd170 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -330,14 +330,26 @@ namespace OpenSim.Region.Framework.Scenes
/// If the object is being attached, then the avatarID will be present. If the object is being detached then
/// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
- public event Attach OnAttach;
-
- public delegate void SceneObjectDelegate(SceneObjectGroup so);
+ public event Attach OnAttach;
///
/// Called immediately after an object is loaded from storage.
///
public event SceneObjectDelegate OnSceneObjectLoaded;
+ public delegate void SceneObjectDelegate(SceneObjectGroup so);
+
+ ///
+ /// Called immediately before an object is saved to storage.
+ ///
+ ///
+ /// 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.
+ ///
+ ///
+ /// The original scene object being persisted. Changes here will stay in memory but will not be saved to storage on this save.
+ ///
+ public event SceneObjectPreSaveDelegate OnSceneObjectPreSave;
+ public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo);
public delegate void RegionUp(GridRegion region);
public event RegionUp OnRegionUp;
@@ -2040,6 +2052,27 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
+ }
+
+ 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);
+ }
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 1ca390a..451b93e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1479,6 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
HasGroupChanged = false;
+ m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
backup_group.ForEachPart(delegate(SceneObjectPart part)
--
cgit v1.1
From d5e8272ad44e87a4ac1a7b142ca36b5c5978fca7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 21:09:54 +0100
Subject: relocate serialization code from SQLiteRegionData to MoapModule using
load and save events.
This is better modularity. It also allows MoapModule to be replaced with some other media module that may behave completely differently in the future.
Remaining non-modularity:
PrimitiveBaseShape needs explicit Media and MediaRaw fields. MediaRaw is required in order to shuttle the pre-serialization data back and forth from the database layer.
The database also needs to know about MediaRaw though not about Media.
IMO, it would be extremely nice to remove these hard codings but this is a bridge too far at the present time.
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 55 +----------------
OpenSim/Framework/PrimitiveBaseShape.cs | 6 ++
.../CoreModules/World/Media/Moap/MoapModule.cs | 70 +++++++++++++++++++++-
3 files changed, 76 insertions(+), 55 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index b564419..f63d35e 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -31,7 +31,6 @@ using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
-using System.Xml;
using log4net;
using Mono.Data.Sqlite;
using OpenMetaverse;
@@ -1862,28 +1861,7 @@ namespace OpenSim.Data.SQLite
s.ExtraParams = (byte[]) row["ExtraParams"];
if (!(row["Media"] is System.DBNull))
- {
- using (StringReader sr = new StringReader((string)row["Media"]))
- {
- using (XmlTextReader xtr = new XmlTextReader(sr))
- {
- xtr.ReadStartElement("osmedia");
-
- OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
-
- List mediaEntries = new List();
- foreach (OSD osdMe in osdMeArray)
- {
- MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
- mediaEntries.Add(me);
- }
-
- s.Media = mediaEntries;
-
- xtr.ReadEndElement();
- }
- }
- }
+ s.MediaRaw = (string)row["Media"];
return s;
}
@@ -1928,36 +1906,7 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams;
-
- if (null != s.Media)
- {
- using (StringWriter sw = new StringWriter())
- {
- using (XmlTextWriter xtw = new XmlTextWriter(sw))
- {
- xtw.WriteStartElement("osmedia");
- xtw.WriteAttributeString("type", "sl");
- xtw.WriteAttributeString("major_version", "0");
- xtw.WriteAttributeString("minor_version", "1");
-
- OSDArray meArray = new OSDArray();
- foreach (MediaEntry me in s.Media)
- {
- 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();
- row["Media"] = sw.ToString();
- }
- }
- }
+ row["Media"] = s.MediaRaw;
}
///
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 85638ca..03ddb33 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -174,6 +174,12 @@ namespace OpenSim.Framework
}
///
+ /// Raw media data suitable for serialization operations. This should only ever be used by an IMoapModule.
+ ///
+ [XmlIgnore]
+ public string MediaRaw { get; set; }
+
+ ///
/// Entries to store media textures on each face
///
/// Do not change this value directly - always do it through an IMoapModule.
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 263ee57..0e03318 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -32,6 +32,7 @@ using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
+using System.Xml;
using log4net;
using Mono.Addins;
using Nini.Config;
@@ -46,6 +47,7 @@ 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
@@ -162,12 +164,76 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void OnSceneObjectLoaded(SceneObjectGroup so)
{
m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", so.Name, so.UUID);
+
+ so.ForEachPart(OnSceneObjectPartLoaded);
}
public void OnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo)
{
- m_log.DebugFormat("[MOAP]: OnSceneObjectPreSave fired for {0} {1}", persistingSo.Name, persistingSo.UUID);
- }
+ m_log.DebugFormat("[MOAP]: OnSceneObjectPreSave fired for {0} {1}", persistingSo.Name, persistingSo.UUID);
+
+ persistingSo.ForEachPart(OnSceneObjectPartPreSave);
+ }
+
+ protected void OnSceneObjectPartLoaded(SceneObjectPart part)
+ {
+ if (null == part.Shape.MediaRaw)
+ return;
+
+ using (StringReader sr = new StringReader(part.Shape.MediaRaw))
+ {
+ using (XmlTextReader xtr = new XmlTextReader(sr))
+ {
+ xtr.ReadStartElement("osmedia");
+
+ OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
+
+ List mediaEntries = new List();
+ foreach (OSD osdMe in osdMeArray)
+ {
+ MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
+ mediaEntries.Add(me);
+ }
+
+ xtr.ReadEndElement();
+
+ part.Shape.Media = mediaEntries;
+ }
+ }
+ }
+
+ protected void OnSceneObjectPartPreSave(SceneObjectPart part)
+ {
+ if (null == part.Shape.Media)
+ return;
+
+ using (StringWriter sw = new StringWriter())
+ {
+ using (XmlTextWriter xtw = new XmlTextWriter(sw))
+ {
+ xtw.WriteStartElement("osmedia");
+ xtw.WriteAttributeString("type", "sl");
+ xtw.WriteAttributeString("major_version", "0");
+ xtw.WriteAttributeString("minor_version", "1");
+
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in part.Shape.Media)
+ {
+ 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();
+ part.Shape.MediaRaw = sw.ToString();
+ }
+ }
+ }
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
--
cgit v1.1
From f34795c6b3cd022bd9f6ed4cea02631f5b17bf72 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 21:41:39 +0100
Subject: provide config option for media on a prim
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 21 +++++++++++++++++++--
.../World/Permissions/PermissionsModule.cs | 4 ++--
bin/OpenSim.ini.example | 5 +++++
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 0e03318..7afeeec 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -61,6 +61,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public Type ReplaceableInterface { get { return null; } }
///
+ /// Is this module enabled?
+ ///
+ protected bool m_isEnabled = true;
+
+ ///
/// The scene to which this module is attached
///
protected Scene m_scene;
@@ -85,13 +90,19 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
protected Dictionary m_omuCapUrls = new Dictionary();
- public void Initialise(IConfigSource config)
+ public void Initialise(IConfigSource configSource)
{
- // TODO: Add config switches to enable/disable this module
+ IConfig config = configSource.Configs["MediaOnAPrim"];
+
+ if (config != null && !config.GetBoolean("Enabled", false))
+ m_isEnabled = false;
}
public void AddRegion(Scene scene)
{
+ if (!m_isEnabled)
+ return;
+
m_scene = scene;
m_scene.RegisterModuleInterface(this);
}
@@ -100,6 +111,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void RegionLoaded(Scene scene)
{
+ if (!m_isEnabled)
+ return;
+
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded;
@@ -108,6 +122,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void Close()
{
+ if (!m_isEnabled)
+ return;
+
m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded;
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 7f6f851..982ac52 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -401,8 +401,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_moapModule = m_scene.RequestModuleInterface();
// 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");
+// 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()
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index f4d9a18..a533f45 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1248,6 +1248,11 @@
; enabled=false
+[MediaOnAPrim]
+ ; Enable media on a prim facilities
+ Enabled = true;
+
+
;;
;; These are defaults that are overwritten below in [Architecture].
;; These defaults allow OpenSim to work out of the box with
--
cgit v1.1
From d00466f09af214da8bedac89440ecad1d8c7b00d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 23:19:31 +0100
Subject: add mysql support for media on a prim
---
OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 8 ++++++--
OpenSim/Data/MySQL/Resources/RegionStore.migrations | 9 ++++++++-
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index bfeae12..f17e8ae 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Data.MySQL
"PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " +
- "ExtraParams, State) values (?UUID, " +
+ "ExtraParams, State, Media) values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " +
@@ -233,7 +233,7 @@ namespace OpenSim.Data.MySQL
"?PathTwistBegin, ?ProfileBegin, " +
"?ProfileEnd, ?ProfileCurve, " +
"?ProfileHollow, ?Texture, ?ExtraParams, " +
- "?State)";
+ "?State, ?Media)";
FillShapeCommand(cmd, prim);
@@ -1700,6 +1700,9 @@ namespace OpenSim.Data.MySQL
s.ExtraParams = (byte[])row["ExtraParams"];
s.State = (byte)(int)row["State"];
+
+ if (!(row["Media"] is System.DBNull))
+ s.MediaRaw = (string)row["Media"];
return s;
}
@@ -1743,6 +1746,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
cmd.Parameters.AddWithValue("State", s.State);
+ cmd.Parameters.AddWithValue("Media", s.MediaRaw);
}
public void StorePrimInventory(UUID primID, ICollection items)
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
index 3f644f9..1369704 100644
--- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
@@ -1,4 +1,4 @@
-
+
:VERSION 1 #---------------------
BEGIN;
@@ -800,3 +800,10 @@ BEGIN;
ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`;
COMMIT;
+:VERSION 35 #---------------------
+-- Added post 0.7
+
+BEGIN;
+ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
+ALTER TABLE primshapes ADD COLUMN Media TEXT;
+COMMIT;
\ No newline at end of file
--
cgit v1.1
From 09231b1d123263a04804977904429d975647b22e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 23:26:22 +0100
Subject: add mssql support for media on a prim
compiles but not tested. please test and correct if necessary!
---
OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 10 +++++++---
OpenSim/Data/MSSQL/Resources/RegionStore.migrations | 9 ++++++++-
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
index d6cb91f..e61b4d9 100644
--- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
@@ -385,7 +385,7 @@ IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID)
PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions,
PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin,
ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow,
- Texture = @Texture, ExtraParams = @ExtraParams, State = @State
+ Texture = @Texture, ExtraParams = @ExtraParams, State = @State, Media = @Media
WHERE UUID = @UUID
END
ELSE
@@ -394,11 +394,11 @@ ELSE
primshapes (
UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY,
PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin,
- ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State
+ ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State, Media
) VALUES (
@UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY,
@PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin,
- @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State
+ @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State, @Media
)
END";
@@ -1180,6 +1180,9 @@ VALUES
{
}
+ if (!(shapeRow["Media"] is System.DBNull))
+ baseShape.MediaRaw = (string)shapeRow["Media"];
+
return baseShape;
}
@@ -1557,6 +1560,7 @@ VALUES
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
parameters.Add(_Database.CreateParameter("State", s.State));
+ parameters.Add(_Database.CreateParameter("Media", s.MediaRaw));
return parameters.ToArray();
}
diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
index e912d64..e2e8cbb 100644
--- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
@@ -1,4 +1,4 @@
-
+
:VERSION 1
CREATE TABLE [dbo].[prims](
@@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
COMMIT
+:VERSION 24
+-- Added post 0.7
+
+BEGIN TRANSACTION
+ALTER TABLE prims ADD COLUMN MediaURL varchar(255)
+ALTER TABLE primshapes ADD COLUMN Media TEXT
+COMMIT
\ No newline at end of file
--
cgit v1.1
From ede446cad6ecb987badbc04b8436d449dee5e08b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 30 Jun 2010 20:46:35 +0100
Subject: add stub media-on-a-prim (shared media) module
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 56 ++++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
new file mode 100644
index 0000000..1e5c767
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -0,0 +1,56 @@
+/*
+ * 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.Reflection;
+using Nini.Config;
+using log4net;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using Mono.Addins;
+using OpenMetaverse;
+
+namespace OpenSim.Region.CoreModules.Media.Moap
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
+ public class MoapModule : INonSharedRegionModule
+ {
+ public string Name { get { return "MoapModule"; } }
+ public Type ReplaceableInterface { get { return null; } }
+
+ public void Initialise(IConfigSource config) {}
+
+ public void AddRegion(Scene scene) { Console.WriteLine("YEAH I'M HERE, BABY!"); }
+
+ public void RemoveRegion(Scene scene) {}
+
+ public void RegionLoaded(Scene scene) {}
+
+ public void Close() {}
+ }
+}
\ No newline at end of file
--
cgit v1.1
From 2be7d0cdd43f1b3037fa06cca87bcc0c84ac47e5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 30 Jun 2010 22:30:05 +0100
Subject: Register ObjectMedia and ObjectMediaNavigate capabilities from moap
module.
Not sure if these are correct, but just supplying these to the viewer is enough to allow it to put media textures on prims (previously the icons were greyed out).
This is not yet persisted even in-memory, so no other avatars will see it yet.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 58 ++++++++++++++++++++--
1 file changed, 53 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 1e5c767..68b9b43 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -26,31 +26,79 @@
*/
using System;
+using System.Collections;
+using System.Collections.Specialized;
using System.Reflection;
-using Nini.Config;
+using System.IO;
+using System.Web;
using log4net;
+using Mono.Addins;
+using Nini.Config;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
using OpenSim.Framework;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
-using Mono.Addins;
-using OpenMetaverse;
+using OpenSim.Services.Interfaces;
+using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Region.CoreModules.Media.Moap
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
public class MoapModule : INonSharedRegionModule
{
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
+ protected Scene m_scene;
+
public void Initialise(IConfigSource config) {}
- public void AddRegion(Scene scene) { Console.WriteLine("YEAH I'M HERE, BABY!"); }
+ public void AddRegion(Scene scene)
+ {
+ m_scene = scene;
+ }
public void RemoveRegion(Scene scene) {}
- public void RegionLoaded(Scene scene) {}
+ public void RegionLoaded(Scene scene)
+ {
+ m_scene.EventManager.OnRegisterCaps += RegisterCaps;
+ }
public void Close() {}
+
+ public void RegisterCaps(UUID agentID, Caps caps)
+ {
+ m_log.DebugFormat(
+ "[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
+
+ caps.RegisterHandler(
+ "ObjectMedia", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaRequest));
+ caps.RegisterHandler(
+ "ObjectMediaNavigate", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaNavigateRequest));
+ }
+
+ protected string OnObjectMediaRequest(
+ string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia request for {0}", path);
+ //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+
+ return string.Empty;
+ }
+
+ protected string OnObjectMediaNavigateRequest(
+ string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
+ //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+
+ return string.Empty;
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 701f39c8c256d77669fc88f73deb5217a785d0d6 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 00:24:30 +0100
Subject: do a whole load of crappy hacking to get cubes to display google.com
currently, for smoe reason the page only appears when you click a face.
also, actually navigating anywhere always snaps you back to the google search box, for some unknown reason
you can still change the url and normal navigation will work again
---
.../Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +-
.../CoreModules/World/Media/Moap/MoapModule.cs | 95 ++++++++++++++++++++--
2 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 8123f2f..f85cb57 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -362,7 +362,7 @@ namespace OpenSim.Framework.Servers.HttpServer
string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path);
- //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
+ m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
if (TryGetStreamHandler(handlerKey, out requestHandler))
{
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 68b9b43..b6fa53f 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -35,8 +35,10 @@ 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;
@@ -77,28 +79,109 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
+ // We do receive a post to ObjectMedia when a new avatar enters the region - though admittedly this is the
+ // avatar that set the texture in the first place.
+ // Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaRequest));
+ "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaRequest));
+
+ // We do get these posts when the url has been changed.
+ // Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("GET", "/CAPS/" + UUID.Random(), OnObjectMediaNavigateRequest));
+ "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateRequest));
}
- protected string OnObjectMediaRequest(
+ ///
+ /// Sets or gets per face media textures.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected string HandleObjectMediaRequest(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMedia request for {0}", path);
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
+
+ Hashtable osdParams = new Hashtable();
+ osdParams = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
+
+ foreach (Object key in osdParams.Keys)
+ m_log.DebugFormat("[MOAP]: Param {0}={1}", key, osdParams[key]);
+
+ string verb = (string)osdParams["verb"];
+
+ if ("GET" == verb)
+ return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
+
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+ // TODO: Persist in memory
+ // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
+ // TODO: Persist in database
+
return string.Empty;
}
- protected string OnObjectMediaNavigateRequest(
+ protected string HandleObjectMediaRequestGet(
+ string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ // Yeah, only for cubes right now. I know it's dumb.
+ int faces = 6;
+
+ MediaEntry[] media = new MediaEntry[faces];
+ for (int i = 0; i < faces; i++)
+ {
+ MediaEntry me = new MediaEntry();
+ me.HomeURL = "google.com";
+ me.CurrentURL = "google.com";
+ me.AutoScale = true;
+ //me.Height = 300;
+ //me.Width = 240;
+ media[i] = me;
+ }
+
+ ObjectMediaResponse resp = new ObjectMediaResponse();
+
+ resp.PrimID = (UUID)osdParams["object_id"];
+ resp.FaceMedia = media;
+
+ // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
+ // to minimally satisfy for now to get something working
+ resp.Version = "x-mv:0000000016/" + UUID.Random();
+
+ //string rawResp = resp.Serialize().ToString();
+ string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
+
+ m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp);
+
+ return rawResp;
+ }
+
+ ///
+ /// Received from the viewer if a user has changed the url of a media texture.
+ ///
+ ///
+ ///
+ ///
+ /// /param>
+ /// /param>
+ ///
+ protected string HandleObjectMediaNavigateRequest(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+ // TODO: Persist in memory
+ // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
+ // TODO: Persist in database
+
return string.Empty;
- }
+ }
+
+
}
}
\ No newline at end of file
--
cgit v1.1
From 9301e36fbc545b0bbdb14e1651e1ff1f4ca7c04f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 00:47:12 +0100
Subject: have a stab at sending the correct number of media entries to shapes
actually, this is probably wrong anyway if there's a default texture
it's going to be easier just to gather the object media updates and retain those in-memory now
but what the hell
---
.../Region/CoreModules/World/Media/Moap/MoapModule.cs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index b6fa53f..30507a4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -128,8 +128,20 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected string HandleObjectMediaRequestGet(
string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- // Yeah, only for cubes right now. I know it's dumb.
- int faces = 6;
+ UUID primId = (UUID)osdParams["object_id"];
+
+ 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 the scene",
+ primId);
+ return string.Empty;
+ }
+
+ int faces = part.GetNumberOfSides();
+ m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
MediaEntry[] media = new MediaEntry[faces];
for (int i = 0; i < faces; i++)
--
cgit v1.1
From acac47830e3d7d9103c30729ad0cff50b0e8fcdc Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 02:06:51 +0100
Subject: start storing incoming MediaEntry on a new Media field on
PrimitiveBaseShape
This allows the media texture to persist in memory - logging in and out will redisplay it (after a click) though navigation will be lost
Next need to implement media uri on prim and delegate more incoming llsd parsing to libomv
---
OpenSim/Framework/PrimitiveBaseShape.cs | 7 +++
.../CoreModules/World/Media/Moap/MoapModule.cs | 63 ++++++++++++++++++++--
2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 4d1de22..517dbf6 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -26,12 +26,14 @@
*/
using System;
+using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
@@ -170,6 +172,11 @@ namespace OpenSim.Framework
}
}
}
+
+ ///
+ /// Entries to store media textures on each face
+ ///
+ public List Media { get; set; }
public PrimitiveBaseShape()
{
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 30507a4..90626f4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
@@ -115,6 +116,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if ("GET" == verb)
return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
+ if ("UPDATE" == verb)
+ return HandleObjectMediaRequestUpdate(path, osdParams, httpRequest, httpResponse);
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
@@ -140,6 +143,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
+ /*
int faces = part.GetNumberOfSides();
m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
@@ -154,17 +158,20 @@ namespace OpenSim.Region.CoreModules.Media.Moap
//me.Width = 240;
media[i] = me;
}
+ */
+
+ if (null == part.Shape.Media)
+ return string.Empty;
ObjectMediaResponse resp = new ObjectMediaResponse();
- resp.PrimID = (UUID)osdParams["object_id"];
- resp.FaceMedia = media;
+ resp.PrimID = primId;
+ resp.FaceMedia = part.Shape.Media.ToArray();
// I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
// to minimally satisfy for now to get something working
resp.Version = "x-mv:0000000016/" + UUID.Random();
- //string rawResp = resp.Serialize().ToString();
string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp);
@@ -172,6 +179,56 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return rawResp;
}
+ protected string HandleObjectMediaRequestUpdate(
+ string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ {
+ UUID primId = (UUID)osdParams["object_id"];
+
+ SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
+
+ if (null == part)
+ {
+ m_log.WarnFormat(
+ "[MOAP]: Received am UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
+ primId);
+ return string.Empty;
+ }
+
+ List cookedMediaEntries = new List();
+
+ ArrayList rawMediaEntries = (ArrayList)osdParams["object_media_data"];
+ foreach (Object obj in rawMediaEntries)
+ {
+ Hashtable rawMe = (Hashtable)obj;
+
+ // TODO: Yeah, I know this is silly. Very soon use existing better code in libomv to do this.
+ MediaEntry cookedMe = new MediaEntry();
+ cookedMe.EnableAlterntiveImage = (bool)rawMe["alt_image_enable"];
+ cookedMe.AutoLoop = (bool)rawMe["auto_loop"];
+ cookedMe.AutoPlay = (bool)rawMe["auto_play"];
+ cookedMe.AutoScale = (bool)rawMe["auto_scale"];
+ cookedMe.AutoZoom = (bool)rawMe["auto_zoom"];
+ cookedMe.InteractOnFirstClick = (bool)rawMe["first_click_interact"];
+ cookedMe.Controls = (MediaControls)rawMe["controls"];
+ cookedMe.HomeURL = (string)rawMe["home_url"];
+ cookedMe.CurrentURL = (string)rawMe["current_url"];
+ cookedMe.Height = (int)rawMe["height_pixels"];
+ cookedMe.Width = (int)rawMe["width_pixels"];
+ cookedMe.ControlPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_control"].ToString());
+ cookedMe.InteractPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_interact"].ToString());
+ cookedMe.EnableWhiteList = (bool)rawMe["whitelist_enable"];
+ //cookedMe.WhiteList = (string[])rawMe["whitelist"];
+
+ cookedMediaEntries.Add(cookedMe);
+ }
+
+ m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", cookedMediaEntries.Count, primId);
+
+ part.Shape.Media = cookedMediaEntries;
+
+ return string.Empty;
+ }
+
///
/// Received from the viewer if a user has changed the url of a media texture.
///
--
cgit v1.1
From c290cdd9971ad876fffb3aff24c404675a1c1196 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 18:42:47 +0100
Subject: replace hand parsing of incoming object media messages with parsing
code in libopenmetaverse
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 91 ++++++++--------------
1 file changed, 31 insertions(+), 60 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 90626f4..568170e 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -46,6 +46,7 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
+using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Media.Moap
{
@@ -59,7 +60,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected Scene m_scene;
- public void Initialise(IConfigSource config) {}
+ public void Initialise(IConfigSource config)
+ {
+ // TODO: Add config switches to enable/disable this module
+ }
public void AddRegion(Scene scene)
{
@@ -73,7 +77,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
- public void Close() {}
+ public void Close()
+ {
+ m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
+ }
public void RegisterCaps(UUID agentID, Caps caps)
{
@@ -105,33 +112,26 @@ namespace OpenSim.Region.CoreModules.Media.Moap
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
-
- Hashtable osdParams = new Hashtable();
- osdParams = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
-
- foreach (Object key in osdParams.Keys)
- m_log.DebugFormat("[MOAP]: Param {0}={1}", key, osdParams[key]);
-
- string verb = (string)osdParams["verb"];
-
- if ("GET" == verb)
- return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
- if ("UPDATE" == verb)
- return HandleObjectMediaRequestUpdate(path, osdParams, httpRequest, httpResponse);
-
- //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
-
- // TODO: Persist in memory
- // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
- // TODO: Persist in database
-
- return string.Empty;
+
+ 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(omm.Request as ObjectMediaUpdate);
+
+ throw new Exception(
+ string.Format(
+ "[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}",
+ omm.Request.GetType()));
}
- protected string HandleObjectMediaRequestGet(
- string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
- {
- UUID primId = (UUID)osdParams["object_id"];
+ protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
+ {
+ //UUID primId = (UUID)osdParams["object_id"];
+ UUID primId = omr.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
@@ -179,10 +179,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return rawResp;
}
- protected string HandleObjectMediaRequestUpdate(
- string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
{
- UUID primId = (UUID)osdParams["object_id"];
+ UUID primId = omu.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
@@ -194,37 +193,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- List cookedMediaEntries = new List();
-
- ArrayList rawMediaEntries = (ArrayList)osdParams["object_media_data"];
- foreach (Object obj in rawMediaEntries)
- {
- Hashtable rawMe = (Hashtable)obj;
-
- // TODO: Yeah, I know this is silly. Very soon use existing better code in libomv to do this.
- MediaEntry cookedMe = new MediaEntry();
- cookedMe.EnableAlterntiveImage = (bool)rawMe["alt_image_enable"];
- cookedMe.AutoLoop = (bool)rawMe["auto_loop"];
- cookedMe.AutoPlay = (bool)rawMe["auto_play"];
- cookedMe.AutoScale = (bool)rawMe["auto_scale"];
- cookedMe.AutoZoom = (bool)rawMe["auto_zoom"];
- cookedMe.InteractOnFirstClick = (bool)rawMe["first_click_interact"];
- cookedMe.Controls = (MediaControls)rawMe["controls"];
- cookedMe.HomeURL = (string)rawMe["home_url"];
- cookedMe.CurrentURL = (string)rawMe["current_url"];
- cookedMe.Height = (int)rawMe["height_pixels"];
- cookedMe.Width = (int)rawMe["width_pixels"];
- cookedMe.ControlPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_control"].ToString());
- cookedMe.InteractPermissions = (MediaPermission)Enum.Parse(typeof(MediaPermission), rawMe["perms_interact"].ToString());
- cookedMe.EnableWhiteList = (bool)rawMe["whitelist_enable"];
- //cookedMe.WhiteList = (string[])rawMe["whitelist"];
-
- cookedMediaEntries.Add(cookedMe);
- }
-
- m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", cookedMediaEntries.Count, primId);
+ m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
- part.Shape.Media = cookedMediaEntries;
+ part.Shape.Media = new List(omu.FaceMedia);
return string.Empty;
}
--
cgit v1.1
From 4a6adff4cd66a3bfeaa99af10caf9136e011df46 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 19:25:46 +0100
Subject: start storing a mediaurl on the scene object part
not yet persisted or sent in the update
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 30 +++++++++++++++++-----
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++-
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 568170e..edd0397 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// avatar that set the texture in the first place.
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaRequest));
+ "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaMessage));
// We do get these posts when the url has been changed.
// Even though we're registering for POST we're going to get GETS and UPDATES too
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
///
///
- protected string HandleObjectMediaRequest(
+ protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
@@ -167,10 +167,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
resp.PrimID = primId;
resp.FaceMedia = part.Shape.Media.ToArray();
-
- // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
- // to minimally satisfy for now to get something working
- resp.Version = "x-mv:0000000016/" + UUID.Random();
+ resp.Version = part.MediaUrl;
string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
@@ -197,6 +194,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media = new List(omu.FaceMedia);
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:10D}/{1}", version, UUID.Zero);
+ }
+
+ m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
+
+ // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
+ // to minimally satisfy for now to get something working
+ //resp.Version = "x-mv:0000000016/" + UUID.Random();
+
+ // TODO: schedule full object update for all other avatars. This will trigger them to send an
+ // ObjectMediaRequest once they see that the MediaUrl is different.
+
return string.Empty;
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e331bb0..c25c973 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -970,13 +970,18 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_updateFlag; }
set { m_updateFlag = value; }
}
+
+ ///
+ /// Used for media on a prim
+ ///
+ public string MediaUrl { get; set; }
[XmlIgnore]
public bool CreateSelected
{
get { return m_createSelected; }
set { m_createSelected = value; }
- }
+ }
#endregion
--
cgit v1.1
From b1eb83ed6cd5e25c22a858eefd1fba1e6bf622b7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 19:33:41 +0100
Subject: start sending media url in object full updates
---
OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 0aec01a..c59eedf 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -4288,8 +4288,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendLandObjectOwners(LandData land, List groups, Dictionary ownersAndCount)
{
-
-
int notifyCount = ownersAndCount.Count;
ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
@@ -4561,6 +4559,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
update.Scale = data.Shape.Scale;
update.Text = Util.StringToBytes256(data.Text);
+ update.MediaURL = Util.StringToBytes256(data.MediaUrl);
#region PrimFlags
--
cgit v1.1
From 468450a94db3b103d19f44f55156bf305d55ecb9 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 19:53:03 +0100
Subject: send a full object update out to avatars when a media texture is
initially set
this allows other avatars to see it, but still only after they've clicked on the face
still not handling navigation yet
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index edd0397..0d31732 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -208,12 +208,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
- // I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
- // to minimally satisfy for now to get something working
- //resp.Version = "x-mv:0000000016/" + UUID.Random();
-
- // TODO: schedule full object update for all other avatars. This will trigger them to send an
- // ObjectMediaRequest once they see that the MediaUrl is different.
+ // Arguably we don't need to send a full update to the avatar that just changed the texture.
+ part.ScheduleFullUpdate();
return string.Empty;
}
--
cgit v1.1
From 4ebae14a530f8f5909e93a0dd852297f4f30a736 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 20:25:35 +0100
Subject: handle ObjectMediaNavigateMessage
Other avatars can now see the webpages that you're navigating to.
The requirement for an initial prim click before the texture displayed has gone away.
Flash (e.g. YouTube) appears to work fine.
Still not persisting any media data so this all disappears on server restart
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 69 +++++++++++++++++-----
1 file changed, 55 insertions(+), 14 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 0d31732..c3ec2a6 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -96,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// We do get these posts when the url has been changed.
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateRequest));
+ "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
}
///
@@ -128,6 +128,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
omm.Request.GetType()));
}
+ ///
+ /// Handle a request for media textures
+ ///
+ ///
+ ///
protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
{
//UUID primId = (UUID)osdParams["object_id"];
@@ -138,8 +143,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == part)
{
m_log.WarnFormat(
- "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
- primId);
+ "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
+ primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
@@ -176,6 +181,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return rawResp;
}
+ ///
+ /// Handle an update of media textures.
+ ///
+ /// /param>
+ ///
protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
{
UUID primId = omu.PrimID;
@@ -185,8 +195,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == part)
{
m_log.WarnFormat(
- "[MOAP]: Received am UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
- primId);
+ "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}",
+ primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
@@ -203,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
string rawVersion = part.MediaUrl.Substring(5, 10);
int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:10D}/{1}", version, UUID.Zero);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
}
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
@@ -223,19 +233,50 @@ namespace OpenSim.Region.CoreModules.Media.Moap
/// /param>
/// /param>
///
- protected string HandleObjectMediaNavigateRequest(
+ protected string HandleObjectMediaNavigateMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
- //NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
+ 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;
+ }
+
+ m_log.DebugFormat(
+ "[MOAP]: Updating media entry for face {0} on prim {1} {2} to {3}",
+ omn.Face, part.Name, part.UUID, omn.URL);
+
+ MediaEntry me = part.Shape.Media[omn.Face];
+ me.CurrentURL = omn.URL;
+
+ string oldMediaUrl = part.MediaUrl;
+
+ // TODO: refactor into common method
+ string rawVersion = oldMediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+
+ m_log.DebugFormat(
+ "[MOAP]: Updating media url in prim {0} {1} from [{2}] to [{3}]",
+ part.Name, part.UUID, oldMediaUrl, part.MediaUrl);
+
+ part.ScheduleFullUpdate();
- // TODO: Persist in memory
- // TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
// TODO: Persist in database
return string.Empty;
- }
-
-
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 9682e0c73310dae496912d7b8bc54add0fd0c3e7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 1 Jul 2010 22:52:31 +0100
Subject: Implement media texture persistence over server restarts for sqlite
This is currently persisting media as an OSDArray serialized to LLSD XML.
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 36 +++++++++++++++++++---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 22 ++++++++++++-
prebuild.xml | 1 +
3 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 81d0ac4..fc9667b 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -34,6 +34,7 @@ using System.Reflection;
using log4net;
using Mono.Data.Sqlite;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@@ -974,6 +975,8 @@ namespace OpenSim.Data.SQLite
createCol(prims, "CollisionSoundVolume", typeof(Double));
createCol(prims, "VolumeDetect", typeof(Int16));
+
+ createCol(prims, "MediaURL", typeof(String));
// Add in contraints
prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
@@ -1021,6 +1024,7 @@ namespace OpenSim.Data.SQLite
// way to specify this as a blob atm
createCol(shapes, "Texture", typeof (Byte[]));
createCol(shapes, "ExtraParams", typeof (Byte[]));
+ createCol(shapes, "Media", typeof(String));
shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
@@ -1339,6 +1343,12 @@ namespace OpenSim.Data.SQLite
if (Convert.ToInt16(row["VolumeDetect"]) != 0)
prim.VolumeDetectActive = true;
+
+ if (!(row["MediaURL"] is System.DBNull))
+ {
+ m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType());
+ prim.MediaUrl = (string)row["MediaURL"];
+ }
return prim;
}
@@ -1614,7 +1624,6 @@ namespace OpenSim.Data.SQLite
row["PayButton3"] = prim.PayPrice[3];
row["PayButton4"] = prim.PayPrice[4];
-
row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
@@ -1674,7 +1683,8 @@ namespace OpenSim.Data.SQLite
row["VolumeDetect"] = 1;
else
row["VolumeDetect"] = 0;
-
+
+ row["MediaURL"] = prim.MediaUrl;
}
///
@@ -1849,6 +1859,19 @@ namespace OpenSim.Data.SQLite
s.TextureEntry = textureEntry;
s.ExtraParams = (byte[]) row["ExtraParams"];
+
+ if (!(row["Media"] is System.DBNull))
+ {
+ string rawMeArray = (string)row["Media"];
+ OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(rawMeArray);
+
+ List mediaEntries = new List();
+ foreach (OSD osdMe in osdMeArray)
+ mediaEntries.Add(MediaEntry.FromOSD(osdMe));
+
+ s.Media = mediaEntries;
+ }
+
return s;
}
@@ -1892,17 +1915,22 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams;
+
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in s.Media)
+ meArray.Add(me.GetOSD());
+
+ row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
///
- ///
+ /// Persistently store a prim.
///
///
///
///
private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
{
-
DataTable prims = ds.Tables["prims"];
DataTable shapes = ds.Tables["primshapes"];
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c25c973..a8c20dd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -320,6 +320,11 @@ namespace OpenSim.Region.Framework.Scenes
protected Vector3 m_lastAcceleration;
protected Vector3 m_lastAngularVelocity;
protected int m_lastTerseSent;
+
+ ///
+ /// Stores media texture data
+ ///
+ protected string m_mediaUrl;
// TODO: Those have to be changed into persistent properties at some later point,
// or sit-camera on vehicles will break on sim-crossing.
@@ -965,6 +970,7 @@ namespace OpenSim.Region.Framework.Scenes
TriggerScriptChangedEvent(Changed.SCALE);
}
}
+
public byte UpdateFlag
{
get { return m_updateFlag; }
@@ -974,7 +980,21 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Used for media on a prim
///
- public string MediaUrl { get; set; }
+ public string MediaUrl
+ {
+ get
+ {
+ return m_mediaUrl;
+ }
+
+ set
+ {
+ m_mediaUrl = value;
+
+ if (ParentGroup != null)
+ ParentGroup.HasGroupChanged = true;
+ }
+ }
[XmlIgnore]
public bool CreateSelected
diff --git a/prebuild.xml b/prebuild.xml
index 1eb8fee..1eabc4b 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -2238,6 +2238,7 @@
+
--
cgit v1.1
From 8f403cb4b87fc99c0274929464229b1497395b86 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 15:47:56 +0100
Subject: Implement llGetPrimMediaParams()
Exposes method to get media entry via IMoapModule
As yet untested.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 19 +++-
OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 47 ++++++++++
.../Shared/Api/Implementation/LSL_Api.cs | 104 +++++++++++++++++++++
.../Shared/Api/Runtime/LSL_Constants.cs | 25 +++++
4 files changed, 193 insertions(+), 2 deletions(-)
create mode 100644 OpenSim/Region/Framework/Interfaces/IMoapModule.cs
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index c3ec2a6..9f74367 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -51,7 +51,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.CoreModules.Media.Moap
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
- public class MoapModule : INonSharedRegionModule
+ public class MoapModule : INonSharedRegionModule, IMoapModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -97,7 +97,22 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
"ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
- }
+ }
+
+ public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
+ {
+ if (face < 0)
+ throw new ArgumentException("Face cannot be less than zero");
+
+ List media = part.Shape.Media;
+
+ if (face > media.Count - 1)
+ throw new ArgumentException(
+ string.Format("Face argument was {0} but max is {1}", face, media.Count - 1));
+
+ // TODO: Really need a proper copy constructor down in libopenmetaverse
+ return MediaEntry.FromOSD(media[face].GetOSD());
+ }
///
/// Sets or gets per face media textures.
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
new file mode 100644
index 0000000..4447f34
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -0,0 +1,47 @@
+/*
+ * 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
+{
+ ///
+ /// Provides methods from manipulating media-on-a-prim
+ ///
+ public interface IMoapModule
+ {
+ ///
+ /// Get the media entry for a given prim face.
+ ///
+ ///
+ ///
+ ///
+ MediaEntry GetMediaEntry(SceneObjectPart part, int face);
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 417cef4..e18e33e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7808,6 +7808,110 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return res;
}
+ public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
+ {
+ m_host.AddScriptLPS(1);
+ ScriptSleep(1000);
+
+ // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
+ // TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
+ // Assuming silently fail means give back an empty list. Ideally, need to check this.
+ if (face < 0 || face > m_host.Shape.Media.Count - 1)
+ return new LSL_List();
+
+ return GetLinkPrimMediaParams(face, rules);
+ }
+
+ public LSL_List GetLinkPrimMediaParams(int face, LSL_List rules)
+ {
+ IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ MediaEntry me = module.GetMediaEntry(m_host, face);
+
+ 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;
+ }
+
//
//
// The .NET definition of base 64 is:
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index dba6502..9a64f8c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -517,6 +517,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int TOUCH_INVALID_FACE = -1;
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
+
+ // constants for llGetPrimMediaParams
+ 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;
// Constants for default textures
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
--
cgit v1.1
From a5ad792e6c90eb9412325e636c6e4eafc4a8a91d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 19:46:23 +0100
Subject: implement llSetPrimMediaParams()
Untested
---
OpenSim/Framework/PrimitiveBaseShape.cs | 1 +
.../CoreModules/World/Media/Moap/MoapModule.cs | 54 ++++++++--
OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 14 ++-
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +-
.../Shared/Api/Implementation/LSL_Api.cs | 113 ++++++++++++++++++++-
.../Shared/Api/Runtime/LSL_Constants.cs | 12 ++-
6 files changed, 184 insertions(+), 13 deletions(-)
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 517dbf6..85638ca 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -176,6 +176,7 @@ namespace OpenSim.Framework
///
/// Entries to store media textures on each face
///
+ /// Do not change this value directly - always do it through an IMoapModule.
public List Media { get; set; }
public PrimitiveBaseShape()
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 9f74367..064047d 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -102,16 +102,54 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
+ throw new ArgumentException("Face cannot be less than zero");
+
+ int maxFaces = part.GetNumberOfSides() - 1;
+ if (face > maxFaces)
+ throw new ArgumentException(
+ string.Format("Face argument was {0} but max is {1}", face, maxFaces));
- List media = part.Shape.Media;
+ List media = part.Shape.Media;
- if (face > media.Count - 1)
+ if (null == media)
+ {
+ return null;
+ }
+ else
+ {
+ // TODO: Really need a proper copy constructor down in libopenmetaverse
+ return MediaEntry.FromOSD(media[face].GetOSD());
+ }
+ }
+
+ public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
+ {
+ if (face < 0)
+ throw new ArgumentException("Face cannot be less than zero");
+
+ int maxFaces = part.GetNumberOfSides() - 1;
+ if (face > maxFaces)
throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, media.Count - 1));
+ string.Format("Face argument was {0} but max is {1}", face, maxFaces));
- // TODO: Really need a proper copy constructor down in libopenmetaverse
- return MediaEntry.FromOSD(media[face].GetOSD());
+ if (null == part.Shape.Media)
+ part.Shape.Media = new List(maxFaces);
+
+ part.Shape.Media[face] = me;
+
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ }
+
+ part.ScheduleFullUpdate();
}
///
@@ -140,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
throw new Exception(
string.Format(
"[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}",
- omm.Request.GetType()));
+ omm.Request.GetType()));
}
///
@@ -233,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
- // Arguably we don't need to send a full update to the avatar that just changed the texture.
+ // Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
return string.Empty;
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
index 4447f34..31bb6d8 100644
--- a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -39,9 +39,19 @@ namespace OpenSim.Region.Framework.Interfaces
///
/// Get the media entry for a given prim face.
///
+ /// A copy of the media entry is returned rather than the original, so this can be altered at will without
+ /// affecting the original settings.
///
///
///
- MediaEntry GetMediaEntry(SceneObjectPart part, int face);
- }
+ MediaEntry GetMediaEntry(SceneObjectPart part, int face);
+
+ ///
+ /// Set the media entry for a given prim face.
+ ///
+ ///
+ ///
+ ///
+ void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me);
+ }
}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index a8c20dd..e6a1696 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -978,8 +978,9 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Used for media on a prim
+ /// Used for media on a prim.
///
+ /// Do not change this value directly - always do it through an IMoapModule.
public string MediaUrl
{
get
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index e18e33e..4d57193 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7816,7 +7816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
// TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
// Assuming silently fail means give back an empty list. Ideally, need to check this.
- if (face < 0 || face > m_host.Shape.Media.Count - 1)
+ if (face < 0 || face > m_host.GetNumberOfSides() - 1)
return new LSL_List();
return GetLinkPrimMediaParams(face, rules);
@@ -7830,6 +7830,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
MediaEntry me = module.GetMediaEntry(m_host, face);
+ // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
+ if (null == me)
+ return new LSL_List();
+
LSL_List res = new LSL_List();
for (int i = 0; i < rules.Length; i++)
@@ -7912,6 +7916,113 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return res;
}
+ public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
+ {
+ m_host.AddScriptLPS(1);
+ ScriptSleep(1000);
+
+ // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
+ // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
+ // Don't perform the media check directly
+ if (face < 0 || face > m_host.GetNumberOfSides() - 1)
+ return ScriptBaseClass.LSL_STATUS_OK;
+
+ return SetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
+ {
+ IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ MediaEntry me = module.GetMediaEntry(m_host, face);
+ if (null == me)
+ me = new MediaEntry();
+
+ int i = 0;
+
+ while (i < rules.Length - 1)
+ {
+ int code = rules.GetLSLIntegerItem(i++);
+
+ switch (code)
+ {
+ case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
+ me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
+ int v = rules.GetLSLIntegerItem(i++);
+ if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
+ me.Controls = MediaControls.Standard;
+ else
+ me.Controls = MediaControls.Mini;
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
+ me.CurrentURL = rules.GetLSLStringItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
+ me.HomeURL = rules.GetLSLStringItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
+ me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
+ me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
+ me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
+ me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
+ me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
+ me.Width = (int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
+ me.Height = (int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
+ me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
+ string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
+ List whiteListUrls = new List();
+ Array.ForEach(
+ rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
+ me.WhiteList = whiteListUrls.ToArray();
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
+ me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
+ break;
+
+ case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
+ me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
+ break;
+ }
+ }
+
+ module.SetMediaEntry(m_host, face, me);
+
+ return ScriptBaseClass.LSL_STATUS_OK;
+ }
+
//
//
// The .NET definition of base 64 is:
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9a64f8c..6ef786a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -518,7 +518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
- // constants for llGetPrimMediaParams
+ // constants for llGetPrimMediaParams/llSetPrimMediaParams
public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
public const int PRIM_MEDIA_CONTROLS = 1;
public const int PRIM_MEDIA_CURRENT_URL = 2;
@@ -542,6 +542,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_MEDIA_PERM_OWNER = 1;
public const int PRIM_MEDIA_PERM_GROUP = 2;
public const int PRIM_MEDIA_PERM_ANYONE = 4;
+
+ // extra constants for llSetPrimMediaParams
+ public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
+ public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
+ public static readonly LSLInteger LSL_STATUS_TYPE_MISMATCH = new LSLInteger(1001);
+ public static readonly LSLInteger LSL_STATUS_BOUNDS_ERROR = new LSLInteger(1002);
+ public static readonly LSLInteger LSL_STATUS_NOT_FOUND = new LSLInteger(1003);
+ public static readonly LSLInteger LSL_STATUS_NOT_SUPPORTED = new LSLInteger(1004);
+ public static readonly LSLInteger LSL_STATUS_INTERNAL_ERROR = new LSLInteger(1999);
+ public static readonly LSLInteger LSL_STATUS_WHITELIST_FAILED = new LSLInteger(2001);
// Constants for default textures
public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
--
cgit v1.1
From cfb79cd411d433b82129de6f3a54db4e8a86fab4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 19:48:20 +0100
Subject: minor: correct a few method names and change accessability
---
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 4d57193..f5089aa 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7819,10 +7819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (face < 0 || face > m_host.GetNumberOfSides() - 1)
return new LSL_List();
- return GetLinkPrimMediaParams(face, rules);
+ return GetPrimMediaParams(face, rules);
}
- public LSL_List GetLinkPrimMediaParams(int face, LSL_List rules)
+ private LSL_List GetPrimMediaParams(int face, LSL_List rules)
{
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
if (null == module)
@@ -7930,7 +7930,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return SetPrimMediaParams(face, rules);
}
- public LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
+ private LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
{
IMoapModule module = m_ScriptEngine.World.RequestModuleInterface();
if (null == module)
--
cgit v1.1
From 74bc4f61fd65e67d41918e73390b3fb48df63dd2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 20:15:10 +0100
Subject: factor out common face parameter checking code
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 56 ++++++++--------------
1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 064047d..9dd46eb 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -101,13 +101,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
- if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
-
- int maxFaces = part.GetNumberOfSides() - 1;
- if (face > maxFaces)
- throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, maxFaces));
+ CheckFaceParam(part, face);
List media = part.Shape.Media;
@@ -124,16 +118,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me)
{
- if (face < 0)
- throw new ArgumentException("Face cannot be less than zero");
-
- int maxFaces = part.GetNumberOfSides() - 1;
- if (face > maxFaces)
- throw new ArgumentException(
- string.Format("Face argument was {0} but max is {1}", face, maxFaces));
+ CheckFaceParam(part, face);
if (null == part.Shape.Media)
- part.Shape.Media = new List(maxFaces);
+ part.Shape.Media = new List(part.GetNumberOfSides());
part.Shape.Media[face] = me;
@@ -187,8 +175,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
///
protected string HandleObjectMediaRequest(ObjectMediaRequest omr)
- {
- //UUID primId = (UUID)osdParams["object_id"];
+ {
UUID primId = omr.PrimID;
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
@@ -200,23 +187,6 @@ namespace OpenSim.Region.CoreModules.Media.Moap
primId, m_scene.RegionInfo.RegionName);
return string.Empty;
}
-
- /*
- int faces = part.GetNumberOfSides();
- m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
-
- MediaEntry[] media = new MediaEntry[faces];
- for (int i = 0; i < faces; i++)
- {
- MediaEntry me = new MediaEntry();
- me.HomeURL = "google.com";
- me.CurrentURL = "google.com";
- me.AutoScale = true;
- //me.Height = 300;
- //me.Width = 240;
- media[i] = me;
- }
- */
if (null == part.Shape.Media)
return string.Empty;
@@ -330,6 +300,22 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// TODO: Persist in database
return string.Empty;
- }
+ }
+
+ ///
+ /// Check that the face number is valid for the given prim.
+ ///
+ ///
+ ///
+ 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));
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From c76e2ce250fc2d0d7880fa1125628f0a13d53f9a Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 20:18:10 +0100
Subject: factor out common code for updating the media url
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 68 +++++++++-------------
1 file changed, 27 insertions(+), 41 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 9dd46eb..242ff6c 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -124,19 +124,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media = new List(part.GetNumberOfSides());
part.Shape.Media[face] = me;
-
- if (null == part.MediaUrl)
- {
- // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
- part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
- }
- else
- {
- string rawVersion = part.MediaUrl.Substring(5, 10);
- int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
- }
-
+ UpdateMediaUrl(part);
part.ScheduleFullUpdate();
}
@@ -223,23 +211,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
+ m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId);
part.Shape.Media = new List(omu.FaceMedia);
- if (null == part.MediaUrl)
- {
- // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
- part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
- }
- else
- {
- string rawVersion = part.MediaUrl.Substring(5, 10);
- int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
- }
-
- m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
+ UpdateMediaUrl(part);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
@@ -267,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
UUID primId = omn.PrimID;
- SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
+ SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
if (null == part)
{
@@ -284,20 +260,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
MediaEntry me = part.Shape.Media[omn.Face];
me.CurrentURL = omn.URL;
- string oldMediaUrl = part.MediaUrl;
-
- // TODO: refactor into common method
- string rawVersion = oldMediaUrl.Substring(5, 10);
- int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
-
- m_log.DebugFormat(
- "[MOAP]: Updating media url in prim {0} {1} from [{2}] to [{3}]",
- part.Name, part.UUID, oldMediaUrl, part.MediaUrl);
-
- part.ScheduleFullUpdate();
+ UpdateMediaUrl(part);
- // TODO: Persist in database
+ part.ScheduleFullUpdate();
return string.Empty;
}
@@ -317,5 +282,26 @@ namespace OpenSim.Region.CoreModules.Media.Moap
throw new ArgumentException(
string.Format("Face argument was {0} but max is {1}", face, maxFaces));
}
+
+ ///
+ /// Update the media url of the given part
+ ///
+ ///
+ protected void UpdateMediaUrl(SceneObjectPart part)
+ {
+ if (null == part.MediaUrl)
+ {
+ // TODO: We can't set the last changer until we start tracking which cap we give to which agent id
+ part.MediaUrl = "x-mv:0000000000/" + UUID.Zero;
+ }
+ else
+ {
+ string rawVersion = part.MediaUrl.Substring(5, 10);
+ int version = int.Parse(rawVersion);
+ part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ }
+
+ m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 43f480864bcca2990b809568eaed04bd27cecf60 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 21:33:27 +0100
Subject: fix problem persisting when only one face had a media texture
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 10 ++++++++--
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 7 +++++++
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index fc9667b..51f4cef 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -1867,7 +1867,10 @@ namespace OpenSim.Data.SQLite
List mediaEntries = new List();
foreach (OSD osdMe in osdMeArray)
- mediaEntries.Add(MediaEntry.FromOSD(osdMe));
+ {
+ MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
+ mediaEntries.Add(me);
+ }
s.Media = mediaEntries;
}
@@ -1918,7 +1921,10 @@ namespace OpenSim.Data.SQLite
OSDArray meArray = new OSDArray();
foreach (MediaEntry me in s.Media)
- meArray.Add(me.GetOSD());
+ {
+ OSD osd = (null == me ? new OSD() : me.GetOSD());
+ meArray.Add(osd);
+ }
row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 242ff6c..93a1ae8 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -212,6 +212,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
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);
+// }
part.Shape.Media = new List(omu.FaceMedia);
--
cgit v1.1
From d1a879927ccc97e90f19d916a6a0e579dd7b4a56 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 21:43:36 +0100
Subject: fix issue with GetMediaEntry if the face requested wasn't set to a
media texture
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 93a1ae8..43953a7 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -112,7 +112,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
else
{
// TODO: Really need a proper copy constructor down in libopenmetaverse
- return MediaEntry.FromOSD(media[face].GetOSD());
+ MediaEntry me = media[face];
+ return (null == me ? null : MediaEntry.FromOSD(me.GetOSD()));
}
}
--
cgit v1.1
From 39a38c4901f00eae15c2eed38191944f8f419f8b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 22:00:45 +0100
Subject: implement llClearPrimMedia()
untested
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 5 +++++
OpenSim/Region/Framework/Interfaces/IMoapModule.cs | 10 ++++++++++
.../Shared/Api/Implementation/LSL_Api.cs | 20 ++++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 43953a7..8699800 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -129,6 +129,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.ScheduleFullUpdate();
}
+ public void ClearMediaEntry(SceneObjectPart part, int face)
+ {
+ SetMediaEntry(part, face, null);
+ }
+
///
/// Sets or gets per face media textures.
///
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
index 31bb6d8..24b6860 100644
--- a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs
@@ -53,5 +53,15 @@ namespace OpenSim.Region.Framework.Interfaces
///
///
void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me);
+
+ ///
+ /// Clear the media entry for a given prim face.
+ ///
+ ///
+ /// This is the equivalent of setting a media entry of null
+ ///
+ ///
+ /// /param>
+ void ClearMediaEntry(SceneObjectPart part, int face);
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f5089aa..8903c3b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -8023,6 +8023,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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();
+ if (null == module)
+ throw new Exception("Media on a prim functions not available");
+
+ module.ClearMediaEntry(m_host, face);
+
+ return ScriptBaseClass.LSL_STATUS_OK;
+ }
+
//
//
// The .NET definition of base 64 is:
--
cgit v1.1
From eb5e39d6efed2516883c729eded38454d05aec68 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Jul 2010 22:27:11 +0100
Subject: Fire CHANGED_MEDIA event if a media texture is set or cleared
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 5 +++++
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++-
OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 1 +
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 8699800..8bccab4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media[face] = me;
UpdateMediaUrl(part);
part.ScheduleFullUpdate();
+ part.TriggerScriptChangedEvent(Changed.MEDIA);
}
public void ClearMediaEntry(SceneObjectPart part, int face)
@@ -233,6 +234,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// 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;
}
@@ -277,6 +280,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.ScheduleFullUpdate();
+ part.TriggerScriptChangedEvent(Changed.MEDIA);
+
return string.Empty;
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e6a1696..444a239 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes
OWNER = 128,
REGION_RESTART = 256,
REGION = 512,
- TELEPORT = 1024
+ TELEPORT = 1024,
+ MEDIA = 2048
}
// I don't really know where to put this except here.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 6ef786a..06f9426 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -276,6 +276,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int CHANGED_REGION_RESTART = 256;
public const int CHANGED_REGION = 512;
public const int CHANGED_TELEPORT = 1024;
+ public const int CHANGED_MEDIA = 2048;
public const int CHANGED_ANIMATION = 16384;
public const int TYPE_INVALID = 0;
public const int TYPE_INTEGER = 1;
--
cgit v1.1
From e5615d3a9b013efef5a76a92eb398b331370bae4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 19:28:07 +0100
Subject: discard an object media update message if it tries to set more media
textures than the prim has faces
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 8bccab4..378ff4a 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -227,6 +227,14 @@ namespace OpenSim.Region.CoreModules.Media.Moap
// 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;
+ }
+
part.Shape.Media = new List(omu.FaceMedia);
UpdateMediaUrl(part);
--
cgit v1.1
From 51b208e96c881bd322b3769b843f0ebae3c09a84 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:19:45 +0100
Subject: implement prim media control permissions serverside in order to stop
bad clients
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 87 ++++++++++++++++------
.../World/Permissions/PermissionsModule.cs | 43 ++++++++++-
.../Region/Framework/Scenes/Scene.Permissions.cs | 21 +++++-
3 files changed, 127 insertions(+), 24 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 378ff4a..d7aede9 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -58,8 +58,21 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
+ ///
+ /// The scene to which this module is attached
+ ///
protected Scene m_scene;
+ ///
+ /// Track the ObjectMedia capabilities given to users
+ ///
+ protected Dictionary m_omCapUsers = new Dictionary();
+
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users
+ ///
+ protected Dictionary m_omuCapUsers = new Dictionary();
+
public void Initialise(IConfigSource config)
{
// TODO: Add config switches to enable/disable this module
@@ -87,16 +100,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
- // We do receive a post to ObjectMedia when a new avatar enters the region - though admittedly this is the
- // avatar that set the texture in the first place.
- // Even though we're registering for POST we're going to get GETS and UPDATES too
- caps.RegisterHandler(
- "ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaMessage));
+ string omCapUrl = "/CAPS/" + UUID.Random();
+
+ lock (m_omCapUsers)
+ {
+ m_omCapUsers[omCapUrl] = agentID;
+
+ // 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();
- // We do get these posts when the url has been changed.
- // Even though we're registering for POST we're going to get GETS and UPDATES too
- caps.RegisterHandler(
- "ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateMessage));
+ lock (m_omuCapUsers)
+ {
+ m_omuCapUsers[omuCapUrl] = agentID;
+
+ // 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 MediaEntry GetMediaEntry(SceneObjectPart part, int face)
@@ -147,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected string HandleObjectMediaMessage(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
- m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
+ m_log.DebugFormat("[MOAP]: Got ObjectMedia path [{0}], raw request [{1}]", path, request);
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
ObjectMediaMessage omm = new ObjectMediaMessage();
@@ -156,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (omm.Request is ObjectMediaRequest)
return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest);
else if (omm.Request is ObjectMediaUpdate)
- return HandleObjectMediaUpdate(omm.Request as ObjectMediaUpdate);
+ return HandleObjectMediaUpdate(path, omm.Request as ObjectMediaUpdate);
throw new Exception(
string.Format(
@@ -165,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
///
- /// Handle a request for media textures
+ /// Handle a fetch request for media textures
///
///
///
@@ -202,9 +226,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
/// Handle an update of media textures.
///
+ /// Path on which this request was made
/// /param>
///
- protected string HandleObjectMediaUpdate(ObjectMediaUpdate omu)
+ protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu)
{
UUID primId = omu.PrimID;
@@ -216,16 +241,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
"[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);
-// }
+ 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())
{
@@ -235,7 +260,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
- part.Shape.Media = new List(omu.FaceMedia);
+ List media = part.Shape.Media;
+
+ if (null == media)
+ {
+ part.Shape.Media = new List(omu.FaceMedia);
+ }
+ else
+ {
+ // We need to go through the media textures one at a time to make sure that we have permission
+ // to change them
+ UUID agentId = default(UUID);
+
+ lock (m_omCapUsers)
+ agentId = m_omCapUsers[path];
+
+ for (int i = 0; i < media.Count; i++)
+ {
+ if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
+ media[i] = omu.FaceMedia[i];
+ }
+ }
UpdateMediaUrl(part);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 69b247c..358ea59 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private Dictionary GrantYP = new Dictionary();
private IFriendsModule m_friendsModule;
private IGroupsModule m_groupsModule;
+ private IMoapModule m_moapModule;
#endregion
@@ -248,6 +249,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
+
+ m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.AddCommand(this, "bypass permissions",
"bypass permissions ",
@@ -393,6 +396,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_groupsModule == null)
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
+
+ m_moapModule = m_scene.RequestModuleInterface();
}
public void Close()
@@ -1893,5 +1898,41 @@ namespace OpenSim.Region.CoreModules.World.Permissions
}
return(false);
}
+
+ private bool CanControlPrimMedia(UUID agentID, UUID primID, int 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;
+
+ if (IsAdministrator(agentID))
+ return true;
+
+ if ((me.ControlPermissions & MediaPermission.Anyone) == MediaPermission.Anyone)
+ return true;
+
+ if ((me.ControlPermissions & MediaPermission.Owner) == MediaPermission.Owner)
+ {
+ if (agentID == part.OwnerID)
+ return true;
+ }
+
+ if ((me.ControlPermissions & MediaPermission.Group) == MediaPermission.Group)
+ {
+ if (IsGroupMember(part.GroupID, agentID, 0))
+ return true;
+ }
+
+ return false;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 7dab04f..70af978 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -81,6 +81,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene);
+ public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion
public class ScenePermissions
@@ -139,6 +140,7 @@ namespace OpenSim.Region.Framework.Scenes
public event CopyUserInventoryHandler OnCopyUserInventory;
public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport;
+ public event ControlPrimMediaHandler OnControlPrimMedia;
#endregion
#region Object Permission Checks
@@ -947,5 +949,20 @@ namespace OpenSim.Region.Framework.Scenes
}
return true;
}
+
+ public bool CanControlPrimMedia(UUID userID, UUID primID, int face)
+ {
+ ControlPrimMediaHandler handler = OnControlPrimMedia;
+ if (handler != null)
+ {
+ Delegate[] list = handler.GetInvocationList();
+ foreach (ControlPrimMediaHandler h in list)
+ {
+ if (h(userID, primID, face) == false)
+ return false;
+ }
+ }
+ return true;
+ }
}
-}
+}
\ No newline at end of file
--
cgit v1.1
From a9101feb107e5d210c93df5ee3119d827a1c8320 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:46:49 +0100
Subject: factor out soon to be common media permissions check code
---
.../CoreModules/World/Permissions/PermissionsModule.cs | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 358ea59..2344e96 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -1914,25 +1914,30 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (null == me)
return true;
+ return GenericPrimMediaPermission(part, agentID, me.ControlPermissions);
+ }
+
+ private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms)
+ {
if (IsAdministrator(agentID))
return true;
- if ((me.ControlPermissions & MediaPermission.Anyone) == MediaPermission.Anyone)
+ if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone)
return true;
- if ((me.ControlPermissions & MediaPermission.Owner) == MediaPermission.Owner)
+ if ((perms & MediaPermission.Owner) == MediaPermission.Owner)
{
if (agentID == part.OwnerID)
return true;
}
- if ((me.ControlPermissions & MediaPermission.Group) == MediaPermission.Group)
+ if ((perms & MediaPermission.Group) == MediaPermission.Group)
{
if (IsGroupMember(part.GroupID, agentID, 0))
return true;
}
- return false;
+ return false;
}
}
}
\ No newline at end of file
--
cgit v1.1
From ee6cd884c9732b492675e043fe318ffcdfecc45d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 13 Jul 2010 23:58:19 +0100
Subject: implement serverside checks for media texture navigation in order to
stop naughty clients
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 20 ++++++++++++++------
.../World/Permissions/PermissionsModule.cs | 21 ++++++++++++++++++++-
.../Region/Framework/Scenes/Scene.Permissions.cs | 19 ++++++++++++++++++-
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index d7aede9..09786ec 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -245,12 +245,12 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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);
- }
+// 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())
{
@@ -322,6 +322,14 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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]: Updating media entry for face {0} on prim {1} {2} to {3}",
omn.Face, part.Name, part.UUID, omn.URL);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 2344e96..3a690af 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -251,6 +251,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
+ m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
m_scene.AddCommand(this, "bypass permissions",
"bypass permissions ",
@@ -1915,7 +1916,25 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return true;
return GenericPrimMediaPermission(part, agentID, me.ControlPermissions);
- }
+ }
+
+ private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int 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;
+
+ return GenericPrimMediaPermission(part, agentID, me.InteractPermissions);
+ }
private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms)
{
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 70af978..0033900 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -82,6 +82,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene);
public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face);
+ public delegate bool InteractWithPrimMediaHandler(UUID userID, UUID primID, int face);
#endregion
public class ScenePermissions
@@ -141,6 +142,7 @@ namespace OpenSim.Region.Framework.Scenes
public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport;
public event ControlPrimMediaHandler OnControlPrimMedia;
+ public event InteractWithPrimMediaHandler OnInteractWithPrimMedia;
#endregion
#region Object Permission Checks
@@ -963,6 +965,21 @@ namespace OpenSim.Region.Framework.Scenes
}
}
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;
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From cf7573c8fda9fb33a0b46bc7a7bd893e974d2561 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Jul 2010 00:16:37 +0100
Subject: implement code to deregister users on DeregisterCaps
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 37 ++++++++++++++++++++--
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 09786ec..ce4e921 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -64,15 +64,25 @@ namespace OpenSim.Region.CoreModules.Media.Moap
protected Scene m_scene;
///
- /// Track the ObjectMedia capabilities given to users
+ /// Track the ObjectMedia capabilities given to users keyed by path
///
protected Dictionary m_omCapUsers = new Dictionary();
///
- /// Track the ObjectMediaUpdate capabilities given to users
+ /// Track the ObjectMedia capabilities given to users keyed by agent. Lock m_omCapUsers to manipulate.
+ ///
+ protected Dictionary m_omCapUrls = new Dictionary();
+
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users keyed by path
///
protected Dictionary m_omuCapUsers = new Dictionary();
+ ///
+ /// Track the ObjectMediaUpdate capabilities given to users keyed by agent. Lock m_omuCapUsers to manipulate
+ ///
+ protected Dictionary m_omuCapUrls = new Dictionary();
+
public void Initialise(IConfigSource config)
{
// TODO: Add config switches to enable/disable this module
@@ -88,11 +98,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void RegionLoaded(Scene scene)
{
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
}
public void Close()
{
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
}
public void RegisterCaps(UUID agentID, Caps caps)
@@ -105,6 +117,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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(
@@ -116,12 +129,30 @@ namespace OpenSim.Region.CoreModules.Media.Moap
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 DeregisterCaps(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);
+ }
+ }
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
--
cgit v1.1
From 049ccba8d3b71583f9f1aa7d13ca4a7f60501871 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Jul 2010 23:26:24 +0100
Subject: fix previous media interact serverside checking. perform very basic
serverside url whitelist checks
at the moment, only checking for the exact name prefix is implemented
for some reason, whitelists are not persisting
this commit also fixes a very recent problem where setting any media texture parameters after the initial configuration would not work
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 71 ++++++++++++++++++++--
.../World/Permissions/PermissionsModule.cs | 30 +++++++--
2 files changed, 91 insertions(+), 10 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index ce4e921..3c546c4 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -91,6 +91,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void AddRegion(Scene scene)
{
m_scene = scene;
+ m_scene.RegisterModuleInterface(this);
}
public void RemoveRegion(Scene scene) {}
@@ -156,20 +157,28 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
+ MediaEntry me = null;
+
CheckFaceParam(part, face);
List media = part.Shape.Media;
if (null == media)
{
- return null;
+ me = null;
}
else
- {
+ {
+ me = media[face];
+
// TODO: Really need a proper copy constructor down in libopenmetaverse
- MediaEntry me = media[face];
- return (null == me ? null : MediaEntry.FromOSD(me.GetOSD()));
+ 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)
@@ -295,6 +304,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (null == media)
{
+ m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name);
part.Shape.Media = new List(omu.FaceMedia);
}
else
@@ -309,7 +319,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
for (int i = 0; i < media.Count; i++)
{
if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
+ {
media[i] = omu.FaceMedia[i];
+// m_log.DebugFormat("[MOAP]: Set media entry for face {0} on {1}", i, part.Name);
+ }
}
}
@@ -362,10 +375,31 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
m_log.DebugFormat(
- "[MOAP]: Updating media entry for face {0} on prim {1} {2} to {3}",
+ "[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 = 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);
@@ -413,5 +447,32 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID);
}
+
+ ///
+ /// Check the given url against the given whitelist.
+ ///
+ ///
+ ///
+ /// true if the url matches an entry on the whitelist, false otherwise
+ protected bool CheckUrlAgainstWhitelist(string url, string[] whitelist)
+ {
+ foreach (string rawWlUrl in whitelist)
+ {
+ string wlUrl = rawWlUrl;
+
+ if (!wlUrl.StartsWith("http://"))
+ wlUrl = "http://" + wlUrl;
+
+ m_log.DebugFormat("[MOAP]: Checking whitelist URL {0}", wlUrl);
+
+ if (url.StartsWith(wlUrl))
+ {
+ m_log.DebugFormat("[MOAP]: Whitelist url {0} matches requested url {1}", wlUrl, url);
+ return true;
+ }
+ }
+
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 3a690af..7f6f851 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule");
- List modules=new List(permissionModules.Split(','));
+ List modules = new List(permissionModules.Split(','));
if (!modules.Contains("DefaultPermissionsModule"))
return;
@@ -399,6 +399,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
m_moapModule = m_scene.RequestModuleInterface();
+
+ // 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()
@@ -1901,7 +1905,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
}
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;
@@ -1909,17 +1917,25 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (null == part)
return false;
- MediaEntry me = m_moapModule.GetMediaEntry(part, face);
+ 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;
@@ -1933,13 +1949,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions
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 (IsAdministrator(agentID))
+// return true;
if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone)
return true;
--
cgit v1.1
From fc76ce0f466c7dfa2328c08e590c86460b068140 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Jul 2010 23:48:24 +0100
Subject: fix bug where prim persistence would fail if media had never been set
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 51f4cef..7acbd22 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -1919,14 +1919,17 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams;
- OSDArray meArray = new OSDArray();
- foreach (MediaEntry me in s.Media)
+ if (null != s.Media)
{
- OSD osd = (null == me ? new OSD() : me.GetOSD());
- meArray.Add(osd);
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in s.Media)
+ {
+ OSD osd = (null == me ? new OSD() : me.GetOSD());
+ meArray.Add(osd);
+ }
+
+ row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
-
- row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
///
--
cgit v1.1
From dce7307aa20f49276139708077e329835829d8c2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 00:15:23 +0100
Subject: properly expose prim media LSL functions to scripts
scripts using these functions should now compile but I don't know how well the methods themselves work yet
llSetPrimMedia(), at least, appears to have problems when a current url is set for a face that doesn't yet have a texture
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 2 +-
.../Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 3 +++
.../Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 15 +++++++++++++++
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 3c546c4..4bbac6e 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -186,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
CheckFaceParam(part, face);
if (null == part.Shape.Media)
- part.Shape.Media = new List(part.GetNumberOfSides());
+ part.Shape.Media = new List(new MediaEntry[part.GetNumberOfSides()]);
part.Shape.Media[face] = me;
UpdateMediaUrl(part);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index cba46a3..561e3b3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -62,6 +62,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llBreakLink(int linknum);
LSL_Integer llCeil(double f);
void llClearCameraParams();
+ LSL_Integer llClearPrimMedia(LSL_Integer face);
void llCloseRemoteDataChannel(string channel);
LSL_Float llCloud(LSL_Vector offset);
void llCollisionFilter(string name, string id, int accept);
@@ -162,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_List llGetParcelPrimOwners(LSL_Vector pos);
LSL_Integer llGetPermissions();
LSL_Key llGetPermissionsKey();
+ LSL_List llGetPrimMediaParams(int face, LSL_List rules);
LSL_Vector llGetPos();
LSL_List llGetPrimitiveParams(LSL_List rules);
LSL_Integer llGetRegionAgentCount();
@@ -332,6 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetParcelMusicURL(string url);
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
void llSetPos(LSL_Vector pos);
+ LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
void llSetPrimitiveParams(LSL_List rules);
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
void llSetPrimURL(string url);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 3339995..451163f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -1832,5 +1832,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
}
+
+ public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
+ {
+ return m_LSL_Functions.llGetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
+ {
+ return m_LSL_Functions.llSetPrimMediaParams(face, rules);
+ }
+
+ public LSL_Integer llClearPrimMedia(LSL_Integer face)
+ {
+ return m_LSL_Functions.llClearPrimMedia(face);
+ }
}
}
--
cgit v1.1
From 0edabffb7d6213db041ba3d01fee157dabcbcda5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 21:14:55 +0100
Subject: Implement * end wildcard for whitelist urls
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 4bbac6e..c24e6d5 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -460,6 +460,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
string wlUrl = rawWlUrl;
+ // Deal with a line-ending wildcard
+ if (wlUrl.EndsWith("*"))
+ wlUrl = wlUrl.Remove(wlUrl.Length - 1);
+
if (!wlUrl.StartsWith("http://"))
wlUrl = "http://" + wlUrl;
@@ -467,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (url.StartsWith(wlUrl))
{
- m_log.DebugFormat("[MOAP]: Whitelist url {0} matches requested url {1}", wlUrl, url);
+ m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, url);
return true;
}
}
--
cgit v1.1
From 664cbe2357cdb05202c01f1575f1e9f08273904e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 21:40:44 +0100
Subject: refactor: simplify current whitelist url checking by using System.Uri
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index c24e6d5..c8e72ca 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -451,11 +451,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
/// Check the given url against the given whitelist.
///
- ///
+ ///
///
/// true if the url matches an entry on the whitelist, false otherwise
- protected bool CheckUrlAgainstWhitelist(string url, string[] whitelist)
+ protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist)
{
+ Uri url = new Uri(rawUrl);
+
foreach (string rawWlUrl in whitelist)
{
string wlUrl = rawWlUrl;
@@ -464,14 +466,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
if (wlUrl.EndsWith("*"))
wlUrl = wlUrl.Remove(wlUrl.Length - 1);
- if (!wlUrl.StartsWith("http://"))
- wlUrl = "http://" + wlUrl;
-
m_log.DebugFormat("[MOAP]: Checking whitelist URL {0}", wlUrl);
+
+ string urlToMatch = url.Authority + url.AbsolutePath;
- if (url.StartsWith(wlUrl))
+ if (urlToMatch.StartsWith(wlUrl))
{
- m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, url);
+ m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, urlToMatch);
return true;
}
}
--
cgit v1.1
From cd985ab71b489d63d9f1033b5159f207ab614b18 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 21:51:57 +0100
Subject: Handle checking of line starting "*" wildcard for whitelist patterns
A line starting * can only be applied to the domain, not the path
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 30 ++++++++++++++++------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index c8e72ca..cbe9af2 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -458,22 +458,36 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
Uri url = new Uri(rawUrl);
- foreach (string rawWlUrl in whitelist)
+ foreach (string origWlUrl in whitelist)
{
- string wlUrl = rawWlUrl;
+ 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 {0}", wlUrl);
+ m_log.DebugFormat("[MOAP]: Checking whitelist URL pattern {0}", origWlUrl);
- string urlToMatch = url.Authority + url.AbsolutePath;
-
- if (urlToMatch.StartsWith(wlUrl))
+ // 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
{
- m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", wlUrl, urlToMatch);
- return true;
+ string urlToMatch = url.Authority + url.AbsolutePath;
+
+ if (urlToMatch.StartsWith(wlUrl))
+ {
+ m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl);
+ return true;
+ }
}
}
--
cgit v1.1
From f872a2af116e5e9cdf80efd2313818200b204a04 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Jul 2010 23:28:36 +0100
Subject: add missing regionstore migration file for new fields. D'oh!
this should enable persistence now
---
OpenSim/Data/SQLite/Resources/020_RegionStore.sql | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 OpenSim/Data/SQLite/Resources/020_RegionStore.sql
diff --git a/OpenSim/Data/SQLite/Resources/020_RegionStore.sql b/OpenSim/Data/SQLite/Resources/020_RegionStore.sql
new file mode 100644
index 0000000..39cb752
--- /dev/null
+++ b/OpenSim/Data/SQLite/Resources/020_RegionStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
+ALTER TABLE primshapes ADD COLUMN Media TEXT;
+
+COMMIT;
\ No newline at end of file
--
cgit v1.1
From 60c52ac0c44a395e3bd3b3ca761ad71ba10906c2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 21 Jul 2010 14:25:21 +0100
Subject: start adding user ids to the media urls
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 28 ++++++++++++----------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index cbe9af2..6755df7 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media = new List(new MediaEntry[part.GetNumberOfSides()]);
part.Shape.Media[face] = me;
- UpdateMediaUrl(part);
+ UpdateMediaUrl(part, UUID.Zero);
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
}
@@ -300,6 +300,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
return string.Empty;
}
+ UUID agentId = default(UUID);
+
+ lock (m_omCapUsers)
+ agentId = m_omCapUsers[path];
+
List media = part.Shape.Media;
if (null == media)
@@ -310,12 +315,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
else
{
// We need to go through the media textures one at a time to make sure that we have permission
- // to change them
- UUID agentId = default(UUID);
-
- lock (m_omCapUsers)
- agentId = m_omCapUsers[path];
-
+ // to change them
for (int i = 0; i < media.Count; i++)
{
if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i))
@@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
- UpdateMediaUrl(part);
+ UpdateMediaUrl(part, agentId);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate();
@@ -402,13 +402,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap
me.CurrentURL = omn.URL;
- UpdateMediaUrl(part);
+ UpdateMediaUrl(part, agentId);
part.ScheduleFullUpdate();
part.TriggerScriptChangedEvent(Changed.MEDIA);
- return string.Empty;
+ return OSDParser.SerializeLLSDXmlString(new OSD());
}
///
@@ -431,12 +431,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
/// Update the media url of the given part
///
///
- protected void UpdateMediaUrl(SceneObjectPart part)
+ ///
+ /// The id to attach to this update. Normally, this is the user that changed the
+ /// texture
+ ///
+ 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/" + UUID.Zero;
+ part.MediaUrl = "x-mv:0000000000/" + updateId;
}
else
{
--
cgit v1.1
From b06308e1d30022f1a240fdc7ca875cc7277b10ea Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 21 Jul 2010 17:12:43 +0100
Subject: Properly set TextureEntry.MediaFlags when a media texture is set
Media flags is cleared via a direct TextureEntry update from the client. If the clearing leaves no media textures on the prim, then a CAP ObjectMediaUpdate is not received. If there are still media textures present then one is received.
This change fixes drag-and-drop on Windows (and Mac?) clients. It may also fix problems with clearing and then subsequently setting new media textures.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 46 ++++++++++++++++++++--
1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 6755df7..4818546 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -311,19 +311,59 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name);
part.Shape.Media = new List(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;
+
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);
--
cgit v1.1
From d764c95d09c2141e1d4459dd608e95fb1f9d7546 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 21 Jul 2010 19:32:05 +0100
Subject: also add avatar id to an updated media url - not just new ones
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 4818546..0130ff9 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -486,7 +486,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
{
string rawVersion = part.MediaUrl.Substring(5, 10);
int version = int.Parse(rawVersion);
- part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, UUID.Zero);
+ part.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);
--
cgit v1.1
From afdbeba4e46f631b320b75bd304197959e650c2e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 19:56:55 +0100
Subject: Put a wrapper around the media texture region serialization
THIS WILL BREAK EXISTING MEDIA TEXTURE PERSISTENCE. Please delete your existing sqlite databases if you are experimenting with this branch.
This wrapper will make it easier to maintain compatibility if the media texture data evolves.
This will also make it easier to store non-sl media texture data.
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 58 ++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 7acbd22..b564419 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -31,6 +31,7 @@ using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
+using System.Xml;
using log4net;
using Mono.Data.Sqlite;
using OpenMetaverse;
@@ -1862,17 +1863,26 @@ namespace OpenSim.Data.SQLite
if (!(row["Media"] is System.DBNull))
{
- string rawMeArray = (string)row["Media"];
- OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(rawMeArray);
-
- List mediaEntries = new List();
- foreach (OSD osdMe in osdMeArray)
+ using (StringReader sr = new StringReader((string)row["Media"]))
{
- MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
- mediaEntries.Add(me);
+ using (XmlTextReader xtr = new XmlTextReader(sr))
+ {
+ xtr.ReadStartElement("osmedia");
+
+ OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
+
+ List mediaEntries = new List();
+ foreach (OSD osdMe in osdMeArray)
+ {
+ MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
+ mediaEntries.Add(me);
+ }
+
+ s.Media = mediaEntries;
+
+ xtr.ReadEndElement();
+ }
}
-
- s.Media = mediaEntries;
}
return s;
@@ -1921,14 +1931,32 @@ namespace OpenSim.Data.SQLite
if (null != s.Media)
{
- OSDArray meArray = new OSDArray();
- foreach (MediaEntry me in s.Media)
+ using (StringWriter sw = new StringWriter())
{
- OSD osd = (null == me ? new OSD() : me.GetOSD());
- meArray.Add(osd);
+ using (XmlTextWriter xtw = new XmlTextWriter(sw))
+ {
+ xtw.WriteStartElement("osmedia");
+ xtw.WriteAttributeString("type", "sl");
+ xtw.WriteAttributeString("major_version", "0");
+ xtw.WriteAttributeString("minor_version", "1");
+
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in s.Media)
+ {
+ 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();
+ row["Media"] = sw.ToString();
+ }
}
-
- row["Media"] = OSDParser.SerializeLLSDXmlString(meArray);
}
}
--
cgit v1.1
From 586ae0f6a07358f8367c4f916bff9fd688a43aa3 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 20:13:26 +0100
Subject: Add EventManager.OnSceneObjectLoaded() for future use. This is fired
immediately after a scene object is loaded from storage.
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 19 +++++++++----
OpenSim/Region/Framework/Scenes/EventManager.cs | 32 ++++++++++++++++++++--
OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-
3 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 0130ff9..2771492 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -98,17 +98,19 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void RegionLoaded(Scene scene)
{
- m_scene.EventManager.OnRegisterCaps += RegisterCaps;
- m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
+ m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
+ m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded;
}
public void Close()
{
- m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
- m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
+ m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
+ m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded;
}
- public void RegisterCaps(UUID agentID, Caps caps)
+ public void OnRegisterCaps(UUID agentID, Caps caps)
{
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
@@ -138,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
- public void DeregisterCaps(UUID agentID, Caps caps)
+ public void OnDeregisterCaps(UUID agentID, Caps caps)
{
lock (m_omCapUsers)
{
@@ -155,6 +157,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
+ public void OnSceneObjectLoaded(SceneObjectGroup sog)
+ {
+ m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", sog.Name, sog.UUID);
+ }
+
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
MediaEntry me = null;
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 9db2e41..0b1f593 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -331,9 +331,16 @@ namespace OpenSim.Region.Framework.Scenes
/// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
public event Attach OnAttach;
+
+ public delegate void SceneObjectDelegate(SceneObjectGroup so);
+
+ ///
+ /// Called immediately after an object is loaded from storage.
+ ///
+ public event SceneObjectDelegate OnSceneObjectLoaded;
public delegate void RegionUp(GridRegion region);
- public event RegionUp OnRegionUp;
+ public event RegionUp OnRegionUp;
public class MoneyTransferArgs : EventArgs
{
@@ -2013,5 +2020,26 @@ 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);
+ }
+ }
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 9141d44..e8dce08 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1887,9 +1887,11 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectGroup group in PrimsFromDB)
{
+ EventManager.TriggerOnSceneObjectLoaded(group);
+
if (group.RootPart == null)
{
- m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children",
+ m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
group.Children == null ? 0 : group.Children.Count);
}
--
cgit v1.1
From b51b2efdc8059548e1da7ac13ee858673b71592f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 20:36:28 +0100
Subject: Add EventManager.OnSceneObjectPreSave() for future use. This is
triggered immediately before a copy of the group is persisted to storage
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 11 ++++--
OpenSim/Region/Framework/Scenes/EventManager.cs | 39 ++++++++++++++++++++--
.../Region/Framework/Scenes/SceneObjectGroup.cs | 1 +
3 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 2771492..263ee57 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -101,6 +101,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded;
+ m_scene.EventManager.OnSceneObjectPreSave += OnSceneObjectPreSave;
}
public void Close()
@@ -108,6 +109,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded;
+ m_scene.EventManager.OnSceneObjectPreSave -= OnSceneObjectPreSave;
}
public void OnRegisterCaps(UUID agentID, Caps caps)
@@ -157,11 +159,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
}
}
- public void OnSceneObjectLoaded(SceneObjectGroup sog)
+ public void OnSceneObjectLoaded(SceneObjectGroup so)
{
- m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", sog.Name, sog.UUID);
+ m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", so.Name, so.UUID);
}
+ public void OnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo)
+ {
+ m_log.DebugFormat("[MOAP]: OnSceneObjectPreSave fired for {0} {1}", persistingSo.Name, persistingSo.UUID);
+ }
+
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
MediaEntry me = null;
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 0b1f593..3b8d727 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -330,14 +330,26 @@ namespace OpenSim.Region.Framework.Scenes
/// If the object is being attached, then the avatarID will be present. If the object is being detached then
/// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
- public event Attach OnAttach;
-
- public delegate void SceneObjectDelegate(SceneObjectGroup so);
+ public event Attach OnAttach;
///
/// Called immediately after an object is loaded from storage.
///
public event SceneObjectDelegate OnSceneObjectLoaded;
+ public delegate void SceneObjectDelegate(SceneObjectGroup so);
+
+ ///
+ /// Called immediately before an object is saved to storage.
+ ///
+ ///
+ /// 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.
+ ///
+ ///
+ /// The original scene object being persisted. Changes here will stay in memory but will not be saved to storage on this save.
+ ///
+ public event SceneObjectPreSaveDelegate OnSceneObjectPreSave;
+ public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo);
public delegate void RegionUp(GridRegion region);
public event RegionUp OnRegionUp;
@@ -2040,6 +2052,27 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
+ }
+
+ 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);
+ }
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 17275d0..c2f9117 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1479,6 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
HasGroupChanged = false;
+ m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
backup_group.ForEachPart(delegate(SceneObjectPart part)
--
cgit v1.1
From 412fed975fc0b28c3af111be89a1bcb4aaa05a9b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 21:09:54 +0100
Subject: relocate serialization code from SQLiteRegionData to MoapModule using
load and save events.
This is better modularity. It also allows MoapModule to be replaced with some other media module that may behave completely differently in the future.
Remaining non-modularity:
PrimitiveBaseShape needs explicit Media and MediaRaw fields. MediaRaw is required in order to shuttle the pre-serialization data back and forth from the database layer.
The database also needs to know about MediaRaw though not about Media.
IMO, it would be extremely nice to remove these hard codings but this is a bridge too far at the present time.
---
OpenSim/Data/SQLite/SQLiteRegionData.cs | 55 +----------------
OpenSim/Framework/PrimitiveBaseShape.cs | 6 ++
.../CoreModules/World/Media/Moap/MoapModule.cs | 70 +++++++++++++++++++++-
3 files changed, 76 insertions(+), 55 deletions(-)
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index b564419..f63d35e 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -31,7 +31,6 @@ using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
-using System.Xml;
using log4net;
using Mono.Data.Sqlite;
using OpenMetaverse;
@@ -1862,28 +1861,7 @@ namespace OpenSim.Data.SQLite
s.ExtraParams = (byte[]) row["ExtraParams"];
if (!(row["Media"] is System.DBNull))
- {
- using (StringReader sr = new StringReader((string)row["Media"]))
- {
- using (XmlTextReader xtr = new XmlTextReader(sr))
- {
- xtr.ReadStartElement("osmedia");
-
- OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
-
- List mediaEntries = new List();
- foreach (OSD osdMe in osdMeArray)
- {
- MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
- mediaEntries.Add(me);
- }
-
- s.Media = mediaEntries;
-
- xtr.ReadEndElement();
- }
- }
- }
+ s.MediaRaw = (string)row["Media"];
return s;
}
@@ -1928,36 +1906,7 @@ namespace OpenSim.Data.SQLite
row["Texture"] = s.TextureEntry;
row["ExtraParams"] = s.ExtraParams;
-
- if (null != s.Media)
- {
- using (StringWriter sw = new StringWriter())
- {
- using (XmlTextWriter xtw = new XmlTextWriter(sw))
- {
- xtw.WriteStartElement("osmedia");
- xtw.WriteAttributeString("type", "sl");
- xtw.WriteAttributeString("major_version", "0");
- xtw.WriteAttributeString("minor_version", "1");
-
- OSDArray meArray = new OSDArray();
- foreach (MediaEntry me in s.Media)
- {
- 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();
- row["Media"] = sw.ToString();
- }
- }
- }
+ row["Media"] = s.MediaRaw;
}
///
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 85638ca..03ddb33 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -174,6 +174,12 @@ namespace OpenSim.Framework
}
///
+ /// Raw media data suitable for serialization operations. This should only ever be used by an IMoapModule.
+ ///
+ [XmlIgnore]
+ public string MediaRaw { get; set; }
+
+ ///
/// Entries to store media textures on each face
///
/// Do not change this value directly - always do it through an IMoapModule.
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 263ee57..0e03318 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -32,6 +32,7 @@ using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
+using System.Xml;
using log4net;
using Mono.Addins;
using Nini.Config;
@@ -46,6 +47,7 @@ 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
@@ -162,12 +164,76 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void OnSceneObjectLoaded(SceneObjectGroup so)
{
m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", so.Name, so.UUID);
+
+ so.ForEachPart(OnSceneObjectPartLoaded);
}
public void OnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo)
{
- m_log.DebugFormat("[MOAP]: OnSceneObjectPreSave fired for {0} {1}", persistingSo.Name, persistingSo.UUID);
- }
+ m_log.DebugFormat("[MOAP]: OnSceneObjectPreSave fired for {0} {1}", persistingSo.Name, persistingSo.UUID);
+
+ persistingSo.ForEachPart(OnSceneObjectPartPreSave);
+ }
+
+ protected void OnSceneObjectPartLoaded(SceneObjectPart part)
+ {
+ if (null == part.Shape.MediaRaw)
+ return;
+
+ using (StringReader sr = new StringReader(part.Shape.MediaRaw))
+ {
+ using (XmlTextReader xtr = new XmlTextReader(sr))
+ {
+ xtr.ReadStartElement("osmedia");
+
+ OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
+
+ List mediaEntries = new List();
+ foreach (OSD osdMe in osdMeArray)
+ {
+ MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
+ mediaEntries.Add(me);
+ }
+
+ xtr.ReadEndElement();
+
+ part.Shape.Media = mediaEntries;
+ }
+ }
+ }
+
+ protected void OnSceneObjectPartPreSave(SceneObjectPart part)
+ {
+ if (null == part.Shape.Media)
+ return;
+
+ using (StringWriter sw = new StringWriter())
+ {
+ using (XmlTextWriter xtw = new XmlTextWriter(sw))
+ {
+ xtw.WriteStartElement("osmedia");
+ xtw.WriteAttributeString("type", "sl");
+ xtw.WriteAttributeString("major_version", "0");
+ xtw.WriteAttributeString("minor_version", "1");
+
+ OSDArray meArray = new OSDArray();
+ foreach (MediaEntry me in part.Shape.Media)
+ {
+ 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();
+ part.Shape.MediaRaw = sw.ToString();
+ }
+ }
+ }
public MediaEntry GetMediaEntry(SceneObjectPart part, int face)
{
--
cgit v1.1
From 4d23749241eb002c3815aa18789e8c3ffd44bfc1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 21:41:39 +0100
Subject: provide config option for media on a prim
---
.../CoreModules/World/Media/Moap/MoapModule.cs | 21 +++++++++++++++++++--
.../World/Permissions/PermissionsModule.cs | 4 ++--
bin/OpenSim.ini.example | 5 +++++
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 0e03318..7afeeec 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -61,6 +61,11 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public Type ReplaceableInterface { get { return null; } }
///
+ /// Is this module enabled?
+ ///
+ protected bool m_isEnabled = true;
+
+ ///
/// The scene to which this module is attached
///
protected Scene m_scene;
@@ -85,13 +90,19 @@ namespace OpenSim.Region.CoreModules.Media.Moap
///
protected Dictionary m_omuCapUrls = new Dictionary();
- public void Initialise(IConfigSource config)
+ public void Initialise(IConfigSource configSource)
{
- // TODO: Add config switches to enable/disable this module
+ IConfig config = configSource.Configs["MediaOnAPrim"];
+
+ if (config != null && !config.GetBoolean("Enabled", false))
+ m_isEnabled = false;
}
public void AddRegion(Scene scene)
{
+ if (!m_isEnabled)
+ return;
+
m_scene = scene;
m_scene.RegisterModuleInterface(this);
}
@@ -100,6 +111,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void RegionLoaded(Scene scene)
{
+ if (!m_isEnabled)
+ return;
+
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded;
@@ -108,6 +122,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public void Close()
{
+ if (!m_isEnabled)
+ return;
+
m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps;
m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded;
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 7f6f851..982ac52 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -401,8 +401,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_moapModule = m_scene.RequestModuleInterface();
// 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");
+// 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()
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 5dcc601..54c013a 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1245,6 +1245,11 @@
; enabled=false
+[MediaOnAPrim]
+ ; Enable media on a prim facilities
+ Enabled = true;
+
+
;;
;; These are defaults that are overwritten below in [Architecture].
;; These defaults allow OpenSim to work out of the box with
--
cgit v1.1
From 849fc0483f02984abf03994967168d6c38174732 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 23:19:31 +0100
Subject: add mysql support for media on a prim
---
OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 8 ++++++--
OpenSim/Data/MySQL/Resources/RegionStore.migrations | 9 ++++++++-
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index bfeae12..f17e8ae 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Data.MySQL
"PathTaperX, PathTaperY, PathTwist, " +
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
"ProfileCurve, ProfileHollow, Texture, " +
- "ExtraParams, State) values (?UUID, " +
+ "ExtraParams, State, Media) values (?UUID, " +
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
"?PCode, ?PathBegin, ?PathEnd, " +
"?PathScaleX, ?PathScaleY, " +
@@ -233,7 +233,7 @@ namespace OpenSim.Data.MySQL
"?PathTwistBegin, ?ProfileBegin, " +
"?ProfileEnd, ?ProfileCurve, " +
"?ProfileHollow, ?Texture, ?ExtraParams, " +
- "?State)";
+ "?State, ?Media)";
FillShapeCommand(cmd, prim);
@@ -1700,6 +1700,9 @@ namespace OpenSim.Data.MySQL
s.ExtraParams = (byte[])row["ExtraParams"];
s.State = (byte)(int)row["State"];
+
+ if (!(row["Media"] is System.DBNull))
+ s.MediaRaw = (string)row["Media"];
return s;
}
@@ -1743,6 +1746,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
cmd.Parameters.AddWithValue("State", s.State);
+ cmd.Parameters.AddWithValue("Media", s.MediaRaw);
}
public void StorePrimInventory(UUID primID, ICollection items)
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
index 3f644f9..1369704 100644
--- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
@@ -1,4 +1,4 @@
-
+
:VERSION 1 #---------------------
BEGIN;
@@ -800,3 +800,10 @@ BEGIN;
ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`;
COMMIT;
+:VERSION 35 #---------------------
+-- Added post 0.7
+
+BEGIN;
+ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
+ALTER TABLE primshapes ADD COLUMN Media TEXT;
+COMMIT;
\ No newline at end of file
--
cgit v1.1
From 109ddd1bd5fcabf3155e579fe6eb15e07869b9b8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 26 Jul 2010 23:26:22 +0100
Subject: add mssql support for media on a prim
compiles but not tested. please test and correct if necessary!
---
OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 10 +++++++---
OpenSim/Data/MSSQL/Resources/RegionStore.migrations | 9 ++++++++-
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
index d6cb91f..e61b4d9 100644
--- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
@@ -385,7 +385,7 @@ IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID)
PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions,
PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin,
ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow,
- Texture = @Texture, ExtraParams = @ExtraParams, State = @State
+ Texture = @Texture, ExtraParams = @ExtraParams, State = @State, Media = @Media
WHERE UUID = @UUID
END
ELSE
@@ -394,11 +394,11 @@ ELSE
primshapes (
UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY,
PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin,
- ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State
+ ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State, Media
) VALUES (
@UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY,
@PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin,
- @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State
+ @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State, @Media
)
END";
@@ -1180,6 +1180,9 @@ VALUES
{
}
+ if (!(shapeRow["Media"] is System.DBNull))
+ baseShape.MediaRaw = (string)shapeRow["Media"];
+
return baseShape;
}
@@ -1557,6 +1560,7 @@ VALUES
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
parameters.Add(_Database.CreateParameter("State", s.State));
+ parameters.Add(_Database.CreateParameter("Media", s.MediaRaw));
return parameters.ToArray();
}
diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
index e912d64..e2e8cbb 100644
--- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
@@ -1,4 +1,4 @@
-
+
:VERSION 1
CREATE TABLE [dbo].[prims](
@@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
COMMIT
+:VERSION 24
+-- Added post 0.7
+
+BEGIN TRANSACTION
+ALTER TABLE prims ADD COLUMN MediaURL varchar(255)
+ALTER TABLE primshapes ADD COLUMN Media TEXT
+COMMIT
\ No newline at end of file
--
cgit v1.1
From ac542a907bb9612a0580019d645a16697fc1c3b4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 27 Jul 2010 18:59:05 +0100
Subject: Make MoapModule ignore non-sl media texture data
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 7afeeec..81e4449 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -200,8 +200,16 @@ namespace OpenSim.Region.CoreModules.Media.Moap
using (StringReader sr = new StringReader(part.Shape.MediaRaw))
{
using (XmlTextReader xtr = new XmlTextReader(sr))
- {
- xtr.ReadStartElement("osmedia");
+ {
+ xtr.MoveToContent();
+
+ string type = xtr.GetAttribute("type");
+ //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type);
+
+ if (type != "sl")
+ return;
+
+ xtr.ReadStartElement("osmedia");
OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
--
cgit v1.1
From 30ac67fb3d10c0cdeb82bb995b579986a4fed528 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 27 Jul 2010 20:15:43 +0100
Subject: make MoapModule ignore possible future media texture data that it
can't handle
---
OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 81e4449..3a86167 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -60,6 +60,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
+ public const string MEDIA_TEXTURE_TYPE = "sl";
+
///
/// Is this module enabled?
///
@@ -206,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
string type = xtr.GetAttribute("type");
//m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type);
- if (type != "sl")
+ if (type != MEDIA_TEXTURE_TYPE)
return;
xtr.ReadStartElement("osmedia");
@@ -237,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap
using (XmlTextWriter xtw = new XmlTextWriter(sw))
{
xtw.WriteStartElement("osmedia");
- xtw.WriteAttributeString("type", "sl");
+ xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE);
xtw.WriteAttributeString("major_version", "0");
xtw.WriteAttributeString("minor_version", "1");
--
cgit v1.1
From 1996eb93b99a566a30a8ed447b3740697c18fc4d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 27 Jul 2010 21:52:50 +0100
Subject: Update OpenMetaverse libraries to r3287 + r3294 (removal of
OpenMetaverse.Http.dll dependency) + r3378 (treat MediaPermission as a
bitfield)
As far as I can determine, r3287 + r3294 patch was the previous update to the OpenMetaverse libraries
This change just adds r3378 to overcome problems storing media textures with certain permission combinations in inventory
This is a limited change in order to isolate moap from any other possible libomv update issues
An update to the forthcoming libomv 0.8.3 is expected in due course to replace this
This commit also deletes OpenMetaverse.Utilities.* as it's unused (on the advice of jhurliman).
---
bin/OpenMetaverse.StructuredData.XML | 666 +-
bin/OpenMetaverse.StructuredData.dll | Bin 102400 -> 102400 bytes
bin/OpenMetaverse.Utilities.XML | 98 -
bin/OpenMetaverse.Utilities.dll | Bin 49152 -> 0 bytes
bin/OpenMetaverse.XML | 47265 ++++++++++++++++++---------------
bin/OpenMetaverse.dll | Bin 1691648 -> 1691648 bytes
bin/OpenMetaverse.dll.config | 14 +-
bin/OpenMetaverseTypes.XML | 3809 +--
bin/OpenMetaverseTypes.dll | Bin 106496 -> 106496 bytes
9 files changed, 27547 insertions(+), 24305 deletions(-)
delete mode 100644 bin/OpenMetaverse.Utilities.XML
delete mode 100644 bin/OpenMetaverse.Utilities.dll
diff --git a/bin/OpenMetaverse.StructuredData.XML b/bin/OpenMetaverse.StructuredData.XML
index 374bc25..cce3656 100644
--- a/bin/OpenMetaverse.StructuredData.XML
+++ b/bin/OpenMetaverse.StructuredData.XML
@@ -1,333 +1,333 @@
-
-
-
- OpenMetaverse.StructuredData
-
-
-
-