示例#1
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)
    {
        if (templatePath == null || !Directory.Exists(templatePath))
        {
            return(LoadTemplateInternal(sav));
        }

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

        if (!File.Exists(path))
        {
            return(LoadTemplateInternal(sav));
        }
        var fi = new FileInfo(path);

        if (!EntityDetection.IsSizePlausible(fi.Length))
        {
            return(LoadTemplateInternal(sav));
        }

        var data   = File.ReadAllBytes(path);
        var prefer = EntityFileExtension.GetContextFromExtension(fi.Extension, sav.Context);
        var pk     = EntityFormat.GetFromBytes(data, prefer);

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

        return(EntityConverter.ConvertToType(pk, sav.BlankPKM.GetType(), out _) ?? LoadTemplateInternal(sav));
    }
示例#2
0
    // ReSharper disable once UnusedParameter.Local
    private static void VerifyAll(string folder, string name, bool isValid, bool checkDir = true)
    {
        var  path   = Path.Combine(folder, name);
        bool exists = Directory.Exists(path);

        if (checkDir)
        {
            exists.Should().BeTrue($"the specified test directory at '{path}' should exist");
        }
        else if (!exists)
        {
            return;
        }

        var files = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories);
        var ctr   = 0;

        foreach (var file in files)
        {
            var fi = new FileInfo(file);
            fi.Should().NotBeNull($"the test file '{file}' should be a valid file");
            EntityDetection.IsSizePlausible(fi.Length).Should().BeTrue($"the test file '{file}' should have a valid file length");

            var data   = File.ReadAllBytes(file);
            var prefer = EntityFileExtension.GetContextFromExtension(file);
            prefer.IsValid().Should().BeTrue("filename is expected to have a valid extension");

            var dn = fi.DirectoryName ?? string.Empty;
            ParseSettings.AllowGBCartEra     = dn.Contains("GBCartEra");
            ParseSettings.AllowGen1Tradeback = dn.Contains("1 Tradeback");
            var pk = EntityFormat.GetFromBytes(data, prefer);
            pk.Should().NotBeNull($"the PKM '{new FileInfo(file).Name}' should have been loaded");
            if (pk == null)
            {
                continue;
            }
            var legality = new LegalityAnalysis(pk);
            if (legality.Valid == isValid)
            {
                ctr++;
                continue;
            }

            var fn = Path.Combine(dn, fi.Name);
            if (isValid)
            {
                var info   = legality.Info;
                var result = legality.Results.Cast <ICheckResult>().Concat(info.Moves).Concat(info.Relearn);
                // ReSharper disable once ConstantConditionalAccessQualifier
                var invalid = result.Where(z => !z.Valid);
                var msg     = string.Join(Environment.NewLine, invalid.Select(z => z.Comment));
                legality.Valid.Should().BeTrue($"because the file '{fn}' should be Valid, but found:{Environment.NewLine}{msg}");
            }
            else
            {
                legality.Valid.Should().BeFalse($"because the file '{fn}' should be invalid, but found Valid.");
            }
        }
        ctr.Should().BeGreaterThan(0);
    }
示例#3
0
    /// <summary>
    /// Tries to get an <see cref="PKM"/> object from the input parameters.
    /// </summary>
    /// <param name="data">Binary data</param>
    /// <param name="pk">Output result</param>
    /// <param name="ext">Format hint</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 TryGetPKM(byte[] data, [NotNullWhen(true)] out PKM?pk, string ext, ITrainerInfo?sav = null)
    {
        if (ext == ".pgt") // size collision with pk6
        {
            pk = null;
            return(false);
        }
        var format = EntityFileExtension.GetContextFromExtension(ext, sav?.Context ?? EntityContext.Gen6);

        pk = EntityFormat.GetFromBytes(data, prefer: format);
        return(pk != null);
    }
