void DownloadWorker_DoWork(object sender, DoWorkEventArgs e) { DownloadArguments args = (DownloadArguments)e.Argument; RemoteIndex remoteIndex = WebAPI.GetIndex(); // determine files to delete AddonGroup addonGroup = args.AddonGroup; foreach (RemoteAddon webAddon in addonGroup.RemoteAddons) { Uuid webAddonUuid = webAddon.Uuid; if (!FileIndexer.Instance.addonUuidToLocalAddonMap.ContainsKey(webAddonUuid)) { continue; } RemoteAddon remAddon = remoteIndex.FilesIndex[webAddon.Uuid]; List <LocalAddon> localAddons = FileIndexer.Instance.addonUuidToLocalAddonMap[webAddonUuid]; foreach (LocalAddon localAddon in localAddons) { List <FilePath> removals = new(); foreach (LocalFileIndex fileIndex in localAddon.Files.Values) { FilePath relativeFilepath = fileIndex.Relative_filepath; if (!remAddon.Files.ContainsKey(relativeFilepath.Replace("\\", "/"))) { FilePath filePath = fileIndex.Absolute_filepath; Log.Debug("deleting " + filePath); removals.Add(filePath); File.Delete(@filePath.Value); } } foreach (FilePath removal in removals) { localAddon.Files.Remove(removal); } } } // determine files to download downloadManager = new DownloadManager(args.AddonGroup); downloadManager.StateChanged += DownloadManager_StateChanged; downloadManager.ProgressChanged += DownloadManager_ProgressChanged; foreach (RemoteAddon webAddon in addonGroup.RemoteAddons) { RemoteAddon remoteAddon = FileIndexer.Instance.RemoteIndex.FilesIndex[webAddon.Uuid]; Uuid uuid = webAddon.Uuid; string name = webAddon.Name; if (!remoteAddon.Uuid.Equals(uuid)) { throw new InvalidOperationException(string.Format("uuid {0} of local addon {1} does not match remote uuid {2} of addon {3}", uuid, name, remoteAddon.Uuid, remoteAddon.Name)); } FilePath destinationFolder = args.DownloadDirectoryDict[webAddon]; if (!FileIndexer.Instance.addonUuidToLocalAddonMap.ContainsKey(uuid)) { // download all foreach (RemoteAddonFile remoteAddonFile in remoteAddon.Files.Values) { FilePath remoteFilePath = remoteAddonFile.Path; FilePath destinationFilePath = FilePath.Combine(destinationFolder, remoteFilePath.Replace("/", "\\")); downloadManager.AddDownload(WebAPI.RepoUrl + "/" + remoteFilePath.OriginalValue, destinationFilePath, remoteAddonFile.Size); } } else { Dictionary <FilePath, LocalFileIndex> relativeFilePathToFileIndexMap = new(); List <LocalAddon> localAddons = FileIndexer.Instance.addonUuidToLocalAddonMap[uuid]; foreach (LocalAddon localAddon in localAddons) { foreach (LocalFileIndex fileIndex in localAddon.Files.Values) { relativeFilePathToFileIndexMap.Add(fileIndex.Relative_filepath, fileIndex); } } // parts of the addon already exist, update existing and download missing foreach (RemoteAddonFile remoteAddonFile in remoteAddon.Files.Values) { FilePath remoteFilePath = remoteAddonFile.Path.Replace("/", "\\"); string remoteHash = remoteAddonFile.Hash; if (relativeFilePathToFileIndexMap.ContainsKey(remoteFilePath)) { LocalFileIndex localFileIndex = relativeFilePathToFileIndexMap[remoteFilePath]; if (!remoteHash.Equals(localFileIndex.Hash)) { FilePath destinationFilepath = FilePath.Combine(destinationFolder, remoteFilePath); downloadManager.AddDownload(WebAPI.RepoUrl + "/" + remoteFilePath.OriginalValue, destinationFilepath, remoteAddonFile.Size); } } else { FilePath destinationFilepath = FilePath.Combine(destinationFolder, remoteFilePath); downloadManager.AddDownload(WebAPI.RepoUrl + "/" + remoteFilePath.OriginalValue, destinationFilepath, remoteAddonFile.Size); } } } } downloadManager.StartDownloads(); }
public static RemoteIndex GetIndex() { using WebClient wc = new(); var json = wc.DownloadString(IndexUrl); var jRoot = JObject.Parse(json); Dictionary <Uuid, RemoteAddon> filesIndex = new(); JToken jFilesIndex = jRoot["files_index"]; foreach (JToken jFileIndexTuple in jFilesIndex) { JToken value = ((JProperty)jFileIndexTuple).Value; string addonName = (string)value["name"]; Uuid addonUuid = new((string)value["uuid"]); string addonVersion = (string)value["version"]; Dictionary <FilePath, RemoteAddonFile> files = new(); var jAddonFiles = value["files"]; foreach (JToken jAddonFile in jAddonFiles) { JToken jAddonFileValue = ((JProperty)jAddonFile).Value; string addonFileHash = (string)jAddonFileValue["hash"]; FilePath addonFilePath = new((string)jAddonFileValue["path"]); long addonFileSize = (long)jAddonFileValue["size"]; RemoteAddonFile remoteAddonFile = new() { Hash = addonFileHash, Path = addonFilePath, Size = addonFileSize, }; files.Add(addonFilePath, remoteAddonFile); } RemoteAddon remoteAddon = new() { Uuid = addonUuid, Name = addonName, Version = addonVersion, Files = files, }; filesIndex.Add(addonUuid, remoteAddon); } List <AddonGroup> addonGroups = new(); JToken jAddonGroups = jRoot["addon_groups"]; foreach (JToken jAddonGroup in jAddonGroups) { string addonGroupAuthor = (string)jAddonGroup["author"]; string addonGroupName = (string)jAddonGroup["name"]; string addonGroupUuid = (string)jAddonGroup["uuid"]; string addonGroupVersion = (string)jAddonGroup["version"]; List <RemoteAddon> addons = new(); var jAddonUuids = jAddonGroup["addons"]; foreach (JToken jAddonUuid in jAddonUuids) { Uuid addonUuid = new((string)jAddonUuid); Debug.Assert(filesIndex.ContainsKey(addonUuid)); RemoteAddon remoteAddon = filesIndex[addonUuid]; Debug.Assert(remoteAddon.Uuid.Equals(addonUuid)); addons.Add(remoteAddon); } AddonGroup addonGroup = new(addonGroupName, addonGroupAuthor, addonGroupUuid, addonGroupVersion, addons); addonGroups.Add(addonGroup); } return(new RemoteIndex() { AddonGroups = addonGroups, FilesIndex = filesIndex }); }