// 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); }
/// <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)); }
/// <summary> /// Gets the <see cref="PKM"/> data from the message that is encoded in a QR. /// </summary> /// <param name="message">QR Message</param> /// <param name="format">Preferred <see cref="PKM.Format"/> to expect.</param> /// <returns>Decoded <see cref="PKM"/> object, null if invalid.</returns> public static PKM?GetPKM(string message, int format) { var data = DecodeMessagePKM(message); if (data == null) { return(null); } return(EntityFormat.GetFromBytes(data, format)); }
/// <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); }
public static IEnumerable <T> GetPKMFilesOfType <T>(IEnumerable <string> files) { foreach (var file in files) { var data = File.ReadAllBytes(file); var pkm = EntityFormat.GetFromBytes(data); if (pkm is T dest) { yield return(dest); } } }
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); }
public static IEnumerable <PKM> GetPKMsFromPaths(IEnumerable <string> files, int generation) { var result = files .Where(file => EntityDetection.IsSizePlausible(new FileInfo(file).Length)) .Select(File.ReadAllBytes) .Select(data => EntityFormat.GetFromBytes(data, prefer: generation)); foreach (var pkm in result) { if (pkm?.Species is > 0) { yield return(pkm); } } }
/// <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); }
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); } } }
protected override PKM GetPKM(byte[] data) => EntityFormat.GetFromBytes(data, prefer: Context) ?? blank;
protected override PKM GetPKM(byte[] data) => EntityFormat.GetFromBytes(data, prefer: Generation) ?? blank;