public void CheckForUpdates(HashWebClient.RemoteFileInfo patches) { if (_isChecking) return; _lastPatchesJsonLoc = patches; _isChecking = true; Status = DayZeroLauncherUpdater.STATUS_CHECKINGFORUPDATES; new Thread(() => { try { string patchesFileName = PatchesMeta.GetFileName(); PatchesMeta patchInfo = null; HashWebClient.DownloadWithStatusDots(patches, patchesFileName, DayZeroLauncherUpdater.STATUS_CHECKINGFORUPDATES, newStatus => { Status = newStatus; }, (wc, fileInfo, destPath) => { patchInfo = PatchesMeta.LoadFromFile(patchesFileName); }); if (patchInfo != null) { Status = DayZeroLauncherUpdater.STATUS_CHECKINGFORUPDATES; Thread.Sleep(100); try { PatchesMeta.PatchInfo thePatch = patchInfo.Updates.Where(x => x.Version == patchInfo.LatestRevision).Single(); SetLatestServerVersion(thePatch); Status = VersionMismatch ? (DayZeroLauncherUpdater.STATUS_OUTOFDATE) : (DayZeroLauncherUpdater.STATUS_UPTODATE); } catch (Exception) { Status = "Could not determine revision"; } } } finally { _isChecking = false; } }).Start(); }
public void CheckForUpdates(HashWebClient.RemoteFileInfo mods) { if (_isChecking) return; _lastModsJsonLoc = mods; _isChecking = true; new Thread(() => { try { string modsFileName = ModsMeta.GetFileName(); ModsMeta modsInfo = null; HashWebClient.DownloadWithStatusDots(mods, modsFileName, DayZeroLauncherUpdater.STATUS_CHECKINGFORUPDATES, newStatus => { Status = newStatus; }, (wc, fileInfo, destPath) => { modsInfo = ModsMeta.LoadFromFile(modsFileName); }); if (modsInfo != null) { Status = DayZeroLauncherUpdater.STATUS_CHECKINGFORUPDATES; Thread.Sleep(100); try { ModsMeta.ModInfo theMod = modsInfo.Mods.Where(x => x.Version.Equals(modsInfo.LatestModVersion, StringComparison.OrdinalIgnoreCase)) .Single(); SetLatestModVersion(theMod); string currVersion = CalculatedGameSettings.Current.ModContentVersion; if (!theMod.Version.Equals(currVersion, StringComparison.OrdinalIgnoreCase)) { Status = DayZeroLauncherUpdater.STATUS_OUTOFDATE; //this lets them seed/repair version they already have if it's not discontinued ModsMeta.ModInfo currMod = modsInfo.Mods.SingleOrDefault(x => x.Version.Equals(currVersion, StringComparison.OrdinalIgnoreCase)); if (currMod != null) DownloadSpecificVersion(currMod, false); else //try getting it from file cache (necessary for switching branches) DownloadLocalVersion(currVersion, false); } else { Status = DayZeroLauncherUpdater.STATUS_UPTODATE; DownloadLatestVersion(false); } } catch (Exception) { Status = "Could not determine revision"; } } } finally { _isChecking = false; } }).Start(); }
public static void DownloadWithStatusDots(RemoteFileInfo fileInfo, string destPath, string initialStatus, StatusChangeString statusCb, StatusDownloadComplete finishCb) { using (var downloadingEvt = new ManualResetEvent(false)) { string updateInfoString = initialStatus.Replace("...", String.Empty); statusCb(updateInfoString); var wc = new HashWebClient(); wc.DownloadFileCompleted += (source, evt) => { if (evt.Cancelled) statusCb("Async operation cancelled"); else if (evt.Error != null) statusCb(evt.Error.Message); else { try { if (finishCb != null) finishCb(wc, fileInfo, destPath); } catch (Exception ex) { statusCb(ex.Message); } } downloadingEvt.Set(); }; wc.BeginDownload(fileInfo, destPath); int numDots = 0; uint loops = 0; while (downloadingEvt.WaitOne(10) == false) { if (loops >= 10) { numDots = (numDots + 1)%3; statusCb(updateInfoString + new String('.', numDots)); loops = 0; } loops++; } if (wc != null) { wc.Dispose(); wc = null; } } }
public TorrentUpdater(string versionString, List<MetaAddon> addOns, bool fullSystemCheck, TorrentLauncher downloader, DayZUpdater updater, bool errorMsgsOnly) { addOnTorrents = new List<AddOnTorrent>(); this.versionString = versionString; this.fullSystemCheck = fullSystemCheck; this.downloader = downloader; this.updater = updater; this.errorMsgsOnly = errorMsgsOnly; string torrentsDir = null; try { torrentsDir = Path.Combine(UserSettings.ContentMetaPath, versionString); { var dirInfo = new DirectoryInfo(torrentsDir); if (!dirInfo.Exists) dirInfo = Directory.CreateDirectory(torrentsDir); } } catch (Exception ex) { updater.Status = "Error creating torrents directory"; downloader.Status = ex.Message; downloader.IsRunning = false; return; } foreach (MetaAddon addOn in addOns) { var newAddOn = new AddOnTorrent(); newAddOn.Meta = addOn; newAddOn.torrentFileName = Path.Combine(torrentsDir, newAddOn.Meta.Description + "-" + newAddOn.Meta.Version + ".torrent"); newAddOn.torrentSavePath = null; //will be filled in if successfull download addOnTorrents.Add(newAddOn); } //delete .torrent files that do not match the ones we want string[] allTorrents = Directory.GetFiles(torrentsDir, "*.torrent", SearchOption.TopDirectoryOnly); foreach (string torrentPath in allTorrents) { if ( addOnTorrents.Count( naot => { return naot.torrentFileName.Equals(torrentPath, StringComparison.InvariantCultureIgnoreCase); }) < 1) { //this is an unwanted torrent file try { var fileInfo = new FileInfo(torrentPath); if (fileInfo.IsReadOnly) { fileInfo.IsReadOnly = false; fileInfo.Refresh(); } fileInfo.Delete(); } catch (Exception) { } } } for (int i = 0; i < addOnTorrents.Count; i++) { int idxCopy = i; AddOnTorrent newAddOn = addOnTorrents[i]; try { var wc = new HashWebClient(); wc.DownloadFileCompleted += (sender, args) => { TorrentDownloadComplete(sender, args, idxCopy); }; wc.BeginDownload(newAddOn.Meta.Torrent, newAddOn.torrentFileName); } catch (Exception ex) { updater.Status = "Error starting torrent file download"; downloader.Status = ex.Message; downloader.IsRunning = false; return; } } }
private void StartInstallerDownload(int arrIdx) { InstallersMeta.InstallerInfo inst = installers.ElementAt(arrIdx); LowerProgressText = "Downloading " + inst.Archive.Url; LowerProgressValue = 0; LowerProgressLimit = 100; var wc = new HashWebClient(); wc.DownloadProgressChanged += (sender, args) => { LowerProgressValue = args.ProgressPercentage; }; wc.DownloadFileCompleted += (sender, args) => { if (HandlePossibleError("Error " + UpperProgressText, args)) return; LowerProgressLimit = 100; LowerProgressValue = 100; UpperProgressValue = UpperProgressValue + 1; if (UpperProgressValue == UpperProgressLimit) //downloaded all installers VerifyAndInstallPackages(); else StartInstallerDownload(arrIdx + 1); }; wc.BeginDownload(inst.Archive, inst.GetArchiveFileName()); }
protected void GetInstallersMeta() { Closeable = false; UpperProgressValue = 0; UpperProgressLimit = 1; LocatorInfo locator = CalculatedGameSettings.Current.Locator; if (locator == null) { UpperProgressText = "Please check for updates first."; UpperProgressLimit = 0; Closeable = true; return; } UpperProgressText = "Getting installer info..."; string installersFileName = InstallersMeta.GetFileName(); var wc = new HashWebClient(); wc.DownloadProgressChanged += (sender, args) => { UpperProgressLimit = 100; UpperProgressValue = args.ProgressPercentage; }; wc.DownloadFileCompleted += (sender, args) => { if (HandlePossibleError("Installer index download failed", args)) return; UpperProgressLimit = 100; UpperProgressValue = 100; UpperProgressText = "Parsing installer info..."; InstallersMeta newInsts = null; try { newInsts = InstallersMeta.LoadFromFile(installersFileName); } catch (Exception ex) { HandleException("Error parsing installer info", ex); return; } var wntInsts = new List<InstallersMeta.InstallerInfo>(); try { foreach (MetaAddon addon in addOns) { InstallersMeta.InstallerInfo instMatch = wntInsts.FirstOrDefault(x => { return String.Equals(x.Version, addon.InstallerName); }); if (instMatch == null) instMatch = newInsts.Installers.FirstOrDefault(x => { return String.Equals(x.Version, addon.InstallerName); }); if (instMatch == null) throw new InstallerNotFound(addon.InstallerName); wntInsts.Add(instMatch); } } catch (Exception ex) { HandleException("Error matching installers", ex); return; } installers = wntInsts; DownloadInstallerPackages(); }; wc.BeginDownload(locator.Installers, installersFileName); }
public void DownloadAndInstall(int revision, HashWebClient.RemoteFileInfo archiveInfo, bool steamBeta, string steamBuild, UpdatesView view) { if (steamBeta) { const int appId = 33930; string gameName = "Arma 2: Operation Arrowhead Beta"; DirectoryInfo armaPath = null; try { armaPath = new DirectoryInfo(CalculatedGameSettings.Current.Arma2OAPath); } catch (ArgumentException aex) { bool overridenPath = string.IsNullOrWhiteSpace(UserSettings.Current.GameOptions.Arma2OADirectoryOverride); Execute.OnUiThreadSync(() => { var popup = new InfoPopup("Invalid path", MainWindow.GetWindow(view)); popup.Headline.Content = "Game could not be found"; popup.SetMessage(overridenPath ? "Invalid game override path, please enter a new game path or remove it" : "Game could not located via the registry, please enter an override path"); popup.Show(); }, null, DispatcherPriority.Input); return; } for (armaPath = armaPath.Parent; armaPath != null; armaPath = armaPath.Parent) { if (armaPath.Name.Equals("steamapps", StringComparison.OrdinalIgnoreCase)) { string manifestName = "appmanifest_" + appId.ToString() + ".acf"; string fullManifestPath = Path.Combine(armaPath.FullName, manifestName); if (File.Exists(fullManifestPath)) { // Kill Steam so we can edit the game configuration. Process[] processes = Process.GetProcessesByName("Steam"); foreach (Process process in processes) { // #YOLO try { process.Kill(); process.WaitForExit(); } catch { MessageBox.Show("Unable to shut down steam to start patching.", "Patch error", MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } } var acfKeys = new KeyValue(); var reader = new StreamReader(fullManifestPath); var acfReader = new KVTextReader(acfKeys, reader.BaseStream); reader.Close(); KeyValue currentBuild = acfKeys.Children.FirstOrDefault(k => k.Name == "buildid"); if (!String.IsNullOrEmpty(currentBuild.Value)) { if (Equals(currentBuild.Value, steamBuild)) { Execute.OnUiThreadSync(() => { var popup = new InfoPopup("User intervention required", MainWindow.GetWindow(view)); popup.Headline.Content = "Game update using Steam"; popup.SetMessage(gameName + " might be corrupted.\n" + "Please validate your client files manually.\n" + "Or by clicking on the following link:"); popup.SetLink("steam://validate/" + appId.ToString() + "/", "Update " + gameName); popup.Closed += (sender, args) => view.CheckForUpdates(); popup.Show(); }, null, DispatcherPriority.Input); } else { KeyValue gameState = acfKeys.Children.FirstOrDefault(k => k.Name == "StateFlags"); if (!String.IsNullOrEmpty(gameState.Value)) { currentBuild.Value = steamBuild; gameState.Value = "2"; acfKeys.SaveToFile(fullManifestPath, false); Thread.Sleep(1000); Execute.OnUiThreadSync(() => { var popup = new InfoPopup("User intervention required", MainWindow.GetWindow(view)); popup.Headline.Content = "Game update using Steam"; popup.SetMessage(gameName + " branch switched to BETA.\n" + "Please restart Steam to download update."); popup.Closed += (sender, args) => view.CheckForUpdates(); popup.Show(); }, null, DispatcherPriority.Input); } } } else { MessageBox.Show("Patching failed, '" + gameName + "' is not located inside a SteamLibrary folder.", "Patch error", MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } return; } else { Execute.OnUiThreadSync(() => { var popup = new InfoPopup("User intervention required", MainWindow.GetWindow(view)); popup.Headline.Content = "Game update using Steam"; popup.SetMessage(gameName + " is not installed.\n" + "Please install it from the Library tab.\n" + "Or by clicking on the following link:"); popup.SetLink("steam://install/" + appId.ToString() + "/", "Install " + gameName); popup.Closed += (sender, args) => view.CheckForUpdates(); popup.Show(); }, null, DispatcherPriority.Input); return; } } } if (armaPath == null) { MessageBox.Show("Patching failed, '" + gameName + "' is not located inside a SteamLibrary folder.", "Patch error", MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } } else { DownloadAndInstall(revision, archiveInfo); } }
public void DownloadAndInstall(int revision, HashWebClient.RemoteFileInfo archiveInfo) { IsRunning = true; Status = "Getting file info..."; string extractedFolderLocation = Path.Combine(UserSettings.PatchesPath, revision.ToString()); string zipFileLocation = extractedFolderLocation + ".zip"; var wc = new HashWebClient(); wc.DownloadProgressChanged += (sender, args) => { Status = string.Format("Downloading... {0}%", args.ProgressPercentage); }; wc.DownloadFileCompleted += (sender, args) => { if (args.Error != null) { Status = "Error: " + args.Error.Message; IsRunning = false; return; } ExtractFile(zipFileLocation, extractedFolderLocation); }; wc.BeginDownload(archiveInfo, zipFileLocation); }
public void StartFromNetContent(string versionString, bool forceFullSystemsCheck, HashWebClient.RemoteFileInfo jsonIndex, DayZUpdater updater, bool errorMsgsOnly = false) { if (jsonIndex == null) { MessageBox.Show("No version index specified, please Check first.", "Error initiating torrent download", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (string.IsNullOrWhiteSpace(versionString)) { MessageBox.Show("Invalid version specified for download", "Error initiating torrent download", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (IsRunning) { if (_updatingVersion.Equals(versionString, StringComparison.OrdinalIgnoreCase)) return; //already running for this same version } _updatingVersion = versionString; if (!errorMsgsOnly) updater.Status = DayZeroLauncherUpdater.STATUS_DOWNLOADING; Status = "Initiating Download..."; string metaJsonFilename = MetaModDetails.GetFileName(versionString); var wc = new HashWebClient(); wc.DownloadFileCompleted += (sender, args) => { if (args.Cancelled) { Status = updater.Status = "Async operation cancelled"; IsRunning = false; _gameLauncher.SetModDetails(null, true, null); } else if (args.Error != null) { updater.Status = "Error downloading content index file"; Status = args.Error.Message; IsRunning = false; _gameLauncher.SetModDetails(null, false, args.Error); } else ContinueFromContentFile(versionString, metaJsonFilename, forceFullSystemsCheck, updater, errorMsgsOnly); }; wc.BeginDownload(jsonIndex, metaJsonFilename); }