public void Add(AssetFile assetFile) { assets.Add(assetFile); }
private AssetEntry getEntryForFileName(string filename, RequestCategory requestCategory = RequestCategory.NONE) { //logger.Debug("get entry for filename:" + filename + " with request category " + requestCategory); List <ManifestEntry> entries = Manifest.getEntriesForFilenameHash(Util.hashFileName(filename)); if (entries.Count() == 0) { // lets see if the filename is actually a hash (this shouldn't happen, but whatevers) entries = Manifest.getEntriesForFilenameHash(filename); if (entries.Count() == 0) { throw new Exception("Filename hash not found in manifest: '" + filename + "'"); } logger.Warn("Using filename[" + filename + "] as hash"); } // strip out duplicate patch paks entries.RemoveAll(e => { return(Manifest.getPAKName(e.pakIndex).Contains("patch") && entries.Any(x => x != e && x.idStr.Equals(e.idStr))); }); // logger.Debug("found " + entries.Count() + " entries in manifest that match"); string id = ""; if (entries.Count() == 1) { // if there was only one result, then use it id = entries.First().idStr; } else { ManifestEntry finalEntry = null; // work out which one we want based on the category string requestStr = requestCategory.ToString().ToLower(); //logger.Debug("multiple ids found for " + filename + ", using request category " + requestStr); foreach (ManifestEntry entry in entries) { //logger.Debug("[" + filename + "]: considering entry:" + entry + " :" + manifest.getPAKName(entry.pakIndex)); ManifestPAKFileEntry pak = Manifest.getPAK(entry.pakIndex); string pakName = pak.name; if (pakName.Contains(requestStr)) { finalEntry = entry; break; } } if (finalEntry == null) { // if we were still unable to break the tie logger.Error("tiebreak for " + filename + " no id match"); // one final check on the language, if an english one exists, use that over any other non-english one IEnumerable <ManifestEntry> engUni = entries.Where(e => e.lang == 0 || e.lang == 1); // if the number of english entries is different to the number of entries, then we should choose an english one and assume it is that one if (engUni.Count() > 0 && engUni.Count() != entries.Count()) { logger.Debug("tie broken with english language choice: " + finalEntry + " :" + Manifest.getPAKName(finalEntry.pakIndex)); finalEntry = engUni.First(); } else { // fail? String str = ""; foreach (ManifestEntry entry in entries) { str += "\t" + entry + " :" + Manifest.getPAKName(entry.pakIndex) + "\n"; } string errStr = ("Multiple ids match the filename [" + filename + "] but no request category was given, unable to determine which to return.\n" + str); throw new Exception(errStr); } } id = finalEntry.idStr; //logger.Debug("settled on entry:" + finalEntry + " :" + manifest.getPAKName(finalEntry.pakIndex)); } //logger.Debug("find asset file for id:" + id); AssetFile assetFile = FindAssetFileForId(id); //logger.Debug("result:" + assetFile); if (assetFile == null) { throw new Exception( "Filename found in manifest but unable to locate ID[" + id + "] in assets: '" + filename + "'"); } //logger.Debug("found with id:" + id); return(assetFile.getEntry(id)); }
public AssetEntry(byte[] id, int offset, int size, int sizeD, bool compressed, byte[] hash, AssetFile file) { Id = id; StringId = Util.bytesToHexString(id); SizeD = sizeD; Offset = offset; Size = size; Compressed = compressed; Hash = hash; File = file; }
private static AssetFile buildAssetFileDatabase(string file, Manifest manifest) { AssetFile assetFile = new AssetFile(file); using (BinaryReader dis = new BinaryReader(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))) { byte[] magic = dis.ReadBytes(4); string magicStr = System.Text.Encoding.Default.GetString(magic); if (!magicStr.Equals("TWAD")) { throw new Exception("Invalid AssetFile:" + file + ": Invalid magic signature: " + magicStr); } int version = dis.ReadInt32(); int headersize = dis.ReadInt32(); int maxfiles = dis.ReadInt32(); int files = dis.ReadInt32(); //System.out.println( // "Version:" + version + " headerSize:" + headersize + ", maxFiles:" + maxfiles + ", files:" + files); // System.out.println("\t assets " + files + ", max:" + maxfiles); // FIXME: For some reason, using the "files" variable doesnt read the proper amount of actual files, deleted? renamed? moved? int actualFiles = 0; for (int i = 0; i < maxfiles; i++) { byte[] entry = dis.ReadBytes(44); using (BinaryReader bis = new BinaryReader(new MemoryStream(entry))) { byte[] id = bis.ReadBytes(8); int offset = bis.ReadInt32(); int size1 = bis.ReadInt32(); int size2 = bis.ReadInt32(); // not sure what size2 is, it is always the same as size1? int filenum = bis.ReadInt16(); int flag = bis.ReadInt16(); //compressed? byte[] hash = bis.ReadBytes(20); int sizeD = manifest.getFileSize(Util.bytesToHexString(id)); if (offset == 0) { // entry was deleted? Corrupt? No longer exists? //System.err.println( // "found zero offset entry for data entry " + i + ", entry:" // + Util.bytesToHexString(entry) + " @" + streamOffset); } else { if (sizeD < 0) { logger.Warn("ID[" + Util.bytesToHexString(id) + "] does not have an entry in the manifest: assetFile:" + file + "@" + offset + ", size:" + size1); sizeD = size2; } assetFile.AddAsset(new AssetEntry(id, offset, size1, sizeD, flag != 0, hash, assetFile)); actualFiles++; } } } } return(assetFile); }
private AssetFile findAssetFileForID(string id) { if (assetFiles == null) { lock (locko) { if (assetFiles == null) { assetFiles = new Dictionary <string, List <AssetFile> >(); foreach (AssetFile file in assets) { foreach (AssetEntry ae in file.getEntries()) { List <AssetFile> list; if (!assetFiles.TryGetValue(ae.strID, out list)) { list = new List <AssetFile>(); assetFiles.Add(ae.strID, list); } list.Add(file); } } } } } if (id == null) { return(null); } List <AssetFile> holders; if (!assetFiles.TryGetValue(id, out holders)) { return(null); } //new List<AssetFile>(); //foreach (AssetFile file in assets) // if (file.contains(id)) // holders.Add(file); if (holders.Count == 0) { return(null); } if (holders.Count > 1) { try { // we have a 32 and 64 bit one pick the right one AssetFile f_32 = (from f in holders where !f.is64 select f).First(); AssetFile f_64 = (from f in holders where f.is64 select f).First(); if (is64) { return(f_64); } return(f_32); } catch (Exception ex) { //Debug.LogWarning(ex); //string holdersStr = String.Join(",", holders.Select(x => x.file).ToArray()); //Debug.LogWarning("More than one asset file [" + holdersStr + "] contains id [" + id + "]"); } } return(holders[0]); }