public string BHasherSHA256Test(string toHash) { BHasher hasher = new BHasherSHA256(); byte[] byt = Encoding.ASCII.GetBytes(toHash); hasher.Add(byt, 0, byt.Length); BHash hash = hasher.Finish(); System.Console.WriteLine("BHasherSHA256 hash output = " + hash.ToString()); return(hash.ToString()); }
// Write the region spec file. private async Task <LHandle> WriteRegionSpec(AssetManager pAssetManager, BHash pRegionHash, string pFilename, string pRegionSpecURI) { // Create a simple tileset defining the region Tiles.TileSet regSpec = new Tiles.TileSet { root = new Tiles.Tile() { content = new Tiles.TileContent() { uri = pRegionSpecURI, extras = new Tiles.TileExtensions() { { "contentHash", pRegionHash.ToString() } } }, boundingVolume = new Tiles.TileBoundingVolume() { box = new Tiles.TileBox() }, geometricError = 0.5f }, }; using (var outm = new MemoryStream()) { using (var outt = new StreamWriter(outm)) { regSpec.ToJSON(outt); } await pAssetManager.AssetStorage.Store(pFilename, outm.ToArray()); } return(new LHandle(new BHashULong(), pFilename)); }
// Given a BScene, write out a GLTF version and return a handle to the version. private async Task <LHandle> WriteOutLevel(BHash pLevelHash, BScene pBScene, AssetManager pAssetManager) { Gltf gltf; try { gltf = new Gltf(_scene.Name, LContext.log, LContext.parms); gltf.LoadScene(pBScene); } catch (Exception e) { string emsg = String.Format("{0} Exeception loading scene into Gltf: {1}", _logHeader, e); LContext.log.ErrorFormat(emsg); throw new Exception(emsg); } string topLevelFilename = pLevelHash.ToString() + ".gltf"; LContext.log.DebugFormat("{0}: writing top level region GLTF to {1}", _logHeader, topLevelFilename); try { using (var outm = new MemoryStream()) { using (StreamWriter outt = new StreamWriter(outm)) { gltf.ToJSON(outt); } await pAssetManager.AssetStorage.Store(topLevelFilename, outm.ToArray()); } gltf.WriteBinaryFiles(pAssetManager.AssetStorage); gltf.WriteImages(pAssetManager.AssetStorage); } catch (Exception e) { string emsg = String.Format("{0} Exeception writing top level GLTF files: {1}", _logHeader, e); LContext.log.ErrorFormat(emsg); throw new Exception(emsg); } return(new LHandle(pLevelHash, topLevelFilename)); }
private void TestHasher(string name, BHasher hasher1, BHasher hasher2, byte[] testBytes) { hasher1.Add(testBytes, 0, testBytes.Length); BHash hash1 = hasher1.Finish(); hasher2.Add(testBytes[0]); hasher2.Add(testBytes, 1, 10); hasher2.Add(testBytes[11]); hasher2.Add(testBytes, 12, testBytes.Length - 12); BHash hash2 = hasher2.Finish(); Assert.AreEqual(hash1.ToString(), hash2.ToString(), "Adding bytes in different order gave different results in " + name); }
public override string ToString() { string ret; if (String.IsNullOrEmpty(Filename)) { ret = Hash.ToString(); } else { ret = Filename; } return(ret); }
// Given a hash for an SOG, return a handle for the SOG entry. // If there is no SOG info in the database, return 'null'. public async Task <LHandle> GetHandle(BHash pHash) { LHandle ret = null; string filename = PersistRules.GetFilename(PersistRules.AssetType.Scene, _scene.RegionInfo.RegionName, pHash.ToString(), _context.parms); filename = Path.GetFileNameWithoutExtension(filename); string dir = PersistRules.StorageDirectory(pHash.ToString(), _context.parms); // Heavy handed async stuff but the checks for existance could take a while // if the storage system is remote. if (await Task.Run(() => { return(Directory.Exists(dir) && (File.Exists(Path.Combine(dir, pHash + ".gltf")) || File.Exists(Path.Combine(dir, pHash + ".glb")))); })) { ret = new LHandle(pHash, dir); } return(ret); }
private async Task ConvertRegionAssets() { _assetTools = new LodenAssets(_scene, LContext); // Subscribe to changes in the region so we know when to start rebuilding // TODO: BHash regionHash = LodenRegion.CreateRegionHash(_scene); LContext.log.DebugFormat("{0} SOGs in region: {1}", _logHeader, _scene.GetSceneObjectGroups().Count); LContext.log.DebugFormat("{0} Computed region hash: {1}", _logHeader, regionHash.ToString()); // Cleaned up region identifier string regionIdentifier = _scene.RegionInfo.RegionID.ToString().Replace("-", ""); using (AssetManager assetManager = new AssetManager(_scene.AssetService, LContext.log, LContext.parms)) { string specFilename = regionIdentifier + ".json"; RegionTopLevelSpecURL = CreateFileURI(regionIdentifier + ".json", LContext.parms); // See if region specification file has been built bool buildRegion = true; try { string regionSpec = await assetManager.AssetStorage.FetchText(specFilename); if (!String.IsNullOrEmpty(regionSpec)) { // Read in the spec file TileSet regionTiles = TileSet.FromString(regionSpec); if (regionTiles.root.content.extras.ContainsKey("contentHash")) { // If the content hash matches, the region doesn't need rebuilding if ((string)regionTiles.root.content.extras["contentHash"] == regionHash.ToString()) { LContext.log.DebugFormat("{0} Content hash matches. Not rebuilding", _logHeader); buildRegion = false; } else { LContext.log.DebugFormat("{0} Content hash does not match. Rebuilding", _logHeader); } } } } catch (Exception e) { LContext.log.ErrorFormat("{0} Exception reading region spec file: {1}", _logHeader, e); buildRegion = true; } if (buildRegion) { // The region has not been built. LContext.log.DebugFormat("{0}: region does not match. Rebuilding", _logHeader); // Convert the OpenSimulator scene to BScene object for manipulation BScene bScene = await ConvertSceneToBScene(assetManager); // Write out the 'top level' (highest quality) version of the region LHandle topLevelHandle = await WriteOutLevel(regionHash, bScene, assetManager); // Create the region specification which defines the top of the region LOD tree LHandle regionSpecFile = await WriteRegionSpec(assetManager, regionHash, specFilename, topLevelHandle.Filename); } else { LContext.log.DebugFormat("{0}: region spec file exists.", _logHeader); } } // Partition region and verify all partitions have been created and not different. // TODO: // Walk up the LOD chain and verify existance or build each LOD level // TODO: // Wait for changes and do rebuilds of necessary // TODO: }