|
1 |
| -import ManifestV2 from "src/model/ManifestV2"; |
2 | 1 | import ThunderstoreVersion from '../../model/ThunderstoreVersion';
|
3 | 2 | import ThunderstoreMod from '../../model/ThunderstoreMod';
|
4 | 3 | import StatusEnum from '../../model/enums/StatusEnum';
|
5 | 4 | import axios, { AxiosResponse } from 'axios';
|
| 5 | +import ManifestV2 from "../../model/ManifestV2"; |
6 | 6 | import ThunderstoreCombo from '../../model/ThunderstoreCombo';
|
7 | 7 | import ZipExtract from '../installing/ZipExtract';
|
8 | 8 | import R2Error from '../../model/errors/R2Error';
|
@@ -83,68 +83,64 @@ export default class BetterThunderstoreDownloader extends ThunderstoreDownloader
|
83 | 83 | });
|
84 | 84 | }
|
85 | 85 |
|
86 |
| - public async download(profile: ImmutableProfile, mod: ThunderstoreMod, modVersion: ThunderstoreVersion, |
87 |
| - ignoreCache: boolean, |
88 |
| - callback: (progress: number, modName: string, status: number, err: R2Error | null) => void, |
89 |
| - completedCallback: (modList: ThunderstoreCombo[]) => void) { |
| 86 | + public async download( |
| 87 | + profile: ImmutableProfile, |
| 88 | + combo: ThunderstoreCombo, |
| 89 | + ignoreCache: boolean, |
| 90 | + totalProgressCallback: (progress: number, modName: string, status: number, err: R2Error | null) => void |
| 91 | + ): Promise<ThunderstoreCombo[]> { |
90 | 92 |
|
91 | 93 | const modList = await ProfileModList.getModList(profile);
|
92 | 94 | if (modList instanceof R2Error) {
|
93 |
| - return callback(0, mod.getName(), StatusEnum.FAILURE, modList); |
| 95 | + totalProgressCallback(0, combo.getMod().getName(), StatusEnum.FAILURE, modList); |
| 96 | + throw modList; |
94 | 97 | }
|
95 | 98 |
|
96 |
| - let dependencies: ThunderstoreCombo[] = []; |
97 |
| - await this.buildDependencySet(modVersion, dependencies, DependencySetBuilderMode.USE_EXACT_VERSION); |
98 |
| - this.sortDependencyOrder(dependencies); |
99 |
| - const combo = new ThunderstoreCombo(); |
100 |
| - combo.setMod(mod); |
101 |
| - combo.setVersion(modVersion); |
102 |
| - |
103 |
| - dependencies = await this.determineDependencyVersions(dependencies, combo, modVersion, modList); |
104 |
| - let downloadableDependencySize = this.calculateInitialDownloadSize(dependencies); |
| 99 | + let dependencies = await this.getDependenciesWithCorrectVersions(combo, modList); |
| 100 | + const allModsToDownload = [...dependencies, combo]; |
105 | 101 |
|
106 | 102 | let downloadCount = 0;
|
107 |
| - await this.downloadAndSave(combo, ignoreCache, async (progress: number, status: number, err: R2Error | null) => { |
| 103 | + const singleModProgressCallback = (progress: number, status: number, err: R2Error | null) => { |
108 | 104 | if (status === StatusEnum.FAILURE) {
|
109 |
| - callback(0, mod.getName(), status, err); |
110 |
| - } else if (status === StatusEnum.PENDING) { |
111 |
| - callback(this.generateProgressPercentage(progress, downloadCount, downloadableDependencySize + 1), mod.getName(), status, err); |
| 105 | + throw err; |
| 106 | + } |
| 107 | + |
| 108 | + let totalProgress: number; |
| 109 | + if (status === StatusEnum.PENDING) { |
| 110 | + totalProgress = this.generateProgressPercentage(progress, downloadCount, allModsToDownload.length); |
112 | 111 | } else if (status === StatusEnum.SUCCESS) {
|
| 112 | + totalProgress = this.generateProgressPercentage(100, downloadCount, allModsToDownload.length); |
113 | 113 | downloadCount += 1;
|
114 |
| - // If no dependencies, end here. |
115 |
| - if (dependencies.length === 0) { |
116 |
| - callback(100, mod.getName(), StatusEnum.PENDING, err); |
117 |
| - completedCallback([combo]); |
118 |
| - return; |
119 |
| - } |
| 114 | + } else { |
| 115 | + console.error(`Ignore unknown status code "${status}"`); |
| 116 | + return; |
| 117 | + } |
| 118 | + totalProgressCallback(totalProgress, combo.getMod().getName(), status, err); |
| 119 | + } |
120 | 120 |
|
121 |
| - // If dependencies, queue and download. |
122 |
| - await this.queueDownloadDependencies(dependencies.entries(), ignoreCache, (progress: number, modName: string, status: number, err: R2Error | null) => { |
123 |
| - if (status === StatusEnum.FAILURE) { |
124 |
| - callback(0, modName, status, err); |
125 |
| - } else if (status === StatusEnum.PENDING) { |
126 |
| - callback(this.generateProgressPercentage(progress, downloadCount, downloadableDependencySize + 1), modName, status, err); |
127 |
| - } else if (status === StatusEnum.SUCCESS) { |
128 |
| - callback(this.generateProgressPercentage(progress, downloadCount, downloadableDependencySize + 1), modName, StatusEnum.PENDING, err); |
129 |
| - downloadCount += 1; |
130 |
| - if (downloadCount >= dependencies.length + 1) { |
131 |
| - callback(100, modName, StatusEnum.PENDING, err); |
132 |
| - completedCallback([...dependencies, combo]); |
133 |
| - } |
134 |
| - } |
135 |
| - }); |
| 121 | + for (const combo of allModsToDownload) { |
| 122 | + if (!ignoreCache && await this.isVersionAlreadyDownloaded(combo)) { |
| 123 | + totalProgressCallback(100, combo.getMod().getName(), StatusEnum.SUCCESS, null); |
| 124 | + continue; |
136 | 125 | }
|
137 |
| - }) |
| 126 | + |
| 127 | + try { |
| 128 | + const response = await this._downloadCombo(combo, singleModProgressCallback); |
| 129 | + await this._saveDownloadResponse(response, combo, singleModProgressCallback); |
| 130 | + } catch(e) { |
| 131 | + throw R2Error.fromThrownValue(e, `Failed to download mod ${combo.getVersion().getFullName()}`); |
| 132 | + } |
| 133 | + } |
| 134 | + return allModsToDownload; |
138 | 135 | }
|
139 | 136 |
|
140 | 137 | // If combo is a modpack, use the modpack's dependency versions. If it isn't, get the latest versions.
|
141 |
| - public async determineDependencyVersions(dependencies: ThunderstoreCombo[], combo: ThunderstoreCombo, modVersion: ThunderstoreVersion, modList: ManifestV2[]) { |
142 |
| - let isModpack = combo.getMod().getCategories().find(value => value === "Modpacks") !== undefined; |
143 |
| - if (isModpack) { |
144 |
| - return dependencies; |
145 |
| - } |
146 |
| - dependencies = []; |
147 |
| - await this.buildDependencySet(modVersion, dependencies, DependencySetBuilderMode.USE_LATEST_VERSION); |
| 138 | + private async getDependenciesWithCorrectVersions(combo: ThunderstoreCombo, modList: ManifestV2[]) { |
| 139 | + let dependencies: ThunderstoreCombo[] = []; |
| 140 | + const isModpack = combo.getMod().getCategories().find(value => value === "Modpacks") !== undefined; |
| 141 | + const versionMode = isModpack ? DependencySetBuilderMode.USE_EXACT_VERSION : DependencySetBuilderMode.USE_LATEST_VERSION; |
| 142 | + |
| 143 | + await this.buildDependencySet(combo.getVersion(), dependencies, versionMode); |
148 | 144 | this.sortDependencyOrder(dependencies);
|
149 | 145 | // #270: Remove already-installed dependencies to prevent updating.
|
150 | 146 | return dependencies.filter(dep => modList.find(installed => installed.getName() === dep.getMod().getFullName()) === undefined);
|
|
0 commit comments