public Tasker.Conclusion DeleteCovers(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.RemovingCovers); tasker.SetStatusImage(Resources.sign_trashcan); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.RemovingCovers); int i = 0; foreach (NesApplication game in Games) { game.Image = null; tasker.SetProgress(++i, Games.Count); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion UploadGames(Tasker tasker, Object syncObject = null) { // get specialized view transferForm = tasker.GetSpecificViews <TaskerTransferForm>().First(); // set up progress bar tasker.SetTitle(Resources.UploadGames); tasker.SetState(Tasker.State.Starting); tasker.SetStatusImage(Resources.sign_up); // safeguards if (!hakchi.Shell.IsOnline || Games == null || Games.Count == 0) { return(Tasker.Conclusion.Error); } // set up upload path if (ConfigIni.Instance.UploadToTmp) { uploadPath = remoteTempDirectory; } else { uploadPath = hakchi.GetRemoteGameSyncPath(ConfigIni.Instance.ConsoleType); } // add sub-tasks tasker.AddTask(BuildMenu, 0); tasker.AddTask(BuildFiles, 1); tasker.AddTask(CheckRemoteStorageRequirements, 1); tasker.AddTask(PrepareRemoteTransfer, 1); tasker.AddTask(CalculateRemoteDiff, 1); if (ConfigIni.Instance.ForceSSHTransfers || hakchi.Shell is clovershell.ClovershellConnection) { tasker.AddTask(SyncRemoteGamesShell, 28); } else if (hakchi.Shell is INetworkShell) { tasker.AddTask(SyncRemoteGamesFTP, 28); } tasker.AddTask(RemoteCleanup, 1); tasker.AddTask(LinkGames, 1); tasker.AddTask(ShellTasks.SyncConfig, 1); return(Tasker.Conclusion.Success); }
public Tasker.Conclusion SetCoverArtForMultipleGames(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.ApplyChanges); tasker.SetStatusImage(Resources.sign_file_picture); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.ApplyChanges); NesApplication.CachedCoverFiles = null; int i = 0, max = GamesChanged.Count; foreach (var pair in GamesChanged) { pair.Key.SetImageFile(pair.Value, ConfigIni.Instance.CompressCover); tasker.SetProgress(++i, max); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion LoadGames(Tasker tasker, Object syncObject = null) { tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.LoadingGames); tasker.SetStatusImage(Resources.sign_down); tasker.SetTitle(Resources.LoadingGames); tasker.SyncObject = new LoadGamesSyncObject(); tasker.AddTasks( CreateListViewGroups, this.reloadFromFiles ? (Tasker.TaskFunc)LoadGamesFromFiles : (Tasker.TaskFunc)LoadGamesFromList, AssignGroupsToGames, AssignListViewGroups, UpdateListView); return(Tasker.Conclusion.Success); }
public Tasker.Conclusion RepairGames(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.RepairGames); tasker.SetStatusImage(Resources.sign_cogs); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.RepairGames); NesApplication.ParentForm = tasker.HostForm; int i = 0, max = Games.Count; foreach (var game in Games) { tasker.SetStatus(string.Format(Resources.RepairingGame, game.Name)); bool success = game.Repair(); Debug.WriteLine($"Repairing game \"{game.Name}\" was " + (success ? "successful" : "not successful")); tasker.SetProgress(++i, max); } return(Tasker.Conclusion.Success); }
private void buttonImport_Click(object sender, EventArgs e) { if (listViewGames.SelectedItems.Count > 0) { gameCopied = true; using (var tasker = new Tasks.Tasker(this)) { tasker.AttachView(new TaskerTaskbar()); tasker.AttachView(new TaskerForm()); tasker.SetTitle(Resources.CopyingGames); if (hakchi.Shell.IsOnline) { foreach (var game in SelectedGames) { tasker.AddTask(GameCopyTask(game)); } } tasker.Start(); } } }
public Tasker.Conclusion UpdateLocal(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.UpdatingLocalCache); tasker.SetStatusImage(Resources.sign_sync); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.UpdatingLocalCache); var shell = hakchi.Shell; if (!shell.IsOnline) { return(Tasker.Conclusion.Abort); } string gamesCloverPath = shell.ExecuteSimple("hakchi eval 'echo \"$squashfs$gamepath\"'", 2000, true); string cachePath = Path.Combine(Program.BaseDirectoryExternal, "games_cache"); try { var reply = shell.ExecuteSimple($"[ -d {gamesCloverPath} ] && echo YES || echo NO"); if (reply == "NO") { gamesCloverPath = hakchi.GamesPath; reply = shell.ExecuteSimple($"[ -d {gamesCloverPath} ] && echo YES || echo NO"); if (reply == "NO") { throw new Exception("Unable to update local cache. games directory not accessible"); } } int i = 0; foreach (NesDefaultGame game in Games) { string gamePath = Path.Combine(cachePath, game.Code); if (!Directory.Exists(gamePath)) { try { Directory.CreateDirectory(gamePath); using (var tar = new MemoryStream()) { string cmd = $"cd {gamesCloverPath}/{game.Code} && tar -c *"; shell.Execute(cmd, null, tar, null, 10000, true); tar.Seek(0, SeekOrigin.Begin); using (var szExtractorTar = new SevenZipExtractor(tar)) szExtractorTar.ExtractArchive(gamePath); } } catch (Exception ex) { Debug.WriteLine(ex.Message + ex.StackTrace); if (Directory.Exists(gamePath)) { Debug.WriteLine($"Exception, erasing \"{gamePath}\"."); Directory.Delete(gamePath, true); } } } tasker.SetProgress(++i, Games.Count); } } catch (Exception ex) { Debug.WriteLine(ex.Message + ex.StackTrace); return(Tasker.Conclusion.Error); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion UpdateLocal(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.UpdatingLocalCache); tasker.SetStatusImage(Resources.sign_sync); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.UpdatingLocalCache); var shell = hakchi.Shell; if (!shell.IsOnline) { return(Tasker.Conclusion.Abort); } string gamesCloverPath = shell.ExecuteSimple("hakchi eval 'echo \"$squashfs$gamepath\"'", 2000, true); string cachePath = Path.Combine(Program.BaseDirectoryExternal, "games_cache"); try { var reply = shell.ExecuteSimple($"[ -d \"{gamesCloverPath}\" ] && echo YES || echo NO"); if (reply == "NO") { gamesCloverPath = hakchi.GamesSquashFsPath; reply = shell.ExecuteSimple($"[ -d \"{gamesCloverPath}\" ] && echo YES || echo NO"); if (reply == "NO") { throw new Exception("Unable to update local cache. games directory not accessible"); } } var list = shell.ExecuteSimple($"ls \"{gamesCloverPath}\" -p -1 | grep '/'").Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); int i = 0; foreach (var folder in list) { string gameCode = folder.Substring(0, folder.Length - 1); string gamePath = Path.Combine(cachePath, gameCode); if (!Directory.Exists(gamePath)) { try { Directory.CreateDirectory(gamePath); using (var tar = new MemoryStream()) { string cmd = $"cd {gamesCloverPath}/{gameCode} && tar -c *"; shell.Execute(cmd, null, tar, null, 10000, true); tar.Seek(0, SeekOrigin.Begin); using (var extractorTar = SharpCompress.Archives.Tar.TarArchive.Open(tar)) extractorTar.WriteToDirectory(gamePath, new SharpCompress.Common.ExtractionOptions() { ExtractFullPath = true, Overwrite = true }); } ++LoadedGames; } catch (Exception ex) { Trace.WriteLine(ex.Message + ex.StackTrace); if (Directory.Exists(gamePath)) { Trace.WriteLine($"Exception occured while loading data from NES/SNES mini, deleting \"{gamePath}\"."); Directory.Delete(gamePath, true); } } } tasker.SetProgress(++i, list.Length); } } catch (Exception ex) { Trace.WriteLine(ex.Message + ex.StackTrace); return(Tasker.Conclusion.Error); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion AddGames(Tasker tasker, Object syncObject = null) { tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.AddingGames); tasker.SetTitle(Resources.AddingGames); tasker.SetStatusImage(Resources.sign_cogs); // static presets NesApplication.ParentForm = tasker.HostForm; NesApplication.NeedPatch = null; NesApplication.Need3rdPartyEmulator = null; NesApplication.CachedCoverFiles = null; NesGame.IgnoreMapper = null; SnesGame.NeedAutoDownloadCover = null; int total = files.Count(); int count = 0; foreach (var sourceFileName in files) { NesApplication app = null; try { tasker.SetStatus(string.Format(Resources.AddingGame, Path.GetFileName(sourceFileName))); var fileName = sourceFileName; var ext = Path.GetExtension(sourceFileName).ToLower(); byte[] rawData = null; string tmp = null; if (ext == ".7z" || ext == ".zip" || ext == ".rar") { using (var szExtractor = new SevenZipExtractor(sourceFileName)) { var filesInArchive = szExtractor.ArchiveFileNames; var gameFilesInArchive = new List <string>(); foreach (var f in szExtractor.ArchiveFileNames) { var e = Path.GetExtension(f).ToLower(); if (e == ".desktop") { gameFilesInArchive.Clear(); gameFilesInArchive.Add(f); break; } else if (CoreCollection.Extensions.Contains(e)) { gameFilesInArchive.Add(f); } } if (gameFilesInArchive.Count == 1) // Only one known file (or app) { fileName = gameFilesInArchive[0]; } else if (gameFilesInArchive.Count > 1) // Many known files, need to select { var r = SelectFile(tasker, gameFilesInArchive.ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } } else if (filesInArchive.Count == 1) // No known files but only one another file { fileName = filesInArchive[0]; } else // Need to select { var r = SelectFile(tasker, filesInArchive.ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } } if (fileName != sourceFileName) { var o = new MemoryStream(); if (Path.GetExtension(fileName).ToLower() == ".desktop" || // App in archive, need the whole directory szExtractor.ArchiveFileNames.Contains(Path.GetFileNameWithoutExtension(fileName) + ".jpg") || // Or it has cover in archive szExtractor.ArchiveFileNames.Contains(Path.GetFileNameWithoutExtension(fileName) + ".png") || szExtractor.ArchiveFileNames.Contains(Path.GetFileNameWithoutExtension(fileName) + ".ips") // Or IPS file ) { tmp = Path.Combine(tempDirectory, fileName); Directory.CreateDirectory(tmp); szExtractor.ExtractArchive(tmp); fileName = Path.Combine(tmp, fileName); } else { szExtractor.ExtractFile(fileName, o); rawData = new byte[o.Length]; o.Seek(0, SeekOrigin.Begin); o.Read(rawData, 0, (int)o.Length); } } } } app = NesApplication.Import(fileName, sourceFileName, rawData); if (app is ISupportsGameGenie && Path.GetExtension(fileName).ToLower() == ".nes") { var lGameGeniePath = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".xml"); if (File.Exists(lGameGeniePath)) { GameGenieDataBase lGameGenieDataBase = new GameGenieDataBase(app); lGameGenieDataBase.ImportCodes(lGameGeniePath, true); lGameGenieDataBase.Save(); } } if (!string.IsNullOrEmpty(tmp) && Directory.Exists(tmp)) { Directory.Delete(tmp, true); } } catch (Exception ex) { if (ex is ThreadAbortException) { return(Tasker.Conclusion.Abort); } if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message)) { Debug.WriteLine(ex.InnerException.Message + ex.InnerException.StackTrace); tasker.ShowError(ex.InnerException, Path.GetFileName(sourceFileName)); } else { Debug.WriteLine(ex.Message + ex.StackTrace, Path.GetFileName(sourceFileName)); tasker.ShowError(ex); } return(Tasker.Conclusion.Error); } if (app != null) { addedApps.Add(app); } tasker.SetProgress(++count, total); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion UpdateListView(Tasker tasker, Object syncObject = null) { if (tasker.HostForm.Disposing) { return(Tasker.Conclusion.Abort); } if (tasker.HostForm.InvokeRequired) { return((Tasker.Conclusion)tasker.HostForm.Invoke(new Func <Tasker, Object, Tasker.Conclusion>(UpdateListView), new object[] { tasker, syncObject })); } if (addedApps != null) { tasker.SetTitle(Resources.UpdatingList); // show select core dialog if applicable var unknownApps = new List <NesApplication>(); foreach (var app in addedApps) { if (app.Metadata.AppInfo.Unknown) { unknownApps.Add(app); } } if (unknownApps.Count > 0) { using (SelectCoreDialog selectCoreDialog = new SelectCoreDialog()) { selectCoreDialog.Games.AddRange(unknownApps); selectCoreDialog.ShowDialog(tasker.HostForm); } } // show select cover dialog if applicable unknownApps.Clear(); foreach (var app in addedApps) { if (!app.CoverArtMatchSuccess && app.CoverArtMatches.Any()) { unknownApps.Add(app); } } if (unknownApps.Count > 0) { using (SelectCoverDialog selectCoverDialog = new SelectCoverDialog()) { selectCoverDialog.Games.AddRange(unknownApps); selectCoverDialog.ShowDialog(tasker.HostForm); } } // update list view try { listViewGames.BeginUpdate(); foreach (ListViewItem item in listViewGames.Items) { item.Selected = false; } // add games, only new ones var newApps = addedApps.Distinct(new NesApplication.NesAppEqualityComparer()); var newCodes = from app in newApps select app.Code; var oldAppsReplaced = from app in listViewGames.Items.Cast <ListViewItem>().ToArray() where (app.Tag is NesApplication) && newCodes.Contains((app.Tag as NesApplication).Code) select app; // find "new apps" group ListViewGroup newGroup = null; if (listViewGames.Groups.Count > 0) { newGroup = listViewGames.Groups.OfType <ListViewGroup>().Where(group => group.Header == Resources.ListCategoryNew).FirstOrDefault(); } int i = 0, max = newApps.Count() + oldAppsReplaced.Count(); foreach (var replaced in oldAppsReplaced) { listViewGames.Items.Remove(replaced); tasker.SetProgress(++i, max); } foreach (var newApp in newApps) { var item = new ListViewItem(newApp.Name); item.Group = newGroup; item.Tag = newApp; item.Selected = true; item.Checked = true; listViewGames.Items.Add(item); tasker.SetProgress(++i, max); } } finally { listViewGames.EndUpdate(); } } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion SyncOriginalGames(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.ResettingOriginalGames); tasker.SetStatusImage(Resources.sign_sync); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.ResettingOriginalGames); string desktopEntriesArchiveFile = Path.Combine(Path.Combine(Program.BaseDirectoryInternal, "data"), "desktop_entries.7z"); string originalGamesPath = Path.Combine(Program.BaseDirectoryExternal, "games_originals"); var selectedGames = ConfigIni.Instance.SelectedGames; if (!Directory.Exists(originalGamesPath)) { Directory.CreateDirectory(originalGamesPath); } if (!File.Exists(desktopEntriesArchiveFile)) { throw new FileLoadException("desktop_entries.7z data file was deleted, cannot sync original games."); } try { var defaultGames = ResetAllOriginalGames ? NesApplication.AllDefaultGames : NesApplication.DefaultGames; using (var szExtractor = new SevenZipExtractor(desktopEntriesArchiveFile)) { int i = 0; foreach (var f in szExtractor.ArchiveFileNames) { var code = Path.GetFileNameWithoutExtension(f); var query = defaultGames.Where(g => g.Code == code); if (query.Count() != 1) { continue; } var ext = Path.GetExtension(f).ToLower(); if (ext != ".desktop") // sanity check { throw new FileLoadException($"invalid file \"{f}\" found in desktop_entries.7z data file."); } string path = Path.Combine(originalGamesPath, code); string outputFile = Path.Combine(path, code + ".desktop"); bool exists = File.Exists(outputFile); if (exists && !NonDestructiveSync) { Shared.EnsureEmptyDirectory(path); Thread.Sleep(0); } if (!exists || !NonDestructiveSync) { Directory.CreateDirectory(path); // extract .desktop file from archive using (var o = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) { szExtractor.ExtractFile(f, o); o.Flush(); if (!this.ResetAllOriginalGames && !selectedGames.Contains(code)) { selectedGames.Add(code); } } // create game temporarily to perform cover search Debug.WriteLine(string.Format("Resetting game \"{0}\".", query.Single().Name)); var game = NesApplication.FromDirectory(path); game.FindCover(code + ".desktop"); game.Save(); } tasker.SetProgress(++i, defaultGames.Length); } } } catch (Exception ex) { Debug.WriteLine("Error synchronizing original games " + ex.Message + ex.StackTrace); tasker.ShowError(ex, Resources.ErrorRestoringAllOriginalGames); return(Tasker.Conclusion.Error); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion SyncOriginalGames(Tasker tasker, Object SyncObject = null) { tasker.SetTitle(Resources.ResettingOriginalGames); tasker.SetStatusImage(Resources.sign_sync); tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.ResettingOriginalGames); string desktopEntriesArchiveFile = Path.Combine(Path.Combine(Program.BaseDirectoryInternal, "data"), "desktop_entries.tar"); string originalGamesPath = Path.Combine(Program.BaseDirectoryExternal, "games_originals"); if (!Directory.Exists(originalGamesPath)) { Directory.CreateDirectory(originalGamesPath); } if (!File.Exists(desktopEntriesArchiveFile)) { throw new FileLoadException("desktop_entries.tar data file was deleted, cannot sync original games."); } try { var defaultGames = ResetAllOriginalGames ? NesApplication.AllDefaultGames.Select(g => g.Key) : NesApplication.CurrentDefaultGames; using (var extractor = ArchiveFactory.Open(desktopEntriesArchiveFile)) using (var reader = extractor.ExtractAllEntries()) { int i = 0; while (reader.MoveToNextEntry()) { if (reader.Entry.IsDirectory) { continue; } var code = Path.GetFileNameWithoutExtension(reader.Entry.Key); if (!defaultGames.Contains(code)) { continue; } var ext = Path.GetExtension(reader.Entry.Key).ToLower(); if (ext != ".desktop") // sanity check { throw new FileLoadException($"invalid file \"{reader.Entry.Key}\" found in desktop_entries.tar data file."); } string path = Path.Combine(originalGamesPath, code); string outputFile = Path.Combine(path, code + ".desktop"); bool exists = File.Exists(outputFile); if (exists && !NonDestructiveSync) { Shared.EnsureEmptyDirectory(path); Thread.Sleep(0); } if (!exists || !NonDestructiveSync) { Directory.CreateDirectory(path); // extract .desktop file from archive using (var o = new FileStream(outputFile, FileMode.Create, FileAccess.Write)) { reader.WriteEntryTo(o); o.Flush(); if (!this.ResetAllOriginalGames && !ConfigIni.Instance.OriginalGames.Contains(code)) { ConfigIni.Instance.OriginalGames.Add(code); } } // create game temporarily to perform cover search Trace.WriteLine(string.Format($"Resetting game \"{NesApplication.AllDefaultGames[code].Name}\".")); var game = NesApplication.FromDirectory(path); game.FindCover(code + ".desktop"); game.Save(); } tasker.SetProgress(++i, defaultGames.Count()); } } } catch (Exception ex) { Trace.WriteLine("Error synchronizing original games " + ex.Message + ex.StackTrace); tasker.ShowError(ex, Resources.ErrorRestoringAllOriginalGames); return(Tasker.Conclusion.Error); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion AddGames(Tasker tasker, Object syncObject = null) { tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.AddingGames); tasker.SetTitle(Resources.AddingGames); tasker.SetStatusImage(Resources.sign_cogs); // static presets NesApplication.ParentForm = tasker.HostForm; NesApplication.NeedPatch = null; NesApplication.Need3rdPartyEmulator = null; NesApplication.CachedCoverFiles = null; NesGame.IgnoreMapper = null; SnesGame.NeedAutoDownloadCover = null; int total = files.Count(); int count = 0; var gamesWithMultipleArt = new List <NesApplication>(); foreach (var sourceFileName in files) { NesApplication app = null; try { tasker.SetStatus(string.Format(Resources.AddingGame, Path.GetFileName(sourceFileName))); var fileName = sourceFileName; var ext = Path.GetExtension(sourceFileName).ToLower(); byte[] rawData = null; string tmp = null; if (!asIs && (ext == ".7z" || ext == ".zip" || ext == ".rar" || ext == ".clvg")) { if (ext == ".clvg") { tmp = TempHelpers.getUniqueTempPath(); Directory.CreateDirectory(tmp); using (var file = File.OpenRead(sourceFileName)) using (var reader = ReaderFactory.Open(file)) { reader.WriteAllToDirectory(tmp, new ExtractionOptions() { ExtractFullPath = true, PreserveFileTime = true }); } var gameFilesInArchive = Directory.GetFiles(tmp, "*.desktop").Select(o => new DirectoryInfo(o)).Cast <DirectoryInfo>().ToArray(); switch (gameFilesInArchive.LongLength) { case 0: // no files found break; case 1: // one file found fileName = gameFilesInArchive[0].FullName; break; default: // multiple files found var r = SelectFile(tasker, gameFilesInArchive.Select(o => o.FullName).ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } break; } } else { using (var extractor = ArchiveFactory.Open(sourceFileName)) { var filesInArchive = extractor.Entries; var gameFilesInArchive = new List <string>(); foreach (var f in extractor.Entries) { if (!f.IsDirectory) { var e = Path.GetExtension(f.Key).ToLower(); if (e == ".desktop") { gameFilesInArchive.Clear(); gameFilesInArchive.Add(f.Key); break; } else if (CoreCollection.Extensions.Contains(e)) { gameFilesInArchive.Add(f.Key); } } } if (gameFilesInArchive.Count == 1) // Only one known file (or app) { fileName = gameFilesInArchive[0]; } else if (gameFilesInArchive.Count > 1) // Many known files, need to select { var r = SelectFile(tasker, gameFilesInArchive.ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } } else if (filesInArchive.Count() == 1) // No known files but only one another file { fileName = filesInArchive.First().Key; } else // Need to select { var r = SelectFile(tasker, filesInArchive.Select(f => f.Key).ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } } if (fileName != sourceFileName) { var o = new MemoryStream(); if (Path.GetExtension(fileName).ToLower() == ".desktop" || // App in archive, need the whole directory filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".jpg") || // Or it has cover in archive filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".png") || filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".ips") // Or IPS file ) { tmp = Path.Combine(tempDirectory, fileName); Directory.CreateDirectory(tmp); extractor.WriteToDirectory(tmp, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true }); fileName = Path.Combine(tmp, fileName); } else { extractor.Entries.Where(f => f.Key == fileName).First().WriteTo(o); rawData = new byte[o.Length]; o.Seek(0, SeekOrigin.Begin); o.Read(rawData, 0, (int)o.Length); } } } } } app = NesApplication.Import(fileName, sourceFileName, rawData, asIs); if (ext == ".clvg") { app.SkipCoreSelect = true; } else { if (app != null && app.CoverArtMatches != null && app.CoverArtMatches.Count() > 1) { gamesWithMultipleArt.Add(app); } NewGames.Add(app); } if (app is ISupportsGameGenie && Path.GetExtension(fileName).ToLower() == ".nes") { var lGameGeniePath = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".xml"); if (File.Exists(lGameGeniePath)) { GameGenieDataBase lGameGenieDataBase = new GameGenieDataBase(app); lGameGenieDataBase.ImportCodes(lGameGeniePath, true); lGameGenieDataBase.Save(); } } if (!string.IsNullOrEmpty(tmp) && Directory.Exists(tmp)) { Directory.Delete(tmp, true); } } catch (Exception ex) { if (ex is ThreadAbortException) { return(Tasker.Conclusion.Abort); } if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message)) { Trace.WriteLine(ex.InnerException.Message + ex.InnerException.StackTrace); tasker.ShowError(ex.InnerException, Path.GetFileName(sourceFileName)); } else { Trace.WriteLine(ex.Message + ex.StackTrace, Path.GetFileName(sourceFileName)); tasker.ShowError(ex); } return(Tasker.Conclusion.Error); } if (app != null) { addedApps.Add(app); } tasker.SetProgress(++count, total); } if (gamesWithMultipleArt.Count > 0) { tasker.HostForm.Invoke(new Action(() => { using (SelectCoverDialog selectCoverDialog = new SelectCoverDialog()) { selectCoverDialog.Games.AddRange(gamesWithMultipleArt); selectCoverDialog.ShowDialog(tasker.HostForm); } })); } return(Tasker.Conclusion.Success); }
public Tasker.Conclusion AddGames(Tasker tasker, Object syncObject = null) { tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.AddingGames); tasker.SetTitle(Resources.AddingGames); tasker.SetStatusImage(Resources.sign_cogs); // static presets NesApplication.ParentForm = tasker.HostForm; NesApplication.NeedPatch = null; NesApplication.Need3rdPartyEmulator = null; NesApplication.CachedCoverFiles = null; NesGame.IgnoreMapper = null; SnesGame.NeedAutoDownloadCover = null; int total = files.Count(); int count = 0; var gamesWithMultipleArt = new List <NesApplication>(); foreach (var sourceFileName in files) { NesApplication app = null; try { tasker.SetStatus(string.Format(Resources.AddingGame, Path.GetFileName(sourceFileName))); var fileName = sourceFileName; var ext = Path.GetExtension(sourceFileName).ToLower(); byte[] rawData = null; string tmp = null; if (!asIs && (ext == ".7z" || ext == ".zip" || ext == ".rar" || ext == ".clvg")) { if (ext == ".clvg") { tmp = TempHelpers.getUniqueTempPath(); Directory.CreateDirectory(tmp); using (var file = File.OpenRead(sourceFileName)) using (var reader = ReaderFactory.Open(file)) { reader.WriteAllToDirectory(tmp, new ExtractionOptions() { ExtractFullPath = true, PreserveFileTime = true }); } var gameFilesInArchive = Directory.GetFiles(tmp, "*.desktop").Select(o => new DirectoryInfo(o)).Cast <DirectoryInfo>().ToArray(); switch (gameFilesInArchive.LongLength) { case 0: // no files found break; case 1: // one file found fileName = gameFilesInArchive[0].FullName; break; default: // multiple files found var r = SelectFile(tasker, gameFilesInArchive.Select(o => o.FullName).ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } break; } } else { using (var extractor = ArchiveFactory.Open(sourceFileName)) { var filesInArchive = extractor.Entries; var gameFilesInArchive = new List <string>(); foreach (var f in extractor.Entries) { if (!f.IsDirectory) { var e = Path.GetExtension(f.Key).ToLower(); if (e == ".desktop") { gameFilesInArchive.Clear(); gameFilesInArchive.Add(f.Key); break; } else if (CoreCollection.Extensions.Contains(e)) { gameFilesInArchive.Add(f.Key); } } } if (gameFilesInArchive.Count == 1) // Only one known file (or app) { fileName = gameFilesInArchive[0]; } else if (gameFilesInArchive.Count > 1) // Many known files, need to select { var r = SelectFile(tasker, gameFilesInArchive.ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } } else if (filesInArchive.Count() == 1) // No known files but only one another file { fileName = filesInArchive.First().Key; } else // Need to select { var r = SelectFile(tasker, filesInArchive.Select(f => f.Key).ToArray()); if (r == DialogResult.OK) { fileName = selectedFile; } else if (r == DialogResult.Ignore) { fileName = sourceFileName; } else { continue; } } if (fileName != sourceFileName) { var o = new MemoryStream(); if (Path.GetExtension(fileName).ToLower() == ".desktop" || // App in archive, need the whole directory filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".jpg") || // Or it has cover in archive filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".png") || filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".ips") // Or IPS file ) { tmp = Path.Combine(tempDirectory, fileName); Directory.CreateDirectory(tmp); extractor.WriteToDirectory(tmp, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true }); fileName = Path.Combine(tmp, fileName); } else { extractor.Entries.Where(f => f.Key == fileName).First().WriteTo(o); rawData = new byte[o.Length]; o.Seek(0, SeekOrigin.Begin); o.Read(rawData, 0, (int)o.Length); } } } } } app = NesApplication.Import(fileName, sourceFileName, rawData, asIs); if (ext == ".clvg") { app.SkipCoreSelect = true; } else { if (app.CoverArtMatches != null && app.CoverArtMatches.Count() > 1) { gamesWithMultipleArt.Add(app); } if (ConfigIni.Instance.EnableImportScraper && Program.TheGamesDBAPI != null && app.Metadata.OriginalCrc32 != 0 && data.GamesDB.HashLookup.ContainsKey(app.Metadata.OriginalCrc32) && data.GamesDB.HashLookup[app.Metadata.OriginalCrc32].Length > 0) { var api = Program.TheGamesDBAPI; var task = api.GetInfoByID(data.GamesDB.HashLookup[app.Metadata.OriginalCrc32]); try { task.Wait(); var result = task.Result; if (result.Items.Count() > 0) { var first = result.Items.First(); if (first.Name != null) { app.Desktop.Name = first.Name; app.Desktop.SortName = Shared.GetSortName(first.Name); } if (first.Publishers != null && first.Publishers.Length > 0) { app.Desktop.Publisher = String.Join(", ", first.Publishers).ToUpper(); } else if (first.Developers != null && first.Developers.Length > 0) { if (first.ReleaseDate != null) { app.Desktop.Copyright = $"© {first.ReleaseDate.Year} {String.Join(", ", first.Developers)}"; } else { app.Desktop.Copyright = $"© {String.Join(", ", first.Developers)}"; } } if (first.Description != null) { app.Desktop.Description = first.Description; } if (first.ReleaseDate != null) { app.Desktop.ReleaseDate = first.ReleaseDate.ToString("yyyy-MM-dd"); } if (first.PlayerCount > 0) { app.Desktop.Players = Convert.ToByte(first.PlayerCount); app.Desktop.Simultaneous = first.PlayerCount == 2; } if (first.Genres != null && first.Genres.Length > 0) { foreach (var genre in first.Genres) { var match = ScraperForm.TheGamesDBGenreLookup.Where(g => g.Value.Contains(genre.ID)).Select(g => g.Key); if (match.Count() > 0) { var firstGenre = match.First(); app.Desktop.Genre = firstGenre; break; } } } using (var wc = new HakchiWebClient()) { try { var front = first.Images.Where(i => i.Type == TeamShinkansen.Scrapers.Enums.ArtType.Front).ToArray(); if (front.Length > 0 && !app.CoverArtMatchSuccess) { var data = wc.DownloadData(front[0].Url); using (var ms = new MemoryStream(data)) using (var bm = new Bitmap(ms)) { app.SetImage(bm); } } } catch (WebException ex) { } try { var imageData = wc.DownloadData($"https://cdn.thegamesdb.net/images/original/clearlogo/{first.ID}.png"); using (var ms = new MemoryStream(imageData)) using (var clearLogo = File.OpenWrite(Path.Combine(app.BasePath, $"{app.Code}_logo.png"))) { ms.Seek(0, SeekOrigin.Begin); ms.CopyTo(clearLogo); } } catch (WebException ex) { } } } } catch (Exception) { } } } if (app is ISupportsGameGenie && Path.GetExtension(fileName).ToLower() == ".nes") { var lGameGeniePath = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".xml"); if (File.Exists(lGameGeniePath)) { GameGenieDataBase lGameGenieDataBase = new GameGenieDataBase(app); lGameGenieDataBase.ImportCodes(lGameGeniePath, true); lGameGenieDataBase.Save(); } } if (!string.IsNullOrEmpty(tmp) && Directory.Exists(tmp)) { Directory.Delete(tmp, true); } } catch (Exception ex) { if (ex is ThreadAbortException) { return(Tasker.Conclusion.Abort); } if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message)) { Trace.WriteLine(ex.InnerException.Message + ex.InnerException.StackTrace); tasker.ShowError(ex.InnerException, Path.GetFileName(sourceFileName)); } else { Trace.WriteLine(ex.Message + ex.StackTrace, Path.GetFileName(sourceFileName)); tasker.ShowError(ex); } return(Tasker.Conclusion.Error); } if (app != null) { addedApps.Add(app); } tasker.SetProgress(++count, total); } if (gamesWithMultipleArt.Count > 0) { tasker.HostForm.Invoke(new Action(() => { using (SelectCoverDialog selectCoverDialog = new SelectCoverDialog()) { selectCoverDialog.Games.AddRange(gamesWithMultipleArt); selectCoverDialog.ShowDialog(tasker.HostForm); } })); } return(Tasker.Conclusion.Success); }