/// <summary> /// Downloads a mod for updating. /// </summary> /// <param name="release">The mods release to be downloaded.</param> /// <param name="username">The username.</param> /// <param name="token">The login token.</param> /// <param name="progress">A progress object used to report the progress of the operation.</param> /// <param name="cancellationToken">A cancelation token that can be used to cancel the operation.</param> public static async Task <ModFile> DownloadUpdateAsync(ModRelease release, string username, string token, IProgress <double> progress, CancellationToken cancellationToken) { DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(release.InfoFile.FactorioVersion); if (!modDirectory.Exists) { modDirectory.Create(); } var downloadUrl = BuildUrl(release, username, token); var file = new FileInfo(Path.Combine(modDirectory.FullName, release.FileName)); await WebHelper.DownloadFileAsync(downloadUrl, null, file, progress, cancellationToken); if (cancellationToken.IsCancellationRequested) { return(null); } ModFile modFile; if (!ModFile.TryLoadFromFile(file, out modFile)) { throw new InvalidOperationException("The server sent an invalid mod file."); } return(modFile); }
/// <summary> /// Checks if a dependency is present on the mod portal. /// </summary> public bool IsPresent(ExtendedModInfo modInfo, Version factorioVersion, out ModRelease release) { bool result = false; release = null; if (IsBase || IsInverted) { result = true; } else if (HasRestriction) { var comparison = comparisonFunctions[RestrictionComparison]; var candidates = modInfo.Releases.Where(item => (item.InfoFile.FactorioVersion == factorioVersion) && comparison(item.Version, RestrictionVersion)); release = candidates.MaxBy(candidate => candidate.Version, new VersionComparer()); result = release != null; } else { var candidates = modInfo.Releases.Where(item => item.InfoFile.FactorioVersion == factorioVersion); release = candidates.MaxBy(candidate => candidate.Version, new VersionComparer()); result = release != null; } return(result); }
private async Task UpdateModAsyncInner(Mod oldMod, ModRelease newestRelease, string token, IProgress <double> progress, CancellationToken cancellationToken) { FileInfo modFile = await ModWebsite.UpdateReleaseAsync(newestRelease, GlobalCredentials.Instance.Username, token, progress, cancellationToken); Mod newMod; if (App.Instance.Settings.AlwaysUpdateZipped || (oldMod is ZippedMod)) { newMod = new ZippedMod(oldMod.Name, newestRelease.Version, newestRelease.FactorioVersion, modFile, InstalledMods, InstalledModpacks); } else { DirectoryInfo modDirectory = await Task.Run(() => { progress.Report(2); DirectoryInfo modsDirectory = App.Instance.Settings.GetModDirectory(newestRelease.FactorioVersion); ZipFile.ExtractToDirectory(modFile.FullName, modsDirectory.FullName); modFile.Delete(); return(new DirectoryInfo(Path.Combine(modsDirectory.FullName, modFile.NameWithoutExtension()))); }); newMod = new ExtractedMod(oldMod.Name, newestRelease.Version, newestRelease.FactorioVersion, modDirectory, InstalledMods, InstalledModpacks); } InstalledMods.Add(newMod); if (oldMod.Update(newMod)) { InstalledModpacks.ExchangeMods(oldMod, newMod); } ModpackTemplateList.Instance.Update(InstalledModpacks); ModpackTemplateList.Instance.Save(); }
/// <summary> /// Downloads a mod. /// </summary> /// <param name="release">The mods release to be downloaded.</param> /// <param name="username">The username.</param> /// <param name="token">The login token.</param> /// <param name="fileName">The destination file name.</param> /// <param name="progress">A progress object used to report the progress of the operation.</param> /// <param name="cancellationToken">A cancelation token that can be used to cancel the operation.</param> public static async Task <Mod> DownloadReleaseToFileAsync(ModRelease release, string username, string token, string fileName, IProgress <double> progress, CancellationToken cancellationToken) { if (username == null || token == null) { return(null); } DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(release.InfoFile.FactorioVersion); if (!modDirectory.Exists) { modDirectory.Create(); } var downloadUrl = BuildUrl(release, username, token); var modFile = new FileInfo(fileName); try { await WebHelper.DownloadFileAsync(downloadUrl, null, modFile, progress, cancellationToken); } catch (Exception) { if (modFile.Exists) { modFile.Delete(); } throw; } return(null); }
public ModUpdateInfo(string modName, string friendlyName, ModRelease update) { ModName = modName; FriendlyName = friendlyName; Update = update; isSelected = true; ModVersions = new List <ModVersionUpdateInfo>(); }
public ModUpdateInfo(string title, string name, Version currentVersion, Version newestVersion, Mod mod, ModRelease newestRelease) { Title = title; Name = name; CurrentVersion = currentVersion; NewestVersion = newestVersion; Mod = mod; NewestRelease = newestRelease; isSelected = true; }
public ModUpdateInfo(Mod mod, ModRelease newestRelease) { Title = mod.Title; Name = mod.Name; CurrentVersion = mod.Version; NewestVersion = newestRelease.Version; Mod = mod; NewestRelease = newestRelease; FactorioVersion = mod.FactorioVersion; isSelected = true; }
private ModRelease GetNewestRelease(ExtendedModInfo info, ModRelease currentRelease) { if (App.Instance.Settings.ManagerMode == ManagerMode.PerFactorioVersion) { return(info.Releases.Where(release => release.FactorioVersion == currentRelease.FactorioVersion) .MaxBy(release => release.Version, new VersionComparer())); } else { return(info.Releases.MaxBy(release => release.Version, new VersionComparer())); } }
public ModUpdateInfo(Mod mod, ModRelease newestRelease, bool exchangeInModpacks, bool keepOld) { Title = mod.Title; Name = mod.Name; CurrentVersion = mod.Version; NewestVersion = newestRelease.Version; Mod = mod; NewestRelease = newestRelease; CurrentFactorioVersion = mod.FactorioVersion; NewestFactorioVersion = newestRelease.InfoFile.FactorioVersion; ExchangeInModpacks = exchangeInModpacks; KeepOld = keepOld; isSelected = true; }
private async Task DownloadModRelease(ModExportTemplate modTemplate, ModRelease release, DirectoryInfo fileLocation, IProgress <double> progress, CancellationToken cancellationToken) { if (Mods.TryGetMod(modTemplate.Name, release.Version, out Mod installedMod)) { modTemplate.Mod = installedMod; return; } string token; GlobalCredentials.Instance.LogIn(Window, out token); string fileName = Path.Combine(fileLocation.FullName, $"{modTemplate.Uid}+{release.FileName}"); await ModWebsite.DownloadReleaseToFileAsync(release, GlobalCredentials.Instance.Username, token, fileName, progress, cancellationToken); }
/// <summary> /// Downloads a mod for updating. /// </summary> /// <param name="release">The mods release to be downloaded.</param> /// <param name="username">The username.</param> /// <param name="token">The login token.</param> /// <param name="progress">A progress object used to report the progress of the operation.</param> /// <param name="cancellationToken">A cancelation token that can be used to cancel the operation.</param> public static async Task <FileInfo> UpdateReleaseAsync(ModRelease release, string username, string token, IProgress <double> progress, CancellationToken cancellationToken) { DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(release.FactorioVersion); if (!modDirectory.Exists) { modDirectory.Create(); } var downloadUrl = new Uri($"{BaseUrl}{release.DownloadUrl}?username={username}&token={token}"); var modFile = new FileInfo(Path.Combine(modDirectory.FullName, release.FileName)); await WebHelper.DownloadFileAsync(downloadUrl, null, modFile, progress, cancellationToken); return(cancellationToken.IsCancellationRequested ? null : modFile); }
/// <summary> /// Downloads a mod. /// </summary> /// <param name="release">The mods release to be downloaded.</param> /// <param name="username">The username.</param> /// <param name="token">The login token.</param> /// <param name="progress">A progress object used to report the progress of the operation.</param> /// <param name="cancellationToken">A cancelation token that can be used to cancel the operation.</param> /// <param name="parentCollection">The collection to contain the mods.</param> /// <param name="modpackCollection">The collection containing all modpacks.</param> public static async Task <Mod> DownloadReleaseAsync(ModRelease release, string username, string token, IProgress <double> progress, CancellationToken cancellationToken, ICollection <Mod> parentCollection, ICollection <Modpack> modpackCollection) { DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(release.InfoFile.FactorioVersion); if (!modDirectory.Exists) { modDirectory.Create(); } var downloadUrl = BuildUrl(release, username, token); Debug.Print(token); var modFile = new FileInfo(Path.Combine(modDirectory.FullName, release.FileName)); try { await WebHelper.DownloadFileAsync(downloadUrl, null, modFile, progress, cancellationToken); if (!cancellationToken.IsCancellationRequested) { Version factorioVersion; string name; Version version; if (Mod.ArchiveFileValid(modFile, out factorioVersion, out name, out version)) { if (factorioVersion == release.InfoFile.FactorioVersion) { return(new ZippedMod(name, version, factorioVersion, modFile, parentCollection, modpackCollection)); } } throw new InvalidOperationException("The server sent an invalid mod file."); } } catch (Exception) { if (modFile.Exists) { modFile.Delete(); } throw; } return(null); }
/// <summary> /// Downloads a mod. /// </summary> /// <param name="release">The mods release to be downloaded.</param> /// <param name="username">The username.</param> /// <param name="token">The login token.</param> /// <param name="progress">A progress object used to report the progress of the operation.</param> /// <param name="cancellationToken">A cancelation token that can be used to cancel the operation.</param> /// <param name="parentCollection">The collection to contain the mods.</param> /// <param name="modpackCollection">The collection containing all modpacks.</param> public static async Task <Mod> DownloadReleaseAsync(ModRelease release, string username, string token, IProgress <double> progress, CancellationToken cancellationToken, ModCollection parentCollection, ModpackCollection modpackCollection) { DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(release.InfoFile.FactorioVersion); if (!modDirectory.Exists) { modDirectory.Create(); } var downloadUrl = BuildUrl(release, username, token); var file = new FileInfo(Path.Combine(modDirectory.FullName, release.FileName)); try { await WebHelper.DownloadFileAsync(downloadUrl, null, file, progress, cancellationToken); if (!cancellationToken.IsCancellationRequested) { if (ModFile.TryLoadFromFile(file, out ModFile modFile)) { if (modFile.InfoFile.FactorioVersion == release.InfoFile.FactorioVersion) { return(await Mod.Add(modFile, parentCollection, modpackCollection, false)); } } throw new InvalidOperationException("The server sent an invalid mod file."); } } catch (Exception) { if (file.Exists) { file.Delete(); } throw; } return(null); }
private async Task DownloadIncludedMod(ModExportTemplate modTemplate, DirectoryInfo fileLocation, ExtendedModInfo info, IProgress <double> progress, CancellationToken cancellationToken) { var file = GetIncludedFileOrDirectory(modTemplate, fileLocation); if ((file == null) || !file.Exists) // File should exist, download if it doesn't { await DownloadExcludedMod(modTemplate, fileLocation, info, progress, cancellationToken); return; } ModRelease targetRelease = null; switch (modTemplate.MaskedExportMode) { case ExportMode.NewestVersion: targetRelease = info.Releases.MaxBy(release => release.Version); break; case ExportMode.SpecificVersion: targetRelease = info.Releases.FirstOrDefault(release => release.Version == modTemplate.Version); break; case ExportMode.FactorioVersion: targetRelease = info.Releases.Where(release => release.InfoFile.FactorioVersion == modTemplate.FactorioVersion).MaxBy(release => release.Version); break; } if (targetRelease != null) { var fileVersion = GetVersionFromFile(file); if (fileVersion != targetRelease.Version) { file.Delete(); await DownloadModRelease(modTemplate, targetRelease, fileLocation, progress, cancellationToken); } } }
private async Task UpdateSelectedModRelease() { string token; if (GlobalCredentials.Instance.LogIn(Window, out token)) { ModRelease newestRelease = GetNewestRelease(ExtendedInfo, SelectedRelease); Mod mod = InstalledMods.FindByFactorioVersion(SelectedMod.Name, newestRelease.FactorioVersion); var zippedMod = mod as ZippedMod; var extractedMod = mod as ExtractedMod; var cancellationSource = new CancellationTokenSource(); var progressWindow = new ProgressWindow { Owner = Window }; var progressViewModel = (ProgressViewModel)progressWindow.ViewModel; progressViewModel.ActionName = App.Instance.GetLocalizedResourceString("UpdatingAction"); progressViewModel.ProgressDescription = string.Format(App.Instance.GetLocalizedResourceString("DownloadingDescription"), newestRelease.FileName); progressViewModel.CanCancel = true; progressViewModel.CancelRequested += (sender, e) => cancellationSource.Cancel(); IProgress <double> progress = new Progress <double>(p => { if (p > 1) { progressViewModel.ProgressDescription = App.Instance.GetLocalizedResourceString("ExtractingDescription"); progressViewModel.IsIndeterminate = true; progressViewModel.CanCancel = false; } else { progressViewModel.Progress = p; } }); try { Task closeWindowTask = null; try { Task downloadTask = ModWebsite.UpdateReleaseAsync(newestRelease, GlobalCredentials.Instance.Username, token, progress, cancellationSource.Token); if (extractedMod != null) { downloadTask = downloadTask.ContinueWith(t => { progress.Report(2); FileInfo modFile = ((Task <FileInfo>)t).Result; DirectoryInfo modDirectory = App.Instance.Settings.GetModDirectory(newestRelease.FactorioVersion); ZipFile.ExtractToDirectory(modFile.FullName, modDirectory.FullName); modFile.Delete(); return(new DirectoryInfo(Path.Combine(modDirectory.FullName, modFile.NameWithoutExtension()))); }, TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.NotOnCanceled); } closeWindowTask = downloadTask.ContinueWith(t => progressWindow.Dispatcher.Invoke(progressWindow.Close)); progressWindow.ShowDialog(); if (zippedMod != null) { FileInfo newModFile = await(Task <FileInfo>) downloadTask; if (zippedMod.FactorioVersion == newestRelease.FactorioVersion) { zippedMod.Update(newModFile, newestRelease.Version); } else { var newMod = new ZippedMod(zippedMod.Name, newestRelease.Version, newestRelease.FactorioVersion, newModFile, InstalledMods, MainViewModel.Instance.Modpacks); InstalledMods.Add(newMod); foreach (var modpack in MainViewModel.Instance.Modpacks) { ModReference reference; if (modpack.Contains(zippedMod, out reference)) { modpack.Mods.Remove(reference); modpack.Mods.Add(new ModReference(newMod, modpack)); } } zippedMod.File.Delete(); InstalledMods.Remove(extractedMod); } } if (extractedMod != null) { DirectoryInfo newModDirectory = await(Task <DirectoryInfo>) downloadTask; if (extractedMod.FactorioVersion == newestRelease.FactorioVersion) { extractedMod.Update(newModDirectory, newestRelease.Version); } else { var newMod = new ExtractedMod(extractedMod.Name, newestRelease.Version, newestRelease.FactorioVersion, newModDirectory, InstalledMods, MainViewModel.Instance.Modpacks); InstalledMods.Add(newMod); foreach (var modpack in MainViewModel.Instance.Modpacks) { ModReference reference; if (modpack.Contains(extractedMod, out reference)) { modpack.Mods.Remove(reference); modpack.Mods.Add(new ModReference(newMod, modpack)); } } extractedMod.Directory.Delete(true); InstalledMods.Remove(extractedMod); ModpackTemplateList.Instance.Update(MainViewModel.Instance.Modpacks); ModpackTemplateList.Instance.Save(); } } } finally { if (closeWindowTask != null) { await closeWindowTask; } } } catch (HttpRequestException) { MessageBox.Show(Window, App.Instance.GetLocalizedMessage("InternetConnection", MessageType.Error), App.Instance.GetLocalizedMessageTitle("InternetConnection", MessageType.Error), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedRelease = null; foreach (var release in SelectedReleases) { release.IsInstalled = InstalledMods.Contains(selectedMod.Name, release.Version); release.IsVersionInstalled = !release.IsInstalled && InstalledMods.ContainsByFactorioVersion(selectedMod.Name, release.FactorioVersion); } } }
private OnlineModsViewModel() { InstalledMods = MainViewModel.Instance.Mods; InstalledModpacks = MainViewModel.Instance.Modpacks; SelectedReleases = new ObservableCollection <ModRelease>(); asyncFetchExtendedInfoIndex = -1; DownloadCommand = new RelayCommand(async() => await DownloadSelectedModRelease(), () => SelectedRelease != null && !SelectedRelease.IsInstalled); UpdateCommand = new RelayCommand(async() => await UpdateSelectedModRelease(), () => { ModRelease newestRelease = GetNewestRelease(ExtendedInfo); return((SelectedRelease != null) && SelectedRelease.IsInstalled && !newestRelease.IsInstalled && (SelectedRelease != newestRelease)); }); DeleteCommand = new RelayCommand(DeleteSelectedModRelease, () => SelectedRelease != null && SelectedRelease.IsInstalled); RefreshCommand = new RelayCommand(async() => await RefreshModList()); OpenLicenseLinkCommand = new RelayCommand(() => { string url = SelectedMod.LicenseUrl; if (!string.IsNullOrWhiteSpace(url)) { try { Process.Start(url); } catch { } } }); OpenHomepageCommand = new RelayCommand(() => { string url = SelectedMod.Homepage; if (!string.IsNullOrWhiteSpace(url)) { try { Process.Start(url); } catch { } } }); OpenGitHubLinkCommand = new RelayCommand(() => { const string prefix = "https://www.github.com/"; string url = SelectedMod.GitHubUrl; if (!url.StartsWith(prefix)) { url = prefix + url; } if (!string.IsNullOrWhiteSpace(url)) { try { Process.Start(url); } catch { } } }); ClearFilterCommand = new RelayCommand(() => Filter = string.Empty); }
private async Task UpdateSelectedModRelease() { string token; if (GlobalCredentials.Instance.LogIn(Window, out token)) { ModRelease newestRelease = GetNewestRelease(ExtendedInfo); Mod oldMod = InstalledMods.Find(SelectedMod.Name).MaxBy(mod => mod.Version); var cancellationSource = new CancellationTokenSource(); var progressWindow = new ProgressWindow { Owner = Window }; var progressViewModel = (ProgressViewModel)progressWindow.ViewModel; progressViewModel.ActionName = App.Instance.GetLocalizedResourceString("UpdatingAction"); progressViewModel.ProgressDescription = string.Format(App.Instance.GetLocalizedResourceString("DownloadingDescription"), newestRelease.FileName); progressViewModel.CanCancel = true; progressViewModel.CancelRequested += (sender, e) => cancellationSource.Cancel(); IProgress <double> progress = new Progress <double>(p => { if (p > 1) { progressViewModel.ProgressDescription = App.Instance.GetLocalizedResourceString("ExtractingDescription"); progressViewModel.IsIndeterminate = true; progressViewModel.CanCancel = false; } else { progressViewModel.Progress = p; } }); try { Task closeWindowTask = null; try { Task updateTask = UpdateModAsyncInner(oldMod, newestRelease, token, progress, cancellationSource.Token); closeWindowTask = updateTask.ContinueWith(t => progressWindow.Dispatcher.Invoke(progressWindow.Close)); progressWindow.ShowDialog(); await updateTask; } finally { if (closeWindowTask != null) { await closeWindowTask; } } } catch (HttpRequestException) { MessageBox.Show(Window, App.Instance.GetLocalizedMessage("InternetConnection", MessageType.Error), App.Instance.GetLocalizedMessageTitle("InternetConnection", MessageType.Error), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedRelease = null; foreach (var release in SelectedReleases) { release.IsInstalled = InstalledMods.Contains(selectedMod.Name, release.Version); release.IsVersionInstalled = !release.IsInstalled && InstalledMods.ContainsByFactorioVersion(selectedMod.Name, release.FactorioVersion); } } }
//private static bool IsEmail(string username) //{ // string[] parts = username.Split('@'); // if (parts.Length != 2) return false; // string domain = parts[1]; // int dotIndex = domain.LastIndexOf('.'); // return (dotIndex < (domain.Length - 1)); //} private static Uri BuildUrl(ModRelease release, string username, string token) { return(new Uri($"{BaseUrl}{release.DownloadUrl}?username={username}&token={token}")); }