private static void TryAddPKMsFromSaveFilePath(ConcurrentBag <PKM> dbTemp, string file, string externalFilePrefix) { try { var sav = SaveUtil.GetVariantSAV(file); if (sav == null) { Console.WriteLine("Unable to load SaveFile: " + file); return; } var path = externalFilePrefix + Path.GetFileName(file); if (sav.HasBox) { foreach (var pk in sav.BoxData) { addPKM(pk); } } void addPKM(PKM pk) { pk.Identifier = Path.Combine(path, pk.Identifier); dbTemp.Add(pk); } } catch (Exception ex) { Console.WriteLine("ERROR: Unable to load SaveFile: " + file); Console.WriteLine(ex.Message); } }
/// <summary> /// Finds a compatible save file that was most recently saved (by file write time). /// </summary> /// <param name="path">If this function returns true, full path of a save file or null if no path could be found. If this function returns false, this parameter will be set to the error message.</param> /// <param name="extra">Paths to check in addition to the default paths</param> /// <returns>A boolean indicating whether or not a file was detected</returns> public static bool DetectSaveFile(out string path, params string[] extra) { var foldersToCheck = extra.Where(f => f?.Length > 0); string path3DS = Path.GetPathRoot(Get3DSLocation()); if (path3DS != null) // check for Homebrew/CFW backups { foldersToCheck = foldersToCheck.Concat(Get3DSBackupPaths(path3DS)); } string pathNX = Path.GetPathRoot(GetSwitchLocation()); if (pathNX != null) // check for Homebrew/CFW backups { foldersToCheck = foldersToCheck.Concat(GetSwitchBackupPaths(pathNX)); } path = null; List <string> possiblePaths = new List <string>(); foreach (var folder in foldersToCheck) { if (!SaveUtil.GetSavesFromFolder(folder, true, out IEnumerable <string> files)) { if (files != null) // can be null if folder doesn't exist { path = string.Join(Environment.NewLine, files); // `files` contains the error message return(false); } } if (files != null) { possiblePaths.AddRange(files); } } // return newest save file path that is valid foreach (var file in possiblePaths.OrderByDescending(f => new FileInfo(f).LastWriteTime)) { try { var data = File.ReadAllBytes(file); var sav = SaveUtil.GetVariantSAV(data); if (sav?.ChecksumsValid != true) { continue; } path = file; return(true); } catch (Exception e) { path = e.Message + Environment.NewLine + file; return(false); } } return(true); }
private void CompareSaves() { var p1 = TB_OldSAV.Text; var p2 = TB_NewSAV.Text; var f1 = new FileInfo(p1); if (!SaveUtil.IsSizeValid((int)f1.Length)) { return; } var f2 = new FileInfo(p1); if (!SaveUtil.IsSizeValid((int)f2.Length)) { return; } var s1 = SaveUtil.GetVariantSAV(p1); if (!(s1 is SAV8SWSH w1)) { return; } var s2 = SaveUtil.GetVariantSAV(p2); if (!(s2 is SAV8SWSH w2)) { return; } var compare = new SCBlockCompare(w1, w2); richTextBox1.Lines = compare.Summary().ToArray(); }
private static List <PKM> LoadPKMSaves(string pkmdb, string savdb, string EXTERNAL_SAV, SaveFile SAV) { var dbTemp = new ConcurrentBag <PKM>(); var files = Directory.EnumerateFiles(pkmdb, "*", SearchOption.AllDirectories); var extensions = new HashSet <string>(PKM.Extensions.Select(z => $".{z}")); Parallel.ForEach(files, file => { var fi = new FileInfo(file); if (!extensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length)) { return; } var data = File.ReadAllBytes(file); var prefer = PKX.GetPKMFormatFromExtension(fi.Extension, SAV.Generation); var pk = PKMConverter.GetPKMfromBytes(data, prefer); if (!(pk?.Species > 0)) { return; } pk.Identifier = file; dbTemp.Add(pk); }); #if LOADALL if (SaveUtil.GetSavesFromFolder(savdb, false, out IEnumerable <string> result)) { Parallel.ForEach(result, file => { var sav = SaveUtil.GetVariantSAV(file); var path = EXTERNAL_SAV + new FileInfo(file).Name; if (sav.HasBox) { foreach (var pk in sav.BoxData) { addPKM(pk); } } void addPKM(PKM pk) { pk.Identifier = Path.Combine(path, pk.Identifier); dbTemp.Add(pk); } }); } #endif // Fetch from save file var savpkm = SAV.BoxData.Where(pk => pk.Species != 0); var bakpkm = dbTemp.Where(pk => pk.Species != 0).OrderBy(pk => pk.Identifier); var db = bakpkm.Concat(savpkm).Where(pk => pk.ChecksumValid && pk.Sanity == 0); // Prepare Database return(new List <PKM>(db)); }
private void LoadDatabase() { var dbTemp = new ConcurrentBag <PKM>(); var files = Directory.EnumerateFiles(DatabasePath, "*", SearchOption.AllDirectories); Parallel.ForEach(files, file => { FileInfo fi = new FileInfo(file); if (!fi.Extension.Contains(".pk") || !PKX.IsPKM(fi.Length)) { return; } var pk = PKMConverter.GetPKMfromBytes(File.ReadAllBytes(file), file, prefer: (fi.Extension.Last() - '0') & 0xF); if (pk != null) { dbTemp.Add(pk); } }); #if LOADALL if (SaveUtil.GetSavesFromFolder(Main.BackupPath, false, out IEnumerable <string> result)) { Parallel.ForEach(result, file => { var sav = SaveUtil.GetVariantSAV(File.ReadAllBytes(file)); var path = EXTERNAL_SAV + new FileInfo(file).Name; if (sav.HasBox) { foreach (var pk in sav.BoxData) { addPKM(pk); } } void addPKM(PKM pk) { pk.Identifier = Path.Combine(path, pk.Identifier); dbTemp.Add(pk); } }); } #endif // Prepare Database RawDB = new List <PKM>(dbTemp.OrderBy(pk => pk.Identifier) .Concat(SAV.BoxData.Where(pk => pk.Species != 0)) // Fetch from save file .Where(pk => pk.ChecksumValid && pk.Species != 0 && pk.Sanity == 0) .Distinct()); try { BeginInvoke(new MethodInvoker(() => SetResults(RawDB))); } catch { /* Window Closed? */ } }
public static async Task <SaveFile> TryGetSaveFile() { try { var path = await PickFile().ConfigureAwait(false); if (path == null) { return(null); } var fi = new FileInfo(path); var len = fi.Length; bool isPossibleSAV = SaveUtil.IsSizeValid((int)len); if (!isPossibleSAV) { var lenD = len - 122; bool isPossibleDSAV = SaveUtil.IsSizeValid((int)lenD); if (isPossibleDSAV) { var data1 = File.ReadAllBytes(path); Byte[] dataD = new Byte[lenD]; Array.ConstrainedCopy(data1, 0, dataD, 0, (int)lenD); var savD = SaveUtil.GetVariantSAV(data1); savD?.SetFileInfo(path); return(savD); } return(null); } var data = File.ReadAllBytes(path); var sav = SaveUtil.GetVariantSAV(data); sav?.SetFileInfo(path); return(sav); } catch (FileNotFoundException ex) { await UserDialogs.Instance.AlertAsync($"The file is being passed as a URI instead of a path. Please try moving your saves to a different folder.\n\nStack Trace:\n{ex}").ConfigureAwait(false); return(null); } catch (Exception ex) { await UserDialogs.Instance.AlertAsync($"Exception choosing file: {ex}").ConfigureAwait(false); return(null); } }
private void DiffSaves() { if (!File.Exists(TB_OldSAV.Text)) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return; } if (!File.Exists(TB_NewSAV.Text)) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return; } if (new FileInfo(TB_OldSAV.Text).Length > 0x100000) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return; } if (new FileInfo(TB_NewSAV.Text).Length > 0x100000) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return; } var s1 = SaveUtil.GetVariantSAV(TB_OldSAV.Text); var s2 = SaveUtil.GetVariantSAV(TB_NewSAV.Text); if (s1 == null) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return; } if (s2 == null) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return; } if (s1.GetType() != s2.GetType()) { WinFormsUtil.Alert(MsgSaveDifferentTypes, $"S1: {s1.GetType().Name}", $"S2: {s2.GetType().Name}"); return; } if (s1.Version != s2.Version) { WinFormsUtil.Alert(MsgSaveDifferentVersions, $"S1: {s1.Version}", $"S2: {s2.Version}"); return; } EventWorkUtil.DiffSavesFlag(((SAV7b)s1).EventWork, ((SAV7b)s2).EventWork, out var on, out var off); EventWorkUtil.DiffSavesWork(((SAV7b)s1).EventWork, ((SAV7b)s2).EventWork, out var changed, out var changes); var ew = ((SAV7b)s1).EventWork; var fOn = on.Select(z => new { Type = ew.GetFlagType(z, out var subIndex), Index = subIndex, Raw = z })
public static async Task <SaveFile> TryGetSaveFile() { try { var file = await PickFile().ConfigureAwait(false); if (file == null) { return(null); } await using var stream = await file.OpenReadAsync().ConfigureAwait(false); var len = stream.Length; bool isPossibleSAV = SaveUtil.IsSizeValid((int)len); if (!isPossibleSAV) { return(null); } var data = new byte[len]; stream.Read(data); var sav = SaveUtil.GetVariantSAV(data); sav?.Metadata.SetExtraInfo(file.FullPath); return(sav); } catch (FileNotFoundException ex) { await UserDialogs.Instance.AlertAsync($"The file is being passed as a URI instead of a path. Please try moving your saves to a different folder.\n\nStack Trace:\n{ex}").ConfigureAwait(false); return(null); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { await UserDialogs.Instance.AlertAsync($"Exception choosing file: {ex}").ConfigureAwait(false); return(null); } }
public static SaveFile TryGetSaveFile(string filePath) { try { var data = File.ReadAllBytes(filePath); var len = data.Length; bool isPossibleSAV = SaveUtil.IsSizeValid(len); if (!isPossibleSAV) { return(null); } var sav = SaveUtil.GetVariantSAV(data); sav?.Metadata.SetExtraInfo(filePath); return(sav); } catch { //Ignore errors as this is meant to be a background scanning function return(null); } }
private void CompareSaves() { var p1 = TB_OldSAV.Text; var p2 = TB_NewSAV.Text; var f1 = new FileInfo(p1); if (!SaveUtil.IsSizeValid((int)f1.Length)) { return; } var f2 = new FileInfo(p1); if (!SaveUtil.IsSizeValid((int)f2.Length)) { return; } var s1 = SaveUtil.GetVariantSAV(p1); if (s1 is not ISCBlockArray w1) { return; } var s2 = SaveUtil.GetVariantSAV(p2); if (s2 is not ISCBlockArray w2) { return; } // Get an external source of names if available. var extra = GetExtraKeyNames(w1); var compare = new SCBlockCompare(w1.Accessor, w2.Accessor, extra); richTextBox1.Lines = compare.Summary().ToArray(); }
private void DiffSaves() { if (!File.Exists(TB_OldSAV.Text)) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return; } if (!File.Exists(TB_NewSAV.Text)) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return; } if (new FileInfo(TB_OldSAV.Text).Length > 0x100000) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return; } if (new FileInfo(TB_NewSAV.Text).Length > 0x100000) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return; } var s1 = SaveUtil.GetVariantSAV(TB_OldSAV.Text); var s2 = SaveUtil.GetVariantSAV(TB_NewSAV.Text); if (s1 == null) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 1)); return; } if (s2 == null) { WinFormsUtil.Alert(string.Format(MsgSaveNumberInvalid, 2)); return; } if (s1.GetType() != s2.GetType()) { WinFormsUtil.Alert(MsgSaveDifferentTypes, $"S1: {s1.GetType().Name}", $"S2: {s2.GetType().Name}"); return; } if (s1.Version != s2.Version) { WinFormsUtil.Alert(MsgSaveDifferentVersions, $"S1: {s1.Version}", $"S2: {s2.Version}"); return; } var tbIsSet = new List <int>(); var tbUnSet = new List <int>(); var result = new List <string>(); bool[] oldBits = s1.EventFlags; bool[] newBits = s2.EventFlags; var oldConst = s1.EventConsts; var newConst = s2.EventConsts; for (int i = 0; i < oldBits.Length; i++) { if (oldBits[i] != newBits[i]) { (newBits[i] ? tbIsSet : tbUnSet).Add(i); } } TB_IsSet.Text = string.Join(", ", tbIsSet.Select(z => $"{z:0000}")); TB_UnSet.Text = string.Join(", ", tbUnSet.Select(z => $"{z:0000}")); for (int i = 0; i < newConst.Length; i++) { if (oldConst[i] != newConst[i]) { result.Add($"{i}: {oldConst[i]}->{newConst[i]}"); } } if (result.Count == 0) { WinFormsUtil.Alert("No Event Constant diff found."); return; } if (DialogResult.Yes == WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Copy Event Constant diff to clipboard?")) { Clipboard.SetText(string.Join(Environment.NewLine, result)); } }
private void DiffSaves() { if (!File.Exists(TB_OldSAV.Text)) { WinFormsUtil.Alert("Save 1 path invalid."); return; } if (!File.Exists(TB_NewSAV.Text)) { WinFormsUtil.Alert("Save 2 path invalid."); return; } if (new FileInfo(TB_OldSAV.Text).Length > 0x100000) { WinFormsUtil.Alert("Save 1 file invalid."); return; } if (new FileInfo(TB_NewSAV.Text).Length > 0x100000) { WinFormsUtil.Alert("Save 2 file invalid."); return; } SaveFile s1 = SaveUtil.GetVariantSAV(File.ReadAllBytes(TB_OldSAV.Text)); SaveFile s2 = SaveUtil.GetVariantSAV(File.ReadAllBytes(TB_NewSAV.Text)); if (s1 == null) { WinFormsUtil.Alert("Save 1 file invalid."); return; } if (s2 == null) { WinFormsUtil.Alert("Save 2 file invalid."); return; } if (s1.GetType() != s2.GetType()) { WinFormsUtil.Alert("Save types are different.", $"S1: {s1.GetType().Name}", $"S2: {s2.GetType().Name}"); return; } if (s1.Version != s2.Version) { WinFormsUtil.Alert("Save versions are different.", $"S1: {s1.Version}", $"S2: {s2.Version}"); return; } string tbIsSet = ""; string tbUnSet = ""; try { bool[] oldBits = s1.EventFlags; bool[] newBits = s2.EventFlags; if (oldBits.Length != newBits.Length) { WinFormsUtil.Alert("Event flag lengths for games are different.", $"S1: {(GameVersion)s1.Game}", $"S2: {(GameVersion)s2.Game}"); return; } for (int i = 0; i < oldBits.Length; i++) { if (oldBits[i] == newBits[i]) { continue; } if (newBits[i]) { tbIsSet += $"{i:0000},"; } else { tbUnSet += $"{i:0000},"; } } } catch (Exception e) { WinFormsUtil.Error("An unexpected error has occurred.", e); Debug.WriteLine(e); } TB_IsSet.Text = tbIsSet; TB_UnSet.Text = tbUnSet; string r = ""; try { ushort[] oldConst = s1.EventConsts; ushort[] newConst = s2.EventConsts; if (oldConst.Length != newConst.Length) { WinFormsUtil.Alert("Event flag lengths for games are different.", $"S1: {(GameVersion)s1.Game}", $"S2: {(GameVersion)s2.Game}"); return; } for (int i = 0; i < newConst.Length; i++) { if (oldConst[i] != newConst[i]) { r += $"{i}: {oldConst[i]}->{newConst[i]}{Environment.NewLine}"; } } } catch (Exception e) { WinFormsUtil.Error("An unexpected error has occurred.", e); Debug.WriteLine(e); } if (string.IsNullOrEmpty(r)) { WinFormsUtil.Alert("No Event Constant diff found."); return; } if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Copy Event Constant diff to clipboard?")) { return; } Clipboard.SetText(r); }
public static bool IsFileTooSmall(long length) => length < 0x20; // bigger than PK1 /// <summary> /// Tries to get an <see cref="SaveFile"/> object from the input parameters. /// </summary> /// <param name="data">Binary data</param> /// <param name="sav">Output result</param> /// <returns>True if file object reference is valid, false if none found.</returns> public static bool TryGetSAV(byte[] data, [NotNullWhen(true)] out SaveFile?sav) { sav = SaveUtil.GetVariantSAV(data); return(sav != null); }
public SAV_Database(PKMEditor f1, SAVEditor saveditor) { SAV = saveditor.SAV; BoxView = saveditor; PKME_Tabs = f1; InitializeComponent(); // Preset Filters to only show PKM available for loaded save CB_FormatComparator.SelectedIndex = 3; // <= PKXBOXES = new[] { bpkx1, bpkx2, bpkx3, bpkx4, bpkx5, bpkx6, bpkx7, bpkx8, bpkx9, bpkx10, bpkx11, bpkx12, bpkx13, bpkx14, bpkx15, bpkx16, bpkx17, bpkx18, bpkx19, bpkx20, bpkx21, bpkx22, bpkx23, bpkx24, bpkx25, bpkx26, bpkx27, bpkx28, bpkx29, bpkx30, bpkx31, bpkx32, bpkx33, bpkx34, bpkx35, bpkx36, bpkx37, bpkx38, bpkx39, bpkx40, bpkx41, bpkx42, bpkx43, bpkx44, bpkx45, bpkx46, bpkx47, bpkx48, bpkx49, bpkx50, bpkx51, bpkx52, bpkx53, bpkx54, bpkx55, bpkx56, bpkx57, bpkx58, bpkx59, bpkx60, bpkx61, bpkx62, bpkx63, bpkx64, bpkx65, bpkx66, }; // Enable Scrolling when hovered over PAN_Box.MouseWheel += (sender, e) => { if (ActiveForm == this) { SCR_Box.Focus(); } }; foreach (var slot in PKXBOXES) { slot.MouseWheel += (sender, e) => { if (ActiveForm == this) { SCR_Box.Focus(); } }; // Enable Click slot.MouseClick += (sender, e) => { if (ModifierKeys == Keys.Control) { ClickView(sender, e); } else if (ModifierKeys == Keys.Alt) { ClickDelete(sender, e); } else if (ModifierKeys == Keys.Shift) { ClickSet(sender, e); } }; } Counter = L_Count.Text; Viewed = L_Viewed.Text; L_Viewed.Text = ""; // invis for now var hover = new ToolTip(); L_Viewed.MouseEnter += (sender, e) => hover.SetToolTip(L_Viewed, L_Viewed.Text); PopulateComboBoxes(); ContextMenuStrip mnu = new ContextMenuStrip(); ToolStripMenuItem mnuView = new ToolStripMenuItem("View"); ToolStripMenuItem mnuDelete = new ToolStripMenuItem("Delete"); // Assign event handlers mnuView.Click += ClickView; mnuDelete.Click += ClickDelete; // Add to main context menu mnu.Items.AddRange(new ToolStripItem[] { mnuView, mnuDelete }); // Assign to datagridview foreach (PictureBox p in PKXBOXES) { p.ContextMenuStrip = mnu; } // Load Data var dbTemp = new ConcurrentBag <PKM>(); var files = Directory.GetFiles(DatabasePath, "*", SearchOption.AllDirectories); Parallel.ForEach(files, file => { FileInfo fi = new FileInfo(file); if (!fi.Extension.Contains(".pk") || !PKX.IsPKM(fi.Length)) { return; } var pk = PKMConverter.GetPKMfromBytes(File.ReadAllBytes(file), file, prefer: (fi.Extension.Last() - 0x30) & 7); if (pk != null) { dbTemp.Add(pk); } }); #if DEBUG if (SaveUtil.GetSavesFromFolder(Main.BackupPath, false, out IEnumerable <string> result)) { Parallel.ForEach(result, file => { var sav = SaveUtil.GetVariantSAV(File.ReadAllBytes(file)); var path = EXTERNAL_SAV + new FileInfo(file).Name; if (sav.HasBox) { foreach (var pk in sav.BoxData) { addPKM(pk); } } void addPKM(PKM pk) { pk.Identifier = Path.Combine(path, pk.Identifier); dbTemp.Add(pk); } }); } #endif // Prepare Database RawDB = new List <PKM>(dbTemp.OrderBy(pk => pk.Identifier) .Concat(SAV.BoxData.Where(pk => pk.Species != 0)) // Fetch from save file .Where(pk => pk.ChecksumValid && pk.Species != 0 && pk.Sanity == 0) .Distinct()); SetResults(RawDB); Menu_SearchSettings.DropDown.Closing += (sender, e) => { if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked) { e.Cancel = true; } }; CenterToParent(); }