From 05af8a3f9e2d0b16f561ab9f5d59d0b771a424b9 Mon Sep 17 00:00:00 2001 From: FinnHornhoover Date: Sat, 23 Sep 2023 02:18:03 +0300 Subject: [PATCH] WIP ipc downloads --- assets/js/server-selector.js | 55 ++++++++++++++----- index.js | 101 +++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 14 deletions(-) diff --git a/assets/js/server-selector.js b/assets/js/server-selector.js index 06aeedb..08f245f 100644 --- a/assets/js/server-selector.js +++ b/assets/js/server-selector.js @@ -1,3 +1,4 @@ +var ipc = require("ipc"); var remote = require("remote"); var remotefs = remote.require("fs-extra"); var dns = remote.require("dns"); @@ -19,6 +20,7 @@ var cdn = "cdn.dexlabs.systems"; var versionArray; var versionHashes; +var versionSizes; var serverArray; var config; @@ -460,7 +462,19 @@ function loadCacheList() { $(".cache-listing-entry").remove(); + versionSizes = { playable: {}, offline: {} }; $.each(versionArray, function (key, value) { + versionSizes.playable[value.name] = { + intact: 0, + altered: 0, + total: value.playable_size, + }; + versionSizes.offline[value.name] = { + intact: 0, + altered: 0, + total: value.offline_size, + }; + var row = document.createElement("tr"); row.className = "cache-listing-entry" row.setAttribute("id", value.name); @@ -547,6 +561,7 @@ function downloadOfflineCache(versionString) { ); */ + /* downloadFiles( version.url, offlineRoot, @@ -557,6 +572,13 @@ function downloadOfflineCache(versionString) { checkOfflineCache(versionString); } ); + */ + ipc.send("download-files", { + nginxDir: version.url, + localDir: offlineRoot, + fileRelativePaths: Object.keys(versionHashes.offline[versionString]), + versionString: versionString, + }); } function deleteOfflineCache(versionString) { @@ -580,13 +602,7 @@ function checkPlayableCache(versionString) { var button = document.getElementById(getCacheButtonID(versionString, "playable", "delete")); var label = document.getElementById(getCacheElemID(versionString, "playable", "label")); - var sizes = { - intact: 0, - altered: 0, - total: versionArray.filter(function (value) { - return value.name === versionString; - })[0].playable_size - }; + var sizes = versionSizes.playable[versionString]; resetCacheNames(); @@ -624,13 +640,7 @@ function checkOfflineCache(versionString) { var buttonDelete = document.getElementById(getCacheButtonID(versionString, "offline", "delete")); var label = document.getElementById(getCacheElemID(versionString, "offline", "label")); - var sizes = { - intact: 0, - altered: 0, - total: versionArray.filter(function (value) { - return value.name === versionString; - })[0].offline_size - }; + var sizes = versionSizes.offline[versionString]; $.each(versionHashes.offline[versionString], function (filePath, fileHash) { var fullFilePath = path.join(offlineRoot, filePath); @@ -883,3 +893,20 @@ $("#of-deleteservermodal").on("show.bs.modal", function (e) { })[0]; $("#deleteserver-servername").html(result.description); }); + +ipc.on("download-update", function (arg) { + var sizes = versionSizes.offline[arg.versionString]; + sizes.intact += arg.size; + + var label = document.getElementById(getCacheElemID(arg.versionString, "offline", "label")); + label.innerHTML = getCacheLabelText(sizes); +}); + +ipc.on("download-success", function (versionString) { + var buttonDownload = document.getElementById(getCacheButtonID(versionString, "offline", "download")); + var buttonFix = document.getElementById(getCacheButtonID(versionString, "offline", "fix")); + + buttonDownload.children[0].setAttribute("class", "fas fa-download"); + buttonFix.children[0].setAttribute("class", "fas fa-hammer"); + checkOfflineCache(versionString); +}); diff --git a/index.js b/index.js index 68d2c76..c3de65f 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,9 @@ var fs = require("fs-extra"); var ipc = require("ipc"); var os = require("os"); var path = require("path"); +var url = require("url"); +var http = require("http"); +var async = require("async"); var BrowserWindow = require("browser-window"); var mainWindow = null; @@ -83,6 +86,7 @@ app.on("ready", function () { show: false, "web-preferences": { plugins: true, + nodeIntegration: true, }, }); mainWindow.setMinimumSize(640, 480); @@ -168,3 +172,100 @@ function showMainWindow() { } }); } + +function downloadFile(nginxDir, localDir, relativePath, callback, updateCallback) { + var nginxUrl = path.dirname(nginxDir) + "/" + relativePath; + var localPath = path.join(localDir, relativePath); + + // Create directories if they don't exist + var dirName = path.dirname(localPath); + fs.ensureDirSync(dirName); + + // HTTP request to download the file + var fileStream = fs.createWriteStream(localPath); + + var urlParse = url.parse(nginxUrl); + var client = http.createClient(80, urlParse.hostname); + var options = { + method: "GET", + url: urlParse.hostname, + port: 80, + path: urlParse.path, + headers: { + "Host": urlParse.hostname, + "Content-Type": "application/octet-stream", + "Referer": nginxDir, + "Connection": "keep-alive", + } + }; + + var request = client.request("GET", urlParse.path, options); + + request.on("response", function(response) { + response.pipe(fileStream); + + // When the download is complete, invoke the callback + response.on("end", function() { + fileStream.end(); + updateCallback(fs.statSync(localPath).size); + callback(null, relativePath); + }); + + // Handle errors + response.on("error", function(err) { + console.error("Error downloading " + relativePath + ": " + err.message); + retryDownload(nginxDir, localDir, relativePath, callback, updateCallback); // Retry download + }); + }); + + // Handle HTTP errors + request.on("error", function(err) { + console.error("Error downloading " + relativePath + ": " + err.message); + retryDownload(nginxDir, localDir, relativePath, callback, updateCallback); // Retry download + }); + + request.end(); +} + + // Function to retry downloading a file after a delay +function retryDownload(nginxDir, localDir, relativePath, callback, updateCallback) { + setTimeout(function() { + downloadFile(nginxDir, localDir, relativePath, callback, updateCallback); + }, 1000); // Retry after 1 second +} + + // Function to download multiple files in parallel +function downloadFiles(nginxDir, localDir, fileRelativePaths, updateCallback, allDoneCallback) { + async.eachLimit( + fileRelativePaths, + 5, // Number of parallel downloads + function(relativePath, callback) { + downloadFile(nginxDir, localDir, relativePath, callback, updateCallback); + }, + function(err) { + if (err) { + console.error("Download failed: " + err); + } else { + console.log("All files downloaded successfully."); + allDoneCallback(); + } + } + ); +} + +ipc.on("download-files", function (event, arg) { + downloadFiles( + arg.nginxDir, + arg.localDir, + arg.fileRelativePaths, + function (size) { + mainWindow.webContents.send("download-update", { + size: size, + versionString: arg.versionString, + }); + }, + function () { + mainWindow.webContents.send("download-success", arg.versionString); + } + ); +}); \ No newline at end of file