Esempio n. 1
0
        /// <summary>
        ///		Finds the EngineDatabase that matches a cache file from a stream, if available.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="engineDb">The engine database to use to process the cache file.</param>
        /// <returns>The EngineDescription used to describe the cache file, otherwise null.</returns>
        public static EngineDescription FindEngineDescription(IReader reader, EngineDatabase engineDb)
        {
            // Set the reader's endianness based upon the file's header magic
            reader.SeekTo(0);
            byte[] headerMagic = reader.ReadBlock(4);
            reader.Endianness = DetermineCacheFileEndianness(headerMagic);

            reader.SeekTo(0x4);
            int fileVersion = reader.ReadInt32();

            var matches = engineDb.FindEnginesByVersion(fileVersion, reader.Endianness);

            Dictionary <int, string> offsetCache = new Dictionary <int, string>();

            foreach (EngineDescription engine in matches)
            {
                if (offsetCache.ContainsKey(engine.BuildStringOffset))
                {
                    if (offsetCache[engine.BuildStringOffset] == engine.BuildVersion)
                    {
                        return(engine);
                    }
                    else
                    {
                        continue;
                    }
                }

                reader.SeekTo(engine.BuildStringOffset);
                string buildString = reader.ReadAscii();

                if (buildString == engine.BuildVersion)
                {
                    return(engine);
                }

                offsetCache[engine.BuildStringOffset] = buildString;
            }

            return(null);
        }
Esempio n. 2
0
        /// <summary>
        ///		Finds any EngineDatabase that matches a cache file from a stream, if available.
        ///		List return is intended to be passed to the user to make the final choice in case of > 1 matches.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="engineDb">The engine database to use to process the cache file.</param>
        /// <returns>List containing matching EngineDescriptions that could possibly describe the cache file, if any.</returns>
        public static List <EngineDescription> FindEngineDescriptions(IReader reader, EngineDatabase engineDb)
        {
            // Set the reader's endianness based upon the file's header magic
            reader.SeekTo(0);
            byte[] headerMagic = reader.ReadBlock(4);
            var    endian      = DetermineCacheFileEndianness(headerMagic);
            int    fileVersion;

            if (endian != null)
            {
                reader.Endianness = endian.Value;
                reader.SeekTo(0x4);
                fileVersion = reader.ReadInt32();
            }
            else
            {
                //halo trial lol
                reader.SeekTo(0x2C0);
                headerMagic = reader.ReadBlock(4);
                var trialendian = DetermineTrialCacheFileEndianness(headerMagic);

                reader.Endianness = trialendian;
                reader.SeekTo(0x588);
                fileVersion = reader.ReadInt32();
            }

            var possibleEngines = engineDb.FindEnginesByVersion(fileVersion, reader.Endianness);

            //reduce extra reads by caching the value at each offset
            Dictionary <int, string> offsetCache = new Dictionary <int, string>();

            List <EngineDescription> matches = new List <EngineDescription>();

            foreach (EngineDescription engine in possibleEngines)
            {
                if (offsetCache.ContainsKey(engine.BuildStringOffset))
                {
                    if (offsetCache[engine.BuildStringOffset] == engine.BuildVersion)
                    {
                        matches.Add(engine);
                        if (!string.IsNullOrEmpty(engine.BuildVersion))
                        {
                            break;
                        }
                    }

                    continue;
                }

                reader.SeekTo(engine.BuildStringOffset);
                string buildString = reader.ReadAscii(0x20);

                if (buildString == engine.BuildVersion)
                {
                    matches.Add(engine);
                    if (!string.IsNullOrEmpty(engine.BuildVersion))
                    {
                        break;
                    }
                }

                offsetCache[engine.BuildStringOffset] = buildString;
            }

            return(matches);
        }