private void DeleteItem_Click(object sender, RoutedEventArgs e) { DisplayedMetadata row = (DisplayedMetadata)ModGrid.SelectedItem; if (row != null) { MessageBoxResult result = MessageBox.Show($@"Are you sure you want to delete Packages\{row.path}?", "Aemulus Package Manager", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (Directory.Exists($@"Packages\{row.path}") && result == MessageBoxResult.Yes) { Console.WriteLine($@"[INFO] Deleted Packages\{row.path}."); try { Directory.Delete($@"Packages\{row.path}", true); } catch (Exception ex) { Console.WriteLine($@"[ERROR] Couldn't delete Packages\{row.path} ({ex.Message})"); } Refresh(); updateConfig(); } } }
// Update config order when rows are changed private void ModGrid_LoadingRow(object sender, DataGridRowEventArgs e) { DisplayedMetadata dm = (DisplayedMetadata)e.Row.Item; foreach (var p in PackageList.ToList()) { if (dm.path == p.path) { Package temp = p; PackageList.Remove(p); PackageList.Insert(DisplayedPackages.IndexOf(dm), temp); } } updateConfig(); }
private void ModGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { string editedColumn = e.Column.Header.ToString(); string editedContent = (e.EditingElement as TextBox).Text; DisplayedMetadata row = (DisplayedMetadata)ModGrid.SelectedItem; if (File.Exists($@"Packages\{row.path}\Package.xml")) { Metadata metadata = new Metadata(); metadata.name = row.name; metadata.id = row.id; metadata.author = row.author; metadata.version = row.version; metadata.link = row.link; metadata.description = row.description; switch (editedColumn) { case "Name": if (metadata.name != editedContent) { Console.WriteLine($"Changed {metadata.name} to {editedContent}"); metadata.name = editedContent; } break; case "Author": if (metadata.author != editedContent) { Console.WriteLine($"Changed {metadata.author} to {editedContent}"); metadata.author = editedContent; } break; case "Version": if (metadata.version != editedContent) { Console.WriteLine($"Changed {metadata.version} to {editedContent}"); metadata.version = editedContent; } break; } using (FileStream streamWriter = File.Create($@"Packages\{row.path}\Package.xml")) { xsp.Serialize(streamWriter, metadata); } } }
private async Task DownloadFile(string uri, string fileName, string game, DisplayedMetadata row, string version, Progress <DownloadProgress> progress, CancellationTokenSource cancellationToken, GameBananaItemUpdate update = null) { try { // Create the downloads folder if necessary if (!Directory.Exists($@"{assemblyLocation}\Downloads")) { Directory.CreateDirectory($@"{assemblyLocation}\Downloads"); } // Download the file if it doesn't already exist if (!FileIOWrapper.Exists($@"{assemblyLocation}\Downloads\{fileName}")) { progressBox = new UpdateProgressBox(cancellationToken); progressBox.progressBar.Value = 0; progressBox.progressText.Text = $"Downloading {fileName}"; progressBox.finished = false; progressBox.Title = $"{row.name} Update Progress"; progressBox.Show(); progressBox.Activate(); Console.WriteLine($"[INFO] Downloading {fileName}"); // Write and download the file using (var fs = new FileStream( $@"{assemblyLocation}\Downloads\{fileName}", System.IO.FileMode.Create, FileAccess.Write, FileShare.None)) { await client.DownloadAsync(uri, fs, fileName, progress, cancellationToken.Token); } Console.WriteLine($"[INFO] Finished downloading {fileName}"); progressBox.Close(); } else { Console.WriteLine($"[INFO] {fileName} already exists in downloads, using this instead"); } ExtractFile(fileName, game, row, version, update); } catch (OperationCanceledException) { // Remove the file is it will be a partially downloaded one and close up FileIOWrapper.Delete(@$ "Downloads\{fileName}"); if (progressBox != null) { progressBox.finished = true; progressBox.Close(); } return; }
public DisplayedMetadata InitDisplayedMetadata(Metadata m) { DisplayedMetadata dm = new DisplayedMetadata(); dm.name = m.name; dm.id = m.id; dm.author = m.author; Version v; if (Version.TryParse(m.version, out v)) { dm.version = m.version; } dm.description = m.description; dm.link = m.link; return(dm); }
// Events for Enabled checkboxes private void OnUnchecked(object sender, RoutedEventArgs e) { var checkBox = e.OriginalSource as CheckBox; DisplayedMetadata package = checkBox?.DataContext as DisplayedMetadata; if (package != null) { package.enabled = false; foreach (var p in PackageList.ToList()) { if (p.path == package.path) { p.enabled = false; } } updateConfig(); } }
private void OpenItem_Click(object sender, RoutedEventArgs e) { DisplayedMetadata row = (DisplayedMetadata)ModGrid.SelectedItem; if (row != null) { if (Directory.Exists($@"Packages\{row.path}")) { try { ProcessStartInfo StartInformation = new ProcessStartInfo(); StartInformation.FileName = $@"Packages\{row.path}"; Process process = Process.Start(StartInformation); Console.WriteLine($@"[INFO] Opened Packages\{row.path}."); } catch (Exception ex) { Console.WriteLine($@"[ERROR] Couldn't open Packages\{row.path} ({ex.Message})"); } } } }
private void EditItem_Click(object sender, RoutedEventArgs e) { DisplayedMetadata row = (DisplayedMetadata)ModGrid.SelectedItem; if (row != null && File.Exists($@"Packages\{row.path}\Package.xml")) { Metadata m = new Metadata(); m.name = row.name; m.author = row.author; m.id = row.id; m.version = row.version; m.link = row.link; m.description = row.description; CreatePackage createPackage = new CreatePackage(m); createPackage.ShowDialog(); if (createPackage.metadata != null) { try { using (FileStream streamWriter = File.Create($@"Packages\{row.path}\Package.xml")) { xsp.Serialize(streamWriter, createPackage.metadata); } if (File.Exists(createPackage.thumbnailPath)) { File.Copy(createPackage.thumbnailPath, $@"Packages\{row.path}\Preview.png", true); } } catch (Exception ex) { Console.WriteLine($"[ERROR] {ex.Message}"); } Refresh(); updateConfig(); } } }
private void rowSelected(object sender, SelectionChangedEventArgs e) { DisplayedMetadata row = (DisplayedMetadata)ModGrid.SelectedItem; if (row != null) { // Set description if (row.description != null && row.description.Length > 0) { //Description.IsReadOnly = false; Description.Text = row.description; } else { Description.Text = "Aemulus means \"Rival\" in Latin. It was chosen since it sounds cool. (You are seeing this message because no mod package is selected or the package has no description)."; //Description.IsReadOnly = true; } // Set requirement visibility if (Directory.Exists($@"Packages\{row.path}\patches")) { Inaba.Visibility = Visibility.Visible; } else { Inaba.Visibility = Visibility.Collapsed; } if (File.Exists($@"Packages\{row.path}\SND\HeeHeeHo.uwus")) { HHH.Visibility = Visibility.Visible; } else { HHH.Visibility = Visibility.Collapsed; } if (Directory.Exists($@"Packages\{row.path}\patches") || File.Exists($@"Packages\{row.path}\SND\HeeHeeHo.uwus")) { Reqs.Visibility = Visibility.Visible; } else { Reqs.Visibility = Visibility.Collapsed; } // Set image string path = $@"Packages\{row.path}"; if (File.Exists($@"{path}\Preview.png")) { try { byte[] imageBytes = File.ReadAllBytes($@"{path}\Preview.png"); var stream = new MemoryStream(imageBytes); var img = new BitmapImage(); img.BeginInit(); img.StreamSource = stream; img.EndInit(); Preview.Source = img; } catch (Exception ex) { Console.WriteLine($"[ERROR] ex.Message"); } } else { Preview.Source = bitmap; } } }
// Refresh both PackageList and DisplayedPackages private void Refresh() { Metadata metadata; // First remove all deleted packages and update package id's to match metadata foreach (var package in PackageList.ToList()) { if (!Directory.Exists($@"Packages\{package.path}")) { PackageList.Remove(package); List <DisplayedMetadata> temp = DisplayedPackages.ToList(); temp.RemoveAll(x => x.path == package.path); DisplayedPackages = new ObservableCollection <DisplayedMetadata>(temp); } if (File.Exists($@"Packages\{package.path}\Package.xml")) { try { using (FileStream streamWriter = File.Open($@"Packages\{package.path}\Package.xml", FileMode.Open)) { metadata = (Metadata)xsp.Deserialize(streamWriter); package.id = metadata.id; } } catch (Exception ex) { Console.WriteLine($"[ERROR] Invalid Package.xml for {package.path} ({ex.Message})"); } } } UpdateMetadata(); // Get all packages from Packages folder (Adding packages) foreach (var package in Directory.EnumerateDirectories("Packages")) { if (File.Exists($@"{package}\Package.xml")) { using (FileStream streamWriter = File.Open($@"{package}\Package.xml", FileMode.Open)) { metadata = (Metadata)xsp.Deserialize(streamWriter); // Add package to list if it doesn't exist if (!PackageList.ToList().Any(x => x.path == Path.GetFileName(package)) && !DisplayedPackages.ToList().Any(x => x.path == Path.GetFileName(package))) { // Add new package to both collections DisplayedMetadata dm = InitDisplayedMetadata(metadata); Package p = new Package(); p.enabled = false; p.id = metadata.id; p.path = Path.GetFileName(package); PackageList.Add(p); dm.enabled = false; dm.path = Path.GetFileName(package); DisplayedPackages.Add(dm); } } } // Create Package.xml else { Console.WriteLine($"[WARNING] No Package.xml found for {Path.GetFileName(package)}, creating a simple one..."); // Create metadata Metadata newMetadata = new Metadata(); newMetadata.name = Path.GetFileName(package); newMetadata.id = newMetadata.name.Replace(" ", "").ToLower(); newMetadata.author = ""; newMetadata.version = ""; newMetadata.link = ""; newMetadata.description = ""; using (FileStream streamWriter = File.Create($@"{package}\Package.xml")) { xsp.Serialize(streamWriter, newMetadata); } if (!PackageList.ToList().Any(x => x.path == Path.GetFileName(package)) && !DisplayedPackages.ToList().Any(x => x.path == Path.GetFileName(package))) { // Create package Package newPackage = new Package(); newPackage.enabled = false; newPackage.path = Path.GetFileName(package); newPackage.id = newMetadata.id; PackageList.Add(newPackage); // Create displayedmetadata DisplayedMetadata newDisplayedMetadata = InitDisplayedMetadata(newMetadata); newDisplayedMetadata.enabled = false; newDisplayedMetadata.path = newPackage.path; DisplayedPackages.Add(newDisplayedMetadata); } else { UpdateMetadata(); } } } // Update DisplayedPackages App.Current.Dispatcher.Invoke((Action) delegate { ModGrid.ItemsSource = DisplayedPackages; // Trigger select event to refresh description and Preview.png ModGrid.SetSelectedItem(ModGrid.GetSelectedItem()); }); Console.WriteLine($"[INFO] Refreshed!"); }
public MainWindow() { InitializeComponent(); DataContext = this; outputter.WriteEvent += consoleWriter_WriteEvent; outputter.WriteLineEvent += consoleWriter_WriteLineEvent; Console.SetOut(outputter); binMerger = new binMerge(); tblPatcher = new tblPatch(); pacUnpacker = new PacUnpacker(); DisplayedPackages = new ObservableCollection <DisplayedMetadata>(); PackageList = new ObservableCollection <Package>(); // Retrieve initial thumbnail from embedded resource Assembly asm = Assembly.GetExecutingAssembly(); Stream iconStream = asm.GetManifestResourceStream("AemulusModManager.Preview.png"); bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = iconStream; bitmap.EndInit(); Preview.Source = bitmap; // Initialize config config = new Config(); // Initialize xml serializers xs = new XmlSerializer(typeof(Config)); xsp = new XmlSerializer(typeof(Metadata)); Console.WriteLine("[INFO] Initializing packages from Config.xml"); // Load in Config if it exists if (File.Exists(@"Config.xml")) { try { using (FileStream streamWriter = File.Open(@"Config.xml", FileMode.Open)) { // Call the Deserialize method and cast to the object type. config = (Config)xs.Deserialize(streamWriter); reloadedPath = config.reloadedPath; p4gPath = config.exePath; modPath = config.modDir; emptySND = config.emptySND; // Compatibility with old Config.xml List <Package> temp = config.package.ToList(); foreach (var p in temp) { if (p.name != null && p.path == null) { p.path = p.name; p.name = null; } } PackageList = new ObservableCollection <Package>(temp); tbl = config.tbl; } } catch (Exception ex) { Console.WriteLine($"Invalid Config.xml ({ex.Message})"); } // Create displayed metadata from packages in PackageList and their respective Package.xml's foreach (var package in PackageList) { string xml = $@"Packages\{package.path}\Package.xml"; Metadata m; DisplayedMetadata dm = new DisplayedMetadata(); try { if (File.Exists(xml)) { m = new Metadata(); try { using (FileStream streamWriter = File.Open(xml, FileMode.Open)) { m = (Metadata)xsp.Deserialize(streamWriter); dm.name = m.name; dm.id = m.id; dm.author = m.author; dm.version = m.version; dm.link = m.link; dm.description = m.description; } } catch (Exception ex) { Console.WriteLine($"[ERROR] Invalid Package.xml for {package.path} ({ex.Message})"); } } dm.path = package.path; dm.enabled = package.enabled; DisplayedPackages.Add(dm); } catch (Exception ex) { Console.WriteLine($"[ERROR] Invalid Package.xml for package {package.id} ({ex.Message})"); continue; } } ModGrid.ItemsSource = DisplayedPackages; } if (modPath == null) { MergeButton.IsEnabled = false; } if (config.modDir != null) { modPath = config.modDir; } // Create Packages directory if it doesn't exist if (!Directory.Exists("Packages")) { Directory.CreateDirectory("Packages"); } if (!Directory.Exists("Original")) { Directory.CreateDirectory("Original"); } Refresh(); updateConfig(); // Check if Original Folder is unpacked if (!Directory.EnumerateFileSystemEntries("Original").Any()) { Console.WriteLine("[WARNING] Aemulus can't find your Vanilla files in the Original folder."); Console.WriteLine("Please click the Config button and select \"Unpack data00004.pac\" before building."); } }
private async Task GitHubUpdate(Release release, DisplayedMetadata row, string game, Progress <DownloadProgress> progress, CancellationTokenSource cancellationToken) { Match onlineVersionMatch = Regex.Match(release.TagName, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); string onlineVersion = null; if (onlineVersionMatch.Success) { onlineVersion = onlineVersionMatch.Groups["version"].Value; } Match localVersionMatch = Regex.Match(row.version, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); string localVersion = null; if (localVersionMatch.Success) { localVersion = localVersionMatch.Groups["version"].Value; } if (row.skippedVersion != null) { if (row.skippedVersion == "all" || !UpdateAvailable(onlineVersion, row.skippedVersion)) { Console.WriteLine($"[INFO] No updates available for {row.name}"); return; } } if (UpdateAvailable(onlineVersion, localVersion)) { Console.WriteLine($"[INFO] An update is available for {row.name} ({release.TagName})"); NotificationBox notification = new NotificationBox($"{row.name} has an update ({release.TagName}):\n{release.Body}\n\nWould you like to update?", false); notification.ShowDialog(); notification.Activate(); if (!notification.YesNo) { return; } string downloadUrl, fileName; if (release.Assets.Count > 1) { UpdateFileBox fileBox = new UpdateFileBox(release.Assets, row.name); fileBox.Activate(); fileBox.ShowDialog(); downloadUrl = fileBox.chosenFileUrl; fileName = fileBox.chosenFileName; } else if (release.Assets.Count == 1) { downloadUrl = release.Assets.First().BrowserDownloadUrl; fileName = release.Assets.First().Name; } else { Console.WriteLine($"[INFO] An update is available for {row.name} ({release.TagName}) but no downloadable files are available."); notification = new NotificationBox($"{row.name} has an update ({release.TagName}) but no downloadable files.\nWould you like to go to the page to manually download the update?", false); notification.ShowDialog(); notification.Activate(); if (notification.YesNo) { Process.Start(row.link); } return; } if (downloadUrl != null && fileName != null) { await DownloadFile(downloadUrl, fileName, game, row, release.TagName, progress, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken.Token)); } else { Console.WriteLine($"[INFO] Cancelled update for {row.name}"); } } else { Console.WriteLine($"[INFO] No updates available for {row.name}"); } }
private async Task GameBananaUpdate(GameBananaItem item, DisplayedMetadata row, string game, Progress <DownloadProgress> progress, CancellationTokenSource cancellationToken) { if (item.HasUpdates) { GameBananaItemUpdate[] updates = item.Updates; string updateTitle = updates[0].Title; int updateIndex = 0; Match onlineVersionMatch = Regex.Match(updateTitle, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); string onlineVersion = null; if (onlineVersionMatch.Success) { onlineVersion = onlineVersionMatch.Groups["version"].Value; } // GB Api only returns two latest updates, so if the first doesn't have a version try the second else if (updates.Length > 1) { updateTitle = updates[1].Title; onlineVersionMatch = Regex.Match(updateTitle, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); updateIndex = 1; if (onlineVersionMatch.Success) { onlineVersion = onlineVersionMatch.Groups["version"].Value; } } Match localVersionMatch = Regex.Match(row.version, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); string localVersion = null; if (localVersionMatch.Success) { localVersion = localVersionMatch.Groups["version"].Value; } if (row.skippedVersion != null) { if (row.skippedVersion == "all" || !UpdateAvailable(onlineVersion, row.skippedVersion)) { Console.WriteLine($"[INFO] No updates available for {row.name}"); return; } } if (UpdateAvailable(onlineVersion, localVersion)) { Console.WriteLine($"[INFO] An update is available for {row.name} ({onlineVersion})"); // Display the changelog and confirm they want to update ChangelogBox changelogBox = new ChangelogBox(updates[updateIndex], row.name, $"Would you like to update {row.name} to version {onlineVersion}?", row, onlineVersion, $@"{assemblyLocation}\Packages\{game}\{row.path}\Package.xml", false); changelogBox.Activate(); changelogBox.ShowDialog(); if (!changelogBox.YesNo) { Console.WriteLine($"[INFO] Cancelled update for {row.name}"); return; } // Download the update Dictionary <String, GameBananaItemFile> files = item.Files; string downloadUrl, fileName; // Work out which are Aemulus comptaible by examining the file tree Dictionary <String, GameBananaItemFile> aemulusCompatibleFiles = new Dictionary <string, GameBananaItemFile>(); foreach (KeyValuePair <string, GameBananaItemFile> file in files) { if (file.Value.FileMetadata.Values.Count > 2) { string fileTree = file.Value.FileMetadata.Values.ElementAt(3).ToString(); if (fileTree.ToLower().Contains("package.xml") || fileTree.ToLower().Contains("mod.xml") || fileTree == "[]") { aemulusCompatibleFiles.Add(file.Key, file.Value); } } } if (aemulusCompatibleFiles.Count > 1) { UpdateFileBox fileBox = new UpdateFileBox(aemulusCompatibleFiles, row.name); fileBox.Activate(); fileBox.ShowDialog(); downloadUrl = fileBox.chosenFileUrl; fileName = fileBox.chosenFileName; } else if (aemulusCompatibleFiles.Count == 1) { downloadUrl = aemulusCompatibleFiles.ElementAt(0).Value.DownloadUrl; fileName = aemulusCompatibleFiles.ElementAt(0).Value.FileName; } else { Console.WriteLine($"[INFO] An update is available for {row.name} ({onlineVersion}) but no downloadable files are available."); NotificationBox notification = new NotificationBox($"{row.name} has an update ({onlineVersion}) but no downloadable files.\nWould you like to go to the page to manually download the update?", false); notification.ShowDialog(); notification.Activate(); if (notification.YesNo) { Process.Start(row.link); } return; } if (downloadUrl != null && fileName != null) { await DownloadFile(downloadUrl, fileName, game, row, onlineVersion, progress, cancellationToken, updates[updateIndex]); } else { Console.WriteLine($"[INFO] Cancelled update for {row.name}"); } } else { Console.WriteLine($"[INFO] No updates available for {row.name}"); } // TODO Check if there was no version number } else { Console.WriteLine($"[INFO] No updates available for {row.name}"); } }
// Refresh both PackageList and DisplayedPackages private void Refresh() { Metadata metadata; // First remove all deleted packages and update package id's to match metadata foreach (var package in PackageList.ToList()) { if (!Directory.Exists($@"Packages\{package.path}")) { PackageList.Remove(package); List <DisplayedMetadata> temp = DisplayedPackages.ToList(); temp.RemoveAll(x => x.path == package.path); DisplayedPackages = new ObservableCollection <DisplayedMetadata>(temp); } if (File.Exists($@"Packages\{package.path}\Package.xml")) { try { using (FileStream streamWriter = File.Open($@"Packages\{package.path}\Package.xml", FileMode.Open)) { metadata = (Metadata)xsp.Deserialize(streamWriter); package.id = metadata.id; } } catch (Exception ex) { Console.WriteLine($"[ERROR] Invalid Package.xml for {package.path} ({ex.Message})"); } } } UpdateMetadata(); // Get all packages from Packages folder (Adding packages) foreach (var package in Directory.EnumerateDirectories("Packages")) { if (File.Exists($@"{package}\Package.xml")) { using (FileStream streamWriter = File.Open($@"{package}\Package.xml", FileMode.Open)) { metadata = (Metadata)xsp.Deserialize(streamWriter); // Add package to list if it doesn't exist if (!PackageList.ToList().Any(x => x.path == Path.GetFileName(package)) && !DisplayedPackages.ToList().Any(x => x.path == Path.GetFileName(package))) { // Add new package to both collections DisplayedMetadata dm = InitDisplayedMetadata(metadata); Package p = new Package(); p.enabled = false; p.id = metadata.id; p.path = Path.GetFileName(package); PackageList.Add(p); dm.enabled = false; dm.path = Path.GetFileName(package); DisplayedPackages.Add(dm); } } } // Create Package.xml else { Console.WriteLine($"[WARNING] No Package.xml found for {Path.GetFileName(package)}, creating a simple one..."); // Create metadata Metadata newMetadata = new Metadata(); newMetadata.name = Path.GetFileName(package); newMetadata.id = newMetadata.name.Replace(" ", "").ToLower(); List <string> dirFiles = Directory.GetFiles(package).ToList(); List <string> dirFolders = Directory.GetDirectories(package, "*", SearchOption.TopDirectoryOnly).ToList(); dirFiles = dirFiles.Concat(dirFolders).ToList(); if (dirFiles.Any(x => Path.GetFileName(x).Equals("Mod.xml")) && dirFiles.Any(x => Path.GetFileName(x).Equals("Data"))) { //If mod folder contains Data folder and mod.xml, import mod compendium mod.xml... string modXml = dirFiles.First(x => Path.GetFileName(x).Equals("Mod.xml")); using (FileStream streamWriter = File.Open(modXml, FileMode.Open)) { //Deserialize Mod.xml & Use metadata ModXmlMetadata m = (ModXmlMetadata)xsm.Deserialize(streamWriter); newMetadata.id = m.Author.ToLower().Replace(" ", "") + "." + m.Title.ToLower().Replace(" ", ""); newMetadata.author = m.Author; newMetadata.version = m.Version; newMetadata.link = m.Url; newMetadata.description = m.Description; } //Move files out of Data folder string dataDir = dirFiles.First(x => Path.GetFileName(x).Equals("Data")); if (Directory.Exists(dataDir)) { MoveDir(dataDir, Path.GetDirectoryName(dataDir)); } //Delete prebuild.bat if exists if (dirFiles.Any(x => Path.GetFileName(x).Equals("prebuild.bat"))) { File.Delete(dirFiles.First(x => Path.GetFileName(x).Equals("prebuild.bat"))); } //Make sure Data folder is gone if (Directory.Exists(dataDir)) { Directory.Delete(dataDir, true); } //Goodbye old friend File.Delete(modXml); } else { newMetadata.author = ""; newMetadata.version = ""; newMetadata.link = ""; newMetadata.description = ""; } using (FileStream streamWriter = File.Create($@"{package}\Package.xml")) { xsp.Serialize(streamWriter, newMetadata); } if (!PackageList.ToList().Any(x => x.path == Path.GetFileName(package)) && !DisplayedPackages.ToList().Any(x => x.path == Path.GetFileName(package))) { // Create package Package newPackage = new Package(); newPackage.enabled = false; newPackage.path = Path.GetFileName(package); newPackage.id = newMetadata.id; PackageList.Add(newPackage); // Create displayedmetadata DisplayedMetadata newDisplayedMetadata = InitDisplayedMetadata(newMetadata); newDisplayedMetadata.enabled = false; newDisplayedMetadata.path = newPackage.path; DisplayedPackages.Add(newDisplayedMetadata); } else { UpdateMetadata(); } } } // Update DisplayedPackages App.Current.Dispatcher.Invoke((Action) delegate { ModGrid.ItemsSource = DisplayedPackages; // Trigger select event to refresh description and Preview.png ModGrid.SetSelectedItem(ModGrid.GetSelectedItem()); }); Console.WriteLine($"[INFO] Refreshed!"); }
private async Task GameBananaUpdate(GameBananaItem item, DisplayedMetadata row, string game, Progress <DownloadProgress> progress, CancellationTokenSource cancellationToken) { if (item.HasUpdates) { GameBananaItemUpdate[] updates = item.Updates; string updateTitle = updates[0].Title; int updateIndex = 0; Match onlineVersionMatch = Regex.Match(updateTitle, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); string onlineVersion = null; if (onlineVersionMatch.Success) { onlineVersion = onlineVersionMatch.Groups["version"].Value; } // GB Api only returns two latest updates, so if the first doesn't have a version try the second else if (updates.Length > 1) { updateTitle = updates[1].Title; onlineVersionMatch = Regex.Match(updateTitle, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); updateIndex = 1; if (onlineVersionMatch.Success) { onlineVersion = onlineVersionMatch.Groups["version"].Value; } } Match localVersionMatch = Regex.Match(row.version, @"(?<version>([0-9]+\.?)+)[^a-zA-Z]*"); string localVersion = null; if (localVersionMatch.Success) { localVersion = localVersionMatch.Groups["version"].Value; } if (row.skippedVersion != null) { if (row.skippedVersion == "all" || !UpdateAvailable(onlineVersion, row.skippedVersion)) { Console.WriteLine($"[INFO] No updates available for {row.name}"); return; } } if (UpdateAvailable(onlineVersion, localVersion)) { Console.WriteLine($"[INFO] An update is available for {row.name} ({onlineVersion})"); // Display the changelog and confirm they want to update ChangelogBox changelogBox = new ChangelogBox(updates[updateIndex], row.name, $"Would you like to update {row.name} to version {onlineVersion}?", row, onlineVersion, $@"{assemblyLocation}\Packages\{game}\{row.path}\Package.xml", false); changelogBox.Activate(); changelogBox.ShowDialog(); if (!changelogBox.YesNo) { Console.WriteLine($"[INFO] Cancelled update for {row.name}"); return; } // Download the update Dictionary <String, GameBananaItemFile> files = item.Files; string downloadUrl, fileName; // Work out which are Aemulus comptaible by examining the file tree Dictionary <String, GameBananaItemFile> aemulusCompatibleFiles = new Dictionary <string, GameBananaItemFile>(); foreach (KeyValuePair <string, GameBananaItemFile> file in files) { if (file.Value.FileMetadata.Values.Count > 0) { string fileTree = file.Value.FileMetadata.Values.ElementAt(1).ToString(); if (!fileTree.ToLower().Contains(".disable_gb1click") && (fileTree.ToLower().Contains("package.xml") || fileTree.ToLower().Contains("mod.xml") || fileTree == "[]")) { aemulusCompatibleFiles.Add(file.Key, file.Value); } } } if (aemulusCompatibleFiles.Count > 1) { UpdateFileBox fileBox = new UpdateFileBox(aemulusCompatibleFiles.Values.ToList(), row.name); fileBox.Activate(); fileBox.ShowDialog(); downloadUrl = fileBox.chosenFileUrl; fileName = fileBox.chosenFileName; } else if (aemulusCompatibleFiles.Count == 1) { downloadUrl = aemulusCompatibleFiles.ElementAt(0).Value.DownloadUrl; fileName = aemulusCompatibleFiles.ElementAt(0).Value.FileName; } else { Console.WriteLine($"[INFO] An update is available for {row.name} ({onlineVersion}) but there are no downloads directly from GameBanana."); // Convert the url Uri uri = CreateUri(row.link); string itemType = uri.Segments[1]; itemType = char.ToUpper(itemType[0]) + itemType.Substring(1, itemType.Length - 3); string itemId = uri.Segments[2]; // Parse the response string responseString = await client.GetStringAsync($"https://gamebanana.com/apiv4/{itemType}/{itemId}"); var response = JsonConvert.DeserializeObject <GameBananaAPIV4>(responseString); new AltLinkWindow(response.AlternateFileSources, row.name, game, true).ShowDialog(); return; } if (downloadUrl != null && fileName != null) { await DownloadFile(downloadUrl, fileName, game, row, onlineVersion, progress, cancellationToken, updates[updateIndex]); } else { Console.WriteLine($"[INFO] Cancelled update for {row.name}"); } } else { Console.WriteLine($"[INFO] No updates available for {row.name}"); } } else { Console.WriteLine($"[INFO] No updates available for {row.name}"); } }