release: prepare v2.0.83

This commit is contained in:
Sucukdeluxe
2026-09-01 02:04:53 +02:00
parent f3f2f60ece
commit 9c512b6de7
9 changed files with 202 additions and 82 deletions
+88 -57
View File
@@ -3701,10 +3701,11 @@ export class DownloadManager extends EventEmitter {
item.speedBps = 0;
item.downloadedBytes = 0;
item.totalBytes = null;
item.progressPercent = 0;
item.resumable = true;
item.attempts = 0;
item.lastError = "";
item.progressPercent = 0;
item.resumable = true;
item.attempts = 0;
delete item.archiveRecoveryRedownloads;
item.lastError = "";
item.fullStatus = "Wartet";
item.provider = null;
item.updatedAt = nowMs();
@@ -6065,10 +6066,11 @@ export class DownloadManager extends EventEmitter {
item.downloadedBytes = 0;
item.totalBytes = null;
item.progressPercent = 0;
item.speedBps = 0;
item.attempts = 0;
item.retries = 0;
item.lastError = "";
item.speedBps = 0;
item.attempts = 0;
item.retries = 0;
delete item.archiveRecoveryRedownloads;
item.lastError = "";
item.resumable = true;
item.targetPath = "";
item.provider = null;
@@ -6147,10 +6149,11 @@ export class DownloadManager extends EventEmitter {
item.downloadedBytes = 0;
item.totalBytes = null;
item.progressPercent = 0;
item.speedBps = 0;
item.attempts = 0;
item.retries = 0;
item.lastError = "";
item.speedBps = 0;
item.attempts = 0;
item.retries = 0;
delete item.archiveRecoveryRedownloads;
item.lastError = "";
item.resumable = true;
item.targetPath = "";
item.provider = null;
@@ -7819,44 +7822,66 @@ export class DownloadManager extends EventEmitter {
return 0;
}
const inspectedArchiveItems = archiveItems
.map((item) => ({ item, state: inspectPackageItemDiskState(pkg, item) }));
const corruptArchiveItems = inspectedArchiveItems
.filter(({ state }) => state.reason !== "ok");
if (corruptArchiveItems.length === 0) {
const firstPart = inspectedArchiveItems.find(({ state }) => state.diskPath);
let hasValidSignature = false;
if (firstPart?.state.diskPath) {
try {
const fd = fs.openSync(firstPart.state.diskPath, "r");
try {
const header = Buffer.alloc(8);
fs.readSync(fd, header, 0, 8, 0);
hasValidSignature =
(header[0] === 0x52 && header[1] === 0x61 && header[2] === 0x72 && header[3] === 0x21 && header[4] === 0x1a && header[5] === 0x07) ||
(header[0] === 0x37 && header[1] === 0x7a && header[2] === 0xbc && header[3] === 0xaf) ||
(header[0] === 0x50 && header[1] === 0x4b && header[2] === 0x03 && header[3] === 0x04);
} finally {
fs.closeSync(fd);
}
} catch { }
}
if (hasValidSignature) {
logger.warn(
`Auto-Recovery (${scope}): ${failure.archiveName} uebersprungen - ` +
`Dateien haben korrekte Groesse und gueltige Archiv-Signatur, ` +
`wahrscheinlicher Passwort-/Extractor-Fall statt defektem Download`
);
return 0;
}
logger.warn(
`Auto-Recovery (${scope}): ${failure.archiveName} - Dateien korrekte Groesse aber ungueltige Archiv-Signatur, ` +
`erzwinge Re-Download aller ${archiveItems.length} Parts`
);
corruptArchiveItems.push(...inspectedArchiveItems);
const inspectedArchiveItems = archiveItems
.map((item) => ({ item, state: inspectPackageItemDiskState(pkg, item) }));
const recoveryRedownloads = Math.max(
0,
...archiveItems.map((item) => Math.max(0, Math.floor(Number(item.archiveRecoveryRedownloads) || 0)))
);
if (recoveryRedownloads >= 1) {
logger.warn(
`Auto-Recovery (${scope}): ${failure.archiveName} nicht erneut heruntergeladen - ` +
`automatischer Archiv-Neudownload bereits versucht`
);
return 0;
}
const corruptArchiveItems = inspectedArchiveItems
.filter(({ state }) => state.reason !== "ok");
if (corruptArchiveItems.length === 0) {
if (failure.category === "crc_error") {
logger.warn(
`Auto-Recovery (${scope}): ${failure.archiveName} meldet CRC-Fehler trotz korrekter Größe und Archiv-Signatur, ` +
`erzwinge einmaligen Neu-Download aller ${archiveItems.length} Parts`
);
corruptArchiveItems.push(...inspectedArchiveItems);
}
if (failure.category !== "crc_error") {
const firstPart = inspectedArchiveItems.find(({ state }) => state.diskPath);
let hasValidSignature = false;
if (firstPart?.state.diskPath) {
try {
const fd = fs.openSync(firstPart.state.diskPath, "r");
try {
const header = Buffer.alloc(8);
fs.readSync(fd, header, 0, 8, 0);
hasValidSignature =
(header[0] === 0x52 && header[1] === 0x61 && header[2] === 0x72 && header[3] === 0x21 && header[4] === 0x1a && header[5] === 0x07) ||
(header[0] === 0x37 && header[1] === 0x7a && header[2] === 0xbc && header[3] === 0xaf) ||
(header[0] === 0x50 && header[1] === 0x4b && header[2] === 0x03 && header[3] === 0x04);
} finally {
fs.closeSync(fd);
}
} catch { }
}
if (hasValidSignature) {
logger.warn(
`Auto-Recovery (${scope}): ${failure.archiveName} übersprungen - ` +
`Dateien haben korrekte Größe und gültige Archiv-Signatur, ` +
`wahrscheinlicher Passwort-/Extractor-Fall statt defektem Download`
);
return 0;
}
logger.warn(
`Auto-Recovery (${scope}): ${failure.archiveName} - Dateien korrekte Größe aber ungültige Archiv-Signatur, ` +
`erzwinge Neu-Download aller ${archiveItems.length} Parts`
);
corruptArchiveItems.push(...inspectedArchiveItems);
}
}
const queuedAt = nowMs();
@@ -7872,13 +7897,19 @@ export class DownloadManager extends EventEmitter {
}
this.releaseTargetPath(item.id);
this.dropItemContribution(item.id);
item.targetPath = "";
item.status = "queued";
item.attempts = 0;
item.downloadedBytes = 0;
item.progressPercent = 0;
item.speedBps = 0;
item.lastError = failure.errorText;
item.targetPath = "";
item.status = "queued";
item.attempts = 0;
item.archiveRecoveryRedownloads = recoveryRedownloads + 1;
item.downloadedBytes = 0;
item.totalBytes = null;
item.progressPercent = 0;
item.speedBps = 0;
item.provider = null;
item.providerLabel = undefined;
item.providerAccountId = undefined;
item.providerAccountLabel = undefined;
item.lastError = failure.errorText;
item.fullStatus = reason;
item.updatedAt = queuedAt;
changed += 1;
+5 -2
View File
@@ -1039,8 +1039,11 @@ export function normalizeLoadedSession(raw: unknown): SessionState {
targetPath: asText(item.targetPath),
metadataRenameTargetPath: asText(item.metadataRenameTargetPath) || undefined,
resumable: item.resumable === undefined ? true : Boolean(item.resumable),
attempts: clampNumber(item.attempts, 0, 0, 10_000),
lastError: asText(item.lastError),
attempts: clampNumber(item.attempts, 0, 0, 10_000),
archiveRecoveryRedownloads: item.archiveRecoveryRedownloads === undefined
? undefined
: clampNumber(item.archiveRecoveryRedownloads, 0, 0, 1),
lastError: asText(item.lastError),
fullStatus: asText(item.fullStatus),
onlineStatus: VALID_ONLINE_STATUSES.has(onlineStatusRaw) ? onlineStatusRaw as "online" | "offline" | "checking" : undefined,
createdAt: clampNumber(item.createdAt, now, 0, Number.MAX_SAFE_INTEGER),
+3 -2
View File
@@ -492,8 +492,9 @@ export interface DownloadItem {
targetPath: string;
metadataRenameTargetPath?: string;
resumable: boolean;
attempts: number;
lastError: string;
attempts: number;
archiveRecoveryRedownloads?: number;
lastError: string;
fullStatus: string;
createdAt: number;
updatedAt: number;