mirror of
https://github.com/mmvanheusden/SteamDepotDownloaderGUI.git
synced 2026-02-04 05:31:19 +01:00
feat: rewrite command builder
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -135,7 +135,9 @@ dist
|
||||
# IntelliJ
|
||||
.idea/
|
||||
|
||||
# SteamDepotDownloaderGUI specific directories
|
||||
/depotdownloader/
|
||||
/games/
|
||||
*.zip
|
||||
# SteamDepotDownloaderGUI specific
|
||||
depotdownloader
|
||||
games
|
||||
*.zip
|
||||
run.bat
|
||||
run.sh
|
||||
@@ -2,14 +2,23 @@
|
||||
// License can be found at https://github.com/SteamRE/DepotDownloader/blob/master/LICENSE
|
||||
const {ipcRenderer, shell} = require("electron")
|
||||
const {
|
||||
preDownloadCheck, download, createCommand, runCommand, removeDir, removeFile, unzip, forceTerminals
|
||||
preDownloadCheck,
|
||||
download,
|
||||
runCommand,
|
||||
removeDir,
|
||||
removeFile,
|
||||
unzip,
|
||||
forceTerminals,
|
||||
generateRunScript,
|
||||
executeCommandWithTerminal,
|
||||
platformpath
|
||||
} = require("./utils")
|
||||
const electron = require("electron")
|
||||
const {sep} = require("path")
|
||||
|
||||
// Initializes the variable that holds the path to the specified download location
|
||||
let exportedFile
|
||||
let exportedFile = ""
|
||||
let ready = true
|
||||
let os
|
||||
let app_version
|
||||
|
||||
const DOTNET_DOWNLOAD_URL = "https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_2.5.0/depotdownloader-2.5.0.zip" // the url to the depotdownloader zip
|
||||
@@ -35,24 +44,25 @@ function submitForm() {
|
||||
|
||||
// Clean up the old files
|
||||
await removeFile(DOTNET_ZIP_FILE)
|
||||
// username, password, appid, depotid, manifestid, folderinput, chosenPath, hold):
|
||||
|
||||
// Generate the run script (run.sh for linux, or run.bat for windows).
|
||||
await generateRunScript(document.getElementById("username").value, document.getElementById("password").value, document.getElementById("appid").value, document.getElementById("depotid").value, document.getElementById("manifestid").value, document.getElementById("folder-name-custom-input"), exportedFile)
|
||||
|
||||
let command
|
||||
if (process.platform.includes("linux")) {
|
||||
// if the OS is linux, run the sh file with the chosen terminal
|
||||
command = await executeCommandWithTerminal(`sh \`${platformpath()}${sep}run.sh\``, document.getElementById("terminal-dropdown").selectedIndex, document.getElementById("os-dropdown").selectedIndex)
|
||||
} else if (process.platform.includes("win")) {
|
||||
// if the OS is windows, run the batch file
|
||||
console.log(document.getElementById("os-dropdown").selectedIndex)
|
||||
command = await executeCommandWithTerminal(`${platformpath()}${sep}run.bat`, 0, document.getElementById("os-dropdown").selectedIndex)
|
||||
} else if (process.platform.includes("darwin")) {
|
||||
//macOS
|
||||
}
|
||||
|
||||
// Run the final command
|
||||
|
||||
let terminal
|
||||
// if the terminal dropdown is not set to 'auto', set the terminal variable to the selected index.
|
||||
if (document.getElementById("terminal-dropdown").selectedIndex !== 11) {
|
||||
terminal = document.getElementById("terminal-dropdown").selectedIndex
|
||||
} else terminal = "auto"
|
||||
// if the OS dropdown is not set to 'auto', set the os variable to the selected index.
|
||||
if (document.getElementById("os-dropdown").selectedIndex !== 4) {
|
||||
os = document.getElementById("os-dropdown").selectedIndex
|
||||
} else os = "auto"
|
||||
|
||||
// create the command
|
||||
let command = createCommand(terminal, os)
|
||||
|
||||
if (document.getElementById("os-dropdown").selectedIndex !== 3) await console.debug("Command issued: " + command)
|
||||
|
||||
await runCommand(command)
|
||||
}).catch(function (error) {
|
||||
if (error === "noDotnet") {
|
||||
@@ -301,3 +311,7 @@ ipcRenderer.on("version", (event, version) => {
|
||||
document.getElementById("version-info").innerText = `v${version}`
|
||||
app_version = version.toString()
|
||||
})
|
||||
|
||||
ipcRenderer.on("print", (event, message) => {
|
||||
console.log(message)
|
||||
})
|
||||
|
||||
5
main.js
5
main.js
@@ -74,3 +74,8 @@ ipcMain.on("selectpath", (event) => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on("print", (event, args) => {
|
||||
console.log(args)
|
||||
})
|
||||
161
utils.js
161
utils.js
@@ -1,3 +1,4 @@
|
||||
|
||||
var defaultTerminal = ""
|
||||
|
||||
/**
|
||||
@@ -263,6 +264,131 @@ const createCommand = (terminal, os) => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function executeCommandWithTerminal(command, terminal, os) {
|
||||
let cmd = ""
|
||||
/* eslint-disable */
|
||||
if (process.platform.includes("win")) {
|
||||
cmd = `start cmd.exe /k "${command}"`
|
||||
} else if (document.getElementById("os").value === "macos") {
|
||||
}
|
||||
|
||||
if (os === 0) {
|
||||
cmd = `start cmd.exe /k '${command}'`
|
||||
} else if (os === 1) {
|
||||
cmd = `osascript -c 'tell application "Terminal" to do script '${command}'`
|
||||
} else if (os === 2) {
|
||||
switch (terminal) {
|
||||
case 0:
|
||||
cmd = `gnome-terminal -e 'bash -c "${command};$SHELL"'`
|
||||
break
|
||||
case 1:
|
||||
cmd = `konsole --hold -e "${command}"`
|
||||
break
|
||||
case 2:
|
||||
cmd = `xfce4-terminal -H -e "${command}"`
|
||||
break
|
||||
case 3:
|
||||
cmd = `terminator -e 'bash -c "${command};$SHELL"'`
|
||||
break
|
||||
case 4:
|
||||
cmd = `terminology -H -e "${command}"`
|
||||
break
|
||||
case 5:
|
||||
cmd = `xterm -hold -T "Downloading Depot..." -e "${command}"`
|
||||
break
|
||||
case 6:
|
||||
cmd = `kitty --hold sh -c "${command}"`
|
||||
break
|
||||
case 7:
|
||||
cmd = `lxterminal -e "${command};$SHELL"`
|
||||
break
|
||||
case 8:
|
||||
cmd = `tilix -e sh -c "${command};$SHELL"`
|
||||
break
|
||||
case 9:
|
||||
cmd = `deepin-terminal -e 'sh -c "${command};$SHELL"'`
|
||||
break
|
||||
case 10:
|
||||
cmd = `cool-retro-term -e sh -c "${command}"`
|
||||
break
|
||||
default:
|
||||
console.log("terminal not found")
|
||||
}
|
||||
} else if (os === 3) {
|
||||
if (process.platform.toString().includes("win")) {
|
||||
console.log(`COPY-PASTE THE FOLLOWING INTO THE TERMINAL:\n\n${command}`)
|
||||
} else console.log(`COPY-PASTE THE FOLLOWING INTO YOUR TERMINAL:\n\nsh ${command}`)
|
||||
cmd = ""
|
||||
}
|
||||
|
||||
console.log(cmd)
|
||||
return cmd
|
||||
/* eslint-enable */
|
||||
}
|
||||
|
||||
async function generateRunScript(username, password, appid, depotid, manifestid, folderinput, chosenPath) {
|
||||
const path = require("path")
|
||||
const fs = require("fs")
|
||||
const sep = path.sep
|
||||
let foldername = ""
|
||||
|
||||
// allow enormous strings like &$§"&$="§$/"(§NJUIDW>;!%?aQ52V?*['YsDnRy|(+Q 1h6BmnDQp,(Xr& being used as password.
|
||||
// NOT TESTED
|
||||
password = password.replace(/"/g, "\"\"")
|
||||
|
||||
// if either the username or password fields is empty, anonymous login is used
|
||||
let anonymous = username === "" || password === ""
|
||||
|
||||
|
||||
/* put the username and password flags into one string, allowing for anonymous login.
|
||||
if anonymous: false true
|
||||
| |
|
||||
*/
|
||||
let userpass = anonymous ? "" : `-username ${username} -password "${password}"`
|
||||
|
||||
/* if nothing is inputted by the user in the folder input, it will be defaulted to the appid. else to the value */
|
||||
foldername = folderinput.value === "" ? appid : folderinput.value
|
||||
|
||||
/* if the path isn't selected by the user, go for the path the app is located in. else use the path the user chose. */
|
||||
chosenPath = chosenPath === "" ? platformpath() : chosenPath
|
||||
|
||||
let finalPath = (chosenPath + path.sep + foldername)
|
||||
if (process.platform.includes("win")) {
|
||||
if (finalPath.includes(" ")) {
|
||||
console.log("path contains spaces")
|
||||
//finalPath.replaceAll(" ", "\\ ")
|
||||
finalPath = `"${finalPath}"`
|
||||
console.log(finalPath)
|
||||
}
|
||||
} else finalPath = finalPath.replaceAll(" ", "\\ ")
|
||||
|
||||
/* / or \ if nothing is inputted its appid replaces " " with "\ ", so whitespaces can be in path names.
|
||||
finalpath: ((the path the user chose) + (seperator) + (the folder name the user chose)).replaceAll()
|
||||
*/
|
||||
|
||||
|
||||
/* The structure of a DepotDownloader command:
|
||||
.NET CLI Path to the DepotDownloader dll. Username/pass combination app id depot id manifest id the dir chosen by user or app path controls how much download servers and threads are used. Needs benchmark TODO
|
||||
| | | | | | | | |
|
||||
dotnet (path)(sep)depotdownloader(sep)DepotDownloader.dll (userpass) -app (appid) -depot (depotid) -manifest (manifestid) -dir (path)(sep) -max-servers 50 -max-downloads 16
|
||||
*/
|
||||
|
||||
if (process.platform.includes("linux")) {
|
||||
// if linux, write a bash script.
|
||||
let content = `#!/usr/bin/env bash
|
||||
dotnet ${platformpath()}${sep}depotdownloader${sep}DepotDownloader.dll ${userpass} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath}${sep} -max-servers 50 -max-downloads 16
|
||||
`
|
||||
await fs.writeFileSync(`${platformpath()}${sep}run.sh`, content)
|
||||
await fs.chmodSync(`${platformpath()}${sep}run.sh`, "755") // make it executable
|
||||
} else if (process.platform.includes("win")) {
|
||||
// if windows, write a batch script
|
||||
let content = `dotnet ${platformpath()}${sep}depotdownloader${sep}DepotDownloader.dll ${userpass} -app ${appid} -depot ${depotid} -manifest ${manifestid} -dir ${finalPath} -max-servers 50 -max-downloads 16`
|
||||
await fs.writeFileSync(`${platformpath()}${sep}run.bat`, content)
|
||||
} else { /* macos */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a given command in a separate process.
|
||||
*
|
||||
@@ -293,23 +419,22 @@ function runCommand(command) {
|
||||
* @returns {string} The absolute path
|
||||
*/
|
||||
const platformpath = () => {
|
||||
if ((__dirname.includes("AppData") || __dirname.includes("Temp")) && process.platform.toString().includes("win")) {
|
||||
// Windows portable exe
|
||||
return process.env.PORTABLE_EXECUTABLE_DIR
|
||||
} else if (/*__dirname.includes("/tmp/") && */process.platform.toString().includes("linux")) {
|
||||
// in a .zip, __dirname seems to return a broken path, ending with app.asar.
|
||||
// using process.cwd() fixes that, but might not work on all distros as this has been an issue in the past.
|
||||
// see commit 894197e75e774f4a17cced00d9862ab3942a8a5a
|
||||
// On linux, it must return process.cwd(). On windows, it must return process.env.PORTABLE_EXECUTABLE_DIR, but only if the program is running from a portable exe.
|
||||
// On linux, __dirname returns the correct path, but on windows, it returns the path to the app.asar file, which is not what we want.
|
||||
|
||||
// Linux AppImage / .zip
|
||||
if (process.platform.includes("win")) {
|
||||
if (process.env.PORTABLE_EXECUTABLE_DIR !== undefined) {
|
||||
return process.env.PORTABLE_EXECUTABLE_DIR
|
||||
} else {
|
||||
return __dirname
|
||||
}
|
||||
} else {
|
||||
return process.cwd()
|
||||
} /*else {
|
||||
return __dirname
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for the availbility of terminal emulators on Linux.
|
||||
* Checks for the availability of terminal emulators on Linux.
|
||||
* It runs the '--version' command on each terminal emulator and checks if the command is successful.
|
||||
* If the command is successful, it means the terminal emulator is installed and available.
|
||||
* The function returns an array of the indices of the available terminal emulators.
|
||||
@@ -340,5 +465,15 @@ const forceTerminals = async () => {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
preDownloadCheck, download, createCommand, runCommand, removeDir, removeFile, unzip, platformpath, forceTerminals
|
||||
preDownloadCheck,
|
||||
download,
|
||||
createCommand,
|
||||
runCommand,
|
||||
removeDir,
|
||||
removeFile,
|
||||
unzip,
|
||||
platformpath,
|
||||
forceTerminals,
|
||||
generateRunScript,
|
||||
executeCommandWithTerminal
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user