Ejemplo n.º 1
0
 public void Add(AssetFile assetFile)
 {
     assets.Add(assetFile);
 }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
 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;
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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]);
        }