예제 #1
0
        private static bool IsValidPlatform(Big.Platform platform, uint unknown74)
        {
            if (platform == Big.Platform.Any &&
                unknown74 != 0)
            {
                return(false);
            }

            if (platform == Big.Platform.PC &&
                (/*unknown5C < 0 ||*/ unknown74 > 3))
            {
                return(false);
            }

            if (platform == Big.Platform.X360 &&
                (unknown74 < 1 || unknown74 > 4))
            {
                return(false);
            }

            if (platform == Big.Platform.PS3 &&
                (unknown74 < 1 || unknown74 > 4))
            {
                return(false);
            }

            return(true);
        }
예제 #2
0
 internal static void SanityCheckEntry(Big.Entry entry, Big.Platform platform)
 {
     if (entry.CompressionScheme == Big.CompressionScheme.None)
     {
         if (platform != Big.Platform.X360 &&
             entry.UncompressedSize != 0)
         {
             throw new FormatException("got entry with no compression with a non-zero uncompressed size");
         }
     }
     else if (entry.CompressionScheme == Big.CompressionScheme.LZO1x ||
              entry.CompressionScheme == Big.CompressionScheme.Zlib)
     {
         if (entry.CompressedSize == 0 &&
             entry.UncompressedSize > 0)
         {
             throw new FormatException(
                       "got entry with compression with a zero compressed size and a non-zero uncompressed size");
         }
     }
     else
     {
         throw new FormatException("got entry with unsupported compression scheme");
     }
 }
예제 #3
0
        private static bool IsValidTargetPlatform(Big.Target target, Big.Platform platform, byte unknown70)
        {
            if (target == Big.Target.Any)
            {
                if (platform != Big.Platform.Any)
                {
                    return(false);
                }

                if (unknown70 != 0x32)
                {
                    return(false);
                }
            }
            else if (target == Big.Target.Win64)
            {
                if (platform != (Big.Platform) 5)
                {
                    return(false);
                }

                if (unknown70 != 0x32)
                {
                    return(false);
                }
            }
            else if (target == Big.Target.Xbox360)
            {
                if (platform != (Big.Platform) 5)
                {
                    return(false);
                }

                if (unknown70 != 0x37)
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != _Signature)
            {
                throw new FormatException("bad magic");
            }

            var version = input.ReadValueS32(Endian.Little);

            if (version < 7 || version > 8)
            {
                throw new FormatException("unsupported version");
            }

            var flags    = input.ReadValueU32(Endian.Little);
            var target   = (Big.Target)(flags & 0xFF);
            var platform = (Big.Platform)((flags >> 8) & 0xFF);
            var flags02  = (byte)((flags >> 16) & 0xFF);

            if ((flags & ~0xFFFFFFu) != 0)
            {
                throw new FormatException("unknown flags");
            }

            if (target != Big.Target.Any &&
                target != Big.Target.Win32 &&
                target != Big.Target.Xbox360 &&
                target != Big.Target.PS3 &&
                target != Big.Target.Win64 &&
                target != Big.Target.WiiU)
            {
                throw new FormatException("unsupported or invalid platform");
            }

            if (IsValidTargetPlatform(target, platform, flags02) == false)
            {
                throw new FormatException("invalid flags");
            }

            this._Version   = version;
            this._Target    = target;
            this._Platform  = platform;
            this._Unknown70 = flags02;

            var endian          = this.Endian;
            var entrySerializer = this.GetEntrySerializer();

            this._Entries.Clear();
            uint entryCount = input.ReadValueU32(Endian.Little);

            for (uint i = 0; i < entryCount; i++)
            {
                Big.Entry entry;
                entrySerializer.Deserialize(input, Endian.Little, out entry);
                this._Entries.Add(entry);
            }

            uint localizationCount = input.ReadValueU32(Endian.Little);

            for (uint i = 0; i < localizationCount; i++)
            {
                var nameLength = input.ReadValueU32(Endian.Little);
                if (nameLength > 32)
                {
                    throw new FormatException("bad length for localization name");
                }
                var nameBytes    = input.ReadBytes((int)nameLength);
                var unknownValue = input.ReadValueU64(Endian.Little);
            }

            foreach (var entry in this.Entries)
            {
                SanityCheckEntry(entry, target);
            }
        }
예제 #5
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != Signature)
            {
                throw new FormatException("bad magic");
            }

            var version = input.ReadValueS32(Endian.Little);

            if (version < 2 || version > 9)
            {
                throw new FormatException("unsupported file version");
            }
            this.Version = version;

            var  platform  = Big.Platform.Invalid;
            uint unknown74 = 0;

            if (version >= 3)
            {
                unknown74   = input.ReadValueU32(Endian.Little); // ###### ##
                platform    = (Big.Platform)(unknown74 & 0xFF);
                unknown74 >>= 8;
            }

            if (platform != Big.Platform.Any &&
                platform != Big.Platform.PC &&
                platform != Big.Platform.X360 &&
                platform != Big.Platform.PS3)
            {
                throw new FormatException("unsupported/invalid platform");
            }

            if (IsValidPlatform(platform, unknown74) == false)
            {
                throw new FormatException("invalid platform settings");
            }

            this.Platform = platform;
            var endian = this.Endian;

            int subfatTotalEntryCount = 0;
            int subfatCount           = 0;

            if (version >= 9)
            {
                subfatTotalEntryCount = input.ReadValueS32(Endian.Little);
                if (subfatTotalEntryCount < 0)
                {
                    throw new FormatException("invalid subfat first header entry index");
                }

                subfatCount = input.ReadValueS32(Endian.Little);
                if (subfatCount < 0)
                {
                    throw new FormatException("invalid subfat count");
                }
            }

            var entrySerializer = this.EntrySerializer;

            uint entryCount = input.ReadValueU32(Endian.Little);

            for (uint i = 0; i < entryCount; i++)
            {
                Big.Entry entry;
                entrySerializer.Deserialize(input, endian, out entry);
                this.Entries.Add(entry);
            }

            uint unknown1Count = input.ReadValueU32(Endian.Little);

            for (uint i = 0; i < unknown1Count; i++)
            {
                throw new NotSupportedException();
                input.ReadBytes(16);
            }

            if (version >= 7)
            {
                uint unknown2Count = input.ReadValueU32(Endian.Little);
                for (uint i = 0; i < unknown2Count; i++)
                {
                    input.ReadBytes(16);
                }
            }

            for (int i = 0; i < subfatCount; i++)
            {
                var  subFat           = new Big.SubFatEntry();
                uint subfatEntryCount = input.ReadValueU32(Endian.Little);
                for (uint j = 0; j < subfatEntryCount; j++)
                {
                    Big.Entry entry;
                    entrySerializer.Deserialize(input, endian, out entry);
                    subFat.Entries.Add(entry);
                }
                this.SubFats.Add(subFat);
            }

            var subfatComputedTotalEntryCount = this.SubFats.Sum(sf => sf.Entries.Count);

            if (subfatCount > 0 &&
                subfatTotalEntryCount != subfatComputedTotalEntryCount)
            {
                throw new FormatException("subfat total entry count mismatch");
            }

            this.Version   = version;
            this.Platform  = platform;
            this.Unknown74 = unknown74;

            foreach (var entry in this.Entries)
            {
                SanityCheckEntry(entry, platform);
            }

            foreach (var subFat in this.SubFats)
            {
                foreach (var entry in subFat.Entries)
                {
                    SanityCheckEntry(entry, platform);
                }
            }
        }