示例#4
0
        private static PKM GetPKM(string file, FileInfo fi)
        {
            fi.Should().NotBeNull($"the test file '{file}' should be a valid file");
            EntityDetection.IsSizePlausible(fi.Length).Should().BeTrue($"the test file '{file}' should have a valid file length");

            var data   = File.ReadAllBytes(file);
            var prefer = EntityFileExtension.GetContextFromExtension(file, EntityContext.None);
            var pkm    = EntityFormat.GetFromBytes(data, prefer: prefer);

            pkm.Should().NotBeNull($"the PKM '{new FileInfo(file).Name}' should have been loaded");
            return(pkm);
        }
示例#5
0
        /// <summary>
        /// Creates PKSM's bank.bin to individual <see cref="PKM"/> files (v1)
        /// </summary>
        /// <param name="dir">Folder to export all dumped files to</param>
        public static int CreateBank(string dir)
        {
            var files    = Directory.GetFiles(dir, "*.p??", SearchOption.TopDirectoryOnly);
            var ver      = Enum.GetValues(typeof(PKSMBankVersion)).Cast <int>().Max();
            var version  = BitConverter.GetBytes(ver + 1); // Latest bank version
            var pksmsize = GetBankSize((PKSMBankVersion)ver);
            var boxcount = (files.Length / 30) + 1;
            var bank     = new byte[8 + 4 + 4 + (boxcount * pksmsize * 30)];
            var ctr      = 0;
            var magic    = new byte[] { 0x50, 0x4B, 0x53, 0x4D, 0x42, 0x41, 0x4E, 0x4B }; // PKSMBANK

            magic.CopyTo(bank, 0);
            version.CopyTo(bank, 8);
            BitConverter.GetBytes(boxcount).CopyTo(bank, 12); // Number of bank boxes.
            foreach (var f in files)
            {
                var prefer = EntityFileExtension.GetContextFromExtension(f, EntityContext.None);
                var pk     = EntityFormat.GetFromBytes(File.ReadAllBytes(f), prefer);
                if (pk == null)
                {
                    continue;
                }
                if (pk.Species == 0 && pk.Species >= pk.MaxSpeciesID)
                {
                    continue;
                }
                var ofs = 16 + (ctr * pksmsize);
                BitConverter.GetBytes((int)GetPKSMFormat(pk)).CopyTo(bank, ofs);
                pk.DecryptedBoxData.CopyTo(bank, ofs + 4);
                byte[] temp = Enumerable.Repeat((byte)0xFF, pksmsize - pk.DecryptedBoxData.Length - 8).ToArray();
                temp.CopyTo(bank, ofs + pk.DecryptedBoxData.Length + 4);
                temp = Enumerable.Repeat((byte)0x00, 4).ToArray();
                temp.CopyTo(bank, ofs + pksmsize - 4);
                ctr++;
            }
            var empty = (boxcount * 30) - files.Length;

            for (int i = 0; i < empty; i++)
            {
                var    ofs  = 16 + (ctr * pksmsize);
                byte[] temp = Enumerable.Repeat((byte)0xFF, pksmsize).ToArray();
                temp.CopyTo(bank, ofs);
                ctr++;
            }
            File.WriteAllBytes(Path.Combine(dir, "alm.bnk"), bank);
            return(ctr - empty);
        }
示例#6
0
 public static IEnumerable <PKM> GetPKMsFromPaths(IEnumerable <string> files, EntityContext generation)
 {
     foreach (var f in files)
     {
         var fi = new FileInfo(f);
         if (!fi.Exists)
         {
             continue;
         }
         if (!EntityDetection.IsSizePlausible(fi.Length))
         {
             continue;
         }
         var data   = File.ReadAllBytes(f);
         var prefer = EntityFileExtension.GetContextFromExtension(fi.Extension, generation);
         var pk     = EntityFormat.GetFromBytes(data, prefer);
         if (pk?.Species is > 0)
         {
             yield return(pk);
         }
     }
 }