public void Unpack(PackedWeapon packed, Platform platform)
        {
            var alm = InfoManager.AssetLibraryManager;

            this.Type         = alm.Lookup(packed.Type, platform, this.AssetLibrarySetId, AssetGroup.WeaponTypes);
            this.Balance      = alm.Lookup(packed.Balance, platform, this.AssetLibrarySetId, AssetGroup.BalanceDefs);
            this.Manufacturer =
                alm.Lookup(packed.Manufacturer, platform, this.AssetLibrarySetId, AssetGroup.Manufacturers);
            this.ManufacturerGradeIndex = packed.ManufacturerGradeIndex;
            this.GameStage     = packed.GameStage;
            this.BodyPart      = alm.Lookup(packed.BodyPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.GripPart      = alm.Lookup(packed.GripPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.BarrelPart    = alm.Lookup(packed.BarrelPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.SightPart     = alm.Lookup(packed.SightPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.StockPart     = alm.Lookup(packed.StockPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.ElementalPart =
                alm.Lookup(packed.ElementalPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.Accessory1Part =
                alm.Lookup(packed.Accessory1Part, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.Accessory2Part =
                alm.Lookup(packed.Accessory2Part, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.MaterialPart = alm.Lookup(packed.MaterialPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.PrefixPart   = alm.Lookup(packed.PrefixPart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
            this.TitlePart    = alm.Lookup(packed.TitlePart, platform, this.AssetLibrarySetId, AssetGroup.WeaponParts);
        }
        public static IPackableSlot Decode(byte[] data, Platform platform)
        {
            if (data.Length < 5 || data.Length > 40)
            {
                throw new ArgumentOutOfRangeException("data");
            }

            var seed = BitConverter.ToUInt32(data, 1).Swap();
            var unobfuscatedBytes = (byte[])data.Clone();

            BogoDecrypt(seed, unobfuscatedBytes, 5, unobfuscatedBytes.Length - 5);

            var fileCheck = BitConverter.ToUInt16(unobfuscatedBytes, 5).Swap();

            unobfuscatedBytes[5] = 0xFF;
            unobfuscatedBytes[6] = 0xFF;

            if (unobfuscatedBytes.Length < 40)
            {
                var start = unobfuscatedBytes.Length;
                Array.Resize(ref unobfuscatedBytes, 40);
                for (int i = start; i < unobfuscatedBytes.Length; i++)
                {
                    unobfuscatedBytes[i] = 0xFF;
                }
            }

            var hash          = CRC32.Hash(unobfuscatedBytes, 0, unobfuscatedBytes.Length);
            var computedCheck = (ushort)(((hash & 0xFFFF0000) >> 16) ^ ((hash & 0x0000FFFF) >> 0));

            if (fileCheck != computedCheck)
            {
                throw new FormatException("checksum failure in packed data");
            }

            var reader = new BitReader(unobfuscatedBytes);

            var version = reader.ReadInt32(7);

            if (version != InfoManager.AssetLibraryManager.Version)
            {
                throw new FormatException("invalid version in packed data");
            }

            var isWeapon = reader.ReadBoolean();

            int uniqueId = 0;

            if (version >= 3)
            {
                uniqueId = reader.ReadInt32(32);
            }

            ushort check = reader.ReadUInt16(16);

            if (check != 0xFFFF)
            {
                throw new FormatException("invalid check in packed data");
            }

            int setId = 0;

            if (version >= 2)
            {
                setId = reader.ReadInt32(8);
            }

            /*
             * var set = InfoManager.AssetLibraryManager.GetSet(setId);
             * if (set == null)
             * {
             *  throw new FormatException(
             *      string.Format(
             *          "unknown asset library set {0} in packed data (this generally means new DLC that is not supported yet)",
             *          setId));
             * }
             */

            if (isWeapon == true)
            {
                var packed = new PackedWeapon();
                packed.Read(reader, platform);

                var weapon = new TWeapon
                {
                    UniqueId          = uniqueId,
                    AssetLibrarySetId = setId,
                };
                weapon.Unpack(packed, platform);
                return(weapon);
            }
            else
            {
                var packed = new PackedItem();
                packed.Read(reader, platform);

                var item = new TItem
                {
                    UniqueId          = uniqueId,
                    AssetLibrarySetId = setId,
                };
                item.Unpack(packed, platform);
                return(item);
            }
        }