public async Task <bool> UpdateFind() { string updatePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Raf-9600", "PlugY Configurator"); string updateUrl = @"https://raw.githubusercontent.com/Raf-9600/PlugY-Configurator/master/PlugY%20Configurator/update.json"; string updateFile = Path.Combine(updatePath, "Update.json"); #if RELEASE if (File.Exists(updateFile)) { DateTime dateFile = File.GetLastWriteTime(updateFile).AddDays(7); DateTime dateThis = DateTime.Today; if (dateThis.Date > dateFile.Date) { try { await DownloadFileAsync(updateUrl, updateFile); } catch (System.Exception) { } } } else { try { await DownloadFileAsync(updateUrl, updateFile); } catch (System.Exception) { } } #endif UpdateStruct updateJson = JsonSerializer.Deserialize <UpdateStruct>(File.ReadAllText(updateFile)); Version versionExe = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; Version versionJson = new Version(updateJson.Ver); if (versionJson > versionExe) { if (Environment.Is64BitProcess) { UrlNewVer = updateJson.Url; } else { UrlNewVer = updateJson.UrlX86; } return(true); } return(false); }
private void CheckForUpdates() { Thread.Sleep(1000); if (Network.SubmitData("getbgchecksums")) { string webResponse = General.WebResponse; if (webResponse.Split('[', ']')[1] == "SUCCESS") { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(webResponse.Replace("[SUCCESS]", "")); foreach (XmlNode xmlNode in xmlDocument) { foreach (XmlNode fileNode in xmlNode) { foreach (XmlNode xmlInformationNode in fileNode) { UpdateStruct u = new UpdateStruct(); switch (xmlInformationNode.Name) { case "filename": u.FileName = xmlInformationNode.InnerText; break; case "checksum": u.Checksum = xmlInformationNode.InnerText; break; } CheckFile(u); } } } } else { MessageBox.Show(webResponse.Replace("[ERROR]", ""), "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } _isFinalUpdate = true; }
private void CheckFile(UpdateStruct u) { if (u.FileName == null) { return; } if (File.Exists(u.FileName)) { if (General.GetMd5(File.ReadAllBytes(u.FileName)) == u.Checksum) { return; } UpdateFile(u.FileName); } else { UpdateFile(u.FileName); } }
IEnumerator UpdateModCoroutine(UpdateStruct item, string tempDirectory) { Logger.log.Debug($"Steam avaliable: {SteamCheck.IsAvailable}"); ApiEndpoint.Mod.PlatformFile platformFile; if (SteamCheck.IsAvailable || item.externInfo.Files.Oculus == null) { platformFile = item.externInfo.Files.Steam; } else { platformFile = item.externInfo.Files.Oculus; } string url = platformFile.DownloadPath; Logger.log.Debug($"URL = {url}"); const int MaxTries = 3; int maxTries = MaxTries; while (maxTries > 0) { if (maxTries-- != MaxTries) { Logger.log.Info($"Re-trying download..."); } using (var stream = new MemoryStream()) using (var request = UnityWebRequest.Get(url)) using (var taskTokenSource = new CancellationTokenSource()) { var dlh = new StreamDownloadHandler(stream); request.downloadHandler = dlh; Logger.log.Debug("Sending request"); //Logger.log.Debug(request?.downloadHandler?.ToString() ?? "DLH==NULL"); yield return(request.SendWebRequest()); Logger.log.Debug("Download finished"); if (request.isNetworkError) { Logger.log.Error("Network error while trying to update mod"); Logger.log.Error(request.error); taskTokenSource.Cancel(); continue; } if (request.isHttpError) { Logger.log.Error($"Server returned an error code while trying to update mod"); Logger.log.Error(request.error); taskTokenSource.Cancel(); continue; } stream.Seek(0, SeekOrigin.Begin); // reset to beginning var downloadTask = Task.Run(() => { // use slightly more multithreaded approach than coroutines ExtractPluginAsync(stream, item, platformFile, tempDirectory); }, taskTokenSource.Token); while (!(downloadTask.IsCompleted || downloadTask.IsCanceled || downloadTask.IsFaulted)) { yield return(null); // pause coroutine until task is done } if (downloadTask.IsFaulted) { Logger.log.Error($"Error downloading mod {item.plugin.Plugin.Name}"); Logger.log.Error(downloadTask.Exception); continue; } break; } } if (maxTries == 0) { Logger.log.Warn($"Plugin download failed {MaxTries} times, not re-trying"); } else { Logger.log.Debug("Download complete"); } }
private void ExtractPluginAsync(MemoryStream stream, UpdateStruct item, ApiEndpoint.Mod.PlatformFile fileInfo, string tempDirectory) { Logger.log.Debug($"Extracting ZIP file for {item.plugin.Plugin.Name}"); var data = stream.GetBuffer(); SHA1 sha = new SHA1CryptoServiceProvider(); var hash = sha.ComputeHash(data); if (!LoneFunctions.UnsafeCompare(hash, fileInfo.Hash)) { throw new Exception("The hash for the file doesn't match what is defined"); } var newFiles = new List <FileInfo>(); var backup = new BackupUnit(tempDirectory, $"backup-{item.plugin.ModsaberInfo.InternalName}"); try { bool shouldDeleteOldFile = true; using (var zipFile = ZipFile.Read(stream)) { Logger.log.Debug("Streams opened"); foreach (var entry in zipFile) { if (entry.IsDirectory) { Logger.log.Debug($"Creating directory {entry.FileName}"); Directory.CreateDirectory(Path.Combine(Environment.CurrentDirectory, entry.FileName)); } else { using (var ostream = new MemoryStream((int)entry.UncompressedSize)) { entry.Extract(ostream); ostream.Seek(0, SeekOrigin.Begin); sha = new SHA1CryptoServiceProvider(); var fileHash = sha.ComputeHash(ostream); if (!LoneFunctions.UnsafeCompare(fileHash, fileInfo.FileHashes[entry.FileName])) { throw new Exception("The hash for the file doesn't match what is defined"); } ostream.Seek(0, SeekOrigin.Begin); FileInfo targetFile = new FileInfo(Path.Combine(Environment.CurrentDirectory, entry.FileName)); Directory.CreateDirectory(targetFile.DirectoryName); if (targetFile.FullName == item.plugin.Filename) { shouldDeleteOldFile = false; // overwriting old file, no need to delete } if (targetFile.Exists) { backup.Add(targetFile); } else { newFiles.Add(targetFile); } Logger.log.Debug($"Extracting file {targetFile.FullName}"); var fstream = targetFile.Create(); ostream.CopyTo(fstream); } } } } if (item.plugin.Plugin is SelfPlugin) { // currently updating self Process.Start(new ProcessStartInfo { FileName = item.plugin.Filename, Arguments = $"--waitfor={Process.GetCurrentProcess().Id} --nowait", UseShellExecute = false }); } else if (shouldDeleteOldFile) { File.Delete(item.plugin.Filename); } } catch (Exception) { // something failed; restore foreach (var file in newFiles) { file.Delete(); } backup.Restore(); backup.Delete(); throw; } backup.Delete(); Logger.log.Debug("Downloader exited"); }