Beispiel #1
0
        static private void putFilenameCacheEntry(ManifestEntry e, int i, Dictionary <string, List <int> > filenameEntryIndexDict)
        {
            List <int> indices;

            filenameEntryIndexDict.TryGetValue(e.filenameHashStr, out indices);
            if (indices == null)
            {
                indices = new List <int>();
                filenameEntryIndexDict[e.filenameHashStr] = indices;
            }

            indices.Add(i);
        }
Beispiel #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));
        }
Beispiel #3
0
        private void processTable(byte[] manifestData)
        {
            //logger.Debug("process manifest table");
            int tableOffset;
            int count;
            ManifestTableEntry a, b, c;
            int _256tableoffset;
            int _256;

            // See http://forum.xentax.com/viewtopic.php?f=17&t=10119
            using (MemoryStream memStream = new MemoryStream(manifestData))
            {
                using (BinaryReader dis = new BinaryReader(memStream))
                {
                    // read the manifest header


                    byte[] twam = dis.ReadBytes(4);
                    // These two are definitely version numbers
                    ushort majorV = dis.ReadUInt16();
                    ushort minorV = dis.ReadUInt16();

                    _256tableoffset = dis.readInt();
                    _256            = dis.readInt();

                    a = new ManifestTableEntry("pak table", dis);
                    b = new ManifestTableEntry("asset names", dis);
                    c = new ManifestTableEntry("unk", dis);
                }
            }
            tableOffset = b.offset;
            count       = b.count;

            // logger.Debug("read table 0");
            // why is there a 256 table at the start?
            /** TABLE 0 - 256 byte table */
            byte[] table = new byte[256];
            for (int i = 0; i < _256; i++)
            {
                using (BinaryReader dis2 = new BinaryReader(new MemoryStream(manifestData, _256tableoffset + i, 1)))
                {
                    table[i] = dis2.readByte();
                }
            }

            /** TABLE 1 - PAK files */
            // logger.Debug("read table 1");

            for (int i = 0; i < a.count; i++)
            {
                using (BinaryReader dis2 = new BinaryReader(
                           new MemoryStream(manifestData, a.offset + (i * a.stride), a.stride)))
                {
                    pakFiles.Add(new ManifestPAKFileEntry(manifestData, dis2));
                }
            }

            // logger.Debug("read table 3");

            /** TABLE 3 - unknown? */
            using (BinaryReader dis2 = new BinaryReader(
                       new MemoryStream(manifestData, c.offset, c.tableSize)))
            {
                for (int i = 0; i < c.count; i++)
                {
                    int ia     = dis2.readInt() & 0xFFFFFF;
                    int ecount = dis2.readInt();
                    int offset = dis2.readInt();
                    using (BinaryReader dis3 = new BinaryReader(
                               new MemoryStream(manifestData, offset, ecount * 4)))
                    {
                        for (int j = 0; j < ecount; j++)
                        {
                        }
                    }
                }
            }

            // logger.Debug("read table 2");

            /** TABLE 2 - Manifest entries */
            int entrySize = b.stride;

            for (int i = 0; i < count; i++)
            {
                int start = tableOffset + (i * entrySize);

                using (BinaryReader dis = new BinaryReader(
                           new MemoryStream(manifestData, start, entrySize)))
                {
                    ManifestEntry entry = new ManifestEntry(dis);
                    manifestEntries.Add(entry);
                }
            }
            // logger.Debug("build cache");
            Dictionary <string, List <int> > filenameEntryIndexDictT = new Dictionary <string, List <int> >();
            Dictionary <string, List <int> > idEntryIndexDictT       = new Dictionary <string, List <int> >();

            for (int i = 0; i < manifestEntries.Count; i++)
            {
                ManifestEntry e = manifestEntries[i];
                putFilenameCacheEntry(e, i, filenameEntryIndexDictT);
                putIDCacheEntry(e, i, idEntryIndexDictT);
            }
            foreach (string x in filenameEntryIndexDictT.Keys)
            {
                this.filenameEntryIndexDict.Add(x, filenameEntryIndexDictT[x].ToArray());
            }
            foreach (string x in idEntryIndexDictT.Keys)
            {
                this.idEntryIndexDict.Add(x, idEntryIndexDictT[x].ToArray());
            }
        }