diff --git a/PKHeX.csproj b/PKHeX.csproj
index 3185a2d23..5ff4cf2e0 100644
--- a/PKHeX.csproj
+++ b/PKHeX.csproj
@@ -254,7 +254,13 @@
SplashScreen.cs
-
+
+
+
+
+
+
+
QR.cs
Designer
diff --git a/Util/DataUtil.cs b/Util/DataUtil.cs
new file mode 100644
index 000000000..cc661a774
--- /dev/null
+++ b/Util/DataUtil.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace PKHeX
+{
+ public partial class Util
+ {
+ internal static string[] getStringList(string f)
+ {
+ object txt = Properties.Resources.ResourceManager.GetObject(f); // Fetch File, \n to list.
+ if (txt == null) return new string[0];
+ string[] rawlist = ((string)txt).Split('\n');
+ for (int i = 0; i < rawlist.Length; i++)
+ rawlist[i] = rawlist[i].Trim();
+ return rawlist;
+ }
+ internal static string[] getStringList(string f, string l)
+ {
+ object txt = Properties.Resources.ResourceManager.GetObject("text_" + f + "_" + l); // Fetch File, \n to list.
+ if (txt == null) return new string[0];
+ string[] rawlist = ((string)txt).Split('\n');
+ for (int i = 0; i < rawlist.Length; i++)
+ rawlist[i] = rawlist[i].Trim();
+ return rawlist;
+ }
+ internal static string[] getNulledStringArray(string[] SimpleStringList)
+ {
+ try
+ {
+ string[] newlist = new string[Util.ToInt32(SimpleStringList[SimpleStringList.Length - 1].Split(',')[0]) + 1];
+ for (int i = 1; i < SimpleStringList.Length; i++)
+ newlist[Util.ToInt32(SimpleStringList[i].Split(',')[0])] = SimpleStringList[i].Split(',')[1];
+ return newlist;
+ }
+ catch { return null; }
+ }
+
+ // DataSource Providing
+ internal static List getCBList(string textfile, string lang)
+ {
+ // Set up
+ string[] inputCSV = getStringList(textfile);
+
+ // Get Language we're fetching for
+ int index = Array.IndexOf(new[] { "ja", "en", "fr", "de", "it", "es", "ko", "zh", }, lang);
+
+ // Set up our Temporary Storage
+ string[] unsortedList = new string[inputCSV.Length - 1];
+ int[] indexes = new int[inputCSV.Length - 1];
+
+ // Gather our data from the input file
+ for (int i = 1; i < inputCSV.Length; i++)
+ {
+ string[] countryData = inputCSV[i].Split(',');
+ indexes[i - 1] = Convert.ToInt32(countryData[0]);
+ unsortedList[i - 1] = countryData[index + 1];
+ }
+
+ // Sort our input data
+ string[] sortedList = new string[inputCSV.Length - 1];
+ Array.Copy(unsortedList, sortedList, unsortedList.Length);
+ Array.Sort(sortedList);
+
+ // Arrange the input data based on original number
+ return sortedList.Select(s => new cbItem
+ {
+ Text = s,
+ Value = indexes[Array.IndexOf(unsortedList, s)]
+ }).ToList();
+ }
+ internal static List getCBList(string[] inStrings, params int[][] allowed)
+ {
+ List cbList = new List();
+ if (allowed?.First() == null)
+ allowed = new[] { Enumerable.Range(0, inStrings.Length).ToArray() };
+
+ foreach (int[] list in allowed)
+ {
+ // Sort the Rest based on String Name
+ string[] unsortedChoices = new string[list.Length];
+ for (int i = 0; i < list.Length; i++)
+ unsortedChoices[i] = inStrings[list[i]];
+
+ string[] sortedChoices = new string[unsortedChoices.Length];
+ Array.Copy(unsortedChoices, sortedChoices, unsortedChoices.Length);
+ Array.Sort(sortedChoices);
+
+ // Add the rest of the items
+ cbList.AddRange(sortedChoices.Select(s => new cbItem
+ {
+ Text = s,
+ Value = list[Array.IndexOf(unsortedChoices, s)]
+ }));
+ }
+ return cbList;
+ }
+ internal static List getOffsetCBList(List cbList, string[] inStrings, int offset, int[] allowed)
+ {
+ if (allowed == null)
+ allowed = Enumerable.Range(0, inStrings.Length).ToArray();
+
+ int[] list = (int[])allowed.Clone();
+ for (int i = 0; i < list.Length; i++)
+ list[i] -= offset;
+
+ // Sort the Rest based on String Name
+ string[] unsortedChoices = new string[allowed.Length];
+ for (int i = 0; i < allowed.Length; i++)
+ unsortedChoices[i] = inStrings[list[i]];
+
+ string[] sortedChoices = new string[unsortedChoices.Length];
+ Array.Copy(unsortedChoices, sortedChoices, unsortedChoices.Length);
+ Array.Sort(sortedChoices);
+
+ // Add the rest of the items
+ cbList.AddRange(sortedChoices.Select(s => new cbItem
+ {
+ Text = s,
+ Value = allowed[Array.IndexOf(unsortedChoices, s)]
+ }));
+ return cbList;
+ }
+ internal static List getVariedCBList(string[] inStrings, int[] stringNum, int[] stringVal)
+ {
+ // Set up
+ List newlist = new List();
+
+ for (int i = 4; i > 1; i--) // add 4,3,2
+ {
+ // First 3 Balls are always first
+ cbItem ncbi = new cbItem
+ {
+ Text = inStrings[i],
+ Value = i
+ };
+ newlist.Add(ncbi);
+ }
+
+ // Sort the Rest based on String Name
+ string[] ballnames = new string[stringNum.Length];
+ for (int i = 0; i < stringNum.Length; i++)
+ ballnames[i] = inStrings[stringNum[i]];
+
+ string[] sortedballs = new string[stringNum.Length];
+ Array.Copy(ballnames, sortedballs, ballnames.Length);
+ Array.Sort(sortedballs);
+
+ // Add the rest of the balls
+ newlist.AddRange(sortedballs.Select(s => new cbItem
+ {
+ Text = s,
+ Value = stringVal[Array.IndexOf(ballnames, s)]
+ }));
+ return newlist;
+ }
+ internal static List getUnsortedCBList(string textfile)
+ {
+ // Set up
+ List cbList = new List();
+ string[] inputCSV = getStringList(textfile);
+
+ // Gather our data from the input file
+ for (int i = 1; i < inputCSV.Length; i++)
+ {
+ string[] inputData = inputCSV[i].Split(',');
+ cbItem ncbi = new cbItem
+ {
+ Text = inputData[1],
+ Value = Convert.ToInt32(inputData[0])
+ };
+ cbList.Add(ncbi);
+ }
+ return cbList;
+ }
+ }
+}
diff --git a/Util/FormUtil.cs b/Util/FormUtil.cs
new file mode 100644
index 000000000..f09b2a867
--- /dev/null
+++ b/Util/FormUtil.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace PKHeX
+{
+ public partial class Util
+ {
+ // Form Translation
+ internal static void TranslateInterface(Control form, string lang)
+ {
+ // Check to see if a the translation file exists in the same folder as the executable
+ string externalLangPath = "lang_" + lang + ".txt";
+ string[] rawlist;
+ if (File.Exists(externalLangPath))
+ rawlist = File.ReadAllLines(externalLangPath);
+ else
+ {
+ object txt = Properties.Resources.ResourceManager.GetObject("lang_" + lang);
+ if (txt == null) return; // Translation file does not exist as a resource; abort this function and don't translate UI.
+ rawlist = ((string)txt).Split(new[] { "\n" }, StringSplitOptions.None);
+ rawlist = rawlist.Select(i => i.Trim()).ToArray(); // Remove trailing spaces
+ }
+
+ List stringdata = new List();
+ int start = -1;
+ for (int i = 0; i < rawlist.Length; i++)
+ {
+ // Find our starting point
+ if (!rawlist[i].Contains("! " + form.Name)) continue;
+ start = i;
+ break;
+ }
+ if (start < 0)
+ return;
+
+ // Rename Window Title
+ string[] WindowName = rawlist[start].Split(new[] { " = " }, StringSplitOptions.None);
+ if (WindowName.Length > 1) form.Text = WindowName[1];
+
+ // Fetch controls to rename
+ for (int i = start + 1; i < rawlist.Length; i++)
+ {
+ if (rawlist[i].Length == 0) continue; // Skip Over Empty Lines, errhandled
+ if (rawlist[i][0] == '-') continue; // Keep translating if line is a comment line
+ if (rawlist[i][0] == '!') // Stop if we have reached the end of translation
+ break;
+ stringdata.Add(rawlist[i]); // Add the entry to process later.
+ }
+
+ if (stringdata.Count == 0)
+ return;
+
+ // Find control then change display Text.
+ foreach (string str in stringdata)
+ {
+ string[] SplitString = str.Split(new[] { " = " }, StringSplitOptions.None);
+ if (SplitString.Length < 2)
+ continue;
+
+ object c = FindControl(SplitString[0], form.Controls); // Find control within Form's controls
+ if (c == null) // Not found
+ continue;
+
+ string text = SplitString[1]; // Text to set Control.Text to...
+
+ if (c is Control)
+ (c as Control).Text = text;
+ else if (c is ToolStripItem)
+ (c as ToolStripItem).Text = text;
+ }
+ }
+ private static object FindControl(string name, Control.ControlCollection c)
+ {
+ Control control = c.Find(name, true).FirstOrDefault();
+ if (control != null)
+ return control;
+ foreach (MenuStrip menu in c.OfType())
+ {
+ var item = menu.Items.Find(name, true).FirstOrDefault();
+ if (item != null)
+ return item;
+ }
+ foreach (ContextMenuStrip strip in FindContextMenuStrips(c.OfType()))
+ {
+ var item = strip.Items.Find(name, true).FirstOrDefault();
+ if (item != null)
+ return item;
+ }
+ return null;
+ }
+ private static List FindContextMenuStrips(IEnumerable c)
+ {
+ List cs = new List();
+ foreach (Control control in c)
+ {
+ if (control.ContextMenuStrip != null)
+ cs.Add(control.ContextMenuStrip);
+
+ else if (control.Controls.Count > 0)
+ cs.AddRange(FindContextMenuStrips(control.Controls.OfType()));
+ }
+ return cs;
+ }
+ internal static void CenterToForm(Control child, Control parent)
+ {
+ int x = parent.Location.X + (parent.Width - child.Width) / 2;
+ int y = parent.Location.Y + (parent.Height - child.Height) / 2;
+ child.Location = new Point(Math.Max(x, 0), Math.Max(y, 0));
+ }
+
+ // Message Displays
+ internal static DialogResult Error(params string[] lines)
+ {
+ System.Media.SystemSounds.Exclamation.Play();
+ string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
+ return MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ internal static DialogResult Alert(params string[] lines)
+ {
+ System.Media.SystemSounds.Asterisk.Play();
+ string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
+ return MessageBox.Show(msg, "Alert", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ }
+ internal static DialogResult Prompt(MessageBoxButtons btn, params string[] lines)
+ {
+ System.Media.SystemSounds.Question.Play();
+ string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
+ return MessageBox.Show(msg, "Prompt", btn, MessageBoxIcon.Asterisk);
+ }
+
+ internal static int getIndex(ComboBox cb)
+ {
+ return (int)(cb?.SelectedValue ?? 0);
+ }
+ }
+}
diff --git a/Util/ImageUtil.cs b/Util/ImageUtil.cs
new file mode 100644
index 000000000..cf6db53bf
--- /dev/null
+++ b/Util/ImageUtil.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Runtime.InteropServices;
+
+namespace PKHeX
+{
+ public partial class Util
+ {
+ // Image Layering/Blending Utility
+ internal static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y, double trans)
+ {
+ Bitmap img = new Bitmap(baseLayer.Width, baseLayer.Height);
+ using (Graphics gr = Graphics.FromImage(img))
+ {
+ gr.DrawImage(baseLayer, new Point(0, 0));
+ Bitmap o = ChangeOpacity(overLayer, trans);
+ gr.DrawImage(o, new Rectangle(x, y, overLayer.Width, overLayer.Height));
+ }
+ return img;
+ }
+ internal static Bitmap ChangeOpacity(Image img, double trans)
+ {
+ if (img == null)
+ return null;
+ if (img.PixelFormat.HasFlag(PixelFormat.Indexed))
+ return (Bitmap)img;
+
+ Bitmap bmp = (Bitmap)img.Clone();
+ BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
+ IntPtr ptr = bmpData.Scan0;
+
+ int len = bmp.Width * bmp.Height * 4;
+ byte[] data = new byte[len];
+
+ Marshal.Copy(ptr, data, 0, len);
+
+ for (int i = 0; i < data.Length; i += 4)
+ data[i + 3] = (byte)(data[i + 3] * trans);
+
+ Marshal.Copy(data, 0, ptr, len);
+ bmp.UnlockBits(bmpData);
+
+ return bmp;
+ }
+ }
+}
diff --git a/Util/PathUtil.cs b/Util/PathUtil.cs
new file mode 100644
index 000000000..741f16d21
--- /dev/null
+++ b/Util/PathUtil.cs
@@ -0,0 +1,107 @@
+using System;
+using System.IO;
+using System.Linq;
+
+namespace PKHeX
+{
+ public partial class Util
+ {
+ internal static string NormalizePath(string path)
+ {
+ return Path.GetFullPath(new Uri(path).LocalPath)
+ .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ }
+ internal static string GetTempFolder()
+ {
+ return Path.Combine(Path.GetTempPath(), "3DSSE");
+ }
+ internal static string GetCacheFolder()
+ {
+ return Path.Combine(GetBackupLocation(), "cache");
+ }
+ internal static string GetRegistryValue(string key)
+ {
+ Microsoft.Win32.RegistryKey currentUser = Microsoft.Win32.Registry.CurrentUser;
+ Microsoft.Win32.RegistryKey key3 = currentUser.OpenSubKey(GetRegistryBase());
+ if (key3 == null)
+ return null;
+
+ string str = key3.GetValue(key) as string;
+ key3.Close();
+ currentUser.Close();
+ return str;
+ }
+ internal static string GetRegistryBase()
+ {
+ return @"SOFTWARE\CYBER Gadget\3DSSaveEditor";
+ }
+ internal static string GetBackupLocation()
+ {
+ string registryValue = GetRegistryValue("Location");
+ if (!string.IsNullOrEmpty(registryValue))
+ {
+ Directory.CreateDirectory(registryValue);
+ return registryValue;
+ }
+ string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "3DSSaveBank");
+ Directory.CreateDirectory(path);
+ return path;
+ }
+ internal static string get3DSLocation()
+ {
+ try
+ {
+ string[] DriveList = Environment.GetLogicalDrives();
+ for (int i = 1; i < DriveList.Length; i++) // Skip first drive (some users still have floppy drives and would chew up time!)
+ {
+ string potentialPath = Path.Combine(DriveList[i], "Nintendo 3DS");
+ if (Directory.Exists(potentialPath))
+ return potentialPath;
+ }
+ }
+ catch { }
+ return null;
+ }
+ internal static string GetSDFLocation()
+ {
+ try
+ {
+ // Start by checking if the 3DS file path exists or not.
+ string path_SDF = null;
+ string[] DriveList = Environment.GetLogicalDrives();
+ for (int i = 1; i < DriveList.Length; i++) // Skip first drive (some users still have floppy drives and would chew up time!)
+ {
+ string potentialPath_SDF = NormalizePath(Path.Combine(DriveList[i], "filer", "UserSaveData"));
+ if (!Directory.Exists(potentialPath_SDF)) continue;
+
+ path_SDF = potentialPath_SDF; break;
+ }
+ if (path_SDF == null)
+ return null;
+ // 3DS data found in SD card reader. Let's get the title folder location!
+ string[] folders = Directory.GetDirectories(path_SDF, "*", SearchOption.TopDirectoryOnly);
+ Array.Sort(folders); // Don't need Modified Date, sort by path names just in case.
+
+ // Loop through all the folders in the Nintendo 3DS folder to see if any of them contain 'title'.
+ for (int i = folders.Length - 1; i >= 0; i--)
+ {
+ if (File.Exists(Path.Combine(folders[i], "000011c4", "main"))) return Path.Combine(folders[i], "000011c4"); // OR
+ if (File.Exists(Path.Combine(folders[i], "000011c5", "main"))) return Path.Combine(folders[i], "000011c5"); // AS
+ if (File.Exists(Path.Combine(folders[i], "0000055d", "main"))) return Path.Combine(folders[i], "0000055d"); // X
+ if (File.Exists(Path.Combine(folders[i], "0000055e", "main"))) return Path.Combine(folders[i], "0000055e"); // Y
+ }
+ return null; // Fallthrough
+ }
+ catch { return null; }
+ }
+ internal static string CleanFileName(string fileName)
+ {
+ return Path.GetInvalidFileNameChars().Aggregate(fileName, (current, c) => current.Replace(c.ToString(), string.Empty));
+ }
+ internal static string TrimFromZero(string input)
+ {
+ int index = input.IndexOf('\0');
+ return index < 0 ? input : input.Substring(0, index);
+ }
+ }
+}
diff --git a/Util/RandUtil.cs b/Util/RandUtil.cs
new file mode 100644
index 000000000..0ce40a0c9
--- /dev/null
+++ b/Util/RandUtil.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace PKHeX
+{
+ public partial class Util
+ {
+ internal static readonly Random rand = new Random();
+ internal static uint rnd32()
+ {
+ return (uint)rand.Next(1 << 30) << 2 | (uint)rand.Next(1 << 2);
+ }
+ internal static void Shuffle(T[] array)
+ {
+ int n = array.Length;
+ for (int i = 0; i < n; i++)
+ {
+ int r = i + (int)(rand.NextDouble() * (n - i));
+ T t = array[r];
+ array[r] = array[i];
+ array[i] = t;
+ }
+ }
+ }
+}
diff --git a/Util/StringUtil.cs b/Util/StringUtil.cs
new file mode 100644
index 000000000..0fb9dc8b3
--- /dev/null
+++ b/Util/StringUtil.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Linq;
+
+namespace PKHeX
+{
+ public partial class Util
+ {
+ internal static int ToInt32(string value)
+ {
+ string val = value?.Replace(" ", "").Replace("_", "").Trim();
+ return String.IsNullOrWhiteSpace(val) ? 0 : Int32.Parse(val);
+ }
+
+ internal static uint ToUInt32(string value)
+ {
+ string val = value?.Replace(" ", "").Replace("_", "").Trim();
+ return String.IsNullOrWhiteSpace(val) ? 0 : UInt32.Parse(val);
+ }
+
+ internal static uint getHEXval(string s)
+ {
+ string str = getOnlyHex(s);
+ return String.IsNullOrWhiteSpace(str) ? 0 : Convert.ToUInt32(str, 16);
+ }
+
+ internal static string getOnlyHex(string s)
+ {
+ return String.IsNullOrWhiteSpace(s) ? "0" : s.Select(Char.ToUpper).Where("0123456789ABCDEF".Contains).Aggregate("", (str, c) => str + c);
+ }
+ }
+}
diff --git a/Util/Util.cs b/Util/Util.cs
deleted file mode 100644
index 04d52df11..000000000
--- a/Util/Util.cs
+++ /dev/null
@@ -1,489 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.Linq;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Windows.Forms;
-
-namespace PKHeX
-{
- public class Util
- {
- // Image Layering/Blending Utility
- internal static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y, double trans)
- {
- Bitmap img = new Bitmap(baseLayer.Width, baseLayer.Height);
- using (Graphics gr = Graphics.FromImage(img))
- {
- gr.DrawImage(baseLayer, new Point(0, 0));
- Bitmap o = ChangeOpacity(overLayer, trans);
- gr.DrawImage(o, new Rectangle(x, y, overLayer.Width, overLayer.Height));
- }
- return img;
- }
- internal static Bitmap ChangeOpacity(Image img, double trans)
- {
- if (img == null)
- return null;
- if (img.PixelFormat.HasFlag(PixelFormat.Indexed))
- return (Bitmap)img;
-
- Bitmap bmp = (Bitmap)img.Clone();
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
- IntPtr ptr = bmpData.Scan0;
-
- int len = bmp.Width*bmp.Height*4;
- byte[] data = new byte[len];
-
- Marshal.Copy(ptr, data, 0, len);
-
- for (int i = 0; i < data.Length; i += 4)
- data[i + 3] = (byte)(data[i + 3] * trans);
-
- Marshal.Copy(data, 0, ptr, len);
- bmp.UnlockBits(bmpData);
-
- return bmp;
- }
-
- // Strings and Paths
- internal static string NormalizePath(string path)
- {
- return Path.GetFullPath(new Uri(path).LocalPath)
- .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
- }
- internal static string GetTempFolder()
- {
- return Path.Combine(Path.GetTempPath(), "3DSSE");
- }
- internal static string GetCacheFolder()
- {
- return Path.Combine(GetBackupLocation(), "cache");
- }
- internal static string GetRegistryValue(string key)
- {
- Microsoft.Win32.RegistryKey currentUser = Microsoft.Win32.Registry.CurrentUser;
- Microsoft.Win32.RegistryKey key3 = currentUser.OpenSubKey(GetRegistryBase());
- if (key3 == null)
- return null;
-
- string str = key3.GetValue(key) as string;
- key3.Close();
- currentUser.Close();
- return str;
- }
- internal static string GetRegistryBase()
- {
- return @"SOFTWARE\CYBER Gadget\3DSSaveEditor";
- }
- internal static string GetBackupLocation()
- {
- string registryValue = GetRegistryValue("Location");
- if (!string.IsNullOrEmpty(registryValue))
- {
- Directory.CreateDirectory(registryValue);
- return registryValue;
- }
- string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "3DSSaveBank");
- Directory.CreateDirectory(path);
- return path;
- }
- internal static string get3DSLocation()
- {
- try
- {
- string[] DriveList = Environment.GetLogicalDrives();
- for (int i = 1; i < DriveList.Length; i++) // Skip first drive (some users still have floppy drives and would chew up time!)
- {
- string potentialPath = Path.Combine(DriveList[i], "Nintendo 3DS");
- if (Directory.Exists(potentialPath))
- return potentialPath;
- }
- }
- catch { }
- return null;
- }
- internal static string GetSDFLocation()
- {
- try
- {
- // Start by checking if the 3DS file path exists or not.
- string path_SDF = null;
- string[] DriveList = Environment.GetLogicalDrives();
- for (int i = 1; i < DriveList.Length; i++) // Skip first drive (some users still have floppy drives and would chew up time!)
- {
- string potentialPath_SDF = NormalizePath(Path.Combine(DriveList[i], "filer", "UserSaveData"));
- if (!Directory.Exists(potentialPath_SDF)) continue;
-
- path_SDF = potentialPath_SDF; break;
- }
- if (path_SDF == null)
- return null;
- // 3DS data found in SD card reader. Let's get the title folder location!
- string[] folders = Directory.GetDirectories(path_SDF, "*", SearchOption.TopDirectoryOnly);
- Array.Sort(folders); // Don't need Modified Date, sort by path names just in case.
-
- // Loop through all the folders in the Nintendo 3DS folder to see if any of them contain 'title'.
- for (int i = folders.Length - 1; i >= 0; i--)
- {
- if (File.Exists(Path.Combine(folders[i], "000011c4", "main"))) return Path.Combine(folders[i], "000011c4"); // OR
- if (File.Exists(Path.Combine(folders[i], "000011c5", "main"))) return Path.Combine(folders[i], "000011c5"); // AS
- if (File.Exists(Path.Combine(folders[i], "0000055d", "main"))) return Path.Combine(folders[i], "0000055d"); // X
- if (File.Exists(Path.Combine(folders[i], "0000055e", "main"))) return Path.Combine(folders[i], "0000055e"); // Y
- }
- return null; // Fallthrough
- }
- catch { return null; }
- }
- internal static string CleanFileName(string fileName)
- {
- return Path.GetInvalidFileNameChars().Aggregate(fileName, (current, c) => current.Replace(c.ToString(), string.Empty));
- }
- internal static string TrimFromZero(string input)
- {
- int index = input.IndexOf('\0');
- return index < 0 ? input : input.Substring(0, index);
- }
- internal static string[] getStringList(string f)
- {
- object txt = Properties.Resources.ResourceManager.GetObject(f); // Fetch File, \n to list.
- if (txt == null) return new string[0];
- string[] rawlist = ((string)txt).Split('\n');
- for (int i = 0; i < rawlist.Length; i++)
- rawlist[i] = rawlist[i].Trim();
- return rawlist;
- }
- internal static string[] getStringList(string f, string l)
- {
- object txt = Properties.Resources.ResourceManager.GetObject("text_" + f + "_" + l); // Fetch File, \n to list.
- if (txt == null) return new string[0];
- string[] rawlist = ((string)txt).Split('\n');
- for (int i = 0; i < rawlist.Length; i++)
- rawlist[i] = rawlist[i].Trim();
- return rawlist;
- }
- internal static string[] getNulledStringArray(string[] SimpleStringList)
- {
- try
- {
- string[] newlist = new string[ToInt32(SimpleStringList[SimpleStringList.Length - 1].Split(',')[0]) + 1];
- for (int i = 1; i < SimpleStringList.Length; i++)
- newlist[ToInt32(SimpleStringList[i].Split(',')[0])] = SimpleStringList[i].Split(',')[1];
- return newlist;
- }
- catch { return null; }
- }
-
- // Randomization
- internal static readonly Random rand = new Random();
- internal static uint rnd32()
- {
- return (uint)rand.Next(1 << 30) << 2 | (uint)rand.Next(1 << 2);
- }
-
- // Data Retrieval
- internal static int ToInt32(string value)
- {
- string val = value?.Replace(" ", "").Replace("_", "").Trim();
- return string.IsNullOrWhiteSpace(val) ? 0 : int.Parse(val);
- }
- internal static uint ToUInt32(string value)
- {
- string val = value?.Replace(" ", "").Replace("_", "").Trim();
- return string.IsNullOrWhiteSpace(val) ? 0 : uint.Parse(val);
- }
- internal static uint getHEXval(string s)
- {
- string str = getOnlyHex(s);
- return string.IsNullOrWhiteSpace(str) ? 0 : Convert.ToUInt32(str, 16);
- }
- internal static int getIndex(ComboBox cb)
- {
- return (int)(cb?.SelectedValue ?? 0);
- }
- internal static string getOnlyHex(string s)
- {
- return string.IsNullOrWhiteSpace(s) ? "0" : s.Select(char.ToUpper).Where("0123456789ABCDEF".Contains).Aggregate("", (str, c) => str + c);
- }
-
- // Data Manipulation
- internal static void Shuffle(T[] array)
- {
- int n = array.Length;
- for (int i = 0; i < n; i++)
- {
- int r = i + (int)(rand.NextDouble() * (n - i));
- T t = array[r];
- array[r] = array[i];
- array[i] = t;
- }
- }
-
- // Form Translation
- internal static void TranslateInterface(Control form, string lang)
- {
- // Check to see if a the translation file exists in the same folder as the executable
- string externalLangPath = "lang_" + lang + ".txt";
- string[] rawlist;
- if (File.Exists(externalLangPath))
- rawlist = File.ReadAllLines(externalLangPath);
- else
- {
- object txt = Properties.Resources.ResourceManager.GetObject("lang_" + lang);
- if (txt == null) return; // Translation file does not exist as a resource; abort this function and don't translate UI.
- rawlist = ((string)txt).Split(new[] { "\n" }, StringSplitOptions.None);
- rawlist = rawlist.Select(i => i.Trim()).ToArray(); // Remove trailing spaces
- }
-
- List stringdata = new List();
- int start = -1;
- for (int i = 0; i < rawlist.Length; i++)
- {
- // Find our starting point
- if (!rawlist[i].Contains("! " + form.Name)) continue;
- start = i;
- break;
- }
- if (start < 0)
- return;
-
- // Rename Window Title
- string[] WindowName = rawlist[start].Split(new[] {" = "}, StringSplitOptions.None);
- if (WindowName.Length > 1) form.Text = WindowName[1];
-
- // Fetch controls to rename
- for (int i = start + 1; i < rawlist.Length; i++)
- {
- if (rawlist[i].Length == 0) continue; // Skip Over Empty Lines, errhandled
- if (rawlist[i][0] == '-') continue; // Keep translating if line is a comment line
- if (rawlist[i][0] == '!') // Stop if we have reached the end of translation
- break;
- stringdata.Add(rawlist[i]); // Add the entry to process later.
- }
-
- if (stringdata.Count == 0)
- return;
-
- // Find control then change display Text.
- foreach (string str in stringdata)
- {
- string[] SplitString = str.Split(new[] {" = "}, StringSplitOptions.None);
- if (SplitString.Length < 2)
- continue;
-
- object c = FindControl(SplitString[0], form.Controls); // Find control within Form's controls
- if (c == null) // Not found
- continue;
-
- string text = SplitString[1]; // Text to set Control.Text to...
-
- if (c is Control)
- (c as Control).Text = text;
- else if (c is ToolStripItem)
- (c as ToolStripItem).Text = text;
- }
- }
- private static object FindControl(string name, Control.ControlCollection c)
- {
- Control control = c.Find(name, true).FirstOrDefault();
- if (control != null)
- return control;
- foreach (MenuStrip menu in c.OfType())
- {
- var item = menu.Items.Find(name, true).FirstOrDefault();
- if (item != null)
- return item;
- }
- foreach (ContextMenuStrip strip in FindContextMenuStrips(c.OfType()))
- {
- var item = strip.Items.Find(name, true).FirstOrDefault();
- if (item != null)
- return item;
- }
- return null;
- }
- private static List FindContextMenuStrips(IEnumerable c)
- {
- List cs = new List();
- foreach (Control control in c)
- {
- if (control.ContextMenuStrip != null)
- cs.Add(control.ContextMenuStrip);
-
- else if (control.Controls.Count > 0)
- cs.AddRange(FindContextMenuStrips(control.Controls.OfType()));
- }
- return cs;
- }
- internal static void CenterToForm(Control child, Control parent)
- {
- int x = parent.Location.X + (parent.Width - child.Width) / 2;
- int y = parent.Location.Y + (parent.Height - child.Height) / 2;
- child.Location = new Point(Math.Max(x, 0), Math.Max(y, 0));
- }
-
- // Message Displays
- internal static DialogResult Error(params string[] lines)
- {
- System.Media.SystemSounds.Exclamation.Play();
- string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
- return MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- internal static DialogResult Alert(params string[] lines)
- {
- System.Media.SystemSounds.Asterisk.Play();
- string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
- return MessageBox.Show(msg, "Alert", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- }
- internal static DialogResult Prompt(MessageBoxButtons btn, params string[] lines)
- {
- System.Media.SystemSounds.Question.Play();
- string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
- return MessageBox.Show(msg, "Prompt", btn, MessageBoxIcon.Asterisk);
- }
-
- // DataSource Providing
- public class cbItem
- {
- public string Text { get; set; }
- public int Value { get; set; }
- }
- internal static List getCBList(string textfile, string lang)
- {
- // Set up
- string[] inputCSV = getStringList(textfile);
-
- // Get Language we're fetching for
- int index = Array.IndexOf(new[] { "ja", "en", "fr", "de", "it", "es", "ko", "zh", }, lang);
-
- // Set up our Temporary Storage
- string[] unsortedList = new string[inputCSV.Length - 1];
- int[] indexes = new int[inputCSV.Length - 1];
-
- // Gather our data from the input file
- for (int i = 1; i < inputCSV.Length; i++)
- {
- string[] countryData = inputCSV[i].Split(',');
- indexes[i - 1] = Convert.ToInt32(countryData[0]);
- unsortedList[i - 1] = countryData[index + 1];
- }
-
- // Sort our input data
- string[] sortedList = new string[inputCSV.Length - 1];
- Array.Copy(unsortedList, sortedList, unsortedList.Length);
- Array.Sort(sortedList);
-
- // Arrange the input data based on original number
- return sortedList.Select(s => new cbItem
- {
- Text = s,
- Value = indexes[Array.IndexOf(unsortedList, s)]
- }).ToList();
- }
- internal static List getCBList(string[] inStrings, params int[][] allowed)
- {
- List cbList = new List();
- if (allowed?.First() == null)
- allowed = new[] { Enumerable.Range(0, inStrings.Length).ToArray() };
-
- foreach (int[] list in allowed)
- {
- // Sort the Rest based on String Name
- string[] unsortedChoices = new string[list.Length];
- for (int i = 0; i < list.Length; i++)
- unsortedChoices[i] = inStrings[list[i]];
-
- string[] sortedChoices = new string[unsortedChoices.Length];
- Array.Copy(unsortedChoices, sortedChoices, unsortedChoices.Length);
- Array.Sort(sortedChoices);
-
- // Add the rest of the items
- cbList.AddRange(sortedChoices.Select(s => new cbItem
- {
- Text = s,
- Value = list[Array.IndexOf(unsortedChoices, s)]
- }));
- }
- return cbList;
- }
- internal static List getOffsetCBList(List cbList, string[] inStrings, int offset, int[] allowed)
- {
- if (allowed == null)
- allowed = Enumerable.Range(0, inStrings.Length).ToArray();
-
- int[] list = (int[])allowed.Clone();
- for (int i = 0; i < list.Length; i++)
- list[i] -= offset;
-
- // Sort the Rest based on String Name
- string[] unsortedChoices = new string[allowed.Length];
- for (int i = 0; i < allowed.Length; i++)
- unsortedChoices[i] = inStrings[list[i]];
-
- string[] sortedChoices = new string[unsortedChoices.Length];
- Array.Copy(unsortedChoices, sortedChoices, unsortedChoices.Length);
- Array.Sort(sortedChoices);
-
- // Add the rest of the items
- cbList.AddRange(sortedChoices.Select(s => new cbItem
- {
- Text = s, Value = allowed[Array.IndexOf(unsortedChoices, s)]
- }));
- return cbList;
- }
- internal static List getVariedCBList(string[] inStrings, int[] stringNum, int[] stringVal)
- {
- // Set up
- List newlist = new List();
-
- for (int i = 4; i > 1; i--) // add 4,3,2
- {
- // First 3 Balls are always first
- cbItem ncbi = new cbItem
- {
- Text = inStrings[i],
- Value = i
- };
- newlist.Add(ncbi);
- }
-
- // Sort the Rest based on String Name
- string[] ballnames = new string[stringNum.Length];
- for (int i = 0; i < stringNum.Length; i++)
- ballnames[i] = inStrings[stringNum[i]];
-
- string[] sortedballs = new string[stringNum.Length];
- Array.Copy(ballnames, sortedballs, ballnames.Length);
- Array.Sort(sortedballs);
-
- // Add the rest of the balls
- newlist.AddRange(sortedballs.Select(s => new cbItem
- {
- Text = s,
- Value = stringVal[Array.IndexOf(ballnames, s)]
- }));
- return newlist;
- }
- internal static List getUnsortedCBList(string textfile)
- {
- // Set up
- List cbList = new List();
- string[] inputCSV = getStringList(textfile);
-
- // Gather our data from the input file
- for (int i = 1; i < inputCSV.Length; i++)
- {
- string[] inputData = inputCSV[i].Split(',');
- cbItem ncbi = new cbItem
- {
- Text = inputData[1],
- Value = Convert.ToInt32(inputData[0])
- };
- cbList.Add(ncbi);
- }
- return cbList;
- }
- }
-}
\ No newline at end of file
diff --git a/Util/cbItem.cs b/Util/cbItem.cs
new file mode 100644
index 000000000..71b2a522c
--- /dev/null
+++ b/Util/cbItem.cs
@@ -0,0 +1,11 @@
+namespace PKHeX
+{
+ public partial class Util
+ {
+ public class cbItem
+ {
+ public string Text { get; set; }
+ public int Value { get; set; }
+ }
+ }
+}