Release v1.4.33 with DLC import and stats hotfixes
Build and Release / build (push) Has been cancelled

This commit is contained in:
Sucukdeluxe
2026-03-01 01:39:51 +01:00
parent ff1036563a
commit edbfba6663
8 changed files with 231 additions and 7 deletions
+28 -2
View File
@@ -7,6 +7,11 @@ import { ParsedPackageInput } from "../shared/types";
const MAX_DLC_FILE_BYTES = 8 * 1024 * 1024;
function isContainerSizeValidationError(error: unknown): boolean {
const text = compactErrorText(error);
return /zu groß/i.test(text) || /DLC-Datei ungültig oder zu groß/i.test(text);
}
function decodeDcryptPayload(responseText: string): unknown {
let text = String(responseText || "").trim();
const m = text.match(/<textarea[^>]*>([\s\S]*?)<\/textarea>/i);
@@ -187,30 +192,51 @@ async function decryptDlcViaDcrypt(filePath: string): Promise<ParsedPackageInput
export async function importDlcContainers(filePaths: string[]): Promise<ParsedPackageInput[]> {
const out: ParsedPackageInput[] = [];
const failures: string[] = [];
let sawDlc = false;
for (const filePath of filePaths) {
if (path.extname(filePath).toLowerCase() !== ".dlc") {
continue;
}
sawDlc = true;
let packages: ParsedPackageInput[] = [];
let fileFailed = false;
let fileFailureReasons: string[] = [];
try {
packages = await decryptDlcLocal(filePath);
} catch (error) {
if (/zu groß|ungültig/i.test(compactErrorText(error))) {
if (isContainerSizeValidationError(error)) {
failures.push(`${path.basename(filePath)}: ${compactErrorText(error)}`);
continue;
}
fileFailed = true;
fileFailureReasons.push(`lokal: ${compactErrorText(error)}`);
packages = [];
}
if (packages.length === 0) {
try {
packages = await decryptDlcViaDcrypt(filePath);
} catch (error) {
if (/zu groß|ungültig/i.test(compactErrorText(error))) {
if (isContainerSizeValidationError(error)) {
failures.push(`${path.basename(filePath)}: ${compactErrorText(error)}`);
continue;
}
fileFailed = true;
fileFailureReasons.push(`dcrypt: ${compactErrorText(error)}`);
packages = [];
}
}
if (packages.length === 0 && fileFailed) {
failures.push(`${path.basename(filePath)}: ${fileFailureReasons.join("; ")}`);
}
out.push(...packages);
}
if (out.length === 0 && sawDlc && failures.length > 0) {
const details = failures.slice(0, 2).join(" | ");
const suffix = failures.length > 2 ? ` (+${failures.length - 2} weitere)` : "";
throw new Error(`DLC konnte nicht importiert werden: ${details}${suffix}`);
}
return out;
}
+24
View File
@@ -681,6 +681,8 @@ export class DownloadManager extends EventEmitter {
return this.statsCache;
}
this.resetSessionTotalsIfQueueEmpty();
let totalDownloaded = 0;
let totalFiles = 0;
for (const item of Object.values(this.session.items)) {
@@ -714,6 +716,25 @@ export class DownloadManager extends EventEmitter {
return stats;
}
private resetSessionTotalsIfQueueEmpty(): void {
if (this.itemCount > 0 || this.session.packageOrder.length > 0) {
return;
}
if (Object.keys(this.session.items).length > 0 || Object.keys(this.session.packages).length > 0) {
return;
}
this.session.totalDownloadedBytes = 0;
this.session.runStartedAt = 0;
this.lastGlobalProgressBytes = 0;
this.lastGlobalProgressAt = nowMs();
this.speedEvents = [];
this.speedEventsHead = 0;
this.speedBytesLastWindow = 0;
this.statsCache = null;
this.statsCacheAt = 0;
}
public renamePackage(packageId: string, newName: string): void {
const pkg = this.session.packages[packageId];
if (!pkg) {
@@ -922,6 +943,7 @@ export class DownloadManager extends EventEmitter {
this.nonResumableActive = 0;
this.retryAfterByItem.clear();
this.retryStateByItem.clear();
this.resetSessionTotalsIfQueueEmpty();
this.persistNow();
this.emitState(true);
}
@@ -1966,6 +1988,7 @@ export class DownloadManager extends EventEmitter {
pkg.status = "completed";
}
}
this.resetSessionTotalsIfQueueEmpty();
this.persistSoon();
}
@@ -2371,6 +2394,7 @@ export class DownloadManager extends EventEmitter {
this.runPackageIds.delete(packageId);
this.runCompletedPackages.delete(packageId);
this.hybridExtractRequeue.delete(packageId);
this.resetSessionTotalsIfQueueEmpty();
}
private async ensureScheduler(): Promise<void> {
+10 -2
View File
@@ -703,7 +703,11 @@ export function App(): ReactElement {
if (files.length === 0) { return; }
await persistDraftSettings();
const result = await window.rd.addContainers(files);
showToast(`DLC importiert: ${result.addedPackages} Paket(e), ${result.addedLinks} Link(s)`);
if (result.addedLinks > 0) {
showToast(`DLC importiert: ${result.addedPackages} Paket(e), ${result.addedLinks} Link(s)`);
} else {
showToast("Keine gültigen Links in den DLC-Dateien gefunden", 3000);
}
}, (error) => {
showToast(`Fehler beim DLC-Import: ${String(error)}`, 2600);
});
@@ -721,7 +725,11 @@ export function App(): ReactElement {
await performQuickAction(async () => {
await persistDraftSettings();
const result = await window.rd.addContainers(dlc);
showToast(`Drag-and-Drop: ${result.addedPackages} Paket(e), ${result.addedLinks} Link(s)`);
if (result.addedLinks > 0) {
showToast(`Drag-and-Drop: ${result.addedPackages} Paket(e), ${result.addedLinks} Link(s)`);
} else {
showToast("Keine gültigen Links in den DLC-Dateien gefunden", 3000);
}
}, (error) => {
showToast(`Fehler bei Drag-and-Drop: ${String(error)}`, 2600);
});