Exemple #1
0
        /// <summary>
        /// Gets the generation of the Pokemon data.
        /// </summary>
        /// <param name="data">Raw data representing a Pokemon.</param>
        /// <returns>An integer indicating the generation of the PKM file, or -1 if the data is invalid.</returns>
        public static int GetPKMDataFormat(byte[] data)
        {
            if (!PKX.IsPKM(data.Length))
            {
                return(-1);
            }

            switch (data.Length)
            {
            case PKX.SIZE_1JLIST:
            case PKX.SIZE_1ULIST:
                return(1);

            case PKX.SIZE_2ULIST:
            case PKX.SIZE_2JLIST:
                return(2);

            case PKX.SIZE_3PARTY:
            case PKX.SIZE_3STORED:
            case PKX.SIZE_3CSTORED:
            case PKX.SIZE_3XSTORED:
                return(3);

            case PKX.SIZE_4PARTY:
            case PKX.SIZE_4STORED:
            case PKX.SIZE_5PARTY:
                if ((BitConverter.ToUInt16(data, 0x4) == 0) && (BitConverter.ToUInt16(data, 0x80) >= 0x3333 || data[0x5F] >= 0x10) && BitConverter.ToUInt16(data, 0x46) == 0)     // PK5
                {
                    return(5);
                }
                return(4);

            case PKX.SIZE_6STORED:
                return(6);

            case PKX.SIZE_6PARTY:                          // collision with PGT, same size.
                if (BitConverter.ToUInt16(data, 0x4) != 0) // Bad Sanity?
                {
                    return(-1);
                }
                if (BitConverter.ToUInt32(data, 0x06) == PKX.GetCHK(data))
                {
                    return(6);
                }
                if (BitConverter.ToUInt16(data, 0x58) != 0)                // Encrypted?
                {
                    for (int i = data.Length - 0x10; i < data.Length; i++) // 0x10 of 00's at the end != PK6
                    {
                        if (data[i] != 0)
                        {
                            return(6);
                        }
                    }

                    return(-1);
                }
                return(6);
            }
            return(-1);
        }
Exemple #2
0
        /// <summary>
        /// Gets a <see cref="PKM"/> from the provided <see cref="file"/> path, which is to be loaded to the <see cref="SaveFile"/>.
        /// </summary>
        /// <param name="file"><see cref="PKM"/> or <see cref="MysteryGift"/> file path.</param>
        /// <param name="sav">Generation Info</param>
        /// <returns>New <see cref="PKM"/> reference from the file.</returns>
        public static PKM?GetSingleFromPath(string file, ITrainerInfo sav)
        {
            var fi = new FileInfo(file);

            if (!fi.Exists)
            {
                return(null);
            }
            if (fi.Length == GP1.SIZE && TryGetGP1(File.ReadAllBytes(file), out var gp1))
            {
                return(gp1?.ConvertToPB7(sav));
            }
            if (!PKX.IsPKM(fi.Length) && !MysteryGift.IsMysteryGift(fi.Length))
            {
                return(null);
            }
            var data = File.ReadAllBytes(file);
            var ext  = fi.Extension;
            var mg   = MysteryGift.GetMysteryGift(data, ext);
            var gift = mg?.ConvertToPKM(sav);

            if (gift != null)
            {
                return(gift);
            }
            int prefer = PKX.GetPKMFormatFromExtension(ext, sav.Generation);

            return(PKMConverter.GetPKMfromBytes(data, prefer: prefer));
        }
Exemple #3
0
        /// <summary>
        /// Gets a <see cref="PKM"/> from the provided <see cref="file"/> path, which is to be loaded to the <see cref="SaveFile"/>.
        /// </summary>
        /// <param name="file"><see cref="PKM"/> or <see cref="MysteryGift"/> file path.</param>
        /// <param name="sav">Generation Info</param>
        /// <returns>New <see cref="PKM"/> reference from the file.</returns>
        public static PKM?GetSingleFromPath(string file, ITrainerInfo sav)
        {
            var fi = new FileInfo(file);

            if (!fi.Exists)
            {
                return(null);
            }
            if (fi.Length == GP1.SIZE && TryGetGP1(File.ReadAllBytes(file), out var gp1))
            {
                return(gp1.ConvertToPB7(sav));
            }
            if (!PKX.IsPKM(fi.Length) && !MysteryGift.IsMysteryGift(fi.Length))
            {
                return(null);
            }
            var data = File.ReadAllBytes(file);
            var ext  = fi.Extension;
            var mg   = MysteryGift.GetMysteryGift(data, ext);
            var gift = mg?.ConvertToPKM(sav);

            if (gift != null)
            {
                return(gift);
            }
            _ = TryGetPKM(data, out var pk, ext, sav);
            return(pk);
        }
