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 --- .../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 +- 5 files changed, 142 insertions(+), 88 deletions(-) (limited to 'OpenSim/Region') 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 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 (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 --- .../CoreModules/World/Media/Moap/MoapModule.cs | 95 ++++++++++++++++++++-- 1 file changed, 89 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 --- .../CoreModules/World/Media/Moap/MoapModule.cs | 63 ++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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/Region/Framework/Scenes/SceneObjectPart.cs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') 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 -- 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 (limited to 'OpenSim/Region') 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 --- .../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 ++- 5 files changed, 183 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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/Region/CoreModules/World/Media/Moap/MoapModule.cs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(+) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(+) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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. --- .../CoreModules/World/Media/Moap/MoapModule.cs | 70 +++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') 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 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') 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() -- 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(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 b149d8970e0078b81e4b4784b633d95a419aeecb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 27 Jul 2010 22:49:45 +0100 Subject: comment out verbose debug logging --- .../CoreModules/World/Media/Moap/MoapModule.cs | 70 +++++++++++----------- 1 file changed, 36 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 3a86167..d53f573 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -98,6 +98,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (config != null && !config.GetBoolean("Enabled", false)) m_isEnabled = false; +// else +// m_log.Debug("[MOAP]: Initialised module.")l } public void AddRegion(Scene scene) @@ -135,8 +137,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap public void OnRegisterCaps(UUID agentID, Caps caps) { - m_log.DebugFormat( - "[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID); +// m_log.DebugFormat( +// "[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID); string omCapUrl = "/CAPS/" + UUID.Random(); @@ -182,14 +184,14 @@ namespace OpenSim.Region.CoreModules.Media.Moap public void OnSceneObjectLoaded(SceneObjectGroup so) { - m_log.DebugFormat("[MOAP]: OnSceneObjectLoaded fired for {0} {1}", so.Name, so.UUID); +// 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); } @@ -318,7 +320,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 path [{0}], raw request [{1}]", path, request); +// m_log.DebugFormat("[MOAP]: Got ObjectMedia path [{0}], raw request [{1}]", path, request); OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request); ObjectMediaMessage omm = new ObjectMediaMessage(); @@ -348,9 +350,9 @@ 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 region {1}", - primId, m_scene.RegionInfo.RegionName); +// m_log.WarnFormat( +// "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", +// primId, m_scene.RegionInfo.RegionName); return string.Empty; } @@ -365,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize()); - m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp); +// m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp); return rawResp; } @@ -384,13 +386,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == part) { - m_log.WarnFormat( - "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", - primId, m_scene.RegionInfo.RegionName); +// m_log.WarnFormat( +// "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", +// primId, m_scene.RegionInfo.RegionName); return string.Empty; } - m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId); +// m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId); // for (int i = 0; i < omu.FaceMedia.Length; i++) // { @@ -401,9 +403,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap 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()); +// 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; } @@ -416,7 +418,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == media) { - m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name); +// 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++) @@ -430,9 +432,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap 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); +// m_log.DebugFormat( +// "[MOAP]: Media flags for face {0} is {1}", +// i, part.Shape.Textures.FaceTextures[i].MediaFlags); } } } @@ -460,9 +462,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap 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]: 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); } } @@ -495,7 +497,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap protected string HandleObjectMediaNavigateMessage( string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request [{0}]", request); +// m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request [{0}]", request); OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request); ObjectMediaNavigateMessage omn = new ObjectMediaNavigateMessage(); @@ -521,9 +523,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (!m_scene.Permissions.CanInteractWithPrimMedia(agentId, part.UUID, omn.Face)) return string.Empty; - m_log.DebugFormat( - "[MOAP]: Received request to update media entry for face {0} on prim {1} {2} to {3}", - omn.Face, part.Name, part.UUID, omn.URL); +// m_log.DebugFormat( +// "[MOAP]: Received request to update media entry for face {0} on prim {1} {2} to {3}", +// omn.Face, part.Name, part.UUID, omn.URL); // If media has never been set for this prim, then just return. if (null == part.Shape.Media) @@ -539,9 +541,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap { 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); +// 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; } @@ -596,7 +598,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap 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); +// m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID); } /// @@ -617,7 +619,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (wlUrl.EndsWith("*")) wlUrl = wlUrl.Remove(wlUrl.Length - 1); - m_log.DebugFormat("[MOAP]: Checking whitelist URL pattern {0}", origWlUrl); +// m_log.DebugFormat("[MOAP]: Checking whitelist URL pattern {0}", origWlUrl); // Handle a line starting wildcard slightly differently since this can only match the domain, not the path if (wlUrl.StartsWith("*")) @@ -626,7 +628,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (url.Host.Contains(wlUrl)) { - m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl); +// m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl); return true; } } @@ -636,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (urlToMatch.StartsWith(wlUrl)) { - m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl); +// m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl); return true; } } -- cgit v1.1 From 5aa56b12743c19a68cb371609be797e5fb3e2c4b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Jul 2010 18:55:29 +0100 Subject: Fix problem where changes to media textures for prims duplicated by shify copy would change both prims until server restart I also found out that you can crash the current viewer by giving it more media entrys than it's expecting --- .../Region/CoreModules/World/Media/Moap/MoapModule.cs | 18 +++++++++--------- .../World/Permissions/PermissionsModule.cs | 12 ++++++------ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 19 ++++++++++++++++++- 3 files changed, 33 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index d53f573..6d74b8e 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -350,9 +350,9 @@ 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 region {1}", -// primId, m_scene.RegionInfo.RegionName); + m_log.WarnFormat( + "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", + primId, m_scene.RegionInfo.RegionName); return string.Empty; } @@ -386,9 +386,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == part) { -// m_log.WarnFormat( -// "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", -// primId, m_scene.RegionInfo.RegionName); + m_log.WarnFormat( + "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", + primId, m_scene.RegionInfo.RegionName); return string.Empty; } @@ -403,9 +403,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap 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()); + 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; } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 982ac52..3a642f4 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1923,9 +1923,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions 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); +// 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); } @@ -1949,9 +1949,9 @@ 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); +// 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); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 444a239..085da19 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1617,7 +1617,24 @@ namespace OpenSim.Region.Framework.Scenes dupe.DoPhysicsPropertyUpdate(UsePhysics, true); } - return dupe; + if (Shape.Media != null) + { + List dupeMedia = new List(); + + foreach (MediaEntry me in Shape.Media) + { + if (me != null) + dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD())); + else + dupeMedia.Add(null); + } + + dupe.Shape.Media = dupeMedia; + } + +// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); + + return dupe; } protected void AssetReceived(string id, Object sender, AssetBase asset) -- cgit v1.1 From 0f15ccb2cf994c64fb8c7f71a64721a3e5fe3085 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Jul 2010 19:23:30 +0100 Subject: relocate moap specific cloning code to MoapModule --- .../CoreModules/World/Media/Moap/MoapModule.cs | 20 +++++++++++++++ OpenSim/Region/Framework/Scenes/EventManager.cs | 29 +++++++++++++++++++++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 15 +---------- 3 files changed, 49 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 6d74b8e..f4814ce 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -122,6 +122,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps; m_scene.EventManager.OnSceneObjectLoaded += OnSceneObjectLoaded; m_scene.EventManager.OnSceneObjectPreSave += OnSceneObjectPreSave; + m_scene.EventManager.OnSceneObjectPartCopy += OnSceneObjectPartCopy; } public void Close() @@ -133,6 +134,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps; m_scene.EventManager.OnSceneObjectLoaded -= OnSceneObjectLoaded; m_scene.EventManager.OnSceneObjectPreSave -= OnSceneObjectPreSave; + m_scene.EventManager.OnSceneObjectPartCopy -= OnSceneObjectPartCopy; } public void OnRegisterCaps(UUID agentID, Caps caps) @@ -264,6 +266,24 @@ namespace OpenSim.Region.CoreModules.Media.Moap } } + protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original) + { + if (original.Shape.Media != null) + { + List dupeMedia = new List(); + + foreach (MediaEntry me in original.Shape.Media) + { + if (me != null) + dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD())); + else + dupeMedia.Add(null); + } + + copy.Shape.Media = dupeMedia; + } + } + public MediaEntry GetMediaEntry(SceneObjectPart part, int face) { MediaEntry me = null; diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 3b8d727..0a9a29e 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -350,6 +350,12 @@ namespace OpenSim.Region.Framework.Scenes /// public event SceneObjectPreSaveDelegate OnSceneObjectPreSave; public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo); + + /// + /// Called when a scene object part is cloned within the region. + /// + public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; + public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original); public delegate void RegionUp(GridRegion region); public event RegionUp OnRegionUp; @@ -2073,6 +2079,27 @@ namespace OpenSim.Region.Framework.Scenes } } } - } + } + + public void TriggerOnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original) + { + SceneObjectPartCopyDelegate handler = OnSceneObjectPartCopy; + if (handler != null) + { + foreach (SceneObjectPartCopyDelegate d in handler.GetInvocationList()) + { + try + { + d(copy, original); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPartCopy failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 085da19..71ca605 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1617,20 +1617,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.DoPhysicsPropertyUpdate(UsePhysics, true); } - if (Shape.Media != null) - { - List dupeMedia = new List(); - - foreach (MediaEntry me in Shape.Media) - { - if (me != null) - dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD())); - else - dupeMedia.Add(null); - } - - dupe.Shape.Media = dupeMedia; - } + ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this); // m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); -- cgit v1.1 From f067f733ea60cc821d51889871f1f8d476aebd76 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Jul 2010 19:38:20 +0100 Subject: add userExposed parameter to part copy event --- OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 2 +- OpenSim/Region/Framework/Scenes/EventManager.cs | 9 ++++++--- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++++- 4 files changed, 14 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index f4814ce..e9d723b 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -266,7 +266,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap } } - protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original) + protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed) { if (original.Shape.Media != null) { diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 0a9a29e..0ae3146 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -354,8 +354,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// Called when a scene object part is cloned within the region. /// + /// + /// + /// True if the duplicate will immediately be in the scene, false otherwise public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; - public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original); + public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed); public delegate void RegionUp(GridRegion region); public event RegionUp OnRegionUp; @@ -2081,7 +2084,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerOnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original) + public void TriggerOnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed) { SceneObjectPartCopyDelegate handler = OnSceneObjectPartCopy; if (handler != null) @@ -2090,7 +2093,7 @@ namespace OpenSim.Region.Framework.Scenes { try { - d(copy, original); + d(copy, original, userExposed); } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c2f9117..e26e4ae 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1528,6 +1528,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Duplicates this object, including operations such as physics set up and attaching to the backup event. /// + /// True if the duplicate will immediately be in the scene, false otherwise /// public SceneObjectGroup Copy(bool userExposed) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 71ca605..32332f7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1554,6 +1554,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// Duplicates this part. /// + /// + /// + /// + /// + /// True if the duplicate will immediately be in the scene, false otherwise /// public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) { @@ -1617,7 +1622,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.DoPhysicsPropertyUpdate(UsePhysics, true); } - ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this); + ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); // m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); -- cgit v1.1 From 60df76314f89d8a489a7f8a3182277cf1a52925c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Aug 2010 15:45:49 +0100 Subject: serialize media textures to inventory with a largely osd representation rather than .net auto-serialization THIS WILL BREAK ANY EXISTING MEDIA TEXTURE SERIALIZATIONS. If you're testing this, please start with new databases. This makes media textures serialized in the same way, which is probably better in the long term. --- OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index e9d723b..339a979 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -219,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); - List mediaEntries = new List(); + PrimitiveBaseShape.MediaList mediaEntries = new PrimitiveBaseShape.MediaList(); foreach (OSD osdMe in osdMeArray) { MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); @@ -270,7 +270,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap { if (original.Shape.Media != null) { - List dupeMedia = new List(); + PrimitiveBaseShape.MediaList dupeMedia = new PrimitiveBaseShape.MediaList(); foreach (MediaEntry me in original.Shape.Media) { @@ -315,7 +315,7 @@ namespace OpenSim.Region.CoreModules.Media.Moap CheckFaceParam(part, face); if (null == part.Shape.Media) - part.Shape.Media = new List(new MediaEntry[part.GetNumberOfSides()]); + part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); part.Shape.Media[face] = me; UpdateMediaUrl(part, UUID.Zero); @@ -439,7 +439,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); + part.Shape.Media = new PrimitiveBaseShape.MediaList(omu.FaceMedia); for (int i = 0; i < omu.FaceMedia.Length; i++) { -- cgit v1.1 From ac07d853b89d9b2bda2dd058f7f9ea94211a26f1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Aug 2010 15:58:17 +0100 Subject: remove duplicated serialization code --- .../CoreModules/World/Media/Moap/MoapModule.cs | 58 ++-------------------- 1 file changed, 3 insertions(+), 55 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 339a979..52acf81 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -203,67 +203,15 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == part.Shape.MediaRaw) return; - using (StringReader sr = new StringReader(part.Shape.MediaRaw)) - { - using (XmlTextReader xtr = new XmlTextReader(sr)) - { - xtr.MoveToContent(); - - string type = xtr.GetAttribute("type"); - //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); - - if (type != MEDIA_TEXTURE_TYPE) - return; - - xtr.ReadStartElement("osmedia"); - - OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); - - PrimitiveBaseShape.MediaList mediaEntries = new PrimitiveBaseShape.MediaList(); - foreach (OSD osdMe in osdMeArray) - { - MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); - mediaEntries.Add(me); - } - - xtr.ReadEndElement(); - - part.Shape.Media = mediaEntries; - } - } + part.Shape.Media = PrimitiveBaseShape.MediaList.FromXml(part.Shape.MediaRaw); } 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", MEDIA_TEXTURE_TYPE); - 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(); - } - } + + part.Shape.MediaRaw = part.Shape.Media.ToXml(); } protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed) -- cgit v1.1 From 9d8a67fe1348419c41374d1be77737bfa048106c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Aug 2010 16:26:27 +0100 Subject: get rid of PrimitiveBaseShape.MediaRaw staging post using an OSD serialization rather than auto forces serialization code to be placed in OpenSim.Framework this makes the media texture raw data staging post in PrimitiveBaseShape redundant, now we just directly call the code in PrimitiveBaseShape.MediaList itself --- .../CoreModules/World/Media/Moap/MoapModule.cs | 34 ---------------------- 1 file changed, 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 52acf81..d7ce184 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -120,8 +120,6 @@ 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; m_scene.EventManager.OnSceneObjectPartCopy += OnSceneObjectPartCopy; } @@ -132,8 +130,6 @@ 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; m_scene.EventManager.OnSceneObjectPartCopy -= OnSceneObjectPartCopy; } @@ -184,36 +180,6 @@ 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); - - persistingSo.ForEachPart(OnSceneObjectPartPreSave); - } - - protected void OnSceneObjectPartLoaded(SceneObjectPart part) - { - if (null == part.Shape.MediaRaw) - return; - - part.Shape.Media = PrimitiveBaseShape.MediaList.FromXml(part.Shape.MediaRaw); - } - - protected void OnSceneObjectPartPreSave(SceneObjectPart part) - { - if (null == part.Shape.Media) - return; - - part.Shape.MediaRaw = part.Shape.Media.ToXml(); - } - protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed) { if (original.Shape.Media != null) -- cgit v1.1 From 99c0f4c9c7820f6340155f7af30ab91745774c93 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Aug 2010 17:09:20 +0100 Subject: Simplify serialized version string. Change element capitalization for consistency THIS CHANGE ALTERS THE SERIALIZATION FORMAT, HOPEFULLY FOR THE LAST TIME. If you're testing, please start with a new database. This commit also improves locking for manipulation of media entries. --- .../CoreModules/World/Media/Moap/MoapModule.cs | 76 +++++++++++++--------- 1 file changed, 45 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index d7ce184..8549b36 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -185,13 +185,15 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (original.Shape.Media != null) { PrimitiveBaseShape.MediaList dupeMedia = new PrimitiveBaseShape.MediaList(); - - foreach (MediaEntry me in original.Shape.Media) + lock (original.Shape.Media) { - if (me != null) - dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD())); - else - dupeMedia.Add(null); + foreach (MediaEntry me in original.Shape.Media) + { + if (me != null) + dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD())); + else + dupeMedia.Add(null); + } } copy.Shape.Media = dupeMedia; @@ -211,8 +213,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap me = null; } else - { - me = media[face]; + { + lock (media) + me = media[face]; // TODO: Really need a proper copy constructor down in libopenmetaverse if (me != null) @@ -230,11 +233,13 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == part.Shape.Media) part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); - - part.Shape.Media[face] = me; + + lock (part.Shape.Media) + part.Shape.Media[face] = me; + UpdateMediaUrl(part, UUID.Zero); part.ScheduleFullUpdate(); - part.TriggerScriptChangedEvent(Changed.MEDIA); + part.TriggerScriptChangedEvent(Changed.MEDIA); } public void ClearMediaEntry(SceneObjectPart part, int face) @@ -296,7 +301,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap ObjectMediaResponse resp = new ObjectMediaResponse(); resp.PrimID = primId; - resp.FaceMedia = part.Shape.Media.ToArray(); + + lock (part.Shape.Media) + resp.FaceMedia = part.Shape.Media.ToArray(); + resp.Version = part.MediaUrl; string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize()); @@ -382,24 +390,27 @@ namespace OpenSim.Region.CoreModules.Media.Moap // 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); + lock (media) + { + for (int i = 0; i < media.Count; i++) + { + if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i)) + { + media[i] = omu.FaceMedia[i]; + + // When a face is cleared this is done by setting the MediaFlags in the TextureEntry via a normal + // texture update, so we don't need to worry about clearing MediaFlags here. + if (null == media[i]) + continue; + + Primitive.TextureEntryFace face = te.CreateFace((uint)i); + face.MediaFlags = true; + + // m_log.DebugFormat( + // "[MOAP]: Media flags for face {0} is {1}", + // i, face.MediaFlags); + // m_log.DebugFormat("[MOAP]: Set media entry for face {0} on {1}", i, part.Name); + } } } @@ -465,7 +476,10 @@ namespace OpenSim.Region.CoreModules.Media.Moap if (null == part.Shape.Media) return string.Empty; - MediaEntry me = part.Shape.Media[omn.Face]; + MediaEntry me = null; + + lock (part.Shape.Media) + me = part.Shape.Media[omn.Face]; // Do the same if media has not been set up for a specific face if (null == me) -- cgit v1.1 From bda83715e405202e73a2df9eb10daa8f892490c8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 02:51:41 +0200 Subject: Clean up some messiness in IM sending. Having offline IM enabled now no longer suppresses "Inventory Saved" messages. --- .../Avatar/InstantMessage/InstantMessageModule.cs | 3 ++- .../Avatar/InstantMessage/MessageTransferModule.cs | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index ab141eb..a3c40e0 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -162,7 +162,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage delegate(bool success) { if (dialog == (uint)InstantMessageDialog.StartTyping || - dialog == (uint)InstantMessageDialog.StopTyping) + dialog == (uint)InstantMessageDialog.StopTyping || + dialog == (uint)InstantMessageDialog.MessageFromObject) { return; } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 83209fc..d025f0c 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -185,13 +185,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; - // If this event has handlers, then the IM will be considered - // delivered. This will suppress the error message. + // If this event has handlers, then an IM from an agent will be + // considered delivered. This will suppress the error message. // if (handlerUndeliveredMessage != null) { handlerUndeliveredMessage(im); - result(true); + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + result(true); + else + result(false); return; } @@ -504,14 +507,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // if (upd.RegionID == prevRegionID) { - m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); HandleUndeliveredMessage(im, result); return; } } else { - m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); HandleUndeliveredMessage(im, result); return; } -- cgit v1.1 From 09ab32c21e0974e85698d2d758495d99063dedf8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 03:23:19 +0200 Subject: Remove StandAlone from default hardcoded config --- OpenSim/Region/Application/ConfigurationLoader.cs | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index cac5fa9..09f7bea 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -308,21 +308,6 @@ namespace OpenSim } { - IConfig config = defaultConfig.Configs["StandAlone"]; - - if (null == config) - config = defaultConfig.AddConfig("StandAlone"); - - config.Set("accounts_authenticate", true); - config.Set("welcome_message", "Welcome to OpenSimulator"); - config.Set("inventory_plugin", "OpenSim.Data.SQLite.dll"); - config.Set("inventory_source", ""); - config.Set("userDatabase_plugin", "OpenSim.Data.SQLite.dll"); - config.Set("user_source", ""); - config.Set("LibrariesXMLFile", string.Format(".{0}inventory{0}Libraries.xml", Path.DirectorySeparatorChar)); - } - - { IConfig config = defaultConfig.Configs["Network"]; if (null == config) -- cgit v1.1 From 1869572297f82f15db76b76e807859011ccaf29d Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 5 Aug 2010 08:19:46 +0100 Subject: Prevent setting the hovertext from firing changed_color --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e331bb0..7036884 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -865,7 +865,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_color = value; - TriggerScriptChangedEvent(Changed.COLOR); /* ScheduleFullUpdate() need not be called b/c after * setting the color, the text will be set, so then -- cgit v1.1 From 847008ee073f14901c607d8987f4c77dcfede590 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 5 Aug 2010 09:41:24 -0700 Subject: Addresses http://opensimulator.org/mantis/view.php?id=4919 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1e8ce22..e073a9b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -929,7 +929,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void MakeChildAgent() { - Animator.ResetAnimations(); + // It looks like m_animator is set to null somewhere, and MakeChild + // is called after that. Probably in aborted teleports. + if (m_animator == null) + m_animator = new ScenePresenceAnimator(this); + else + Animator.ResetAnimations(); // m_log.DebugFormat( // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", -- cgit v1.1 From 1cae505ea18ea53a4fa9fe1cf99175bc6bba610d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 5 Aug 2010 22:50:09 +0200 Subject: Prevent hammering the grid services with llRequestAgentData requests. Cache the user information permanently, and the online status for 20 seconds. Also cache negatives. --- .../Shared/Api/Implementation/LSL_Api.cs | 55 +++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ed63aee..d5ad5b6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -68,6 +68,14 @@ using System.Reflection; namespace OpenSim.Region.ScriptEngine.Shared.Api { + // MUST be a ref type + public class UserInfoCacheEntry + { + public int time; + public UserAccount account; + public PresenceInfo pinfo; + } + /// /// Contains all LSL ll-functions. This class will be in Default AppDomain. /// @@ -92,6 +100,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int m_scriptConsoleChannel = 0; protected bool m_scriptConsoleChannelEnabled = false; protected IUrlModule m_UrlModule = null; + protected Dictionary m_userInfoCache = + new Dictionary(); public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) { @@ -3908,16 +3918,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID uuid = (UUID)id; + PresenceInfo pinfo = null; + UserAccount account; - UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); - if (account == null) - return UUID.Zero.ToString(); + UserInfoCacheEntry ce; + if (!m_userInfoCache.TryGetValue(uuid, out ce)) + { + account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); + if (account == null) + { + m_userInfoCache[uuid] = null; // Cache negative + return UUID.Zero.ToString(); + } - PresenceInfo pinfo = null; - PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); - if (pinfos != null && pinfos.Length > 0) - pinfo = pinfos[0]; + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + pinfo = pinfos[0]; + + ce = new UserInfoCacheEntry(); + ce.time = Util.EnvironmentTickCount(); + ce.account = account; + ce.pinfo = pinfo; + } + else + { + if (ce == null) + return UUID.Zero.ToString(); + + account = ce.account; + pinfo = ce.pinfo; + } + + if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) + { + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + pinfo = pinfos[0]; + + ce.time = Util.EnvironmentTickCount(); + ce.pinfo = pinfo; + } string reply = String.Empty; -- cgit v1.1 From db2f63706da16ca97c737469f6f6b06478ef1f26 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 6 Aug 2010 00:02:38 +0200 Subject: Prevent users from becoming stuck online. This affects only 0.7 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d5ad5b6..f26fc2e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3955,6 +3955,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); if (pinfos != null && pinfos.Length > 0) pinfo = pinfos[0]; + else + pinfo = null; ce.time = Util.EnvironmentTickCount(); ce.pinfo = pinfo; -- cgit v1.1 From c1ad8a3c170dd1c35c5c892af5fd7fc06037de5f Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 6 Aug 2010 15:05:35 +0100 Subject: People can't leave their hands ooff "well enough". StateSource 0 was region start, and they started at 1 for real values. Whoever changed that enum to start at 0 should bow their head in shame. They broke the region start event. This puts it right again. Meow! --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 9f6ea35..0c99d8c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -38,10 +38,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces { public enum StateSource { - NewRez = 0, - PrimCrossing = 1, - ScriptedRez = 2, - AttachedRez = 3 + RegionStart = 0, + NewRez = 1, + PrimCrossing = 2, + ScriptedRez = 3, + AttachedRez = 4 } public interface IScriptWorkItem -- cgit v1.1 From 120f3a18f298ac023e80da187f70e886a7cacfbd Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 6 Aug 2010 15:11:18 +0100 Subject: Correct some script constants. --- OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 7 ++++--- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index de4c5fb..a90e0f3 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -131,7 +131,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) { // 16384 is CHANGED_ANIMATION - m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); + m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); SendAnimPack(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7036884..69f9627 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -56,9 +56,10 @@ namespace OpenSim.Region.Framework.Scenes LINK = 32, ALLOWED_DROP = 64, OWNER = 128, - REGION_RESTART = 256, - REGION = 512, - TELEPORT = 1024 + REGION = 256, + TELEPORT = 512, + REGION_RESTART = 1024, + ANIMATION = 16384 } // I don't really know where to put this except here. diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e073a9b..4c17615 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3460,7 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes if (m == null) // No script engine loaded continue; - m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { 16384 }); + m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index dba6502..69f48c9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -273,9 +273,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int CHANGED_LINK = 32; public const int CHANGED_ALLOWED_DROP = 64; public const int CHANGED_OWNER = 128; - public const int CHANGED_REGION_RESTART = 256; - public const int CHANGED_REGION = 512; - public const int CHANGED_TELEPORT = 1024; + public const int CHANGED_REGION = 256; + public const int CHANGED_TELEPORT = 512; + public const int CHANGED_REGION_RESTART = 1024; + public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART public const int CHANGED_ANIMATION = 16384; public const int TYPE_INVALID = 0; public const int TYPE_INTEGER = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 3dd381d..ccfe6a7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -392,13 +392,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { // m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); PostEvent(new EventParams("changed", - new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0])); + new Object[] { (int)Changed.REGION_RESTART }, new DetectParams[0])); } else if (m_stateSource == StateSource.PrimCrossing) { // CHANGED_REGION PostEvent(new EventParams("changed", - new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0])); + new Object[] { (int)Changed.REGION }, new DetectParams[0])); } } else -- cgit v1.1 From e1e897ac117ec78ea5636116d15d79d7c24cdf5f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 6 Aug 2010 15:33:22 +0200 Subject: Change XEngine to use the new constant --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index ccfe6a7..6663aa5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -388,7 +388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance PostEvent(new EventParams("attach", new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); } - else if (m_stateSource == StateSource.NewRez) + else if (m_stateSource == StateSource.RegionStart) { // m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); PostEvent(new EventParams("changed", -- cgit v1.1 From 54dcfe3f2df7d26e7351c3bfd72d2babf04160c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Aug 2010 12:37:34 -0400 Subject: Fixes: llSetLinkPrimitiveParams - PRIM_POSITION is not relative to root, causes unexpected movement of child prims Signed-off-by: Melanie --- .../Shared/Api/Implementation/LSL_Api.cs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f26fc2e..50ea489 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1929,7 +1929,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) { // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) - LSL_Vector currentPos = llGetLocalPos(); + LSL_Vector currentPos = GetPartLocalPos((part); float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); @@ -1962,17 +1962,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetLocalPos() { m_host.AddScriptLPS(1); - if (m_host.ParentID != 0) + return GetPartLocalPos(m_host); + } + + protected LSL_Vector GetPartLocalPos(SceneObjectPart part) + { + m_host.AddScriptLPS(1); + if (part.ParentID != 0) { - return new LSL_Vector(m_host.OffsetPosition.X, - m_host.OffsetPosition.Y, - m_host.OffsetPosition.Z); + return new LSL_Vector(part.OffsetPosition.X, + part.OffsetPosition.Y, + part.OffsetPosition.Z); } else { - return new LSL_Vector(m_host.AbsolutePosition.X, - m_host.AbsolutePosition.Y, - m_host.AbsolutePosition.Z); + return new LSL_Vector(part.AbsolutePosition.X, + part.AbsolutePosition.Y, + part.AbsolutePosition.Z); } } -- cgit v1.1 From cc05fc43b92798d32ef334c8129a624881d799f1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 6 Aug 2010 17:55:41 +0100 Subject: Fix a parenthesis in prior commit --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ba1a5f1..32e46ec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1929,7 +1929,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) { // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) - LSL_Vector currentPos = GetPartLocalPos((part); + LSL_Vector currentPos = GetPartLocalPos(part); float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); -- cgit v1.1