bool IAssetMetadataServiceInterface.TryGetValue(UUID key, out AssetMetadata metadata) { if (!m_ResourceAssets.ContainsAsset(key)) { metadata = null; return(false); } AssetData ad = m_ResourceAssets.GetAsset(key); metadata = new AssetMetadata { AccessTime = ad.AccessTime, CreateTime = ad.CreateTime, Flags = ad.Flags, ID = ad.ID, Local = ad.Local, Name = ad.Name, Temporary = ad.Temporary, Type = ad.Type }; return(true); }
public BackendResponse TryCreateAsset(AssetBase asset) { BackendResponse ret; AssetMetadata metadata = asset.Metadata; string path; string filename = String.Format("{0}.{1}", asset.FullID, Utils.ContentTypeToExtension(metadata.ContentType)); if (asset.Temporary) { path = Path.Combine(TEMP_DATA_DIR, filename); } else { path = Path.Combine(DEFAULT_DATA_DIR, filename); } try { File.WriteAllBytes(path, asset.Data); lock (filenames) filenames[asset.FullID] = path; // Set the creation date to right now metadata.CreationDate = DateTime.Now; lock (metadataStorage) metadataStorage[asset.FullID] = metadata; ret = BackendResponse.Success; } catch (Exception ex) { m_log.ErrorFormat("[SIMPLEASSETSTORAGE]: Failed writing data for asset {0} to {1}: {2}", asset.FullID, filename, ex.Message); ret = BackendResponse.Failure; } server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, asset.FullID, asset.Data.Length, DateTime.Now); return(ret); }
public AssetMetadata GetMetadata(string id) { if (m_Cache != null) { AssetBase fullAsset; if (!m_Cache.Get(id, out fullAsset)) { return(null); } if (fullAsset != null) { return(fullAsset.Metadata); } } string uri = MapServer(id) + "/assets/" + id + "/metadata"; AssetMetadata asset = SynchronousRestObjectRequester.MakeRequest <int, AssetMetadata>("GET", uri, 0, m_Auth); return(asset); }
public AssetMetadata GetMetadata(string id) { if (checkForError()) { return(null); } try { AssetMetadata result = m_assetService.GetMetadata(id); if (result == null) { foreach (AssetServerProxy service in m_extraAssetServers) { if (result == null) { result = service.GetMetadata(id); if (result != null) { m_log.Info("[AssetServerProxy]: Get asset metadata for '" + id + "' from external asset storage at " + service.AssetServiceName); } } } } return(result); } catch { m_errorCount++; m_lastError = Tools.getUnixTime(); m_log.Error("[AssetServerProxy]: Add remote asset server to temporary blacklist: " + m_assetServiceURL); } return(null); }
/// <summary> /// Updates the access time of the asset if it was accessed above a given threshhold amount of time. /// </summary> /// <remarks> /// This gives us some insight into assets which haven't ben accessed for a long period. This is only done /// over the threshold time to avoid excessive database writes as assets are fetched. /// </remarks> /// <param name='asset'></param> /// <param name='accessTime'></param> private void UpdateAccessTime(AssetMetadata assetMetadata, int accessTime) { DateTime now = DateTime.UtcNow; if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates) { return; } lock (m_dbLock) { using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) { dbcon.Open(); NpgsqlCommand cmd = new NpgsqlCommand(@"update XAssetsMeta set access_time=:AccessTime where id=:ID", dbcon); try { UUID asset_id; UUID.TryParse(assetMetadata.ID, out asset_id); using (cmd) { // create unix epoch time cmd.Parameters.Add(m_database.CreateParameter("id", asset_id)); cmd.Parameters.Add(m_database.CreateParameter("access_time", (int)Utils.DateTimeToUnixTime(now))); cmd.ExecuteNonQuery(); } } catch (Exception e) { m_log.ErrorFormat( "[XASSET PGSQL DB]: Failure updating access_time for asset {0} with name {1} : {2}", assetMetadata.ID, assetMetadata.Name, e.Message); } } } }
// TODO: unused // private void Dump(Dictionary<UUID, bool> lst) // { // m_log.Debug("XXX -------- UUID DUMP ------- XXX"); // foreach (KeyValuePair<UUID, bool> kvp in lst) // m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")"); // m_log.Debug("XXX -------- UUID DUMP ------- XXX"); // } #endregion #region Public interface public void Get(UUID assetID, UUID ownerID, string userAssetURL) { // Get the item from the remote asset server onto the local AssetService AssetMetadata meta = FetchMetadata(userAssetURL, assetID); if (meta == null) { return; } // The act of gathering UUIDs downloads some assets from the remote server // but not all... HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); uuidGatherer.AddForInspection(assetID); uuidGatherer.GatherAll(); m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", uuidGatherer.GatheredUuids.Count); bool success = true; foreach (UUID uuid in uuidGatherer.GatheredUuids.Keys) { if (FetchAsset(userAssetURL, uuid) == null) { success = false; } } // maybe all pieces got here... if (!success) { m_log.DebugFormat("[HG ASSET MAPPER]: Problems getting item {0} from asset server {1}", assetID, userAssetURL); } else { m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL); } }
public bool Store(AssetMetadata meta, string hash) { try { string oldhash; AssetMetadata existingAsset = Get(meta.ID, out oldhash); using (MySqlCommand cmd = new MySqlCommand()) { cmd.Parameters.AddWithValue("?id", meta.ID); cmd.Parameters.AddWithValue("?name", meta.Name); cmd.Parameters.AddWithValue("?description", meta.Description); cmd.Parameters.AddWithValue("?type", meta.Type.ToString()); cmd.Parameters.AddWithValue("?hash", hash); cmd.Parameters.AddWithValue("?asset_flags", meta.Flags); if (existingAsset == null) { cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table); ExecuteNonQuery(cmd); return(true); } //cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table); //ExecuteNonQuery(cmd); } return(false); } catch (Exception e) { m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID); m_log.Error(e.ToString()); return(false); } }
/// <summary> /// Resolve a new piece of asset data against stored metadata /// </summary> /// <param name="assetFilename"></param> /// <param name="data"></param> protected void ResolveAssetData(string assetPath, byte[] data) { // Right now we're nastily obtaining the UUID from the filename string filename = assetPath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); if (m_metadata.ContainsKey(filename)) { AssetMetadata metadata = m_metadata[filename]; if (ArchiveConstants.ASSET_TYPE_TO_EXTENSION.ContainsKey(metadata.AssetType)) { string extension = ArchiveConstants.ASSET_TYPE_TO_EXTENSION[metadata.AssetType]; filename = filename.Remove(filename.Length - extension.Length); } m_log.DebugFormat("[ARCHIVER]: Importing asset {0}", filename); AssetBase asset = new AssetBase(new UUID(filename), metadata.Name); asset.Description = metadata.Description; asset.Type = metadata.AssetType; asset.Data = data; try { m_cache.AddAsset(asset, AssetRequestInfo.InternalRequest()); } catch (AssetServerException e) { m_log.ErrorFormat("[ARCHIVER] Uploading asset {0} failed: {1}", filename, e); } } else { m_log.ErrorFormat( "[DEARCHIVER]: Tried to dearchive data with filename {0} without any corresponding metadata", assetPath); } }
public bool UpdateContent(string id, byte[] data) { AssetBase asset = null; if (m_Cache != null) { asset = m_Cache.Get(id); } if (asset == null) { AssetMetadata metadata = GetMetadata(id); if (metadata == null) { return(false); } asset = new AssetBase(); asset.Metadata = metadata; } asset.Data = data; string uri = m_ServerURI + "/assets/" + id; if (SynchronousRestObjectRequester.MakeRequest <AssetBase, bool>("POST", uri, asset)) { if (m_Cache != null) { m_Cache.Cache(asset); } return(true); } return(false); }
/// <summary> /// Add asset metadata xml /// </summary> /// <param name="xml"></param> public void AddAssetMetadata(string xml) { m_metadata = new Dictionary <string, AssetMetadata>(); StringReader sr = new StringReader(xml); XmlTextReader reader = new XmlTextReader(sr); reader.DtdProcessing = DtdProcessing.Prohibit; reader.XmlResolver = null; reader.ReadStartElement("assets"); reader.Read(); while (reader.Name.Equals("asset")) { reader.Read(); AssetMetadata metadata = new AssetMetadata(); string filename = reader.ReadElementString("filename"); m_log.DebugFormat("[DEARCHIVER]: Reading node {0}", filename); metadata.Name = reader.ReadElementString("name"); metadata.Description = reader.ReadElementString("description"); metadata.AssetType = Convert.ToSByte(reader.ReadElementString("asset-type")); m_metadata[filename] = metadata; // Read asset end tag reader.ReadEndElement(); reader.Read(); } m_log.DebugFormat("[DEARCHIVER]: Resolved {0} items of asset metadata", m_metadata.Count); ResolvePendingAssetData(); }
public static bool TryGetEntry(Object editorTarget, out AssetMetadata assetMetadata) { if (NullTargetResults.Contains(editorTarget)) { assetMetadata = null; return(false); } if (CachedEditorTargets.TryGetValue(editorTarget, out assetMetadata) || TryGetAndCacheTargetEntry(editorTarget, out assetMetadata)) { return(true); } if (NullTargetResults.Count == NullTargetResultsCapacity) { NullTargetResults.Remove(_lastNullTargetResult); } NullTargetResults.Add(editorTarget); _lastNullTargetResult = editorTarget; return(false); }
public bool Store(AssetMetadata meta, string hash) { try { bool found = false; string oldhash; AssetMetadata existingAsset = Get(meta.ID, out oldhash); string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table); if (existingAsset == null) { query = String.Format("insert into {0} (\"id\", \"type\", \"hash\", \"asset_flags\", \"create_time\", \"access_time\") values ( :id, :type, :hash, :asset_flags, :create_time, :access_time)", m_Table); found = true; } using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) { dbcon.Open(); int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000); cmd.Parameters.Add(m_database.CreateParameter("id", meta.FullID)); cmd.Parameters.Add(m_database.CreateParameter("type", meta.Type)); cmd.Parameters.Add(m_database.CreateParameter("hash", hash)); cmd.Parameters.Add(m_database.CreateParameter("asset_flags", Convert.ToInt32(meta.Flags))); cmd.Parameters.Add(m_database.CreateParameter("create_time", now)); cmd.Parameters.Add(m_database.CreateParameter("access_time", now)); cmd.ExecuteNonQuery(); } return(found); } catch (Exception e) { m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID); m_log.Error(e.ToString()); return(false); } }
/// <summary> /// Returns a list of AssetMetadata objects. The list is a subset of /// the entire data set offset by <paramref name="start" /> containing /// <paramref name="count" /> elements. /// </summary> /// <param name="start">The number of results to discard from the total data set.</param> /// <param name="count">The number of rows the returned list should contain.</param> /// <returns>A list of AssetMetadata objects.</returns> public override List <AssetMetadata> FetchAssetMetadataSet(int start, int count) { List <AssetMetadata> retList = new List <AssetMetadata>(count); string sql = @"WITH OrderedAssets AS ( SELECT id, name, description, assetType, temporary, creatorid, RowNumber = ROW_NUMBER() OVER (ORDER BY id) FROM assets ) SELECT * FROM OrderedAssets WHERE RowNumber BETWEEN @start AND @stop;"; using (SqlConnection conn = new SqlConnection(m_connectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.Add(m_database.CreateParameter("start", start)); cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1)); conn.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { AssetMetadata metadata = new AssetMetadata(); metadata.FullID = DBGuid.FromDB(reader["id"]); metadata.Name = (string)reader["name"]; metadata.Description = (string)reader["description"]; metadata.Type = Convert.ToSByte(reader["assetType"]); metadata.Temporary = Convert.ToBoolean(reader["temporary"]); metadata.CreatorID = (string)reader["creatorid"]; retList.Add(metadata); } } } return(retList); }
public static bool TryGetMapped(string path, out AssetMetadata metadata, bool includeDirs = false) { if (includeDirs) { if (MapDirs.TryGetValue(path, out metadata)) { return(true); } if (MapDirs.TryGetValue(path.ToLowerInvariant(), out metadata)) { return(true); } } if (Map.TryGetValue(path, out metadata)) { return(true); } if (Map.TryGetValue(path.ToLowerInvariant(), out metadata)) { return(true); } return(false); }
/// <summary> /// Returns a list of AssetMetadata objects. The list is a subset of /// the entire data set offset by <paramref name="start" /> containing /// <paramref name="count" /> elements. /// </summary> /// <param name="start">The number of results to discard from the total data set.</param> /// <param name="count">The number of rows the returned list should contain.</param> /// <returns>A list of AssetMetadata objects.</returns> public override List <AssetMetadata> FetchAssetMetadataSet(int start, int count) { List <AssetMetadata> retList = new List <AssetMetadata>(count); lock (this) { using (SqliteCommand cmd = new SqliteCommand(SelectAssetMetadataSQL, m_conn)) { cmd.Parameters.Add(new SqliteParameter(":start", start)); cmd.Parameters.Add(new SqliteParameter(":count", count)); using (IDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { AssetMetadata metadata = buildAssetMetadata(reader); retList.Add(metadata); } } } } return(retList); }
private AssetBase LoadAssetBase(OSDMap map) { AssetBase asset = new AssetBase(); asset.Data = map["AssetData"].AsBinary(); AssetMetadata md = new AssetMetadata(); md.ContentType = map["ContentType"].AsString(); md.CreationDate = map["CreationDate"].AsDate(); md.CreatorID = map["CreatorID"].AsString(); md.Description = map["Description"].AsString(); md.ID = map["ID"].AsString(); md.Name = map["Name"].AsString(); md.Type = (sbyte)map["Type"].AsInteger(); asset.Metadata = md; asset.ID = md.ID; asset.FullID = UUID.Parse(md.ID); asset.Name = md.Name; asset.Type = md.Type; return(asset); }
public void TestAddAsset() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector"); config.AddConfig("AssetService"); config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService"); config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); LocalAssetServicesConnector lasc = new LocalAssetServicesConnector(); lasc.Initialise(config); AssetBase a1 = AssetHelpers.CreateNotecardAsset(); lasc.Store(a1); AssetBase retreivedA1 = lasc.Get(a1.ID); Assert.That(retreivedA1.ID, Is.EqualTo(a1.ID)); Assert.That(retreivedA1.Metadata.ID, Is.EqualTo(a1.Metadata.ID)); Assert.That(retreivedA1.Data.Length, Is.EqualTo(a1.Data.Length)); AssetMetadata retrievedA1Metadata = lasc.GetMetadata(a1.ID); Assert.That(retrievedA1Metadata.ID, Is.EqualTo(a1.ID)); byte[] retrievedA1Data = lasc.GetData(a1.ID); Assert.That(retrievedA1Data.Length, Is.EqualTo(a1.Data.Length)); // TODO: Add cache and check that this does receive a copy of the asset }
/// <summary> /// Updates the access time of the asset if it was accessed above a given threshhold amount of time. /// </summary> /// <remarks> /// This gives us some insight into assets which haven't ben accessed for a long period. This is only done /// over the threshold time to avoid excessive database writes as assets are fetched. /// </remarks> /// <param name='asset'></param> /// <param name='accessTime'></param> private void UpdateAccessTime(AssetMetadata assetMetadata, int accessTime) { DateTime now = DateTime.UtcNow; if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates) { return; } lock (m_dbLock) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); MySqlCommand cmd = new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon); try { using (cmd) { // create unix epoch time cmd.Parameters.AddWithValue("?ID", assetMetadata.ID); cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now)); cmd.ExecuteNonQuery(); } } catch (Exception e) { m_log.ErrorFormat( "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", assetMetadata.ID, assetMetadata.Name); } } } }
/// <summary> /// Track a new asset reference. Will be called during asset creation, after the asset content is downloaded /// or retrieved from cache. /// </summary> /// <param name="id"></param> /// <param name="containerId"></param> /// <param name="asset"></param> /// <param name="colliderGeo"></param> /// <param name="source"></param> public void Set(Guid id, Guid containerId, Object asset, ColliderGeometry colliderGeo = null, AssetSource source = null) { if (!Assets.ContainsKey(id)) { Assets[id] = new AssetMetadata(id, containerId, asset, colliderGeo, source); } if (Callbacks.TryGetValue(id, out List <AssetCallback> callbacks)) { Callbacks.Remove(id); foreach (var cb in callbacks) { try { cb?.Invoke(Assets[id]); } catch (Exception e) { Debug.LogException(e); } } } }
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] result = new byte[0]; string[] p = SplitParams(path); if (p.Length == 0) { return(result); } if (p.Length > 1 && p[1] == "data") { result = m_AssetService.GetData(p[0]); if (result == null) { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; httpResponse.ContentType = "text/plain"; result = new byte[0]; } else { httpResponse.StatusCode = (int)HttpStatusCode.OK; httpResponse.ContentType = "application/octet-stream"; } } else if (p.Length > 1 && p[1] == "metadata") { AssetMetadata metadata = m_AssetService.GetMetadata(p[0]); if (metadata != null) { XmlSerializer xs = new XmlSerializer(typeof(AssetMetadata)); result = ServerUtils.SerializeResult(xs, metadata); httpResponse.StatusCode = (int)HttpStatusCode.OK; httpResponse.ContentType = SLUtil.SLAssetTypeToContentType(metadata.Type); } else { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; httpResponse.ContentType = "text/plain"; result = new byte[0]; } } else { AssetBase asset = m_AssetService.Get(p[0]); if (asset != null) { XmlSerializer xs = new XmlSerializer(typeof(AssetBase)); result = ServerUtils.SerializeResult(xs, asset); httpResponse.StatusCode = (int)HttpStatusCode.OK; httpResponse.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type); } else { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; httpResponse.ContentType = "text/plain"; result = new byte[0]; } } return(result); }
// This is needed for .NET serialization!!! // Do NOT "Optimize" away! public AssetBase() { m_metadata = new AssetMetadata { FullID = UUID.Zero, ID = UUID.Zero.ToString(), Type = (sbyte) AssetType.Unknown, CreatorID = String.Empty }; }
/// <summary> /// Получить ассет аудио данных OpenTK /// </summary> /// <param name="parResourceManager">Менеджер ресурсов</param> /// <param name="parAssetMetadata">Метаданные получаемого ассета</param> /// <returns></returns> private AssetDataOpenTkWaveSound GetWaveSoundAssetData(ResourceManager parResourceManager, AssetMetadata parAssetMetadata) { return(parResourceManager.GetAssetData <AssetDataOpenTkWaveSound>(parAssetMetadata)); }
public void SendNotifications(AssetMetadata metadata) => _messageTypeMapping[metadata.Type]?.Invoke((metadata.StorageMetadata));
/// <summary> /// Recursively copy shared assets from cache into manager so the app can modify them. /// </summary> /// <param name="metadata"></param> private void MakeWriteSafe(AssetMetadata metadata, AssetMetadata?dependency = null, AssetMetadata?updatedDependency = null) { if (metadata.Source == null) { return; } // copy asset var originalAsset = metadata.Asset; Object copyAsset; if (originalAsset is UnityEngine.Texture2D tex2d) { // can't Instantiate GPU-only textures var copyTex = new Texture2D(tex2d.width, tex2d.height, tex2d.format, tex2d.mipmapCount > 1); Graphics.CopyTexture(tex2d, copyTex); copyAsset = copyTex; } else { copyAsset = Object.Instantiate(originalAsset); } var copyMetadata = new AssetMetadata( id: metadata.Id, containerId: metadata.ContainerId, asset: copyAsset, collider: metadata.ColliderGeometry, source: null, sourceAsset: originalAsset); Assets[metadata.Id] = copyMetadata; IEnumerable <AssetMetadata> dependents; if (originalAsset is UnityEngine.Texture tex) { dependents = MakeTextureWriteSafe(tex); } else if (originalAsset is UnityEngine.Material mat) { dependents = MakeMaterialWriteSafe( metadata.Id, mat, (UnityEngine.Material)copyAsset, dependency, updatedDependency); } else if (copyAsset is GameObject prefab) { dependents = MakePrefabWriteSafe(prefab, dependency, updatedDependency); } else { dependents = new AssetMetadata[0]; } // update dependents foreach (var dependent in dependents) { MakeWriteSafe(dependent, metadata, copyMetadata); } // return original assets to cache MREAPI.AppsAPI.AssetCache.StoreAssets( metadata.Source.ParsedUri, new Object[] { originalAsset }, metadata.Source.Version); }
public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store) { int imported = 0; using (MySqlConnection importConn = new MySqlConnection(conn)) { try { importConn.Open(); } catch (MySqlException e) { m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", e.Message.ToString()); return; } using (MySqlCommand cmd = importConn.CreateCommand()) { string limit = String.Empty; if (count != -1) { limit = String.Format(" limit {0},{1}", start, count); } cmd.CommandText = String.Format("select * from {0}{1}", table, limit); MainConsole.Instance.Output("Querying database"); using (IDataReader reader = cmd.ExecuteReader()) { MainConsole.Instance.Output("Reading data"); while (reader.Read()) { if ((imported % 100) == 0) { MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); } AssetBase asset = new AssetBase(); AssetMetadata meta = new AssetMetadata(); meta.ID = reader["id"].ToString(); meta.FullID = new UUID(meta.ID); meta.Name = reader["name"].ToString(); meta.Description = reader["description"].ToString(); meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); asset.Metadata = meta; asset.Data = (byte[])reader["data"]; store(asset, force); imported++; } } } importConn.Close(); } MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); }
public AssetBase(string assetID, string name, sbyte assetType, string creatorID) { if (assetType == (sbyte) AssetType.Unknown) { StackTrace trace = new StackTrace(true); MainConsole.Instance.ErrorFormat("[ASSETBASE]: Creating asset '{0}' ({1}) with an unknown asset type\n{2}", name, assetID, trace); } m_metadata = new AssetMetadata {ID = assetID, Name = name, Type = assetType, CreatorID = creatorID}; }
/// <summary> /// Add asset metadata xml /// </summary> /// <param name="xml"></param> public void AddAssetMetadata(string xml) { m_metadata = new Dictionary<string, AssetMetadata>(); StringReader sr = new StringReader(xml); XmlTextReader reader = new XmlTextReader(sr); reader.ReadStartElement("assets"); reader.Read(); while (reader.Name.Equals("asset")) { reader.Read(); AssetMetadata metadata = new AssetMetadata(); string filename = reader.ReadElementString("filename"); MainConsole.Instance.DebugFormat("[DEARCHIVER]: Reading node {0}", filename); metadata.Name = reader.ReadElementString("name"); metadata.Description = reader.ReadElementString("description"); metadata.AssetType = Convert.ToSByte(reader.ReadElementString("asset-type")); m_metadata[filename] = metadata; // Read asset end tag reader.ReadEndElement(); reader.Read(); } MainConsole.Instance.DebugFormat("[DEARCHIVER]: Resolved {0} items of asset metadata", m_metadata.Count); ResolvePendingAssetData(); }
public void T010_StoreReadVerifyAssets() { TestHelpers.InMethod(); AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString()); AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString()); AssetBase a3 = new AssetBase(uuid3, "asset three", (sbyte)AssetType.Texture, critter3.ToString()); a1.Data = data1; a2.Data = data1; a3.Data = data1; scrambler.Scramble(a1); scrambler.Scramble(a2); scrambler.Scramble(a3); m_db.StoreAsset(a1); m_db.StoreAsset(a2); m_db.StoreAsset(a3); a1.UploadAttempts = 0; a2.UploadAttempts = 0; a3.UploadAttempts = 0; AssetBase a1a = m_db.GetAsset(uuid1); a1a.UploadAttempts = 0; Assert.That(a1a, Constraints.PropertyCompareConstraint(a1)); AssetBase a2a = m_db.GetAsset(uuid2); a2a.UploadAttempts = 0; Assert.That(a2a, Constraints.PropertyCompareConstraint(a2)); AssetBase a3a = m_db.GetAsset(uuid3); a3a.UploadAttempts = 0; Assert.That(a3a, Constraints.PropertyCompareConstraint(a3)); scrambler.Scramble(a1a); scrambler.Scramble(a2a); scrambler.Scramble(a3a); m_db.StoreAsset(a1a); m_db.StoreAsset(a2a); m_db.StoreAsset(a3a); a1a.UploadAttempts = 0; a2a.UploadAttempts = 0; a3a.UploadAttempts = 0; AssetBase a1b = m_db.GetAsset(uuid1); a1b.UploadAttempts = 0; Assert.That(a1b, Constraints.PropertyCompareConstraint(a1a)); AssetBase a2b = m_db.GetAsset(uuid2); a2b.UploadAttempts = 0; Assert.That(a2b, Constraints.PropertyCompareConstraint(a2a)); AssetBase a3b = m_db.GetAsset(uuid3); a3b.UploadAttempts = 0; Assert.That(a3b, Constraints.PropertyCompareConstraint(a3a)); bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 }); Assert.IsTrue(exist[0]); Assert.IsTrue(exist[1]); Assert.IsTrue(exist[2]); List <AssetMetadata> metadatas = m_db.FetchAssetMetadataSet(0, 1000); Assert.That(metadatas.Count >= 3, "FetchAssetMetadataSet() should have returned at least 3 assets!"); // It is possible that the Asset table is filled with data, in which case we don't try to find "our" // assets there: if (metadatas.Count < 1000) { AssetMetadata metadata = metadatas.Find(x => x.FullID == uuid1); Assert.That(metadata.Name, Is.EqualTo(a1b.Name)); Assert.That(metadata.Description, Is.EqualTo(a1b.Description)); Assert.That(metadata.Type, Is.EqualTo(a1b.Type)); Assert.That(metadata.Temporary, Is.EqualTo(a1b.Temporary)); Assert.That(metadata.FullID, Is.EqualTo(a1b.FullID)); } }
public static void Ingest(this Atlas self, AssetMetadata asset) { // Crawl through all child assets. if (asset.AssetType == typeof(AssetTypeDirectory)) { foreach (AssetMetadata child in asset.Children) { self.Ingest(child); } return; } // Forcibly add the mod content to the atlas. if (asset.AssetType == typeof(Texture2D)) { string parentPath = self.GetDataPath(); if (parentPath.StartsWith(Everest.Content.PathContentOrig)) { parentPath = parentPath.Substring(Everest.Content.PathContentOrig.Length + 1); } parentPath = parentPath.Replace('\\', '/'); string path = asset.PathRelative; if (!path.StartsWith(parentPath)) { return; } path = path.Substring(parentPath.Length + 1); VirtualTexture replacementV = VirtualContentExt.CreateTexture(asset); MTexture replacement; MTextureMeta meta = asset.GetMeta <MTextureMeta>(); Dictionary <string, MTexture> textures = self.GetTextures(); MTexture existing; if (textures.TryGetValue(path, out existing)) { // We're the currently active overlay. if (existing.Texture.GetMetadata() == asset) { return; } if (meta != null) { // Apply width and height from existing meta. existing.AddOverlay(replacementV, new Vector2(meta.X, meta.Y), meta.Width, meta.Height); } else { // Keep width and height from existing instance. existing.AddOverlay(replacementV, existing.DrawOffset, existing.Width, existing.Height); } replacement = existing; } else { if (meta != null) { // Apply width and height from existing meta. replacement = new MTexture(replacementV, new Vector2(meta.X, meta.Y), meta.Width, meta.Height); } else { // Apply width and height from replacement texture. replacement = new MTexture(replacementV); } // TODO: What's with the AtlasPath? Seems to stem from an atlas metadata property... } self[path] = replacement; return; } }
/// <summary> /// Стандартный конструктор /// </summary> /// <param name="parLinkedAssetMetadata">Связанные метаданные ассета</param> public AppSoundAsset(AssetMetadata parLinkedAssetMetadata) { LinkedAssetMetadata = parLinkedAssetMetadata; }
public async Task <IAsset> StoreAsset(IDownloadedAsset downloadedAsset) { switch (downloadedAsset.ApiAsset.Type) { case AssetType.Blueprint: case AssetType.Savegame: case AssetType.Scenario: { // Create the directory where the asset should be stored and create a path to where the asset should be stored. var storagePath = _parkitect.Paths.GetAssetPath(downloadedAsset.ApiAsset.Type); var assetPath = Path.Combine(storagePath, downloadedAsset.FileName); Directory.CreateDirectory(storagePath); _log.WriteLine($"Storing asset to {assetPath}."); // If the file already exists, add a number behind the file name. if (File.Exists(assetPath)) { _log.WriteLine("Asset already exists, comparing hashes."); // Compute hash of downloaded asset to match with installed hash. var validHash = downloadedAsset.Stream.CreateMD5Checksum(); if (validHash.SequenceEqual(File.OpenRead(assetPath).CreateMD5Checksum())) { _log.WriteLine("Asset hashes match, aborting."); return(null); } _log.WriteLine("Asset hashes mismatch, computing new file name."); // Separate the filename and the extension. var attempt = 1; var fileName = Path.GetFileNameWithoutExtension(downloadedAsset.FileName); var fileExtension = Path.GetExtension(downloadedAsset.FileName); // Update the path to where the the asset should be stored by adding a number behind the name until an available filename has been found. do { assetPath = Path.Combine(storagePath, $"{fileName} ({++attempt}){fileExtension}"); if (File.Exists(assetPath) && validHash.SequenceEqual(File.OpenRead(assetPath).CreateMD5Checksum())) { return(null); } } while (File.Exists(assetPath)); _log.WriteLine($"Newly computed path is {assetPath}."); } _log.WriteLine("Writing asset to file."); // Write the stream to a file at the asset path. using (var fileStream = File.Create(assetPath)) { downloadedAsset.Stream.Seek(0, SeekOrigin.Begin); await downloadedAsset.Stream.CopyToAsync(fileStream); } var meta = new AssetMetadata { Id = downloadedAsset.ApiAsset.Id // InstalledVersion = downloadedAsset.ApiAsset.UpdatedAt }; // TODO: Re-add installed version _assetMetadataStorage.StoreMetadata(downloadedAsset.ApiAsset.Type, assetPath, meta); var cachedData = await _assetCachedDataStorage.GetData(downloadedAsset.ApiAsset.Type, meta, assetPath); Asset createdAsset = null; switch (downloadedAsset.ApiAsset.Type) { case AssetType.Blueprint: createdAsset = new BlueprintAsset(assetPath, meta, cachedData); break; case AssetType.Savegame: createdAsset = new SavegameAsset(assetPath, meta, cachedData as AssetWithImageCachedData); break; case AssetType.Scenario: createdAsset = new ScenarioAsset(assetPath, meta, cachedData as AssetWithImageCachedData); break; } OnAssetAdded(new AssetEventArgs(createdAsset)); return(createdAsset); } case AssetType.Mod: { _log.WriteLine("Attempting to open mod stream."); using (var zip = new ZipArchive(downloadedAsset.Stream, ZipArchiveMode.Read)) { // Compute name of main directory inside archive. var mainFolder = zip.Entries.FirstOrDefault()?.FullName; if (mainFolder == null) { throw new Exception("invalid archive"); } _log.WriteLine($"Mod archive main folder is {mainFolder}."); // Find the mod.json file. Yay for / \ path divider compatibility. var modJsonPath = Path.Combine(mainFolder, "mod.json").Replace('/', '\\'); var modJson = zip.Entries.FirstOrDefault(e => e.FullName.Replace('/', '\\') == modJsonPath); // Read mod.json. if (modJson == null) { throw new Exception("mod is missing mod.json file"); } using (var streamReader = new StreamReader(modJson.Open())) { var modInformationString = await streamReader.ReadToEndAsync(); var modInformation = JsonConvert.DeserializeObject <ModInformation>(modInformationString); var meta = new ModMetadata { Id = downloadedAsset.ApiAsset.Id, // InstalledVersion = downloadedAsset.ApiAsset.UpdatedAt, Tag = downloadedAsset.Info.Tag, Repository = downloadedAsset.Info.Repository }; // TODO: Re-add installed version var installationPath = Path.Combine(_parkitect.Paths.GetAssetPath(AssetType.Mod), downloadedAsset.Info.Repository.Replace('/', '@')); // TODO: Should actually try and look if the mod has been updated since and delete the whole folder. if (Directory.Exists(installationPath)) { if (File.Exists(Path.Combine(installationPath, "modinfo.meta"))) { File.Delete(Path.Combine(installationPath, "modinfo.meta")); } if (File.Exists(Path.Combine(installationPath, "moddata.cache"))) { File.Delete(Path.Combine(installationPath, "moddata.cache")); } } _log.WriteLine($"mod.json was deserialized to mod object '{modInformation}'."); // Set default mod properties. modInformation.IsEnabled = true; modInformation.IsDevelopment = false; // Find previous version of mod. // TODO uninstall previous versions // Install mod. _log.WriteLine("Copying mod to mods folder."); foreach (var entry in zip.Entries) { if (!entry.FullName.StartsWith(mainFolder)) { continue; } // Compute path. var partDir = entry.FullName.Substring(mainFolder.Length); var path = Path.Combine(installationPath, partDir); var ignoredFiles = new[] { "moddata.cache", "modinfo.meta", "mod.log" }; if (ignoredFiles.Contains(partDir)) { continue; } if (string.IsNullOrEmpty(entry.Name)) { _log.WriteLine($"Creating directory '{path}'."); Directory.CreateDirectory(path); } else { _log.WriteLine($"Storing mod file '{path}'."); using (var openStream = entry.Open()) using (var fileStream = File.OpenWrite(path)) await openStream.CopyToAsync(fileStream); } } _log.WriteLine("Register installation to API."); _website.API.RegisterDownload(downloadedAsset.ApiAsset.Id); _assetMetadataStorage.StoreMetadata(downloadedAsset.ApiAsset.Type, installationPath, meta); var cachedData = await _assetCachedDataStorage.GetData(downloadedAsset.ApiAsset.Type, meta, installationPath); modInformationString = JsonConvert.SerializeObject(modInformation); File.WriteAllText(Path.Combine(installationPath, "mod.json"), modInformationString); var createdAsset = new ModAsset(installationPath, meta, cachedData as AssetWithImageCachedData, modInformation); OnAssetAdded(new AssetEventArgs(createdAsset)); return(createdAsset); } } } default: throw new Exception("unknown asset type"); } }
/// <summary> /// Конструктор ресурса /// </summary> /// <param name="parAssetMetadata">Метаданные ассета</param> /// <param name="parBinaryData">Бинарные данные</param> public AssetDataBinary(AssetMetadata parAssetMetadata, byte[] parBinaryData) : base(parAssetMetadata) { BinaryData = parBinaryData; }
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] result = new byte[0]; string[] p = SplitParams(path); if (p.Length == 0) { return(result); } string id = string.Empty; if (p.Length > 1) { id = p[0]; string cmd = p[1]; if (cmd == "data") { result = m_AssetService.GetData(id); if (result == null) { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; httpResponse.ContentType = "text/plain"; result = new byte[0]; } else { httpResponse.StatusCode = (int)HttpStatusCode.OK; httpResponse.ContentType = "application/octet-stream"; } } else if (cmd == "metadata") { AssetMetadata metadata = m_AssetService.GetMetadata(id); if (metadata != null) { XmlSerializer xs = new XmlSerializer(typeof(AssetMetadata)); result = ServerUtils.SerializeResult(xs, metadata); httpResponse.StatusCode = (int)HttpStatusCode.OK; httpResponse.ContentType = SLUtil.SLAssetTypeToContentType(metadata.Type); } else { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; httpResponse.ContentType = "text/plain"; result = new byte[0]; } } else { // Unknown request httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; httpResponse.ContentType = "text/plain"; result = new byte[0]; } } else if (p.Length == 1) { // Get the entire asset (metadata + data) id = p[0]; AssetBase asset = m_AssetService.Get(id); if (asset != null) { XmlSerializer xs = new XmlSerializer(typeof(AssetBase)); result = ServerUtils.SerializeResult(xs, asset); httpResponse.StatusCode = (int)HttpStatusCode.OK; httpResponse.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type); } else { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; httpResponse.ContentType = "text/plain"; result = new byte[0]; } } else { // Unknown request httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; httpResponse.ContentType = "text/plain"; result = new byte[0]; } if (httpResponse.StatusCode == (int)HttpStatusCode.NotFound && !string.IsNullOrEmpty(m_RedirectURL) && !string.IsNullOrEmpty(id)) { httpResponse.StatusCode = (int)HttpStatusCode.Redirect; string rurl = m_RedirectURL; if (!path.StartsWith("/")) { rurl += "/"; } rurl += path; httpResponse.AddHeader("Location", rurl); m_log.DebugFormat("[ASSET GET HANDLER]: Asset not found, redirecting to {0} ({1})", rurl, httpResponse.StatusCode); } return(result); }