diff --git a/FriishProduce/FriishProduce.csproj b/FriishProduce/FriishProduce.csproj index b4fb6a9d..599280a3 100644 --- a/FriishProduce/FriishProduce.csproj +++ b/FriishProduce/FriishProduce.csproj @@ -546,7 +546,6 @@ - diff --git a/FriishProduce/MainForm.cs b/FriishProduce/MainForm.cs index ec355f67..764e1e31 100644 --- a/FriishProduce/MainForm.cs +++ b/FriishProduce/MainForm.cs @@ -14,6 +14,7 @@ public partial class MainForm : Form { private readonly string[] files = null; private readonly SettingsForm settings = new(); + private Wait wait = new(false); #region //////////////////// Platforms //////////////////// public readonly IDictionary Icons = new Dictionary @@ -26,9 +27,7 @@ public partial class MainForm : Form { Platform.PCE, new Icon(Properties.Resources.nec_turbografx_16, 16, 16).ToBitmap() }, { Platform.PCECD, new Icon(Properties.Resources.nec_turbografx_16, 16, 16).ToBitmap() }, { Platform.NEO, new Icon(Properties.Resources.snk_neo_geo_aes, 16, 16).ToBitmap() }, -#if DEBUG { Platform.C64, Properties.Resources.c64 }, -#endif { Platform.MSX, Properties.Resources.msx }, { Platform.PSX, new Icon(Properties.Resources.sony_playstation, 16, 16).ToBitmap() }, { Platform.Flash, Properties.Resources.flash }, @@ -49,10 +48,8 @@ public partial class MainForm : Form null, Platform.NEO.ToString(), null, -#if DEBUG Platform.C64.ToString(), null, -#endif Platform.MSX.ToString(), null, Platform.Flash.ToString(), @@ -235,6 +232,70 @@ private void MainForm_Closing(object sender, FormClosingEventArgs e) } } + /// + /// Displays wait dialog. + /// + /// Resets the dialog. + /// Shows or hides the dialog. + /// The message to display. + /// Progress value + /// Whether to display the progress bar. + public void Wait(bool show, bool reset, bool showProgress, int progress = 0, int msg = 0) + { + if (InvokeRequired) + { + Invoke(new MethodInvoker(delegate + { + Enabled = !show; + + if (show) + { + if (reset || wait == null) + { + if (wait != null) wait.Visible = false; + wait = new(showProgress, msg) { Visible = false }; + } + + if (!wait.Visible) + wait.Show(this); + } + + else + { + if (wait != null) wait.Visible = false; + Select(); + } + + wait.progress.Value = progress; + })); + } + + else + { + Enabled = !show; + + if (show) + { + if (reset || wait == null) + { + if (wait != null) wait.Visible = false; + wait = new(showProgress, msg) { Visible = false }; + } + + if (!wait.Visible) + wait.Show(this); + } + + else + { + if (wait != null) wait.Visible = false; + Select(); + } + + wait.progress.Value = progress; + } + } + private void Settings_Click(object sender, EventArgs e) => settings.ShowDialog(this); public void TabChanged(object sender, EventArgs e) @@ -451,7 +512,7 @@ private void OpenRecent(object sender, EventArgs e) var control = sender as MenuItem; var list = open_recent.MenuItems.OfType().Where(x => x.Text == control?.Text).ToArray(); - if (list.Length > 1) + if (list?.Length > 0) { for (int i = 0; i < 10; i++) { @@ -469,7 +530,10 @@ private void OpenRecent(object sender, EventArgs e) 0 or _ => Program.Config.paths.recent_00 }; - if (Path.GetFileName(file)?.Replace("&", "&&") == list[0].Text) + string title1 = Path.GetFileName(file)?.Replace("&", "&&"); + string title2 = list[0].Text; + + if (title1 == title2) { OpenProject(new string[] { file }); return; diff --git a/FriishProduce/ProjectForm.cs b/FriishProduce/ProjectForm.cs index 811cddfe..1e45589a 100644 --- a/FriishProduce/ProjectForm.cs +++ b/FriishProduce/ProjectForm.cs @@ -18,7 +18,6 @@ public partial class ProjectForm : Form protected Platform targetPlatform { get; set; } private readonly BannerOptions banner_form; private readonly Savedata savedata; - private Wait wait = new(false); private HTMLForm htmlForm; protected string TIDCode; @@ -107,24 +106,6 @@ public bool IsEmpty } } - public void Wait(bool show, int msg = 0, bool showProgress = false) - { - Invoke(new MethodInvoker(delegate - { - if (!show) ParentForm.Select(); - - if (show) - { - wait = new(showProgress, msg); - wait.Show(this); - } - else - wait.Hide(); - - (ParentForm as MainForm).Enabled = Enabled = !show; - })); - } - public bool IsExportable { get @@ -354,23 +335,66 @@ private libWiiSharp.Region _bannerRegion // ----------------------------------- - private void SetRecentProjects(string path) + private void SetRecentProjects(string project) { - if (path != Program.Config.paths.recent_00) + int max = 10; + bool modified = false; + + // Add project to #1 slot + // ******** + if (project != Program.Config.paths.recent_00) { - Program.Config.paths.recent_09 = Program.Config.paths.recent_08; - Program.Config.paths.recent_08 = Program.Config.paths.recent_07; - Program.Config.paths.recent_07 = Program.Config.paths.recent_06; - Program.Config.paths.recent_06 = Program.Config.paths.recent_05; - Program.Config.paths.recent_05 = Program.Config.paths.recent_04; - Program.Config.paths.recent_04 = Program.Config.paths.recent_03; - Program.Config.paths.recent_03 = Program.Config.paths.recent_02; - Program.Config.paths.recent_02 = Program.Config.paths.recent_01; - Program.Config.paths.recent_01 = Program.Config.paths.recent_00; - Program.Config.paths.recent_00 = path; + for (int i = 0; i < max - 1; i++) + { + var prop1 = Program.Config.paths.GetType().GetProperty($"recent_{i:D2}"); + var prop2 = Program.Config.paths.GetType().GetProperty($"recent_{i + 1:D2}"); + prop2.SetValue(Program.Config.paths, prop1.GetValue(Program.Config.paths, null)); + } - Program.Config.Save(); + Program.Config.paths.recent_00 = project; + modified = true; + } + + // Clean duplicate projects if there are any + // ******** + for (int x = 0; x < max; x++) + { + var prop1 = Program.Config.paths.GetType().GetProperty($"recent_{x:D2}"); + var path1 = prop1.GetValue(Program.Config.paths, null)?.ToString(); + + for (int y = x; y < max; y++) + { + var prop2 = Program.Config.paths.GetType().GetProperty($"recent_{y:D2}"); + var path2 = prop2.GetValue(Program.Config.paths, null)?.ToString(); + + if (path1 == path2 && path2 != null && x != y) + { + prop2.SetValue(Program.Config.paths, null); + modified = true; + } + } + } + // Resort slots in case of empty ones + // ******** + for (int i = 0; i < max - 1; i++) + { + var prop1 = Program.Config.paths.GetType().GetProperty($"recent_{i:D2}"); + + if (prop1.GetValue(Program.Config.paths, null)?.ToString() == null) + { + var prop2 = Program.Config.paths.GetType().GetProperty($"recent_{i + 1:D2}"); + + prop1.SetValue(Program.Config.paths, prop2.GetValue(Program.Config.paths, null)); + prop2.SetValue(Program.Config.paths, null); + + modified = true; + } + } + + if (modified) + { + Program.Config.Save(); Program.MainForm.RefreshRecent(); } } @@ -1266,12 +1290,9 @@ public bool LoadWAD(string path) Failed: SystemSounds.Beep.Play(); - try - { - MessageBox.Show(string.Format(Program.Lang.Msg(5), Reader.UpperTitleID)); - Reader.Dispose(); - } - catch { Reader = null; } + MessageBox.Show(string.Format(Program.Lang.Msg(5), Reader.UpperTitleID == "\0\0\0\0" || Reader.UpperTitleID.Length != 4 ? Program.Lang.String("none") : Reader.UpperTitleID)); + + try { Reader.Dispose(); } catch { Reader = null; } inWadFile = null; return false; } @@ -1533,6 +1554,7 @@ public void LoadROM(string ROMpath, bool AutoScan = true, bool filter = false) /// Gets any game metadata that is available for the file based on its CRC32 reading hash, including the software title, year, players, and title image URL. /// /// + /// The ROM/ISO path. /// protected (string Name, string Serial, string Year, string Players, string Image, bool IsComplete) GetGameData(Platform platform, string path) { @@ -1548,6 +1570,10 @@ public void LoadROM(string ROMpath, bool AutoScan = true, bool filter = false) return (null, null, null, null, null, false); } + if (Databases.LibRetro.IsWeb(platform)) + Web.InternetTest(); + Program.MainForm.Wait(true, true, false); + var result = Databases.LibRetro.Read(path, platform); if (!string.IsNullOrEmpty(result.Name)) @@ -1563,8 +1589,6 @@ public async void GameScan(bool imageOnly) { if (rom == null || rom.FilePath == null) return; - Wait(true); - try { (string Name, string Serial, string Year, string Players, string Image, bool IsComplete) gameData = (null, null, null, null, null, false); @@ -1596,13 +1620,13 @@ public async void GameScan(bool imageOnly) // Set image if (!string.IsNullOrEmpty(gameData.Image)) { - LoadImage(gameData.Image); + await Task.Run(() => { LoadImage(gameData.Image); }); } resetImages(true); } - Wait(false); + Program.MainForm.Wait(false, false, false); // Show message if partially failed to retrieve data if (retrieved && !gameData.IsComplete && !imageOnly) @@ -1612,17 +1636,16 @@ public async void GameScan(bool imageOnly) catch (Exception ex) { - Wait(false); + Program.MainForm.Wait(false, false, false); MessageBox.Error(ex.Message); } } public void SaveToWAD(string targetFile = null) => backgroundWorker.RunWorkerAsync(targetFile); - private void saveToWAD_UpdateProgress(object sender, System.ComponentModel.ProgressChangedEventArgs e) => wait.progress.Value = e.ProgressPercentage; + private void saveToWAD_UpdateProgress(object sender, System.ComponentModel.ProgressChangedEventArgs e) => Program.MainForm.Wait(true, false, true, e.ProgressPercentage); private void saveToWAD(object sender, System.ComponentModel.DoWorkEventArgs e) { Exception error = null; - Wait(true, 1, true); string targetFile = e.Argument.ToString(); if (targetFile == null) targetFile = Paths.WorkingFolder + "out.wad"; @@ -1675,6 +1698,10 @@ private void saveToWAD(object sender, System.ComponentModel.DoWorkEventArgs e) Start: // Get WAD data // ******* + if (inWadFile == null) + Web.InternetTest(); + Program.MainForm.Wait(true, true, true, 0, 1); + if (inWadFile != null) m.GetWAD(inWadFile, baseID.Text); else { @@ -1747,7 +1774,7 @@ private void saveToWAD(object sender, System.ComponentModel.DoWorkEventArgs e) finally { - Wait(false); + Program.MainForm.Wait(false, false, false); Program.CleanTemp(); Invoke(new MethodInvoker(delegate diff --git a/FriishProduce/Strings/en.json b/FriishProduce/Strings/en.json index a76b0e4b..5a8268aa 100644 --- a/FriishProduce/Strings/en.json +++ b/FriishProduce/Strings/en.json @@ -21,6 +21,7 @@ "do_not_show": "Do not show this again", "busy0": "Please wait...", "busy1": "Exportation in progress...", + "busy2": "Testing Internet connection...", "by_default": "Default", "disabled": "Disabled", diff --git a/FriishProduce/Strings/es.json b/FriishProduce/Strings/es.json index 7a71856e..814086c8 100644 --- a/FriishProduce/Strings/es.json +++ b/FriishProduce/Strings/es.json @@ -21,6 +21,7 @@ "do_not_show": "No volver a mostrar este mensaje", "busy0": "Cargando...", "busy1": "Exportación en curso...", + "busy2": "Probando la conexión de Internet...", "by_default": "Por defecto", "disabled": "Deshabilitado(a)", diff --git a/FriishProduce/Strings/fr.json b/FriishProduce/Strings/fr.json index 8f168821..295bd4a6 100644 --- a/FriishProduce/Strings/fr.json +++ b/FriishProduce/Strings/fr.json @@ -21,6 +21,7 @@ "do_not_show": "Ne plus afficher ce message", "busy0": "Veuillez patienter ...", "busy1": "Exportation en cours ...", + "busy2": "Test de connexion en cours ...", "by_default": "Par défaut", "disabled": "Désactivé(e)", diff --git a/FriishProduce/Strings/ja.json b/FriishProduce/Strings/ja.json index ee44f4d9..53a0c451 100644 Binary files a/FriishProduce/Strings/ja.json and b/FriishProduce/Strings/ja.json differ diff --git a/FriishProduce/Strings/ko.json b/FriishProduce/Strings/ko.json index 95e08438..1be97101 100644 --- a/FriishProduce/Strings/ko.json +++ b/FriishProduce/Strings/ko.json @@ -21,6 +21,7 @@ "do_not_show": "다시 표시하지 않음", "busy0": "잠시만 기다리세요...", "busy1": "내보내기 진행 중...", + "busy2": "Testing Internet connection...", "by_default": "기본값", "disabled": "비활성화", diff --git a/FriishProduce/Subforms/Wait.cs b/FriishProduce/Subforms/Wait.cs index ffe00c03..8513ec91 100644 --- a/FriishProduce/Subforms/Wait.cs +++ b/FriishProduce/Subforms/Wait.cs @@ -23,7 +23,8 @@ public Wait(bool showProgress, int msg = 0) fader.Tick += Fade; fader.Start(); - label1.Font = Program.MainForm.Font; + if (Program.MainForm != null) + label1.Font = Program.MainForm.Font; label1.Text = Program.Lang.String($"busy{msg}"); progress.Visible = showProgress; diff --git a/FriishProduce/_classes/Creators/WiiVC/C64.cs b/FriishProduce/_classes/Creators/WiiVC/C64.cs index e434e1fb..d5070b03 100644 --- a/FriishProduce/_classes/Creators/WiiVC/C64.cs +++ b/FriishProduce/_classes/Creators/WiiVC/C64.cs @@ -72,6 +72,7 @@ protected override void ReplaceROM() switch (method) { + default: case MessageBox.Result.Button1: goto Frodo; @@ -103,13 +104,10 @@ protected override void ReplaceROM() } else goto Failed; - - default: - goto Failed; } Failed: - throw new Exception(Program.Lang.Msg(2, true)); + throw new OperationCanceledException(); Frodo: // Copy ROM diff --git a/FriishProduce/_classes/Databases/LibRetro.cs b/FriishProduce/_classes/Databases/LibRetro.cs index 7c29a1b6..3d7a2042 100644 --- a/FriishProduce/_classes/Databases/LibRetro.cs +++ b/FriishProduce/_classes/Databases/LibRetro.cs @@ -101,7 +101,7 @@ public static bool Exists(Platform In) { foreach (KeyValuePair item in list) { - if (item.Value == platform) + if (item.Value == In) { return true; } @@ -110,6 +110,31 @@ public static bool Exists(Platform In) return false; } + public static bool IsWeb(Platform In) + { + bool result = false; + + if (File.Exists(Path.Combine(Paths.Databases, In.ToString().ToLower() + ".xml"))) + return result; + + else + { + // Retrieve database from URL or file + // **************** + List db_lines = new(); + + for (int i = 0; i < 2; i++) + { + string url = db_url(i); + + if (!string.IsNullOrWhiteSpace(url) && !File.Exists(url)) + result = true; + } + } + + return result; + } + public static DataTable Parse(Platform In) { Top: @@ -155,7 +180,7 @@ public static DataTable Parse(Platform In) if (File.Exists(url)) db_lines.Add(File.ReadAllLines(url)); - else if (Web.InternetTest()) + else if (IsWeb(In)) { using (WebClient c = new WebClient()) { diff --git a/FriishProduce/_classes/Method.cs b/FriishProduce/_classes/Method.cs index 51350a90..96607f35 100644 --- a/FriishProduce/_classes/Method.cs +++ b/FriishProduce/_classes/Method.cs @@ -82,7 +82,6 @@ public void GetWAD(string path, string tid) { _progress.max += 1.0; - Web.InternetTest(); WAD = WAD.Load(Web.Get(path)); _updateProgress(); diff --git a/FriishProduce/_classes/Utilities.cs b/FriishProduce/_classes/Utilities.cs index d90da707..acb95cbf 100644 --- a/FriishProduce/_classes/Utilities.cs +++ b/FriishProduce/_classes/Utilities.cs @@ -67,7 +67,9 @@ public static class Web { public static bool InternetTest(string url = null) { - int timeout = 60; + Program.MainForm?.Wait(true, true, false, 0, 2); + + int timeout = 30; int region = System.Globalization.CultureInfo.InstalledUICulture.Name.StartsWith("fa") ? 2 : System.Globalization.CultureInfo.InstalledUICulture.Name.Contains("zh-CN") ? 1 : -1; @@ -87,9 +89,11 @@ public static bool InternetTest(string url = null) request.KeepAlive = false; request.Timeout = timeout * 1000; request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; " + - "Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; " + - ".NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; " + - "InfoPath.2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0)"; + "Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; " + + ".NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; " + + "InfoPath.2; OfficeLiveConnector.1.3; OfficeLivePatch.0.0)"; + + bool result = false; if (CheckDomain(url, timeout)) { @@ -110,21 +114,28 @@ public static bool InternetTest(string url = null) char x = response.ResponseUri.ToString()[i]; } - return true; + result = true; } - return false; + Program.MainForm?.Wait(false, false, false); + return result; } catch (Exception ex) { + Program.MainForm?.Wait(false, false, false); + + // Automatically return true in event of 429: Too many requests + if (ex.GetType() == typeof(WebException) && (ex as WebException).Status == WebExceptionStatus.ProtocolError) + return true; + string message = ex.Message; + int colon = message.IndexOf(':'); + char dot = Program.Lang.GetScript(message) == Language.ScriptType.CJK && !Program.Lang.Current.StartsWith("ko") ? '。' : '.'; - int colon = ex.Message.IndexOf(':'); if (!string.IsNullOrWhiteSpace(url) && message.Contains(url) && colon > 0) message = message.Substring(0, colon); - if (message[message.Length - 1] != '.') message += "."; + if (message[message.Length - 1] != dot) message += dot; - return true; throw new Exception(string.Format(Program.Lang.Msg(0, true), message)); } }