diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 60d1720ba7..b4f1ed6205 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -219,40 +219,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver CreateFoldersForPath(destFolder, archivePathSectionToCreate, resolvedFolders, loadedNodes); return destFolder; - - /* - string[] rawFolders = filePath.Split(new char[] { '/' }); - - // Find the folders that do exist along the path given - int i = 0; - bool noFolder = false; - InventoryFolderImpl foundFolder = rootDestinationFolder; - while (!noFolder && i < rawFolders.Length) - { - InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]); - if (null != folder) - { - m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name); - foundFolder = folder; - i++; - } - else - { - noFolder = true; - } - } - - // Create any folders that did not previously exist - while (i < rawFolders.Length) - { - m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]); - - UUID newFolderId = UUID.Random(); - m_userInfo.CreateFolder( - rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID); - foundFolder = foundFolder.GetChildFolder(newFolderId); - } - */ } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 59cd386c0c..00bd27aaba 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -279,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests public void TestIarV0_1WithEscapedChars() { TestHelper.InMethod(); - log4net.Config.XmlConfigurator.Configure(); +// log4net.Config.XmlConfigurator.Configure(); string itemName = "You & you are a mean/man/"; string humanEscapedItemName = @"You & you are a mean\/man\/"; @@ -505,7 +505,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests /// Test replication of an archive path to the user's inventory. /// [Test] - public void TestReplicateArchivePathToUserInventory() + public void TestNewIarPath() { TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); @@ -540,5 +540,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryFolderBase folder2 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, "b"); Assert.That(folder2, Is.Not.Null, "Could not find folder b"); } + + /// + /// Test replication of a partly existing archive path to the user's inventory. + /// + [Test] + public void TestPartExistingIarPath() + { + TestHelper.InMethod(); + //log4net.Config.XmlConfigurator.Configure(); + + Scene scene = SceneSetupHelpers.SetupScene("inventory"); + UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); + + string folder1ExistingName = "a"; + string folder2Name = "b"; + string itemName = "c.lsl"; + + InventoryFolderBase folder1 + = UserInventoryTestUtils.CreateInventoryFolder( + scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + + string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); + string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); + string itemArchiveName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random()); + + string itemArchivePath + = string.Format( + "{0}{1}{2}{3}", + ArchiveConstants.INVENTORY_PATH, folder1ArchiveName, folder2ArchiveName, itemArchiveName); + + new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) + .ReplicateArchivePathToUserInventory( + itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), + new Dictionary(), new List()); + + InventoryFolderBase folder1Post + = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); + /* + InventoryFolderBase folder2 + = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); + Assert.That(folder2, Is.Not.Null); + InventoryItemBase item = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, folder2, itemName); + Assert.That(item, Is.Not.Null); + */ + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index b71b5f61a5..b96d95a09c 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs @@ -70,10 +70,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap #region IMapImageGenerator Members - public byte[] WriteJpeg2000Image(string gradientmap) + public Bitmap CreateMapTile(string gradientmap) { - byte[] imageData = null; - bool drawPrimVolume = true; bool textureTerrain = false; @@ -98,32 +96,36 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } terrainRenderer.Initialise(m_scene, m_config); - using (Bitmap mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize)) + Bitmap mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb); + //long t = System.Environment.TickCount; + //for (int i = 0; i < 10; ++i) { + terrainRenderer.TerrainToBitmap(mapbmp); + //} + //t = System.Environment.TickCount - t; + //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); + + + if (drawPrimVolume) { - //long t = System.Environment.TickCount; - //for (int i = 0; i < 10; ++i) { - terrainRenderer.TerrainToBitmap(mapbmp); - //} - //t = System.Environment.TickCount - t; - //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); - - - if (drawPrimVolume) - { - DrawObjectVolume(m_scene, mapbmp); - } - - try - { - imageData = OpenJPEG.EncodeFromImage(mapbmp, true); - } - catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke - { - m_log.Error("Failed generating terrain map: " + e); - } + DrawObjectVolume(m_scene, mapbmp); } - return imageData; + return mapbmp; + } + + public byte[] WriteJpeg2000Image(string gradientmap) + { + try + { + using (Bitmap mapbmp = CreateMapTile(gradientmap)) + return OpenJPEG.EncodeFromImage(mapbmp, true); + } + catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke + { + m_log.Error("Failed generating terrain map: " + e); + } + + return null; } #endregion diff --git a/OpenSim/Region/CoreModules/World/WorldMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/WorldMap/ShadedMapTileRenderer.cs index a297cf310b..fef2ef3995 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/ShadedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/ShadedMapTileRenderer.cs @@ -37,6 +37,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { public class ShadedMapTileRenderer : IMapTileTerrainRenderer { + private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -221,8 +223,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap try { - Color water = Color.FromArgb((int)heightvalue, (int)heightvalue, 255); - mapbmp.SetPixel(x, yr, water); + mapbmp.SetPixel(x, yr, WATER_COLOR); } catch (ArgumentException) { diff --git a/OpenSim/Region/CoreModules/World/WorldMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/WorldMap/TexturedMapTileRenderer.cs index 4ecad74316..8b34f6ebdc 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/TexturedMapTileRenderer.cs @@ -136,6 +136,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private static readonly UUID defaultTerrainTexture4 = new UUID("53a2f406-4895-1d13-d541-d2e3b86bc19c"); private static readonly Color defaultColor4 = Color.FromArgb(200, 200, 200); + private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95); + #endregion @@ -406,8 +408,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap heightvalue = 100f - (heightvalue * 100f) / 19f; // 0 - 19 => 100 - 0 - Color water = Color.FromArgb((int)heightvalue, (int)heightvalue, 255); - mapbmp.SetPixel(x, yr, water); + mapbmp.SetPixel(x, yr, WATER_COLOR); } } } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index c6fb18d8f3..0e849e542c 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -1002,41 +1002,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap public void RegenerateMaptile(byte[] data) { - // Overwrites the local Asset cache with new maptile data - // Assets are single write, this causes the asset server to ignore this update, - // but the local asset cache does not - - // this is on purpose! The net result of this is the region always has the most up to date - // map tile while protecting the (grid) asset database from bloat caused by a new asset each - // time a mapimage is generated! - UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID; - int lastMapRefresh = 0; - int twoDays = 172800; -// int RefreshSeconds = twoDays; - - try - { - lastMapRefresh = Convert.ToInt32(m_scene.RegionInfo.lastMapRefresh); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } - m_log.Debug("[MAPTILE]: STORING MAPTILE IMAGE"); m_scene.RegionInfo.RegionSettings.TerrainImageID = UUID.Random(); AssetBase asset = new AssetBase( m_scene.RegionInfo.RegionSettings.TerrainImageID, - "terrainImage_" + m_scene.RegionInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString(), + "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(), (sbyte)AssetType.Texture, m_scene.RegionInfo.RegionID.ToString()); asset.Data = data; diff --git a/OpenSim/Region/Framework/Interfaces/ITerrain.cs b/OpenSim/Region/Framework/Interfaces/ITerrain.cs index f5662cbcf6..b42e872e6f 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrain.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrain.cs @@ -73,6 +73,7 @@ namespace OpenSim.Region.Framework.Interfaces public interface IMapImageGenerator { + System.Drawing.Bitmap CreateMapTile(string gradientmap); byte[] WriteJpeg2000Image(string gradientmap); } } diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 57924b7ab5..119868b967 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -28,17 +28,18 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; using System.Net; using System.Reflection; using log4net; using Mono.Addins; using Nini.Config; using OpenSim.Framework; -using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; -using OpenSim.Server.Base; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -62,7 +63,7 @@ namespace OpenSim.Services.Connectors.SimianGrid #region ISharedRegionModule public Type ReplaceableInterface { get { return null; } } - public void RegionLoaded(Scene scene) { } + public void RegionLoaded(Scene scene) { UploadMapTile(scene); } public void PostInitialise() { } public void Close() { } @@ -358,6 +359,83 @@ namespace OpenSim.Services.Connectors.SimianGrid #endregion IGridService + private void UploadMapTile(IScene scene) + { + string errorMessage = null; + + // Create a PNG map tile and upload it to the AddMapTile API + byte[] pngData = Utils.EmptyBytes; + IMapImageGenerator tileGenerator = scene.RequestModuleInterface(); + if (tileGenerator == null) + { + m_log.Warn("[SIMIAN GRID CONNECTOR]: Cannot upload PNG map tile without an IMapImageGenerator"); + return; + } + + using (Image mapTile = tileGenerator.CreateMapTile("defaultstripe.png")) + { + using (MemoryStream stream = new MemoryStream()) + { + mapTile.Save(stream, ImageFormat.Png); + pngData = stream.ToArray(); + } + } + + List postParameters = new List() + { + new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()), + new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()), + new MultipartForm.File("Tile", "tile.png", "image/png", pngData) + }; + + // Make the remote storage request + try + { + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); + + HttpWebResponse response = MultipartForm.Post(request, postParameters); + using (Stream responseStream = response.GetResponseStream()) + { + string responseStr = null; + + try + { + responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + { + OSDMap responseMap = (OSDMap)responseOSD; + if (responseMap["Success"].AsBoolean()) + m_log.Info("[SIMIAN GRID CONNECTOR]: Uploaded " + pngData.Length + " byte PNG map tile to AddMapTile"); + else + errorMessage = "Upload failed: " + responseMap["Message"].AsString(); + } + else + { + errorMessage = "Response format was invalid:\n" + responseStr; + } + } + catch (Exception ex) + { + if (!String.IsNullOrEmpty(responseStr)) + errorMessage = "Failed to parse the response:\n" + responseStr; + else + errorMessage = "Failed to retrieve the response: " + ex.Message; + } + } + } + catch (WebException ex) + { + errorMessage = ex.Message; + } + + if (!String.IsNullOrEmpty(errorMessage)) + { + m_log.WarnFormat("[SIMIAN GRID CONNECTOR]: Failed to store {0} byte PNG map tile for {1}: {2}", + pngData.Length, scene.RegionInfo.RegionName, errorMessage); + } + } + private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled) { NameValueCollection requestArgs = new NameValueCollection diff --git a/OpenSim/Tests/Common/Setup/AssetHelpers.cs b/OpenSim/Tests/Common/Setup/AssetHelpers.cs index 6dc993f069..f9a80b05b2 100644 --- a/OpenSim/Tests/Common/Setup/AssetHelpers.cs +++ b/OpenSim/Tests/Common/Setup/AssetHelpers.cs @@ -36,25 +36,29 @@ namespace OpenSim.Tests.Common public class AssetHelpers { /// - /// Create an asset from the given data + /// Create a notecard asset with a random uuid and dummy text. /// - public static AssetBase CreateAsset(UUID assetUuid, AssetType assetType, byte[] data, UUID creatorID) + /// /param> + /// + public static AssetBase CreateAsset(UUID creatorId) { - AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)assetType, creatorID.ToString()); - asset.Data = data; - return asset; - } - - /// - /// Create an asset from the given data - /// - public static AssetBase CreateAsset(UUID assetUuid, AssetType assetType, string data, UUID creatorID) - { - return CreateAsset(assetUuid, assetType, Encoding.ASCII.GetBytes(data), creatorID); + return CreateAsset(UUID.Random(), AssetType.Notecard, "hello", creatorId); } /// - /// Create an asset from the given scene object + /// Create and store a notecard asset with a random uuid and dummy text. + /// + /// /param> + /// + public static AssetBase CreateAsset(Scene scene, UUID creatorId) + { + AssetBase asset = CreateAsset(UUID.Random(), AssetType.Notecard, "hello", creatorId); + scene.AssetService.Store(asset); + return asset; + } + + /// + /// Create an asset from the given scene object. /// /// /// @@ -67,5 +71,23 @@ namespace OpenSim.Tests.Common Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(sog)), sog.OwnerID); } + + /// + /// Create an asset from the given data. + /// + public static AssetBase CreateAsset(UUID assetUuid, AssetType assetType, string data, UUID creatorID) + { + return CreateAsset(assetUuid, assetType, Encoding.ASCII.GetBytes(data), creatorID); + } + + /// + /// Create an asset from the given data. + /// + public static AssetBase CreateAsset(UUID assetUuid, AssetType assetType, byte[] data, UUID creatorID) + { + AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)assetType, creatorID.ToString()); + asset.Data = data; + return asset; + } } } diff --git a/OpenSim/Tests/Common/Setup/UserInventoryTestUtils.cs b/OpenSim/Tests/Common/Setup/UserInventoryTestUtils.cs index 7e0c5672df..c57363aa94 100644 --- a/OpenSim/Tests/Common/Setup/UserInventoryTestUtils.cs +++ b/OpenSim/Tests/Common/Setup/UserInventoryTestUtils.cs @@ -28,6 +28,7 @@ using System; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; namespace OpenSim.Tests.Common @@ -39,6 +40,23 @@ namespace OpenSim.Tests.Common { public static readonly string PATH_DELIMITER = "/"; + public static InventoryItemBase CreateInventoryItem( + Scene scene, string itemName, UUID itemId, string folderPath, UUID userId) + { + InventoryItemBase item = new InventoryItemBase(); + item.Name = itemName; + item.AssetID = AssetHelpers.CreateAsset(scene, userId).FullID; + item.ID = itemId; + + // Really quite bad since the objs folder could be moved in the future and confuse the tests + InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object); + + item.Folder = objsFolder.ID; + scene.AddInventoryItem(userId, item); + + return item; + } + /// /// Create inventory folders starting from the user's root folder. ///