Exemple #4
0
 public static IEnumerable <PKM> GetPKMsFromPaths(IEnumerable <string> filepaths, int generation)
 {
     return(filepaths
            .Where(file => PKX.IsPKM(new FileInfo(file).Length))
            .Select(File.ReadAllBytes)
            .Select(data => PKMConverter.GetPKMfromBytes(data, prefer: generation))
            .Where(temp => temp != null));
 }
Exemple #5
0
        public static IEnumerable <PKM> GetPKMsFromPaths(IEnumerable <string> files, int generation)
        {
            var result = files
                         .Where(file => PKX.IsPKM(new FileInfo(file).Length))
                         .Select(File.ReadAllBytes)
                         .Select(data => PKMConverter.GetPKMfromBytes(data, prefer: generation));

            foreach (var pkm in result)
            {
                if (pkm?.Species is > 0)
                {
                    yield return(pkm);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Tries to get an <see cref="IEnumerable{T}"/> object from the input parameters.
        /// </summary>
        /// <param name="data">Binary data</param>
        /// <param name="pkms">Output result</param>
        /// <param name="sav">Reference savefile used for PC Binary compatibility checks.</param>
        /// <returns>True if file object reference is valid, false if none found.</returns>
        public static bool TryGetPCBoxBin(byte[] data, out IEnumerable <byte[]> pkms, SaveFile?sav)
        {
            if (sav == null)
            {
                pkms = Array.Empty <byte[]>();
                return(false);
            }
            var length = data.Length;

            if (PKX.IsPKM(length / sav.SlotCount) || PKX.IsPKM(length / sav.BoxSlotCount))
            {
                pkms = ArrayUtil.EnumerateSplit(data, length);
                return(true);
            }
            pkms = Array.Empty <byte[]>();
            return(false);
        }
Exemple #7
0
        /// <summary>
        /// Tries to get an <see cref="IEnumerable{T}"/> object from the input parameters.
        /// </summary>
        /// <param name="data">Binary data</param>
        /// <param name="pkms">Output result</param>
        /// <param name="SAV">Reference savefile used for PC Binary compatibility checks.</param>
        /// <returns>True if file object reference is valid, false if none found.</returns>
        public static bool TryGetPCBoxBin(byte[] data, out IEnumerable <byte[]> pkms, SaveFile SAV)
        {
            if (SAV == null)
            {
                pkms = Enumerable.Empty <byte[]>();
                return(false);
            }
            var length = data.Length;

            if (PKX.IsPKM(length / SAV.SlotCount) || PKX.IsPKM(length / SAV.BoxSlotCount))
            {
                pkms = PKX.GetPKMDataFromConcatenatedBinary(data, length);
                return(true);
            }
            pkms = Enumerable.Empty <byte[]>();
            return(false);
        }
Exemple #8
0
        /// <summary>
        /// Gets a blank file for the save file. If the template path exists, a template load will be attempted.
        /// </summary>
        /// <param name="sav">Save File to fetch a template for</param>
        /// <param name="templatePath">Path to look for a template in</param>
        /// <returns>Template if it exists, or a blank <see cref="PKM"/> from the <see cref="sav"/></returns>
        public static PKM LoadTemplate(this SaveFile sav, string templatePath = null)
        {
            var blank = sav.BlankPKM;

            if (!Directory.Exists(templatePath))
            {
                return(blank);
            }

            var    di   = new DirectoryInfo(templatePath);
            string path = Path.Combine(templatePath, $"{di.Name}.{blank.Extension}");

            if (!File.Exists(path) || !PKX.IsPKM(new FileInfo(path).Length))
            {
                return(blank);
            }

            var pk = PKMConverter.GetPKMfromBytes(File.ReadAllBytes(path), prefer: blank.Format);

            return(PKMConverter.ConvertToType(pk, sav.BlankPKM.GetType(), out path) ?? blank); // no sneaky plz; reuse string
        }
Exemple #9
0
        public static void AddFromLocalFile(string file, ConcurrentBag <SlotCache> db, ITrainerInfo dest, ICollection <string> validExtensions)
        {
            var fi = new FileInfo(file);

            if (!validExtensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length))
            {
                return;
            }

            var data = File.ReadAllBytes(file);

            _ = FileUtil.TryGetPKM(data, out var pk, fi.Extension, dest);
            if (pk?.Species is not > 0)
            {
                return;
            }

            var info  = new SlotInfoFile(file);
            var entry = new SlotCache(info, pk);

            db.Add(entry);
        }
Exemple #10
0
        public static void AddFromLocalFile(string file, ConcurrentBag <SlotCache> db, ITrainerInfo dest, ICollection <string> validExtensions)
        {
            var fi = new FileInfo(file);

            if (!validExtensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length))
            {
                return;
            }

            var data   = File.ReadAllBytes(file);
            var prefer = PKX.GetPKMFormatFromExtension(fi.Extension, dest.Generation);
            var pk     = PKMConverter.GetPKMfromBytes(data, prefer);

            if (pk?.Species is not > 0)
            {
                return;
            }

            var info  = new SlotInfoFile(file);
            var entry = new SlotCache(info, pk);

            db.Add(entry);
        }
Exemple #11
0
        /// <summary>
        /// Gets the generation of the Pokemon data.
        /// </summary>
        /// <param name="data">Raw data representing a Pokemon.</param>
        /// <returns>An integer indicating the generation of the PKM file, or -1 if the data is invalid.</returns>
        public static int GetPKMDataFormat(ReadOnlySpan <byte> data)
        {
            if (!PKX.IsPKM(data.Length))
            {
                return(-1);
            }

            switch (data.Length)
            {
            case PokeCrypto.SIZE_1JLIST or PokeCrypto.SIZE_1ULIST:
                return(1);

            case PokeCrypto.SIZE_2JLIST or PokeCrypto.SIZE_2ULIST:
            case PokeCrypto.SIZE_2STADIUM:
                return(2);

            case PokeCrypto.SIZE_3PARTY or PokeCrypto.SIZE_3STORED:
            case PokeCrypto.SIZE_3CSTORED:
            case PokeCrypto.SIZE_3XSTORED:
                return(3);

            case PokeCrypto.SIZE_4PARTY or PokeCrypto.SIZE_4STORED:
            case PokeCrypto.SIZE_5PARTY:
                if ((ReadUInt16LittleEndian(data[0x4..]) == 0) && (ReadUInt16LittleEndian(data[0x80..]) >= 0x3333 || data[0x5F] >= 0x10) && ReadUInt16LittleEndian(data[0x46..]) == 0)     // PK5
Exemple #12
0
        /// <summary>
        /// Gets a blank file for the save file. If the template path exists, a template load will be attempted.
        /// </summary>
        /// <param name="sav">Save File to fetch a template for</param>
        /// <param name="templatePath">Path to look for a template in</param>
        /// <returns>Template if it exists, or a blank <see cref="PKM"/> from the <see cref="sav"/></returns>
        public static PKM LoadTemplate(this SaveFile sav, string templatePath)
        {
            if (!Directory.Exists(templatePath))
            {
                return(LoadTemplate(sav));
            }

            var    di   = new DirectoryInfo(templatePath);
            string path = Path.Combine(templatePath, $"{di.Name}.{sav.PKMType.Name.ToLower()}");

            if (!File.Exists(path) || !PKX.IsPKM(new FileInfo(path).Length))
            {
                return(LoadTemplate(sav));
            }

            var pk = PKMConverter.GetPKMfromBytes(File.ReadAllBytes(path), prefer: sav.Generation);

            if (pk == null)
            {
                return(LoadTemplate(sav));
            }

            return(PKMConverter.ConvertToType(pk, sav.BlankPKM.GetType(), out _) ?? LoadTemplate(sav));
        }