9 Commits

Author SHA1 Message Date
mmvanheusden
35b8c476db Release minor version 2.0.3 2022-08-07 08:52:53 +02:00
mmvanheusden
d7260d8976 Cleanup promise utils 2022-08-07 08:52:10 +02:00
mmvanheusden
a7ce59fcd4 Simplify cross-platform compatibility and improve Linux support.Initial cleanup of promise utils 2022-08-07 08:18:00 +02:00
mmvanheusden
cc781b33d2 Make the OS dropdown full-with for improved consistency 2022-08-07 08:15:57 +02:00
mmvanheusden
54a5027f8a Update dependencies 2022-08-06 21:36:08 +02:00
mmvanheusden
1053c7b114 minor fix 2022-07-22 20:48:37 +02:00
mmvanheusden
510d80c58a 2.0.2 2022-07-22 20:20:30 +02:00
mmvanheusden
894197e75e Fix the working directory problem for every platform 2022-07-22 20:18:35 +02:00
mmvanheusden
eca48e2495 Add a notice thing to the youtube tuorial 2022-07-21 09:47:30 +02:00
6 changed files with 847 additions and 249 deletions

View File

@@ -23,7 +23,7 @@ from [GitHub](https://github.com/mmvanheusden/SteamDepotDownloaderGUI/releases/l
Enter everything you normally would in the SteamDepotDownloader console.
There is a video tutorial available [here](https://www.youtube.com/watch?v=dQw4w9WgXcQ).
There is a video tutorial available [here](https://www.youtube.com/watch?v=dQw4w9WgXcQ). (not done yet)
## Contributing

View File

@@ -5,8 +5,7 @@ const {
runCommand,
removeDir,
removeFile,
unzip,
platformpath
unzip
} = require("./utils")
function submitForm() {
@@ -15,19 +14,20 @@ function submitForm() {
console.error("dotnet not found in PATH")
document.getElementById("dotnetwarning").hidden = false
} else {
console.info("dotnet found in PATH")
// Remove the old depotdownloader directory
await removeDir("depotdownloader", platformpath())
await removeDir("depotdownloader")
// Download the DepotDownloader binary, so it doesn't have to be included in the source code
await download("https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_2.4.6/depotdownloader-2.4.6.zip", platformpath())
await download("https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_2.4.6/depotdownloader-2.4.6.zip")
// Unzip the DepotDownloader binary
await unzip("depotdownloader-2.4.6.zip", "depotdownloader", platformpath())
await unzip("depotdownloader-2.4.6.zip", "depotdownloader")
// Clean up the old files
await removeFile("depotdownloader-2.4.6.zip", platformpath())
await removeFile("depotdownloader-2.4.6.zip")
// Run the final command
await runCommand(createCommand().toString())

View File

@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<link href="https://unpkg.com/@primer/css@20.2.4/dist/primer.css" rel="stylesheet"/>
<link href="https://unpkg.com/@primer/css@20.4.1/dist/primer.css" rel="stylesheet"/>
<title>SteamDepotDownloaderGUI</title>
</head>
<body>
@@ -79,7 +79,7 @@
<label for="osdropdown">Operating system</label>
</div>
<div class="form-group-body">
<select aria-label="Preference" class="form-select" id="osdropdown">
<select aria-label="Preference" class="form-select width-full" id="osdropdown">
<option disabled>Choose your OS</option>
<option>Windows</option>
<option disabled>macOS (NOT YET IMPLEMENTED)</option>

937
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,16 @@
{
"name": "steamdepotdownloadergui",
"version": "2.0.1",
"version": "2.0.3",
"description": "DepotDownloader Electron frontend",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron .",
"build": "electron-builder -c electron-builder.yml -wl -p never",
"buildall": "electron-builder -c electron-builder.yml -mwl -p never"
"buildall": "electron-builder -c electron-builder.yml -mwl -p never",
"buildlinux": "electron-builder -c electron-builder.yml -l -p never",
"buildwin": "electron-builder -c electron-builder.yml -w -p never",
"buildmacos": "electron-builder -c electron-builder.yml -m -p never"
},
"repository": {
"type": "git",

134
utils.js
View File

@@ -2,8 +2,6 @@
* Checks if dotnet is installed in the system path
* @returns {Promise<unknown>} A promise that resolves to true if dotnet is installed, false otherwise
*/
function checkDotnet() {
return new Promise((resolve) => {
if (process.platform.toString().includes("win")) {
@@ -34,22 +32,24 @@ function checkDotnet() {
/**
* Download a file from a url, saving it to the current directory (__dirname)
* @param url The url to download from
* @param targetPath The path to save the file to
* @returns {Promise<unknown>} A promise that resolves when the download is finished
* @returns {Promise<unknown>} A promise that resolves when the download is finished, or rejects if something fails
*/
function download(url, targetPath) {
return new Promise((resolve) => {
function download(url) {
return new Promise((resolve, reject) => {
const {https} = require("follow-redirects")
const fs = require("fs")
const path = require("path")
console.log(path.sep)
const file = fs.createWriteStream(targetPath + path.sep + url.split("/").pop())
const file = fs.createWriteStream(platformpath() + path.sep + url.split("/").pop())
https.get(url, function (response) {
response.pipe(file)
file.on("finish", function () {
file.close()
resolve()
})
file.on("error", function (error) {
console.error(error)
reject(error)
})
})
})
}
@@ -57,18 +57,17 @@ function download(url, targetPath) {
/**
* Removes a file from the current directory
* @param file The filename to remove
* @param targetPath The directory the file is located in
* @returns {Promise<unknown>} A promise that resolves when the file is removed (or fails)
* @returns {Promise<unknown>} A promise that resolves when the file is removed, or rejects if something fails
*/
function removeFile(file, targetPath) {
return new Promise((resolve) => {
function removeFile(file) {
return new Promise((resolve, reject) => {
const fs = require("fs")
const path = require("path")
fs.unlink(targetPath + path.sep + file, function (err) {
if (err) {
console.error(err)
}
resolve()
fs.unlink(platformpath() + path.sep + file, function (error) {
if (error) {
reject(error)
console.error(error)
} else resolve()
})
})
}
@@ -76,18 +75,17 @@ function removeFile(file, targetPath) {
/**
* Removes a directory from the current directory
* @param dir The directory to remove
* @param targetPath The directory the directory is located in
* @returns {Promise<unknown>} A promise that resolves when the directory is removed (or fails)
* @returns {Promise<unknown>} A promise that resolves when the directory is removed, or rejects if something fails
*/
function removeDir(dir, targetPath) {
return new Promise((resolve) => {
function removeDir(dir,) {
return new Promise((resolve, reject) => {
const fs = require("fs")
const path = require("path")
fs.rm(targetPath + path.sep + dir, {recursive: true, force: true}, function (err) {
if (err) {
console.error(err)
}
resolve()
fs.rm(platformpath() + path.sep + dir, {recursive: true, force: true}, function (error) {
if (error) {
reject(error)
console.error(error)
} else resolve()
})
})
}
@@ -96,47 +94,41 @@ function removeDir(dir, targetPath) {
* Unzip a file to the current directory
* @param file The file to unzip, preferably a .zip file
* @param target The target directory to unzip to
* @param targetPath The directory the file AND the unzip dir is located in
* @returns {Promise<unknown>} A promise that resolves when the unzip is complete (or fails)
* @returns {Promise<unknown>} A promise that resolves when the unzip is complete, or rejects if something fails
*/
function unzip(file, target, targetPath) {
function unzip(file, target) {
const {exec} = require("child_process")
const path = require("path")
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
if (process.platform.toString().includes("win")) {
const command = "powershell.exe -Command Expand-Archive -Path " + targetPath + path.sep + file + " -Destination " + targetPath + path.sep + target
exec(command, function (error, stdout, stderr) {
const command = "powershell.exe -Command Expand-Archive -Path " + platformpath() + path.sep + file + " -Destination " + platformpath() + path.sep + target
exec(command, function (error) {
if (error) {
console.error("Unzipping failed with error: " + error)
}
console.debug(stdout)
if (stderr) {
console.error(stderr)
}
resolve()
reject(error)
console.error(error)
} else resolve()
})
} else {
const command = "unzip -o " + file + " -d ./" + target + "/"
exec(command, function (error, stdout, stderr) {
exec(command, function (error) {
if (error) {
console.error("Unzipping failed with error: " + error)
}
console.debug(stdout)
if (stderr) {
console.error(stderr)
}
resolve()
reject(error)
console.error(error)
} else resolve()
})
}
})
}
/**
* Creates a command based on the operating system/terminal being selected and the form values
* @returns {string} The final command to run
*/
const createCommand = () => {
// Import path so \ can be put in a string
const path = require("path")
// The values inputted by the user in the form
let username = document.forms["theform"]["username"].value
let password = document.forms["theform"]["password"].value
@@ -145,21 +137,23 @@ const createCommand = () => {
let manifestid = document.forms["theform"]["manifestid"].value
let osdropdown = document.getElementById("osdropdown")
const finalPath = platformpath() + path.sep + "games" + path.sep + appid
// The final command to run, returned by this function
if (osdropdown.options[osdropdown.selectedIndex].text.includes("Gnome")) {
return `gnome-terminal -e 'bash -c "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ./games/${appid}/ -max-servers 50 -max-downloads 16";bash'`
return `gnome-terminal -e 'bash -c "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16";bash'`
} else if (osdropdown.options[osdropdown.selectedIndex].text.includes("Windows")) {
return `start cmd.exe /k dotnet ${platformpath()}/depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${platformpath()}/games/${appid}/ -max-servers 50 -max-downloads 16`
return `start cmd.exe /k dotnet ${platformpath()}${path.sep}depotdownloader${path.sep}DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16`
} else if (osdropdown.options[osdropdown.selectedIndex].text.includes("macOS")) {
return `osascript -c 'tell application "Terminal" to do script 'dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ./games/${appid}/ -max-servers 50 -max-downloads 16'`
return `osascript -c 'tell application "Terminal" to do script 'dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16'`
} else if (osdropdown.options[osdropdown.selectedIndex].text.includes("Konsole")) {
return `konsole --hold -e "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ./games/${appid}/ -max-servers 50 -max-downloads 16"`
return `konsole --hold -e "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16"`
} else if (osdropdown.options[osdropdown.selectedIndex].text.includes("Xfce")) {
return `xfce4-terminal -H -e "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ./games/${appid}/ -max-servers 50 -max-downloads 16"`
return `xfce4-terminal -H -e "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16"`
} else if (osdropdown.options[osdropdown.selectedIndex].text.includes("Terminator")) {
return `terminator -e 'bash -c "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ./games/${appid}/ -max-servers 50 -max-downloads 16";bash'`
return `terminator -e 'bash -c "dotnet ./depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16";bash'`
} else if (osdropdown.options[osdropdown.selectedIndex].text.includes("Print command")) {
console.log(`COPY-PASTE THE FOLLOWING INTO YOUR TERMINAL OF CHOICE:\n\ndotnet ${__dirname}/depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ./games/${appid}/ -max-servers 50 -max-downloads 16`)
console.log(`COPY-PASTE THE FOLLOWING INTO YOUR TERMINAL OF CHOICE:\n\ndotnet ${platformpath()}/depotdownloader/DepotDownloader.dll -username ${username} -password ${password} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}/ -max-servers 50 -max-downloads 16`)
return "echo hello"
}
}
@@ -167,28 +161,36 @@ const createCommand = () => {
/**
* Runs a command in a separate process, printing errors and debugging info to the console
* @param command The command to run
* @returns {Promise<unknown>} A promise that resolves when the command is complete (or fails)
* @returns {Promise<unknown>} A promise that resolves when the command is complete or rejects if something fails
*/
function runCommand(command) {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
const {exec} = require("child_process")
exec(command, function (error, stdout, stderr) {
exec(command, function (error) {
if (error) {
console.debug("Command failed with error: " + error)
}
if (stderr) {
console.error(stderr)
}
resolve()
const msg = "Running command failed with error:\n" + error
reject(msg)
} else resolve()
})
})
}
/**
* Returns the path where the actual program is being run from, depending on the operating system.
* Because __dirname is inconsistent across operating systems, this function is used to get the correct path
* @returns {string} The absolute path
*/
const platformpath = () => {
if (__dirname.includes("AppData") && process.platform.toString().includes("win")) {
if ((__dirname.includes("AppData") || __dirname.includes("Temp")) && process.platform.toString().includes("win")) {
// Windows portable exe
return process.env.PORTABLE_EXECUTABLE_DIR
} else
} else if (__dirname.includes("/tmp/") && process.platform.toString().includes("linux")) {
// Linux AppImage
return process.cwd()
} else {
// .zip binary
return __dirname
}
}
module.exports = {checkDotnet, download, createCommand, runCommand, removeDir, removeFile, unzip, platformpath}