From 121581e460f5f2e44543a2a4e1f43a26ed0fadeb Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:09:10 -0700 Subject: [PATCH 01/50] download script for gc --- .gitignore | 1 + resources/index.html | 1 + resources/js/gcdownloader.js | 24 ++++++++++++++++++++++++ resources/js/helpers.js | 1 + scripts/gcdownload.cmd | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+) create mode 100644 resources/js/gcdownloader.js create mode 100644 scripts/gcdownload.cmd diff --git a/.gitignore b/.gitignore index 2ccb550..66207a5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ bin/ dist/ ext/ temp/ +gc*/ resources/js/neutralino.js resources/bg/official diff --git a/resources/index.html b/resources/index.html index f59f5ea..81a7e7a 100644 --- a/resources/index.html +++ b/resources/index.html @@ -8,6 +8,7 @@ + diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js new file mode 100644 index 0000000..c1b5e1b --- /dev/null +++ b/resources/js/gcdownloader.js @@ -0,0 +1,24 @@ +async function clearGCInstallation() { + Neutralino.os.execCommand(`del /s /q "./gc"`) +} + +async function downloadGC(branch) { + const config = await getCfg() + + // If we are pulling from a new branch, delete the old installation + if (config.grasscutterBranch !== branch) await clearGCInstallation() + + // Keystore for branch (since they can differ) + const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` + + // External service that allows un-authed artifact downloading + const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` + + // Run installer + createCmdWindow(`.\\scripts\\gcdownload.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + + // Set current installation in config + config.grasscutterBranch = branch + + Neutralino.storage.setData('config', JSON.stringify(config)) +} \ No newline at end of file diff --git a/resources/js/helpers.js b/resources/js/helpers.js index c0b31c0..ad313fa 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -12,6 +12,7 @@ serverLaunchPanel: false, language: 'en', useHttps: true, + grasscutterBranch: '', } const cfgStr = await Neutralino.storage.getData('config').catch(e => { // The data isn't set, so this is our first time opening diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd new file mode 100644 index 0000000..9105de2 --- /dev/null +++ b/scripts/gcdownload.cmd @@ -0,0 +1,34 @@ +@echo off + +set KEYSTORE_URL=%1 +set ARTIFACT_URL=%2 +set BRANCH=%3 +set FOLDER_NAME=".\gc-%BRANCH%" + +if not exist %FOLDER_NAME% mkdir %FOLDER_NAME% +if not exist ".\temp" mkdir ".\temp" + +echo Downloading Grasscutter prebuilt jar... + +:: Download the jar +powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" + +echo Extracting... + +powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath %FOLDER_NAME% -Force + +:: Download the keystore.p12 file + +echo Downloading keystore.p12... + +powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" + +:: Remove temp stuff +del /s /q "./temp" + +echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% + +pause + +exit /b + From e6642c897105da70153e2fa3eb5d39ae4cc310f1 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:34:10 -0700 Subject: [PATCH 02/50] fix gc downloader script --- resources/js/gcdownloader.js | 3 +++ scripts/gcdownload.cmd | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index c1b5e1b..0786abe 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -20,5 +20,8 @@ async function downloadGC(branch) { // Set current installation in config config.grasscutterBranch = branch + // Set gc path for people with launcher enabled + config.serverFolder = `${NL_CWD}\\gc-${branch}\\` + Neutralino.storage.setData('config', JSON.stringify(config)) } \ No newline at end of file diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd index 9105de2..3c6c05d 100644 --- a/scripts/gcdownload.cmd +++ b/scripts/gcdownload.cmd @@ -4,8 +4,9 @@ set KEYSTORE_URL=%1 set ARTIFACT_URL=%2 set BRANCH=%3 set FOLDER_NAME=".\gc-%BRANCH%" +set FOLDER_NAME=%FOLDER_NAME:"=% -if not exist %FOLDER_NAME% mkdir %FOLDER_NAME% +if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" if not exist ".\temp" mkdir ".\temp" echo Downloading Grasscutter prebuilt jar... @@ -15,12 +16,20 @@ powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" echo Extracting... -powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath %FOLDER_NAME% -Force +:: Delete old file if there is one there +if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar" -:: Download the keystore.p12 file +powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force + +:: Find the jar file name and rename it, just in case +for %%i in (%FOLDER_NAME%/*) do ( + :: If the extension is jar, rename the file + if %%~xi equ .jar rename "%FOLDER_NAME%\%%i" grasscutter.jar +) echo Downloading keystore.p12... +:: Download the keystore.p12 file powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" :: Remove temp stuff From 4813d413eb61c23da9421e90627df92ca20882c9 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:39:47 -0700 Subject: [PATCH 03/50] extra fixes --- resources/js/gcdownloader.js | 5 ++++- scripts/gcdownload.cmd | 4 +++- scripts/install.cmd | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 0786abe..454c7b6 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -21,7 +21,10 @@ async function downloadGC(branch) { config.grasscutterBranch = branch // Set gc path for people with launcher enabled - config.serverFolder = `${NL_CWD}\\gc-${branch}\\` + config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` Neutralino.storage.setData('config', JSON.stringify(config)) + + // Display folder after saving config + displayServerFolder() } \ No newline at end of file diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd index 3c6c05d..576d117 100644 --- a/scripts/gcdownload.cmd +++ b/scripts/gcdownload.cmd @@ -6,6 +6,8 @@ set BRANCH=%3 set FOLDER_NAME=".\gc-%BRANCH%" set FOLDER_NAME=%FOLDER_NAME:"=% +title GC Download Script + if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" if not exist ".\temp" mkdir ".\temp" @@ -39,5 +41,5 @@ echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% pause -exit /b +taskkill /f /fi "WINDOWTITLE eq GC Download Script" diff --git a/scripts/install.cmd b/scripts/install.cmd index 99e27c3..6e1f7a3 100644 --- a/scripts/install.cmd +++ b/scripts/install.cmd @@ -3,6 +3,8 @@ set ORIGIN=%1 set ORIGIN=%ORIGIN:"=% +title Grassclipper Installer + echo Downloading proxy server... :: Make sure we are in the right directory @@ -48,4 +50,4 @@ echo Done! You can now open GrassClipper.exe! pause -exit /b \ No newline at end of file +taskkill /f /fi "WINDOWTITLE eq Grassclipper Installer" \ No newline at end of file From a618ae471d4abd8beac90d57faf896382f7f7e6b Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:43:57 -0700 Subject: [PATCH 04/50] fix server launcher script --- scripts/local_server_launch.cmd | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/scripts/local_server_launch.cmd b/scripts/local_server_launch.cmd index e052d1a..75dde1f 100644 --- a/scripts/local_server_launch.cmd +++ b/scripts/local_server_launch.cmd @@ -3,15 +3,23 @@ set GRASSCUTTER_JAR=%1 set GRASSCUTTER_JAR=%GRASSCUTTER_JAR:"=% +title Grasscutter + :: Get folder the jar is in set "X=%GRASSCUTTER_JAR%" :l -if "%X:~-1%"=="\" goto al -set "X=%X:~0,-1%" -goto l + set IS_SLASH=false + + if "%X:~-1%"=="\" set IS_SLASH=true + if "%X:~-1%"=="/" set IS_SLASH=true + + if %IS_SLASH% equ true goto al + + set "X=%X:~0,-1%" + goto l :al -set "X=%X:~0,-1%" -set "GRASSCUTTER_ROOT=%X%" + set "X=%X:~0,-1%" + set "GRASSCUTTER_ROOT=%X%" echo Starting local Grasscutter server... From 1430e979a0d0695a24b1a8cf6ca34cff2366d651 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 21:05:24 -0700 Subject: [PATCH 05/50] resource downloader --- resources/js/gcdownloader.js | 2 +- scripts/gcdownload.cmd | 45 ------------------------------------ 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 scripts/gcdownload.cmd diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 454c7b6..d20399e 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -15,7 +15,7 @@ async function downloadGC(branch) { const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` // Run installer - createCmdWindow(`.\\scripts\\gcdownload.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) // Set current installation in config config.grasscutterBranch = branch diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd deleted file mode 100644 index 576d117..0000000 --- a/scripts/gcdownload.cmd +++ /dev/null @@ -1,45 +0,0 @@ -@echo off - -set KEYSTORE_URL=%1 -set ARTIFACT_URL=%2 -set BRANCH=%3 -set FOLDER_NAME=".\gc-%BRANCH%" -set FOLDER_NAME=%FOLDER_NAME:"=% - -title GC Download Script - -if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" -if not exist ".\temp" mkdir ".\temp" - -echo Downloading Grasscutter prebuilt jar... - -:: Download the jar -powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" - -echo Extracting... - -:: Delete old file if there is one there -if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar" - -powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force - -:: Find the jar file name and rename it, just in case -for %%i in (%FOLDER_NAME%/*) do ( - :: If the extension is jar, rename the file - if %%~xi equ .jar rename "%FOLDER_NAME%\%%i" grasscutter.jar -) - -echo Downloading keystore.p12... - -:: Download the keystore.p12 file -powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" - -:: Remove temp stuff -del /s /q "./temp" - -echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% - -pause - -taskkill /f /fi "WINDOWTITLE eq GC Download Script" - From 1e197005e3675c981cee7c66fde7a6eac477cdaf Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 21:07:09 -0700 Subject: [PATCH 06/50] resource downloader (fr this time) --- scripts/gc_download.cmd | 55 ++++++++++++++++++++++++++++++++++ scripts/resources_download.cmd | 29 ++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 scripts/gc_download.cmd create mode 100644 scripts/resources_download.cmd diff --git a/scripts/gc_download.cmd b/scripts/gc_download.cmd new file mode 100644 index 0000000..1b24f2b --- /dev/null +++ b/scripts/gc_download.cmd @@ -0,0 +1,55 @@ +@echo off + +set KEYSTORE_URL=%1 +set ARTIFACT_URL=%2 +set BRANCH=%3 +set FOLDER_NAME=".\gc-%BRANCH%" +set FOLDER_NAME=%FOLDER_NAME:"=% + +title GC Download Script + +if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" +if not exist ".\temp" mkdir ".\temp" + +echo Downloading Grasscutter prebuilt jar... + +:: Download the jar +powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" + +echo Extracting... + +:: Delete old file if there is one there +if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar" + +powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force + +:: Find the jar file name and rename it, just in case +for %%i in (%FOLDER_NAME%/*) do ( + :: If the extension is jar, rename the file + if %%~xi equ .jar rename "%FOLDER_NAME%\%%i" grasscutter.jar +) + +echo Downloading keystore.p12... + +:: Download the keystore.p12 file +powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" + +:: Allow resource downloading to be optional, since it takes a while +set REPLY=y +set /p "REPLY=Download server resources? (This can take a while) [y|n]:" +if /i not "%reply%" == "y" goto :finish + +call .\scripts\resources_download.cmd %FOLDER_NAME% + +goto :finish + +:finish + :: Remove temp stuff + del /s /q "./temp" + + echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% + + pause + + taskkill /f /fi "WINDOWTITLE eq GC Download Script" + diff --git a/scripts/resources_download.cmd b/scripts/resources_download.cmd new file mode 100644 index 0000000..f1e1574 --- /dev/null +++ b/scripts/resources_download.cmd @@ -0,0 +1,29 @@ +@echo off + +set FOLDER_NAME=%1 +set FOLDER_NAME=%FOLDER_NAME:"=% + +if not exist ".\temp" mkdir ".\temp" +if not exist ".\resources" mkdir ".\resources" + +echo Downloading resources, this can take a while... + +:: Grab the giant ass resource zip +powershell Invoke-WebRequest -Uri https://github.com/Koko-boya/Grasscutter_Resources/archive/refs/heads/main.zip -OutFile "./temp/resources.zip" + +echo Extracting... + +:: Extract resources to the folder +powershell Expand-Archive -Path "./temp/resources.zip" -DestinationPath "%FOLDER_NAME%" -Force + +:: Delete old resources folder if there is one there +del /s /q "%FOLDER_NAME%\resources">nul + +echo Moving resources to folder... + +robocopy "%FOLDER_NAME%\Grasscutter_Resources-main\Resources" "%FOLDER_NAME%\resources" /E /MOVE>nul + +:: Delete straggling files +del /s /q "%FOLDER_NAME%\Grasscutter_Resources-main" + +echo Done, resources should be properly extracted \ No newline at end of file From 5ad961d2187a42a08a8f279a6c76518b6e978746 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:19:32 -0700 Subject: [PATCH 07/50] download data and key files --- resources/js/gcdownloader.js | 47 +++++++++++++++++++++++++++++------- resources/js/helpers.js | 2 +- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index d20399e..29eb8a2 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -8,15 +8,6 @@ async function downloadGC(branch) { // If we are pulling from a new branch, delete the old installation if (config.grasscutterBranch !== branch) await clearGCInstallation() - // Keystore for branch (since they can differ) - const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` - - // External service that allows un-authed artifact downloading - const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` - - // Run installer - createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) - // Set current installation in config config.grasscutterBranch = branch @@ -24,6 +15,44 @@ async function downloadGC(branch) { config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` Neutralino.storage.setData('config', JSON.stringify(config)) + + // Keystore for branch (since they can differ) + const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` + + // External service that allows un-authed artifact downloading + const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` + + // For data files + const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`) + const dataList = dataFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + + // For key files + const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`) + const keyList = keyFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + + const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') + + // Download data files + for (const o of dataList) { + const folder = 'data' + Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } + + // Download each file + for (const o of keyList) { + const folder = 'keys' + Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } + + return; + + // Run installer + createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + // Display folder after saving config displayServerFolder() diff --git a/resources/js/helpers.js b/resources/js/helpers.js index ad313fa..4e3a38b 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -98,7 +98,7 @@ async function openGameFolder() { async function openGrasscutterFolder() { const config = await getCfg() - const folder = config.serverFolder.match(/.*\\/g, '')[0] + const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0] openInExplorer(folder) } From a52d42538a8a8c471bcdd3d4aba0a9081356b15d Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:23:33 -0700 Subject: [PATCH 08/50] ensure folders exist --- resources/js/gcdownloader.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 29eb8a2..960a757 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -36,16 +36,21 @@ async function downloadGC(branch) { const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') + // Ensure data and key folders exist + + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`) + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`) + // Download data files for (const o of dataList) { const folder = 'data' - Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) } - // Download each file + // Download key files for (const o of keyList) { const folder = 'keys' - Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) } return; From 8ed80bc55fbf2a6ce74d348739555d9451645e9d Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:24:45 -0700 Subject: [PATCH 09/50] re-enable full installer --- resources/js/gcdownloader.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 960a757..257a5f5 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -52,8 +52,6 @@ async function downloadGC(branch) { const folder = 'keys' await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) } - - return; // Run installer createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) From 8971cee64f3ede87ab5d0dbf9eb702847d7f2c2f Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:56:15 -0700 Subject: [PATCH 10/50] begin downloads panel --- resources/index.html | 27 +++++++++++++++++++++++++++ resources/js/gcdownloader.js | 1 - resources/js/index.js | 14 ++++++++++++++ resources/style/index.css | 13 +++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/resources/index.html b/resources/index.html index 81a7e7a..ed5353e 100644 --- a/resources/index.html +++ b/resources/index.html @@ -115,6 +115,28 @@ + + + +
diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 257a5f5..f101690 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -56,7 +56,6 @@ async function downloadGC(branch) { // Run installer createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) - // Display folder after saving config displayServerFolder() } \ No newline at end of file diff --git a/resources/js/index.js b/resources/js/index.js index 0a4e2ce..b25a6e7 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -246,6 +246,20 @@ async function handleFavoriteList() { } } +async function openDownloads() { + const downloads = document.querySelector('#downloadPanel') + + if (downloads.style.display === 'none') { + downloads.style.removeProperty('display') + } +} + +async function closeDownloads() { + const downloads = document.querySelector('#downloadPanel') + + downloads.style.display = 'none' +} + async function openSettings() { const settings = document.querySelector('#settingsPanel') const config = await getCfg() diff --git a/resources/style/index.css b/resources/style/index.css index ff31870..0b16237 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -157,6 +157,7 @@ a { #firstTimeNotice, #loginPanel, +#downloadPanel, #settingsPanel { display: block; position: absolute; @@ -172,6 +173,7 @@ a { font-family: system-ui; } +#downloadPanel, #settingsPanel { width: 35%; height: 80%; @@ -184,6 +186,7 @@ a { margin-bottom: 10px; } +#downloadPanelInner, #settingsPanelInner { display: flex; flex-direction: column; @@ -192,16 +195,19 @@ a { padding: 10px 10%; } +.downloadRow, .settingsRow { width: 100%; } +.downloadTitle, .settingTitle { font-size: 1.2em; font-weight: bold; margin-bottom: 10px; } +.downloadLabel, .settingLabel { display:inline-block; font-size: 1em; @@ -209,12 +215,14 @@ a { margin: 10px 0px; } +.downloadSubtitle, .settingSubtitle { color: rgb(165, 165, 165); font-size: 0.8em; font-weight: normal; } +.downloadSection, .settingSection { display: flex; flex-direction: row; @@ -222,10 +230,12 @@ a { justify-content: space-between; } +.downloadSection .smolBtn, .settingSection .smolBtn { height: 30px; } +#downloadTitleBar #settingsTitleBar { display: flex; flex-direction: row; @@ -233,15 +243,18 @@ a { justify-content: space-between; } +#downloadClose, #settingsClose { display: inline-block; transition: filter 0.1s ease-in-out; } +#downloadClose img, #settingsClose img { height: 20px; } +#downloadClose:hover, #settingsClose:hover { filter: invert(85%) sepia(31%) saturate(560%) hue-rotate(329deg) brightness(100%) contrast(92%); cursor: pointer; From 1754638ab54ea13b4d879975e85bb261149df8a8 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:59:11 -0700 Subject: [PATCH 11/50] small styling fixes --- resources/index.html | 10 ++++------ resources/style/index.css | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/index.html b/resources/index.html index ed5353e..2d63c3a 100644 --- a/resources/index.html +++ b/resources/index.html @@ -117,12 +117,10 @@ From b936a4f7b2d6f89f934aa7dc2bf28b35aac4968c Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:09:20 -0700 Subject: [PATCH 13/50] download page open/close --- resources/icons/download.svg | 11 +++++++++++ resources/index.html | 13 +++++++++++-- resources/js/index.js | 10 ++++++++++ resources/style/index.css | 4 ++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 resources/icons/download.svg diff --git a/resources/icons/download.svg b/resources/icons/download.svg new file mode 100644 index 0000000..8baf9ed --- /dev/null +++ b/resources/icons/download.svg @@ -0,0 +1,11 @@ + +Created with Fabric.js 1.7.22 + + + + + + + + + \ No newline at end of file diff --git a/resources/index.html b/resources/index.html index 41b951e..6b86265 100644 --- a/resources/index.html +++ b/resources/index.html @@ -134,7 +134,7 @@
- Download Stable Build + Download Grasscutter Stable Build
@@ -143,13 +143,22 @@
- Download Development Build + Download Grasscutter Development Build
Install Grasscutter development branch. This build sometimes has bugs, and is frequently updated. Use at your own risk.
+
+
+ Download Grasscutter Resources + +
+ + Downloads Grasscutter resources into the currently set Grasscutter folder. This should be done unless you plan on getting resources externally. + +
diff --git a/resources/js/index.js b/resources/js/index.js index b25a6e7..20e0502 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -248,10 +248,20 @@ async function handleFavoriteList() { async function openDownloads() { const downloads = document.querySelector('#downloadPanel') + const config = await getCfg() if (downloads.style.display === 'none') { downloads.style.removeProperty('display') } + + // Disable the resource download button if a serverFolder path is not set + if (!config.serverFolder) { + document.querySelector('#resourceInstall').disabled = true + document.querySelector('#resourceInstall').classList.add('disabled') + } else { + document.querySelector('#resourceInstall').disabled = false + document.querySelector('#resourceInstall').classList.remove('disabled') + } } async function closeDownloads() { diff --git a/resources/style/index.css b/resources/style/index.css index d466177..d1e2ea6 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -216,6 +216,10 @@ a { margin: 10px 0px; } +.downloadLabel { + margin: 14px 0px; +} + .downloadSubtitle, .settingSubtitle { color: rgb(165, 165, 165); From b4ac33ebaaf2afd9eeae5adb3e937aa81558e263 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:15:04 -0700 Subject: [PATCH 14/50] organization --- resources/index.html | 6 ++++++ resources/js/onLoad.js | 22 ++++++++++++++++------ resources/style/index.css | 8 ++++---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/resources/index.html b/resources/index.html index 6b86265..f3edc5d 100644 --- a/resources/index.html +++ b/resources/index.html @@ -123,6 +123,9 @@
+
+ GrassClipper +
Installer @@ -132,6 +135,9 @@ Installs proxy and other tools. Required for Grasscutter servers.
+
+ Grasscutter +
Download Grasscutter Stable Build diff --git a/resources/js/onLoad.js b/resources/js/onLoad.js index a1e8773..bc96832 100644 --- a/resources/js/onLoad.js +++ b/resources/js/onLoad.js @@ -38,6 +38,7 @@ window.addEventListener("click", function(e) { const favList = document.querySelector('#ipList') const settingsPanel = document.querySelector('#settingsPanel') + const downloadPanel = document.querySelector('#downloadPanel') // This will close the favorites list no matter what is clicked if (favList.style.display !== 'none') { @@ -46,23 +47,32 @@ } // This will close the settings panel no matter what is clicked - let settingCheckElm = e.target + let checkElm = e.target - while(settingCheckElm.tagName !== 'BODY') { - if (settingCheckElm.id === 'settingsPanel' - || settingCheckElm.id === 'settingsBtn') { + while(checkElm.tagName !== 'BODY') { + if (checkElm.id === 'settingsPanel' + || checkElm.id === 'settingsBtn') { return } - settingCheckElm = settingCheckElm.parentElement + if (checkElm.id === 'downloadPanel' || + checkElm.id === 'downloadBtn') { + return + } + + checkElm = checkElm.parentElement } // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel - if (settingCheckElm.tagName === 'BODY') { + if (checkElm.tagName === 'BODY') { // This will close the settings panel only when something outside of it is clicked if (settingsPanel.style.display !== 'none') { settingsPanel.style.display = 'none' } + + if (downloadPanel.style.display !== 'none') { + downloadPanel.style.display = 'none' + } } }); diff --git a/resources/style/index.css b/resources/style/index.css index d1e2ea6..6bb5548 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -208,6 +208,10 @@ a { margin-bottom: 10px; } +.downloadTitle { + margin: 6px; +} + .downloadLabel, .settingLabel { display:inline-block; @@ -216,10 +220,6 @@ a { margin: 10px 0px; } -.downloadLabel { - margin: 14px 0px; -} - .downloadSubtitle, .settingSubtitle { color: rgb(165, 165, 165); From 85eba69a63eb4a969c218aefc79790513da7e3d4 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:17:23 -0700 Subject: [PATCH 15/50] disallow unset paths --- resources/js/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/js/index.js b/resources/js/index.js index 20e0502..acbd062 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -412,6 +412,8 @@ async function setGameExe() { ] }) + if (!gameexe[0]) return; + // Set the folder in our configuration const config = await getCfg() @@ -433,6 +435,8 @@ async function setGrasscutterFolder() { ] }) + if (!folder[0]) return; + // Set the folder in our configuration const config = await getCfg() From d6961c9335e52cf7c7e545fc5ff093eba9c93862 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:32:51 -0700 Subject: [PATCH 16/50] show when script is beginning to run --- resources/js/gcdownloader.js | 40 ++++++++++++++++++++++++++++++++++++ resources/style/index.css | 4 ++++ 2 files changed, 44 insertions(+) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index f101690..a8523f0 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -2,6 +2,37 @@ async function clearGCInstallation() { Neutralino.os.execCommand(`del /s /q "./gc"`) } +async function setDownloadButtonsToLoading() { + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') + + stableBtn.innerText = localeObj.gcScriptRunning || 'Running...' + + devBtn.innerText = localeObj.gcScriptRunning || 'Running...' + + // Set btns to disabled + stableBtn.disabled = true + stableBtn.classList.add('disabled') + + devBtn.disabled = true + devBtn.classList.add('disabled') +} + +async function resetDownloadButtons() { + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') + + stableBtn.innerText = localeObj.stableInstall || 'Download' + devBtn.innerText = localeObj.devInstall || 'Download' + + // Set btns to enabled + stableBtn.disabled = false + stableBtn.classList.remove('disabled') + + devBtn.disabled = false + devBtn.classList.remove('disabled') +} + async function downloadGC(branch) { const config = await getCfg() @@ -14,8 +45,13 @@ async function downloadGC(branch) { // Set gc path for people with launcher enabled config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` + // Enable server launcher + config.serverLaunchPanel = true + Neutralino.storage.setData('config', JSON.stringify(config)) + setDownloadButtonsToLoading() + // Keystore for branch (since they can differ) const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` @@ -56,6 +92,10 @@ async function downloadGC(branch) { // Run installer createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + // Fix buttons + resetDownloadButtons() + // Display folder after saving config displayServerFolder() + displayServerLaunchSection() } \ No newline at end of file diff --git a/resources/style/index.css b/resources/style/index.css index 6bb5548..f738e24 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -11,6 +11,10 @@ a { color: #fff; } +img { + height: 20px; +} + .darken { filter: brightness(0.6); } From 963866528d686d786621cd096a009fb6c2fb0e50 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:40:11 -0700 Subject: [PATCH 17/50] translation setup for downloads --- languages/en.json | 16 ++++++++++++++++ resources/index.html | 2 +- resources/js/translation.js | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/languages/en.json b/languages/en.json index a7ecafe..1fecb4d 100644 --- a/languages/en.json +++ b/languages/en.json @@ -63,5 +63,21 @@ "alertAuthNoRegister": "Authentication is disabled, no need to register!", "alertRegisterSuccess": "Registration successful!", + "downloadTitle": "Downloads", + "grassclipperTitle": "GrassClipper", + "grasscutterTitle": "Grasscutter", + "installerTitle": "Installer", + "installerSubtitle": "Installs proxy and other tools. Required for Grasscutter servers.", + "downloadStable": "Download Grasscutter Stable Build", + "stableSubtitle": "Install Grasscutter stable branch. This build usually has less bugs, but also less features.", + "downloadDev": "Download Grasscutter Development Build", + "downloadSubtitle": "Install Grasscutter development branch. This build sometimes has bugs, and is frequently updated. Use at your own risk.", + "downloadResources": "Download Grasscutter Resources", + "devSubtitle": "Downloads Grasscutter resources into the currently set Grasscutter folder. This should be done unless you plan on getting resources externally.", + + "gcScriptRunning": "Running...", + "stableInstall": "Download", + "devInstall": "Download", + "updateNotifText": "A new update is available! Newest version: " } diff --git a/resources/index.html b/resources/index.html index f3edc5d..bb71778 100644 --- a/resources/index.html +++ b/resources/index.html @@ -135,7 +135,7 @@ Installs proxy and other tools. Required for Grasscutter servers.
-
+
Grasscutter
diff --git a/resources/js/translation.js b/resources/js/translation.js index 986b03c..2f1d17d 100644 --- a/resources/js/translation.js +++ b/resources/js/translation.js @@ -90,6 +90,21 @@ async function doTranslation() { set('loginPopupContentBodyBtnRegister', 'authRegisterBtn') set('noLoginBtn', 'launchWithoutAuth') + // Downloads section + set('downloadTitle', 'downloadTitle') + set('grassclipperTitle', 'grassclipperTitle') + set('grasscutterTitle', 'grasscutterTitle') + set('installerTitle', 'installerTitle') + set('installerSubtitle', 'installerSubtitle') + set('downloadStable', 'downloadStable') + set('stableSubtitle', 'stableSubtitle') + set('downloadDev', 'downloadDev') + set('downloadSubtitle', 'downloadSubtitle') + set('downloadResources', 'downloadResources') + set('devSubtitle', 'devSubtitle') + set('stableInstall', 'stableInstall') + set('devInstall', 'devInstall') + // update notification set('updateNotifText', 'updateNotifText') } \ No newline at end of file From e60fa35e8d1c7146be425be623bed083703d2995 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:54:40 -0700 Subject: [PATCH 18/50] bugfix --- resources/js/index.js | 2 +- resources/js/translation.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/js/index.js b/resources/js/index.js index acbd062..a322e5a 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -412,7 +412,7 @@ async function setGameExe() { ] }) - if (!gameexe[0]) return; + if (!gameExe[0]) return; // Set the folder in our configuration const config = await getCfg() diff --git a/resources/js/translation.js b/resources/js/translation.js index 2f1d17d..dd80b83 100644 --- a/resources/js/translation.js +++ b/resources/js/translation.js @@ -99,7 +99,7 @@ async function doTranslation() { set('downloadStable', 'downloadStable') set('stableSubtitle', 'stableSubtitle') set('downloadDev', 'downloadDev') - set('downloadSubtitle', 'downloadSubtitle') + set('devSubtitle', 'downloadSubtitle') set('downloadResources', 'downloadResources') set('devSubtitle', 'devSubtitle') set('stableInstall', 'stableInstall') From 1a7a0b1dc4038d704d78d22f842448848ef4cf9b Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:59:20 -0700 Subject: [PATCH 19/50] enable server button --- resources/js/gcdownloader.js | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index a8523f0..e45a0f4 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -97,5 +97,6 @@ async function downloadGC(branch) { // Display folder after saving config displayServerFolder() + enableServerButton() displayServerLaunchSection() } \ No newline at end of file From 93148149efdc457373b756ef72050e943277511a Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 02:47:55 -0700 Subject: [PATCH 20/50] fix killswitch --- scripts/private_server_launch.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/private_server_launch.cmd b/scripts/private_server_launch.cmd index 0cc7b12..5fcbf1e 100644 --- a/scripts/private_server_launch.cmd +++ b/scripts/private_server_launch.cmd @@ -27,7 +27,7 @@ if "%ENABLE_KILLSWITCH%" EQU "true" ( :: Restart in elevated if need be >nul 2>&1 reg query "HKU\S-1-5-19" || ( set params = %*:"="""% - cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 %1 %2 %3 "%4" ""%cd%/../"" %6", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && taskkill /f /fi "WINDOWTITLE eq PS Launcher Script" && exit /b ) + cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 %1 %2 %3 "%4" ""%cd%"" %6", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && taskkill /f /fi "WINDOWTITLE eq PS Launcher Script" && exit /b ) ) ) @@ -41,7 +41,7 @@ reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v Pr reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "127.0.0.1:8080" /f >nul 2>nul :: Start proxy server -start "Proxy Server" "%ORIGIN%/ext/mitmdump.exe" -s "%ORIGIN%/proxy/proxy.py" -k --allow-hosts ".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com" --ssl-insecure --set ip=%IP% --set port=%PORT% --set use_https=%USE_HTTPS% +start "Proxy Server" "%ORIGIN%\ext\mitmdump.exe" -s "%ORIGIN%/proxy/proxy.py" -k --allow-hosts ".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com" --ssl-insecure --set ip=%IP% --set port=%PORT% --set use_https=%USE_HTTPS% echo Opening %GAME_PATH% From 574b2f4f09a3e903160e2fdc1bd2d45ade23c4ed Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 19:50:49 -0700 Subject: [PATCH 21/50] change auth endpoints --- manifest.json | 2 +- neutralino.config.json | 2 +- package.json | 2 +- resources/js/index.js | 5 ++--- resources/js/login.js | 4 ++-- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest.json b/manifest.json index 3df9a34..95e72a6 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { "applicationId": "js.grassclipper.app", - "version": "0.8.5", + "version": "0.8.6", "resourcesURL": "https://github.com/Grasscutters/GrassClipper/releases/latest/download/resources.neu" } \ No newline at end of file diff --git a/neutralino.config.json b/neutralino.config.json index 7abf636..f3a3b87 100644 --- a/neutralino.config.json +++ b/neutralino.config.json @@ -1,6 +1,6 @@ { "applicationId": "js.grassclipper.app", - "version": "0.8.5", + "version": "0.8.6", "defaultMode": "window", "port": 0, "documentRoot": "/resources/", diff --git a/package.json b/package.json index 196bce7..8a336fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grassclipper", - "version": "0.8.5", + "version": "0.8.6", "repository": "https://github.com/Grasscutters/GrassClipper.git", "author": "SpikeHD ", "license": "Apache-2.0", diff --git a/resources/js/index.js b/resources/js/index.js index 0a4e2ce..98b22d8 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -298,9 +298,9 @@ async function openLogin() { // Check if we even need to authenticate try { - const { data } = await axios.get(url + '/grasscutter/auth_status') + const { data } = await axios.get(url + '/authentication/type') - if (data?.message !== 'AUTH_ENABLED') { + if (!data.includes('GCAuthAuthenticationHandler')) { launchPrivate() return } @@ -309,7 +309,6 @@ async function openLogin() { return } - loginIpDisplay.innerText = ip registerIpDisplay.innerText = ip diff --git a/resources/js/login.js b/resources/js/login.js index 5fd7f8e..60188d7 100644 --- a/resources/js/login.js +++ b/resources/js/login.js @@ -62,7 +62,7 @@ async function login() { password, } - const { data } = await axios.post(url + '/grasscutter/login', reqBody) + const { data } = await axios.post(url + '/authentication/login', reqBody) switch(data.message) { case 'INVALID_ACCOUNT': @@ -117,7 +117,7 @@ async function register() { password_confirmation } - const { data } = await axios.post(url + '/grasscutter/register', reqBody) + const { data } = await axios.post(url + '/authentication/register', reqBody) switch(data.message) { case 'USERNAME_TAKEN': From 1f3632753f89fca22b1f0ac2cca6004204f6cfc5 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 21:34:53 -0700 Subject: [PATCH 22/50] fix traditional chinese translation file --- languages/zh-tw.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/zh-tw.json b/languages/zh-tw.json index d551fb9..0d23c08 100644 --- a/languages/zh-tw.json +++ b/languages/zh-tw.json @@ -38,7 +38,7 @@ "proxyInstallDeny": "不用了,謝謝。", "gameFolderDialog": "選擇Genshin Impact game資料夾", - "grasscutterFileDialog": "選擇Grasscutter.jar檔案" + "grasscutterFileDialog": "選擇Grasscutter.jar檔案", "loggingInTo": "登錄至:", "registeringFor": "註冊至:", @@ -60,7 +60,7 @@ "alertUserTaken": "用戶名已被占用", "alertPassMismatch": "兩組密碼不一致", "alertAuthNoRegister": "未啟用認證,無需註冊!", - "alertRegisterSuccess": "註冊成功!" + "alertRegisterSuccess": "註冊成功!", "updateNotifText": "有新的GrassClipper更新可用! 最新版本: " } From 08cd04b134300cd5c763802cdc3f0deb2d1c8a2b Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 21:35:38 -0700 Subject: [PATCH 23/50] version bump --- manifest.json | 2 +- neutralino.config.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index 95e72a6..2fc35a4 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { "applicationId": "js.grassclipper.app", - "version": "0.8.6", + "version": "0.8.7", "resourcesURL": "https://github.com/Grasscutters/GrassClipper/releases/latest/download/resources.neu" } \ No newline at end of file diff --git a/neutralino.config.json b/neutralino.config.json index f3a3b87..be4549a 100644 --- a/neutralino.config.json +++ b/neutralino.config.json @@ -1,6 +1,6 @@ { "applicationId": "js.grassclipper.app", - "version": "0.8.6", + "version": "0.8.7", "defaultMode": "window", "port": 0, "documentRoot": "/resources/", diff --git a/package.json b/package.json index 8a336fe..e5efc86 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grassclipper", - "version": "0.8.6", + "version": "0.8.7", "repository": "https://github.com/Grasscutters/GrassClipper.git", "author": "SpikeHD ", "license": "Apache-2.0", From e152cc3e3c806e460570905839034c88b1936c43 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 21:40:05 -0700 Subject: [PATCH 24/50] Quotes in user profile usage in scripts --- scripts/install.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install.cmd b/scripts/install.cmd index 99e27c3..f8e14f1 100644 --- a/scripts/install.cmd +++ b/scripts/install.cmd @@ -35,12 +35,12 @@ taskkill /f /im mitmdump.exe echo Adding ceritifcate... :: Ensure we are elevated for certs ->nul 2>&1 certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer || ( +>nul 2>&1 certutil -addstore root "%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer" || ( echo ============================================================================================================ echo !! Certificate install failed !! echo. echo Please manually run this command as Administrator: - echo certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer + echo certutil -addstore root "%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer" echo ============================================================================================================ ) From 7c2f36109d7aed1bb37905b056af53c1a5b03f82 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:09:10 -0700 Subject: [PATCH 25/50] download script for gc --- .gitignore | 1 + resources/index.html | 1 + resources/js/gcdownloader.js | 24 ++++++++++++++++++++++++ resources/js/helpers.js | 1 + scripts/gcdownload.cmd | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+) create mode 100644 resources/js/gcdownloader.js create mode 100644 scripts/gcdownload.cmd diff --git a/.gitignore b/.gitignore index 2ccb550..66207a5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ bin/ dist/ ext/ temp/ +gc*/ resources/js/neutralino.js resources/bg/official diff --git a/resources/index.html b/resources/index.html index f59f5ea..81a7e7a 100644 --- a/resources/index.html +++ b/resources/index.html @@ -8,6 +8,7 @@ + diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js new file mode 100644 index 0000000..c1b5e1b --- /dev/null +++ b/resources/js/gcdownloader.js @@ -0,0 +1,24 @@ +async function clearGCInstallation() { + Neutralino.os.execCommand(`del /s /q "./gc"`) +} + +async function downloadGC(branch) { + const config = await getCfg() + + // If we are pulling from a new branch, delete the old installation + if (config.grasscutterBranch !== branch) await clearGCInstallation() + + // Keystore for branch (since they can differ) + const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` + + // External service that allows un-authed artifact downloading + const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` + + // Run installer + createCmdWindow(`.\\scripts\\gcdownload.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + + // Set current installation in config + config.grasscutterBranch = branch + + Neutralino.storage.setData('config', JSON.stringify(config)) +} \ No newline at end of file diff --git a/resources/js/helpers.js b/resources/js/helpers.js index c0b31c0..ad313fa 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -12,6 +12,7 @@ serverLaunchPanel: false, language: 'en', useHttps: true, + grasscutterBranch: '', } const cfgStr = await Neutralino.storage.getData('config').catch(e => { // The data isn't set, so this is our first time opening diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd new file mode 100644 index 0000000..9105de2 --- /dev/null +++ b/scripts/gcdownload.cmd @@ -0,0 +1,34 @@ +@echo off + +set KEYSTORE_URL=%1 +set ARTIFACT_URL=%2 +set BRANCH=%3 +set FOLDER_NAME=".\gc-%BRANCH%" + +if not exist %FOLDER_NAME% mkdir %FOLDER_NAME% +if not exist ".\temp" mkdir ".\temp" + +echo Downloading Grasscutter prebuilt jar... + +:: Download the jar +powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" + +echo Extracting... + +powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath %FOLDER_NAME% -Force + +:: Download the keystore.p12 file + +echo Downloading keystore.p12... + +powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" + +:: Remove temp stuff +del /s /q "./temp" + +echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% + +pause + +exit /b + From 158e10352b1094322b54d11c8c26d3445fe52b42 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:34:10 -0700 Subject: [PATCH 26/50] fix gc downloader script --- resources/js/gcdownloader.js | 3 +++ scripts/gcdownload.cmd | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index c1b5e1b..0786abe 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -20,5 +20,8 @@ async function downloadGC(branch) { // Set current installation in config config.grasscutterBranch = branch + // Set gc path for people with launcher enabled + config.serverFolder = `${NL_CWD}\\gc-${branch}\\` + Neutralino.storage.setData('config', JSON.stringify(config)) } \ No newline at end of file diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd index 9105de2..3c6c05d 100644 --- a/scripts/gcdownload.cmd +++ b/scripts/gcdownload.cmd @@ -4,8 +4,9 @@ set KEYSTORE_URL=%1 set ARTIFACT_URL=%2 set BRANCH=%3 set FOLDER_NAME=".\gc-%BRANCH%" +set FOLDER_NAME=%FOLDER_NAME:"=% -if not exist %FOLDER_NAME% mkdir %FOLDER_NAME% +if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" if not exist ".\temp" mkdir ".\temp" echo Downloading Grasscutter prebuilt jar... @@ -15,12 +16,20 @@ powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" echo Extracting... -powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath %FOLDER_NAME% -Force +:: Delete old file if there is one there +if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar" -:: Download the keystore.p12 file +powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force + +:: Find the jar file name and rename it, just in case +for %%i in (%FOLDER_NAME%/*) do ( + :: If the extension is jar, rename the file + if %%~xi equ .jar rename "%FOLDER_NAME%\%%i" grasscutter.jar +) echo Downloading keystore.p12... +:: Download the keystore.p12 file powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" :: Remove temp stuff From bdea511d543ce310f665c152997cd80118751b78 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:39:47 -0700 Subject: [PATCH 27/50] extra fixes --- resources/js/gcdownloader.js | 5 ++++- scripts/gcdownload.cmd | 4 +++- scripts/install.cmd | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 0786abe..454c7b6 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -21,7 +21,10 @@ async function downloadGC(branch) { config.grasscutterBranch = branch // Set gc path for people with launcher enabled - config.serverFolder = `${NL_CWD}\\gc-${branch}\\` + config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` Neutralino.storage.setData('config', JSON.stringify(config)) + + // Display folder after saving config + displayServerFolder() } \ No newline at end of file diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd index 3c6c05d..576d117 100644 --- a/scripts/gcdownload.cmd +++ b/scripts/gcdownload.cmd @@ -6,6 +6,8 @@ set BRANCH=%3 set FOLDER_NAME=".\gc-%BRANCH%" set FOLDER_NAME=%FOLDER_NAME:"=% +title GC Download Script + if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" if not exist ".\temp" mkdir ".\temp" @@ -39,5 +41,5 @@ echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% pause -exit /b +taskkill /f /fi "WINDOWTITLE eq GC Download Script" diff --git a/scripts/install.cmd b/scripts/install.cmd index f8e14f1..63fbd41 100644 --- a/scripts/install.cmd +++ b/scripts/install.cmd @@ -3,6 +3,8 @@ set ORIGIN=%1 set ORIGIN=%ORIGIN:"=% +title Grassclipper Installer + echo Downloading proxy server... :: Make sure we are in the right directory @@ -48,4 +50,4 @@ echo Done! You can now open GrassClipper.exe! pause -exit /b \ No newline at end of file +taskkill /f /fi "WINDOWTITLE eq Grassclipper Installer" \ No newline at end of file From 6c0a079a41ba7399a6eabfa44b60b684b27dc4f8 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 19:43:57 -0700 Subject: [PATCH 28/50] fix server launcher script --- scripts/local_server_launch.cmd | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/scripts/local_server_launch.cmd b/scripts/local_server_launch.cmd index e052d1a..75dde1f 100644 --- a/scripts/local_server_launch.cmd +++ b/scripts/local_server_launch.cmd @@ -3,15 +3,23 @@ set GRASSCUTTER_JAR=%1 set GRASSCUTTER_JAR=%GRASSCUTTER_JAR:"=% +title Grasscutter + :: Get folder the jar is in set "X=%GRASSCUTTER_JAR%" :l -if "%X:~-1%"=="\" goto al -set "X=%X:~0,-1%" -goto l + set IS_SLASH=false + + if "%X:~-1%"=="\" set IS_SLASH=true + if "%X:~-1%"=="/" set IS_SLASH=true + + if %IS_SLASH% equ true goto al + + set "X=%X:~0,-1%" + goto l :al -set "X=%X:~0,-1%" -set "GRASSCUTTER_ROOT=%X%" + set "X=%X:~0,-1%" + set "GRASSCUTTER_ROOT=%X%" echo Starting local Grasscutter server... From ba91d9058f9909d60435a75f37132a583b7d8366 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 21:05:24 -0700 Subject: [PATCH 29/50] resource downloader --- resources/js/gcdownloader.js | 2 +- scripts/gcdownload.cmd | 45 ------------------------------------ 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 scripts/gcdownload.cmd diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 454c7b6..d20399e 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -15,7 +15,7 @@ async function downloadGC(branch) { const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` // Run installer - createCmdWindow(`.\\scripts\\gcdownload.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) // Set current installation in config config.grasscutterBranch = branch diff --git a/scripts/gcdownload.cmd b/scripts/gcdownload.cmd deleted file mode 100644 index 576d117..0000000 --- a/scripts/gcdownload.cmd +++ /dev/null @@ -1,45 +0,0 @@ -@echo off - -set KEYSTORE_URL=%1 -set ARTIFACT_URL=%2 -set BRANCH=%3 -set FOLDER_NAME=".\gc-%BRANCH%" -set FOLDER_NAME=%FOLDER_NAME:"=% - -title GC Download Script - -if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" -if not exist ".\temp" mkdir ".\temp" - -echo Downloading Grasscutter prebuilt jar... - -:: Download the jar -powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" - -echo Extracting... - -:: Delete old file if there is one there -if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar" - -powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force - -:: Find the jar file name and rename it, just in case -for %%i in (%FOLDER_NAME%/*) do ( - :: If the extension is jar, rename the file - if %%~xi equ .jar rename "%FOLDER_NAME%\%%i" grasscutter.jar -) - -echo Downloading keystore.p12... - -:: Download the keystore.p12 file -powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" - -:: Remove temp stuff -del /s /q "./temp" - -echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% - -pause - -taskkill /f /fi "WINDOWTITLE eq GC Download Script" - From 8f86d5c2834432eba7e18e3cb60d59f1409252f4 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 21:07:09 -0700 Subject: [PATCH 30/50] resource downloader (fr this time) --- scripts/gc_download.cmd | 55 ++++++++++++++++++++++++++++++++++ scripts/resources_download.cmd | 29 ++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 scripts/gc_download.cmd create mode 100644 scripts/resources_download.cmd diff --git a/scripts/gc_download.cmd b/scripts/gc_download.cmd new file mode 100644 index 0000000..1b24f2b --- /dev/null +++ b/scripts/gc_download.cmd @@ -0,0 +1,55 @@ +@echo off + +set KEYSTORE_URL=%1 +set ARTIFACT_URL=%2 +set BRANCH=%3 +set FOLDER_NAME=".\gc-%BRANCH%" +set FOLDER_NAME=%FOLDER_NAME:"=% + +title GC Download Script + +if not exist "%FOLDER_NAME%" mkdir "%FOLDER_NAME%" +if not exist ".\temp" mkdir ".\temp" + +echo Downloading Grasscutter prebuilt jar... + +:: Download the jar +powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip" + +echo Extracting... + +:: Delete old file if there is one there +if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar" + +powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force + +:: Find the jar file name and rename it, just in case +for %%i in (%FOLDER_NAME%/*) do ( + :: If the extension is jar, rename the file + if %%~xi equ .jar rename "%FOLDER_NAME%\%%i" grasscutter.jar +) + +echo Downloading keystore.p12... + +:: Download the keystore.p12 file +powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" + +:: Allow resource downloading to be optional, since it takes a while +set REPLY=y +set /p "REPLY=Download server resources? (This can take a while) [y|n]:" +if /i not "%reply%" == "y" goto :finish + +call .\scripts\resources_download.cmd %FOLDER_NAME% + +goto :finish + +:finish + :: Remove temp stuff + del /s /q "./temp" + + echo Done, latest Grasscutter %BRANCH% now downloaded in %FOLDER_NAME% + + pause + + taskkill /f /fi "WINDOWTITLE eq GC Download Script" + diff --git a/scripts/resources_download.cmd b/scripts/resources_download.cmd new file mode 100644 index 0000000..f1e1574 --- /dev/null +++ b/scripts/resources_download.cmd @@ -0,0 +1,29 @@ +@echo off + +set FOLDER_NAME=%1 +set FOLDER_NAME=%FOLDER_NAME:"=% + +if not exist ".\temp" mkdir ".\temp" +if not exist ".\resources" mkdir ".\resources" + +echo Downloading resources, this can take a while... + +:: Grab the giant ass resource zip +powershell Invoke-WebRequest -Uri https://github.com/Koko-boya/Grasscutter_Resources/archive/refs/heads/main.zip -OutFile "./temp/resources.zip" + +echo Extracting... + +:: Extract resources to the folder +powershell Expand-Archive -Path "./temp/resources.zip" -DestinationPath "%FOLDER_NAME%" -Force + +:: Delete old resources folder if there is one there +del /s /q "%FOLDER_NAME%\resources">nul + +echo Moving resources to folder... + +robocopy "%FOLDER_NAME%\Grasscutter_Resources-main\Resources" "%FOLDER_NAME%\resources" /E /MOVE>nul + +:: Delete straggling files +del /s /q "%FOLDER_NAME%\Grasscutter_Resources-main" + +echo Done, resources should be properly extracted \ No newline at end of file From f2f4179813c60dcdc74c2f75fd9eb0d47c960156 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:19:32 -0700 Subject: [PATCH 31/50] download data and key files --- resources/js/gcdownloader.js | 47 +++++++++++++++++++++++++++++------- resources/js/helpers.js | 2 +- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index d20399e..29eb8a2 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -8,15 +8,6 @@ async function downloadGC(branch) { // If we are pulling from a new branch, delete the old installation if (config.grasscutterBranch !== branch) await clearGCInstallation() - // Keystore for branch (since they can differ) - const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` - - // External service that allows un-authed artifact downloading - const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` - - // Run installer - createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) - // Set current installation in config config.grasscutterBranch = branch @@ -24,6 +15,44 @@ async function downloadGC(branch) { config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` Neutralino.storage.setData('config', JSON.stringify(config)) + + // Keystore for branch (since they can differ) + const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` + + // External service that allows un-authed artifact downloading + const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` + + // For data files + const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`) + const dataList = dataFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + + // For key files + const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`) + const keyList = keyFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + + const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') + + // Download data files + for (const o of dataList) { + const folder = 'data' + Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } + + // Download each file + for (const o of keyList) { + const folder = 'keys' + Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } + + return; + + // Run installer + createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + // Display folder after saving config displayServerFolder() diff --git a/resources/js/helpers.js b/resources/js/helpers.js index ad313fa..4e3a38b 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -98,7 +98,7 @@ async function openGameFolder() { async function openGrasscutterFolder() { const config = await getCfg() - const folder = config.serverFolder.match(/.*\\/g, '')[0] + const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0] openInExplorer(folder) } From daef0d1724f5839a181f760f829a04dac1261c4c Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:23:33 -0700 Subject: [PATCH 32/50] ensure folders exist --- resources/js/gcdownloader.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 29eb8a2..960a757 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -36,16 +36,21 @@ async function downloadGC(branch) { const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') + // Ensure data and key folders exist + + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`) + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`) + // Download data files for (const o of dataList) { const folder = 'data' - Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) } - // Download each file + // Download key files for (const o of keyList) { const folder = 'keys' - Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) } return; From a47389e38b5129adb4d1b17a63aaf0a21250f815 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:24:45 -0700 Subject: [PATCH 33/50] re-enable full installer --- resources/js/gcdownloader.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 960a757..257a5f5 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -52,8 +52,6 @@ async function downloadGC(branch) { const folder = 'keys' await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) } - - return; // Run installer createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) From 8b76778996ffc78b4505b19a21633efb915c71fd Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:56:15 -0700 Subject: [PATCH 34/50] begin downloads panel --- resources/index.html | 27 +++++++++++++++++++++++++++ resources/js/gcdownloader.js | 1 - resources/js/index.js | 14 ++++++++++++++ resources/style/index.css | 13 +++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/resources/index.html b/resources/index.html index 81a7e7a..ed5353e 100644 --- a/resources/index.html +++ b/resources/index.html @@ -115,6 +115,28 @@
+ + + +
diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index 257a5f5..f101690 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -56,7 +56,6 @@ async function downloadGC(branch) { // Run installer createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) - // Display folder after saving config displayServerFolder() } \ No newline at end of file diff --git a/resources/js/index.js b/resources/js/index.js index 98b22d8..2656464 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -246,6 +246,20 @@ async function handleFavoriteList() { } } +async function openDownloads() { + const downloads = document.querySelector('#downloadPanel') + + if (downloads.style.display === 'none') { + downloads.style.removeProperty('display') + } +} + +async function closeDownloads() { + const downloads = document.querySelector('#downloadPanel') + + downloads.style.display = 'none' +} + async function openSettings() { const settings = document.querySelector('#settingsPanel') const config = await getCfg() diff --git a/resources/style/index.css b/resources/style/index.css index ff31870..0b16237 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -157,6 +157,7 @@ a { #firstTimeNotice, #loginPanel, +#downloadPanel, #settingsPanel { display: block; position: absolute; @@ -172,6 +173,7 @@ a { font-family: system-ui; } +#downloadPanel, #settingsPanel { width: 35%; height: 80%; @@ -184,6 +186,7 @@ a { margin-bottom: 10px; } +#downloadPanelInner, #settingsPanelInner { display: flex; flex-direction: column; @@ -192,16 +195,19 @@ a { padding: 10px 10%; } +.downloadRow, .settingsRow { width: 100%; } +.downloadTitle, .settingTitle { font-size: 1.2em; font-weight: bold; margin-bottom: 10px; } +.downloadLabel, .settingLabel { display:inline-block; font-size: 1em; @@ -209,12 +215,14 @@ a { margin: 10px 0px; } +.downloadSubtitle, .settingSubtitle { color: rgb(165, 165, 165); font-size: 0.8em; font-weight: normal; } +.downloadSection, .settingSection { display: flex; flex-direction: row; @@ -222,10 +230,12 @@ a { justify-content: space-between; } +.downloadSection .smolBtn, .settingSection .smolBtn { height: 30px; } +#downloadTitleBar #settingsTitleBar { display: flex; flex-direction: row; @@ -233,15 +243,18 @@ a { justify-content: space-between; } +#downloadClose, #settingsClose { display: inline-block; transition: filter 0.1s ease-in-out; } +#downloadClose img, #settingsClose img { height: 20px; } +#downloadClose:hover, #settingsClose:hover { filter: invert(85%) sepia(31%) saturate(560%) hue-rotate(329deg) brightness(100%) contrast(92%); cursor: pointer; From f8185e5b633175e021079b53b65911173ec0456d Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 22:59:11 -0700 Subject: [PATCH 35/50] small styling fixes --- resources/index.html | 10 ++++------ resources/style/index.css | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/index.html b/resources/index.html index ed5353e..2d63c3a 100644 --- a/resources/index.html +++ b/resources/index.html @@ -117,12 +117,10 @@ From ec27fd0530ced6b61a5df2378d2d94c255b021e0 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:09:20 -0700 Subject: [PATCH 37/50] download page open/close --- resources/icons/download.svg | 11 +++++++++++ resources/index.html | 13 +++++++++++-- resources/js/index.js | 10 ++++++++++ resources/style/index.css | 4 ++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 resources/icons/download.svg diff --git a/resources/icons/download.svg b/resources/icons/download.svg new file mode 100644 index 0000000..8baf9ed --- /dev/null +++ b/resources/icons/download.svg @@ -0,0 +1,11 @@ + +Created with Fabric.js 1.7.22 + + + + + + + + + \ No newline at end of file diff --git a/resources/index.html b/resources/index.html index 41b951e..6b86265 100644 --- a/resources/index.html +++ b/resources/index.html @@ -134,7 +134,7 @@
- Download Stable Build + Download Grasscutter Stable Build
@@ -143,13 +143,22 @@
- Download Development Build + Download Grasscutter Development Build
Install Grasscutter development branch. This build sometimes has bugs, and is frequently updated. Use at your own risk.
+
+
+ Download Grasscutter Resources + +
+ + Downloads Grasscutter resources into the currently set Grasscutter folder. This should be done unless you plan on getting resources externally. + +
diff --git a/resources/js/index.js b/resources/js/index.js index 2656464..db2b550 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -248,10 +248,20 @@ async function handleFavoriteList() { async function openDownloads() { const downloads = document.querySelector('#downloadPanel') + const config = await getCfg() if (downloads.style.display === 'none') { downloads.style.removeProperty('display') } + + // Disable the resource download button if a serverFolder path is not set + if (!config.serverFolder) { + document.querySelector('#resourceInstall').disabled = true + document.querySelector('#resourceInstall').classList.add('disabled') + } else { + document.querySelector('#resourceInstall').disabled = false + document.querySelector('#resourceInstall').classList.remove('disabled') + } } async function closeDownloads() { diff --git a/resources/style/index.css b/resources/style/index.css index d466177..d1e2ea6 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -216,6 +216,10 @@ a { margin: 10px 0px; } +.downloadLabel { + margin: 14px 0px; +} + .downloadSubtitle, .settingSubtitle { color: rgb(165, 165, 165); From bc363759900bafebcb51557c8cbc3b84f410d8d6 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:15:04 -0700 Subject: [PATCH 38/50] organization --- resources/index.html | 6 ++++++ resources/js/onLoad.js | 22 ++++++++++++++++------ resources/style/index.css | 8 ++++---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/resources/index.html b/resources/index.html index 6b86265..f3edc5d 100644 --- a/resources/index.html +++ b/resources/index.html @@ -123,6 +123,9 @@
+
+ GrassClipper +
Installer @@ -132,6 +135,9 @@ Installs proxy and other tools. Required for Grasscutter servers.
+
+ Grasscutter +
Download Grasscutter Stable Build diff --git a/resources/js/onLoad.js b/resources/js/onLoad.js index a1e8773..bc96832 100644 --- a/resources/js/onLoad.js +++ b/resources/js/onLoad.js @@ -38,6 +38,7 @@ window.addEventListener("click", function(e) { const favList = document.querySelector('#ipList') const settingsPanel = document.querySelector('#settingsPanel') + const downloadPanel = document.querySelector('#downloadPanel') // This will close the favorites list no matter what is clicked if (favList.style.display !== 'none') { @@ -46,23 +47,32 @@ } // This will close the settings panel no matter what is clicked - let settingCheckElm = e.target + let checkElm = e.target - while(settingCheckElm.tagName !== 'BODY') { - if (settingCheckElm.id === 'settingsPanel' - || settingCheckElm.id === 'settingsBtn') { + while(checkElm.tagName !== 'BODY') { + if (checkElm.id === 'settingsPanel' + || checkElm.id === 'settingsBtn') { return } - settingCheckElm = settingCheckElm.parentElement + if (checkElm.id === 'downloadPanel' || + checkElm.id === 'downloadBtn') { + return + } + + checkElm = checkElm.parentElement } // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel - if (settingCheckElm.tagName === 'BODY') { + if (checkElm.tagName === 'BODY') { // This will close the settings panel only when something outside of it is clicked if (settingsPanel.style.display !== 'none') { settingsPanel.style.display = 'none' } + + if (downloadPanel.style.display !== 'none') { + downloadPanel.style.display = 'none' + } } }); diff --git a/resources/style/index.css b/resources/style/index.css index d1e2ea6..6bb5548 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -208,6 +208,10 @@ a { margin-bottom: 10px; } +.downloadTitle { + margin: 6px; +} + .downloadLabel, .settingLabel { display:inline-block; @@ -216,10 +220,6 @@ a { margin: 10px 0px; } -.downloadLabel { - margin: 14px 0px; -} - .downloadSubtitle, .settingSubtitle { color: rgb(165, 165, 165); From 092424e3108bb74a216d76808d346fc82866feb4 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:17:23 -0700 Subject: [PATCH 39/50] disallow unset paths --- resources/js/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/js/index.js b/resources/js/index.js index db2b550..6e14f7d 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -411,6 +411,8 @@ async function setGameExe() { ] }) + if (!gameexe[0]) return; + // Set the folder in our configuration const config = await getCfg() @@ -432,6 +434,8 @@ async function setGrasscutterFolder() { ] }) + if (!folder[0]) return; + // Set the folder in our configuration const config = await getCfg() From 42290412bae95c08f33f9e8dfce3cfb83baacfe3 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:32:51 -0700 Subject: [PATCH 40/50] show when script is beginning to run --- resources/js/gcdownloader.js | 40 ++++++++++++++++++++++++++++++++++++ resources/style/index.css | 4 ++++ 2 files changed, 44 insertions(+) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index f101690..a8523f0 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -2,6 +2,37 @@ async function clearGCInstallation() { Neutralino.os.execCommand(`del /s /q "./gc"`) } +async function setDownloadButtonsToLoading() { + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') + + stableBtn.innerText = localeObj.gcScriptRunning || 'Running...' + + devBtn.innerText = localeObj.gcScriptRunning || 'Running...' + + // Set btns to disabled + stableBtn.disabled = true + stableBtn.classList.add('disabled') + + devBtn.disabled = true + devBtn.classList.add('disabled') +} + +async function resetDownloadButtons() { + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') + + stableBtn.innerText = localeObj.stableInstall || 'Download' + devBtn.innerText = localeObj.devInstall || 'Download' + + // Set btns to enabled + stableBtn.disabled = false + stableBtn.classList.remove('disabled') + + devBtn.disabled = false + devBtn.classList.remove('disabled') +} + async function downloadGC(branch) { const config = await getCfg() @@ -14,8 +45,13 @@ async function downloadGC(branch) { // Set gc path for people with launcher enabled config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` + // Enable server launcher + config.serverLaunchPanel = true + Neutralino.storage.setData('config', JSON.stringify(config)) + setDownloadButtonsToLoading() + // Keystore for branch (since they can differ) const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` @@ -56,6 +92,10 @@ async function downloadGC(branch) { // Run installer createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + // Fix buttons + resetDownloadButtons() + // Display folder after saving config displayServerFolder() + displayServerLaunchSection() } \ No newline at end of file diff --git a/resources/style/index.css b/resources/style/index.css index 6bb5548..f738e24 100644 --- a/resources/style/index.css +++ b/resources/style/index.css @@ -11,6 +11,10 @@ a { color: #fff; } +img { + height: 20px; +} + .darken { filter: brightness(0.6); } From fdc3abb6008002cc58a3febda7adb9a583d28b8c Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:40:11 -0700 Subject: [PATCH 41/50] translation setup for downloads --- languages/en.json | 16 ++++++++++++++++ resources/index.html | 2 +- resources/js/translation.js | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/languages/en.json b/languages/en.json index a7ecafe..1fecb4d 100644 --- a/languages/en.json +++ b/languages/en.json @@ -63,5 +63,21 @@ "alertAuthNoRegister": "Authentication is disabled, no need to register!", "alertRegisterSuccess": "Registration successful!", + "downloadTitle": "Downloads", + "grassclipperTitle": "GrassClipper", + "grasscutterTitle": "Grasscutter", + "installerTitle": "Installer", + "installerSubtitle": "Installs proxy and other tools. Required for Grasscutter servers.", + "downloadStable": "Download Grasscutter Stable Build", + "stableSubtitle": "Install Grasscutter stable branch. This build usually has less bugs, but also less features.", + "downloadDev": "Download Grasscutter Development Build", + "downloadSubtitle": "Install Grasscutter development branch. This build sometimes has bugs, and is frequently updated. Use at your own risk.", + "downloadResources": "Download Grasscutter Resources", + "devSubtitle": "Downloads Grasscutter resources into the currently set Grasscutter folder. This should be done unless you plan on getting resources externally.", + + "gcScriptRunning": "Running...", + "stableInstall": "Download", + "devInstall": "Download", + "updateNotifText": "A new update is available! Newest version: " } diff --git a/resources/index.html b/resources/index.html index f3edc5d..bb71778 100644 --- a/resources/index.html +++ b/resources/index.html @@ -135,7 +135,7 @@ Installs proxy and other tools. Required for Grasscutter servers.
-
+
Grasscutter
diff --git a/resources/js/translation.js b/resources/js/translation.js index 986b03c..2f1d17d 100644 --- a/resources/js/translation.js +++ b/resources/js/translation.js @@ -90,6 +90,21 @@ async function doTranslation() { set('loginPopupContentBodyBtnRegister', 'authRegisterBtn') set('noLoginBtn', 'launchWithoutAuth') + // Downloads section + set('downloadTitle', 'downloadTitle') + set('grassclipperTitle', 'grassclipperTitle') + set('grasscutterTitle', 'grasscutterTitle') + set('installerTitle', 'installerTitle') + set('installerSubtitle', 'installerSubtitle') + set('downloadStable', 'downloadStable') + set('stableSubtitle', 'stableSubtitle') + set('downloadDev', 'downloadDev') + set('downloadSubtitle', 'downloadSubtitle') + set('downloadResources', 'downloadResources') + set('devSubtitle', 'devSubtitle') + set('stableInstall', 'stableInstall') + set('devInstall', 'devInstall') + // update notification set('updateNotifText', 'updateNotifText') } \ No newline at end of file From ff9c0f203952ecf55f0ffe98353350054cf3d570 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:54:40 -0700 Subject: [PATCH 42/50] bugfix --- resources/js/index.js | 2 +- resources/js/translation.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/js/index.js b/resources/js/index.js index 6e14f7d..a9a0bee 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -411,7 +411,7 @@ async function setGameExe() { ] }) - if (!gameexe[0]) return; + if (!gameExe[0]) return; // Set the folder in our configuration const config = await getCfg() diff --git a/resources/js/translation.js b/resources/js/translation.js index 2f1d17d..dd80b83 100644 --- a/resources/js/translation.js +++ b/resources/js/translation.js @@ -99,7 +99,7 @@ async function doTranslation() { set('downloadStable', 'downloadStable') set('stableSubtitle', 'stableSubtitle') set('downloadDev', 'downloadDev') - set('downloadSubtitle', 'downloadSubtitle') + set('devSubtitle', 'downloadSubtitle') set('downloadResources', 'downloadResources') set('devSubtitle', 'devSubtitle') set('stableInstall', 'stableInstall') From dc486fd83003904525076a5b2cee5ca527660718 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Sun, 1 May 2022 23:59:20 -0700 Subject: [PATCH 43/50] enable server button --- resources/js/gcdownloader.js | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index a8523f0..e45a0f4 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -97,5 +97,6 @@ async function downloadGC(branch) { // Display folder after saving config displayServerFolder() + enableServerButton() displayServerLaunchSection() } \ No newline at end of file From 2e68da72be3192c293aef38cce05cbfd9b38c04e Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 02:47:55 -0700 Subject: [PATCH 44/50] fix killswitch --- scripts/private_server_launch.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/private_server_launch.cmd b/scripts/private_server_launch.cmd index 0cc7b12..5fcbf1e 100644 --- a/scripts/private_server_launch.cmd +++ b/scripts/private_server_launch.cmd @@ -27,7 +27,7 @@ if "%ENABLE_KILLSWITCH%" EQU "true" ( :: Restart in elevated if need be >nul 2>&1 reg query "HKU\S-1-5-19" || ( set params = %*:"="""% - cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 %1 %2 %3 "%4" ""%cd%/../"" %6", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && taskkill /f /fi "WINDOWTITLE eq PS Launcher Script" && exit /b ) + cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 %1 %2 %3 "%4" ""%cd%"" %6", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && taskkill /f /fi "WINDOWTITLE eq PS Launcher Script" && exit /b ) ) ) @@ -41,7 +41,7 @@ reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v Pr reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "127.0.0.1:8080" /f >nul 2>nul :: Start proxy server -start "Proxy Server" "%ORIGIN%/ext/mitmdump.exe" -s "%ORIGIN%/proxy/proxy.py" -k --allow-hosts ".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com" --ssl-insecure --set ip=%IP% --set port=%PORT% --set use_https=%USE_HTTPS% +start "Proxy Server" "%ORIGIN%\ext\mitmdump.exe" -s "%ORIGIN%/proxy/proxy.py" -k --allow-hosts ".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com" --ssl-insecure --set ip=%IP% --set port=%PORT% --set use_https=%USE_HTTPS% echo Opening %GAME_PATH% From 3379e688a68b6e33c0763d8a953feec77b9e688b Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 22:00:55 -0700 Subject: [PATCH 45/50] java version script --- scripts/javaver.cmd | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 scripts/javaver.cmd diff --git a/scripts/javaver.cmd b/scripts/javaver.cmd new file mode 100644 index 0000000..dad849f --- /dev/null +++ b/scripts/javaver.cmd @@ -0,0 +1,38 @@ +@echo off + +set BRANCH=%1 + +echo Checking java version... + +:: https://stackoverflow.com/questions/5675459/how-to-get-java-version-from-batch-script +for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do ( + @echo Output: %%g + set JAVAVER=%%g +) +set JAVAVER=%JAVAVER:"=% + +for /f "delims=. tokens=1-3" %%v in ("%JAVAVER%") do ( + set MAJOR=%%v + set MINOR=%%w + set BUILD=%%x +) + +if %BRANCH% EQU stable ( + :: Ensure java 8 + if %MAJOR% EQU 1 ( + if %MINOR% LSS 8 ( + echo Java version is less than 8, please download Java 8 + exit /b + ) + ) +) + +if %BRANCH% EQU development ( + :: Ensure java 17 + if %MAJOR% LSS 17 ( + echo Java version is less than 17, please download Java 17 + exit /b + ) +) + +echo Java version is compatible \ No newline at end of file From 66abd0feba68c216bd5e4b7ff7de2655b0803809 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 22:35:53 -0700 Subject: [PATCH 46/50] java version checking --- scripts/gc_download.cmd | 3 +++ scripts/javaver.cmd | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/scripts/gc_download.cmd b/scripts/gc_download.cmd index 1b24f2b..6d822d2 100644 --- a/scripts/gc_download.cmd +++ b/scripts/gc_download.cmd @@ -34,6 +34,9 @@ echo Downloading keystore.p12... :: Download the keystore.p12 file powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12" +:: Check java version, this will automatically output some tuff +call .\scripts\javaver.cmd %BRANCH% + :: Allow resource downloading to be optional, since it takes a while set REPLY=y set /p "REPLY=Download server resources? (This can take a while) [y|n]:" diff --git a/scripts/javaver.cmd b/scripts/javaver.cmd index dad849f..fc97d4d 100644 --- a/scripts/javaver.cmd +++ b/scripts/javaver.cmd @@ -21,16 +21,30 @@ if %BRANCH% EQU stable ( :: Ensure java 8 if %MAJOR% EQU 1 ( if %MINOR% LSS 8 ( - echo Java version is less than 8, please download Java 8 + echo ======================================================================================= + echo !! Java version is less than 8 !! + echo Please download Java 8 to ensure %BRANCH% branch server launches correctly. + echo ======================================================================================= exit /b ) ) + + if %MAJOR% NEQ 1 ( + echo ======================================================================================= + echo !! Java version is not 8 !! + echo Please download Java 8 to ensure %BRANCH% branch server launches correctly. + echo ======================================================================================= + exit /b + ) ) if %BRANCH% EQU development ( :: Ensure java 17 if %MAJOR% LSS 17 ( - echo Java version is less than 17, please download Java 17 + echo ======================================================================================= + echo !! Java version is less than 17 !! + echo Please download Java 17 to ensure %BRANCH% branch server launches correctly. + echo ======================================================================================= exit /b ) ) From f94350af735422547beac147e3ae3045428f363a Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 22:38:04 -0700 Subject: [PATCH 47/50] handle no java installed --- scripts/javaver.cmd | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/scripts/javaver.cmd b/scripts/javaver.cmd index fc97d4d..c22093a 100644 --- a/scripts/javaver.cmd +++ b/scripts/javaver.cmd @@ -4,6 +4,24 @@ set BRANCH=%1 echo Checking java version... +where java >nul 2>nul +if %errorlevel%==1 ( + echo ======================================================================================= + echo No version of Java was found! + + if %BRANCH% EQU stable ( + echo To launch the stable branch server, you must install Java 8 + ) + + if %BRANCH% EQU development ( + echo To launch the development branch server, you must install Java 17 + ) + + echo ======================================================================================= + + exit /b +) + :: https://stackoverflow.com/questions/5675459/how-to-get-java-version-from-batch-script for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do ( @echo Output: %%g From eae6cc087b2b2baff8e3149430516568e04c4e7f Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 22:44:57 -0700 Subject: [PATCH 48/50] eslint changes --- .eslintrc.json | 29 ++ package.json | 3 + resources/js/authAlert.js | 46 +-- resources/js/gcdownloader.js | 132 ++++---- resources/js/helpers.js | 118 +++---- resources/js/hoverEvt.js | 56 ++-- resources/js/index.js | 580 +++++++++++++++++------------------ resources/js/login.js | 182 +++++------ resources/js/onLoad.js | 136 ++++---- resources/js/options.js | 114 +++---- resources/js/translation.js | 176 +++++------ resources/js/windowDrag.js | 32 +- 12 files changed, 818 insertions(+), 786 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..064214d --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,29 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es2021": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 13 + }, + "rules": { + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "never" + ] + } +} diff --git a/package.json b/package.json index e5efc86..9c0eb1a 100644 --- a/package.json +++ b/package.json @@ -9,5 +9,8 @@ "build-win": ".\\build_win.cmd", "build-linux": "./build.sh", "build": "echo !! Run build-win or build-linux to build for your platform !!\n" + }, + "devDependencies": { + "eslint": "^8.14.0" } } diff --git a/resources/js/authAlert.js b/resources/js/authAlert.js index c6b806e..9580530 100644 --- a/resources/js/authAlert.js +++ b/resources/js/authAlert.js @@ -1,45 +1,45 @@ let alertTimeout, alertCooldown = 3000 async function displayLoginAlert(message, type, cooldown = null) { - displayAlert(message, type, cooldown, 'login') + displayAlert(message, type, cooldown, 'login') } async function displayRegisterAlert(message, type, cooldown = null) { - displayAlert(message, type, cooldown, 'register') + displayAlert(message, type, cooldown, 'register') } function displayAlert(message, type, cooldown, name) { - const elm = document.getElementById(`${name}Alert`); - const text = document.getElementById(`${name}AlertText`); + const elm = document.getElementById(`${name}Alert`) + const text = document.getElementById(`${name}AlertText`) - elm.style.removeProperty('display'); + elm.style.removeProperty('display') - // Remove classification classes - elm.classList.remove('error'); - elm.classList.remove('success'); - elm.classList.remove('warn'); + // Remove classification classes + elm.classList.remove('error') + elm.classList.remove('success') + elm.classList.remove('warn') - switch(type) { + switch(type) { case 'error': - elm.classList.add('error'); - break; + elm.classList.add('error') + break case 'success': - elm.classList.add('success'); - break; + elm.classList.add('success') + break case 'warn': default: - elm.classList.add('warn'); - break; - } + elm.classList.add('warn') + break + } - text.innerText = message; + text.innerText = message - clearTimeout(alertTimeout) + clearTimeout(alertTimeout) - // Disappear after cooldown - alertTimeout = setTimeout(() => { - elm.style.display = 'none'; - }, cooldown || alertCooldown) + // Disappear after cooldown + alertTimeout = setTimeout(() => { + elm.style.display = 'none' + }, cooldown || alertCooldown) } \ No newline at end of file diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index e45a0f4..bcc6e7a 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -1,102 +1,102 @@ async function clearGCInstallation() { - Neutralino.os.execCommand(`del /s /q "./gc"`) + Neutralino.os.execCommand('del /s /q "./gc"') } async function setDownloadButtonsToLoading() { - const stableBtn = document.querySelector('#stableInstall') - const devBtn = document.querySelector('#devInstall') + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') - stableBtn.innerText = localeObj.gcScriptRunning || 'Running...' + stableBtn.innerText = localeObj.gcScriptRunning || 'Running...' - devBtn.innerText = localeObj.gcScriptRunning || 'Running...' + devBtn.innerText = localeObj.gcScriptRunning || 'Running...' - // Set btns to disabled - stableBtn.disabled = true - stableBtn.classList.add('disabled') + // Set btns to disabled + stableBtn.disabled = true + stableBtn.classList.add('disabled') - devBtn.disabled = true - devBtn.classList.add('disabled') + devBtn.disabled = true + devBtn.classList.add('disabled') } async function resetDownloadButtons() { - const stableBtn = document.querySelector('#stableInstall') - const devBtn = document.querySelector('#devInstall') + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') - stableBtn.innerText = localeObj.stableInstall || 'Download' - devBtn.innerText = localeObj.devInstall || 'Download' + stableBtn.innerText = localeObj.stableInstall || 'Download' + devBtn.innerText = localeObj.devInstall || 'Download' - // Set btns to enabled - stableBtn.disabled = false - stableBtn.classList.remove('disabled') + // Set btns to enabled + stableBtn.disabled = false + stableBtn.classList.remove('disabled') - devBtn.disabled = false - devBtn.classList.remove('disabled') + devBtn.disabled = false + devBtn.classList.remove('disabled') } async function downloadGC(branch) { - const config = await getCfg() + const config = await getCfg() - // If we are pulling from a new branch, delete the old installation - if (config.grasscutterBranch !== branch) await clearGCInstallation() + // If we are pulling from a new branch, delete the old installation + if (config.grasscutterBranch !== branch) await clearGCInstallation() - // Set current installation in config - config.grasscutterBranch = branch + // Set current installation in config + config.grasscutterBranch = branch - // Set gc path for people with launcher enabled - config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` + // Set gc path for people with launcher enabled + config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` - // Enable server launcher - config.serverLaunchPanel = true + // Enable server launcher + config.serverLaunchPanel = true - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) - setDownloadButtonsToLoading() + setDownloadButtonsToLoading() - // Keystore for branch (since they can differ) - const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` + // Keystore for branch (since they can differ) + const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` - // External service that allows un-authed artifact downloading - const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` + // External service that allows un-authed artifact downloading + const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` - // For data files - const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`) - const dataList = dataFiles.data - .map(file => ({ path: file.path, filename: file.name })) - .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + // For data files + const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`) + const dataList = dataFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) - // For key files - const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`) - const keyList = keyFiles.data - .map(file => ({ path: file.path, filename: file.name })) - .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + // For key files + const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`) + const keyList = keyFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) - const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') + const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') - // Ensure data and key folders exist + // Ensure data and key folders exist - await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`) - await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`) + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`) + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`) - // Download data files - for (const o of dataList) { - const folder = 'data' - await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) - } + // Download data files + for (const o of dataList) { + const folder = 'data' + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } - // Download key files - for (const o of keyList) { - const folder = 'keys' - await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) - } + // Download key files + for (const o of keyList) { + const folder = 'keys' + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } - // Run installer - createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + // Run installer + createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) - // Fix buttons - resetDownloadButtons() + // Fix buttons + resetDownloadButtons() - // Display folder after saving config - displayServerFolder() - enableServerButton() - displayServerLaunchSection() + // Display folder after saving config + displayServerFolder() + enableServerButton() + displayServerLaunchSection() } \ No newline at end of file diff --git a/resources/js/helpers.js b/resources/js/helpers.js index 4e3a38b..a4f514d 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -3,28 +3,28 @@ * * @returns {Promise} */ - async function getCfg() { - const defaultConf = { - gameexe: '', - serverFolder: '', - lastConnect: '', - enableKillswitch: false, - serverLaunchPanel: false, - language: 'en', - useHttps: true, - grasscutterBranch: '', - } - const cfgStr = await Neutralino.storage.getData('config').catch(e => { +async function getCfg() { + const defaultConf = { + gameexe: '', + serverFolder: '', + lastConnect: '', + enableKillswitch: false, + serverLaunchPanel: false, + language: 'en', + useHttps: true, + grasscutterBranch: '', + } + const cfgStr = await Neutralino.storage.getData('config').catch(e => { // The data isn't set, so this is our first time opening - Neutralino.storage.setData('config', JSON.stringify(defaultConf)) + Neutralino.storage.setData('config', JSON.stringify(defaultConf)) - // Show the first time notice if there is no config - document.querySelector('#firstTimeNotice').style.display = 'block' - }) + // Show the first time notice if there is no config + document.querySelector('#firstTimeNotice').style.display = 'block' + }) - const config = cfgStr ? JSON.parse(cfgStr) : defaultConf + const config = cfgStr ? JSON.parse(cfgStr) : defaultConf - return config + return config } /** @@ -32,91 +32,91 @@ * * @returns {Promise} */ - async function getFavIps() { - const ipStr = await Neutralino.storage.getData('favorites').catch(e => { +async function getFavIps() { + const ipStr = await Neutralino.storage.getData('favorites').catch(e => { // The data isn't set, so this is our first time opening - Neutralino.storage.setData('favorites', JSON.stringify([])) - }) + Neutralino.storage.setData('favorites', JSON.stringify([])) + }) - const ipArr = ipStr ? JSON.parse(ipStr) : [] + const ipArr = ipStr ? JSON.parse(ipStr) : [] - return ipArr + return ipArr } async function proxyIsInstalled() { - // Check if the proxy server is installed - const curDirList = await filesystem.readDirectory(NL_CWD) + // Check if the proxy server is installed + const curDirList = await filesystem.readDirectory(NL_CWD) - if (curDirList.find(f => f.entry === 'ext')) { - const extFiles = await filesystem.readDirectory(NL_CWD + '/ext') + if (curDirList.find(f => f.entry === 'ext')) { + const extFiles = await filesystem.readDirectory(NL_CWD + '/ext') - if (extFiles.find(f => f.entry === 'mitmdump.exe')) { - return true + if (extFiles.find(f => f.entry === 'mitmdump.exe')) { + return true + } } - } - return false + return false } async function checkForUpdates() { - const url = 'https://api.github.com/repos/Grasscutters/GrassClipper/releases/latest' + const url = 'https://api.github.com/repos/Grasscutters/GrassClipper/releases/latest' - const { data } = await axios.get(url) - const latest = data.tag_name + const { data } = await axios.get(url) + const latest = data.tag_name - return latest + return latest } async function displayUpdate() { - const latest = await checkForUpdates() - const versionDisplay = document.querySelector('#newestVersion') - const notif = document.querySelector('#downloadNotif') + const latest = await checkForUpdates() + const versionDisplay = document.querySelector('#newestVersion') + const notif = document.querySelector('#downloadNotif') - if (latest === `v${NL_APPVERSION}`) return + if (latest === `v${NL_APPVERSION}`) return - versionDisplay.innerText = latest + versionDisplay.innerText = latest - notif.classList.add('displayed') + notif.classList.add('displayed') - setTimeout(() => { - notif.classList.remove('displayed') - }, 5000) + setTimeout(() => { + notif.classList.remove('displayed') + }, 5000) } async function openLatestDownload() { - const downloadLink = 'https://github.com/Grasscutters/GrassClipper/releases/latest/' + const downloadLink = 'https://github.com/Grasscutters/GrassClipper/releases/latest/' - Neutralino.os.open(downloadLink) + Neutralino.os.open(downloadLink) } async function openGameFolder() { - const config = await getCfg() - const folder = config.gameexe.match(/.*\\/g, '')[0] + const config = await getCfg() + const folder = config.gameexe.match(/.*\\/g, '')[0] - openInExplorer(folder) + openInExplorer(folder) } async function openGrasscutterFolder() { - const config = await getCfg() - const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0] + const config = await getCfg() + const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0] - openInExplorer(folder) + openInExplorer(folder) } /** * Minimize the window */ - function minimizeWin() { - console.log('min') - Neutralino.window.minimize() +function minimizeWin() { + console.log('min') + Neutralino.window.minimize() } /** * Close the window */ function closeWin() { - console.log('close') - Neutralino.app.exit() + console.log('close') + Neutralino.app.exit() - window.close() + window.close() } diff --git a/resources/js/hoverEvt.js b/resources/js/hoverEvt.js index 47adb2c..af98ea0 100644 --- a/resources/js/hoverEvt.js +++ b/resources/js/hoverEvt.js @@ -1,36 +1,36 @@ document.addEventListener('DOMContentLoaded', async () => { - const firstPanel = document.querySelector('#firstPanel') - const secondPanel = document.querySelector('#secondPanel') - const thirdPanel = document.querySelector('#thirdPanel') + const firstPanel = document.querySelector('#firstPanel') + const secondPanel = document.querySelector('#secondPanel') + const thirdPanel = document.querySelector('#thirdPanel') - // Listen to hovers - firstPanel.addEventListener('mouseover', () => { - secondPanel.classList.add('darken') - thirdPanel.classList.add('darken') - }) + // Listen to hovers + firstPanel.addEventListener('mouseover', () => { + secondPanel.classList.add('darken') + thirdPanel.classList.add('darken') + }) - firstPanel.addEventListener('mouseout', () => { - secondPanel.classList.remove('darken') - thirdPanel.classList.remove('darken') - }) + firstPanel.addEventListener('mouseout', () => { + secondPanel.classList.remove('darken') + thirdPanel.classList.remove('darken') + }) - secondPanel.addEventListener('mouseover', () => { - firstPanel.classList.add('darken') - thirdPanel.classList.add('darken') - }) + secondPanel.addEventListener('mouseover', () => { + firstPanel.classList.add('darken') + thirdPanel.classList.add('darken') + }) - secondPanel.addEventListener('mouseout', () => { - firstPanel.classList.remove('darken') - thirdPanel.classList.remove('darken') - }) + secondPanel.addEventListener('mouseout', () => { + firstPanel.classList.remove('darken') + thirdPanel.classList.remove('darken') + }) - thirdPanel.addEventListener('mouseover', () => { - firstPanel.classList.add('darken') - secondPanel.classList.add('darken') - }) + thirdPanel.addEventListener('mouseover', () => { + firstPanel.classList.add('darken') + secondPanel.classList.add('darken') + }) - thirdPanel.addEventListener('mouseout', () => { - firstPanel.classList.remove('darken') - secondPanel.classList.remove('darken') - }) + thirdPanel.addEventListener('mouseout', () => { + firstPanel.classList.remove('darken') + secondPanel.classList.remove('darken') + }) }) \ No newline at end of file diff --git a/resources/js/index.js b/resources/js/index.js index a9a0bee..822fb67 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -1,187 +1,187 @@ -Neutralino.init(); +Neutralino.init() -let localeObj; +let localeObj const filesystem = Neutralino.filesystem const createCmdWindow = async (command) => { - Neutralino.os.execCommand(`cmd.exe /c start "" ${command}`, { background: true }) + Neutralino.os.execCommand(`cmd.exe /c start "" ${command}`, { background: true }) } const openInExplorer = async (path) => { - console.log(`explorer.exe "${path}"`) - createCmdWindow(`explorer.exe "${path}"`) + console.log(`explorer.exe "${path}"`) + createCmdWindow(`explorer.exe "${path}"`) } /** * Enable play buttons */ async function enableButtons() { - const offBtn = document.querySelector('#playOfficial') - const privBtn = document.querySelector('#playPrivate') + const offBtn = document.querySelector('#playOfficial') + const privBtn = document.querySelector('#playPrivate') - offBtn.classList.remove('disabled') - offBtn.disabled = false + offBtn.classList.remove('disabled') + offBtn.disabled = false - // Check if the proxy server is installed - if (await proxyIsInstalled()) { - privBtn.classList.remove('disabled') - privBtn.disabled = false - } + // Check if the proxy server is installed + if (await proxyIsInstalled()) { + privBtn.classList.remove('disabled') + privBtn.disabled = false + } } /** * Enable server launch button */ - async function enableServerButton() { - const serverBtn = document.querySelector('#serverLaunch') +async function enableServerButton() { + const serverBtn = document.querySelector('#serverLaunch') - serverBtn.classList.remove('disabled') - serverBtn.disabled = false + serverBtn.classList.remove('disabled') + serverBtn.disabled = false } /** * Disable buttons when the game folder is not set */ async function handleGameNotSet() { - // Set buttons to greyed out and disable - document.querySelector('#gamePath').innerHTML = localeObj.folderNotSet + // Set buttons to greyed out and disable + document.querySelector('#gamePath').innerHTML = localeObj.folderNotSet - // Set official server background to default - document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")` + // Set official server background to default + document.querySelector('#firstPanel').style.backgroundImage = 'url("../bg/private/default.png")' - const offBtn = document.querySelector('#playOfficial') - const privBtn = document.querySelector('#playPrivate') + const offBtn = document.querySelector('#playOfficial') + const privBtn = document.querySelector('#playPrivate') - offBtn.classList.add('disabled') - offBtn.disabled = true + offBtn.classList.add('disabled') + offBtn.disabled = true - privBtn.classList.add('disabled') - privBtn.disabled = true + privBtn.classList.add('disabled') + privBtn.disabled = true - // TODO show a dialog of sorts + // TODO show a dialog of sorts } async function handleServerNotSet() { - // Set buttons to greyed out and disable - document.querySelector('#serverPath').innerHTML = localeObj.folderNotSet + // Set buttons to greyed out and disable + document.querySelector('#serverPath').innerHTML = localeObj.folderNotSet - // Set official server background to default - // document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")` + // Set official server background to default + // document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")` - const privBtn = document.querySelector('#serverLaunch') + const privBtn = document.querySelector('#serverLaunch') - privBtn.classList.add('disabled') - privBtn.disabled = true + privBtn.classList.add('disabled') + privBtn.disabled = true } /** * Show the game folder under the select button */ async function displayGameFolder() { - const elm = document.querySelector('#gamePath') - const config = await getCfg() + const elm = document.querySelector('#gamePath') + const config = await getCfg() - elm.innerHTML = config.gameexe + elm.innerHTML = config.gameexe } /** * Show the server folder under the select button */ - async function displayServerFolder() { - const elm = document.querySelector('#serverPath') - const config = await getCfg() +async function displayServerFolder() { + const elm = document.querySelector('#serverPath') + const config = await getCfg() - elm.innerHTML = config.serverFolder + elm.innerHTML = config.serverFolder } /** * Set the background images of both the private and public sections */ async function setBackgroundImage() { - const config = await getCfg() + const config = await getCfg() - const privImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/private')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) - const privImage = privImages[Math.floor(Math.random() * privImages.length)].entry + const privImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/private')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) + const privImage = privImages[Math.floor(Math.random() * privImages.length)].entry - const servImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/server')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) - const servImage = servImages[Math.floor(Math.random() * servImages.length)].entry + const servImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/server')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) + const servImage = servImages[Math.floor(Math.random() * servImages.length)].entry - // Set default image, it will change if the bg folder exists - document.querySelector('#firstPanel').style.backgroundImage = `url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")` + // Set default image, it will change if the bg folder exists + document.querySelector('#firstPanel').style.backgroundImage = 'url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")' - // Set the private background image - document.querySelector('#secondPanel').style.backgroundImage = `url("../bg/private/${privImage}")` + // Set the private background image + document.querySelector('#secondPanel').style.backgroundImage = `url("../bg/private/${privImage}")` - // Set the server background image - document.querySelector('#thirdPanel').style.backgroundImage = `url("../bg/server/${servImage}")` + // Set the server background image + document.querySelector('#thirdPanel').style.backgroundImage = `url("../bg/server/${servImage}")` - return + return - // Check if resources folder exists - const mainDir = await filesystem.readDirectory(NL_CWD) - if (!mainDir.find(dir => dir.entry === 'resources')) { - await filesystem.createDirectory(NL_CWD + '/resources') - } - - // Ensure bg folder exists - const bgDir = await filesystem.readDirectory(NL_CWD + '/resources') - if (!bgDir.find(dir => dir.entry === 'bg')) { - await filesystem.createDirectory(NL_CWD + '/resources/bg') - } - - // Ensure official folder exists - const officialDir = await filesystem.readDirectory(NL_CWD + '/resources/bg') - if (!officialDir.find(dir => dir.entry === 'official')) { - await filesystem.createDirectory(NL_CWD + '/resources/bg/official') - } - - if (config.gameexe) { - // See if bg folder exists in parent dir - const parentDir = await filesystem.readDirectory(config.gameexe + '/..') - - if (parentDir.find(dir => dir.entry === 'bg')) { - - const officialImages = (await filesystem.readDirectory(config.gameexe + '/../bg')).filter(file => file.type === 'FILE') - - if (officialImages.length > 0) { - for (const bg of officialImages) { - const path = config.gameexe.replace('\\', '/') + '/../bg/' + bg.entry - - // See if the file exists already - const currentBgs = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official/')).filter(file => file.type === 'FILE') - - if (!currentBgs.find(file => file.entry === bg.entry)) { - await filesystem.copyFile(path, NL_CWD + '/resources/bg/official/' + bg.entry).catch(e => { - // TODO: Handle error - }) - } - } - - // Pick one of the images - const localImg = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official')).filter(file => file.type === 'FILE') - const image = localImg[Math.floor(Math.random() * localImg.length)].entry - - // Set background image - document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/official/${image}")` - } + // Check if resources folder exists + const mainDir = await filesystem.readDirectory(NL_CWD) + if (!mainDir.find(dir => dir.entry === 'resources')) { + await filesystem.createDirectory(NL_CWD + '/resources') + } + + // Ensure bg folder exists + const bgDir = await filesystem.readDirectory(NL_CWD + '/resources') + if (!bgDir.find(dir => dir.entry === 'bg')) { + await filesystem.createDirectory(NL_CWD + '/resources/bg') + } + + // Ensure official folder exists + const officialDir = await filesystem.readDirectory(NL_CWD + '/resources/bg') + if (!officialDir.find(dir => dir.entry === 'official')) { + await filesystem.createDirectory(NL_CWD + '/resources/bg/official') + } + + if (config.gameexe) { + // See if bg folder exists in parent dir + const parentDir = await filesystem.readDirectory(config.gameexe + '/..') + + if (parentDir.find(dir => dir.entry === 'bg')) { + + const officialImages = (await filesystem.readDirectory(config.gameexe + '/../bg')).filter(file => file.type === 'FILE') + + if (officialImages.length > 0) { + for (const bg of officialImages) { + const path = config.gameexe.replace('\\', '/') + '/../bg/' + bg.entry + + // See if the file exists already + const currentBgs = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official/')).filter(file => file.type === 'FILE') + + if (!currentBgs.find(file => file.entry === bg.entry)) { + await filesystem.copyFile(path, NL_CWD + '/resources/bg/official/' + bg.entry).catch(e => { + // TODO: Handle error + }) + } + } + + // Pick one of the images + const localImg = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official')).filter(file => file.type === 'FILE') + const image = localImg[Math.floor(Math.random() * localImg.length)].entry + + // Set background image + document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/official/${image}")` + } + } } - } } /** * When an IP is being input, check if it is part of the favorites */ async function handleFavoriteInput() { - const ip = document.querySelector('#ip').value - const port = document.querySelector('#port').value || '443' - const ipArr = await getFavIps() + const ip = document.querySelector('#ip').value + const port = document.querySelector('#port').value || '443' + const ipArr = await getFavIps() - const addr = `${ip}:${port}` + const addr = `${ip}:${port}` - if (!ip || !ipArr.includes(addr)) { - document.querySelector('#star').src = 'icons/star_empty.svg' - } else { - document.querySelector('#star').src = 'icons/star_filled.svg' - } + if (!ip || !ipArr.includes(addr)) { + document.querySelector('#star').src = 'icons/star_empty.svg' + } else { + document.querySelector('#star').src = 'icons/star_filled.svg' + } } /** @@ -190,182 +190,182 @@ async function handleFavoriteInput() { * @param {String} ip */ async function setIp(ip) { - const ipInput = document.querySelector('#ip') - const portInput = document.querySelector('#port') + const ipInput = document.querySelector('#ip') + const portInput = document.querySelector('#port') - const parseIp = ip.split(':')[0] - const parsePort = ip.split(':')[1] + const parseIp = ip.split(':')[0] + const parsePort = ip.split(':')[1] - // Set star - if (ip) { - document.querySelector('#star').src = 'icons/star_filled.svg' - } + // Set star + if (ip) { + document.querySelector('#star').src = 'icons/star_filled.svg' + } - ipInput.value = parseIp - portInput.value = parsePort + ipInput.value = parseIp + portInput.value = parsePort } /** * Create/hide the favorites list */ async function handleFavoriteList() { - const ipArr = await getFavIps() - const ipList = document.querySelector('#ipList') + const ipArr = await getFavIps() + const ipList = document.querySelector('#ipList') - if (ipList.style.display === 'none') { - ipList.innerHTML = '' + if (ipList.style.display === 'none') { + ipList.innerHTML = '' - const list = ipList.appendChild( - document.createElement('ul') - ) + const list = ipList.appendChild( + document.createElement('ul') + ) - if (ipArr.length < 1) { - const listItem = list.appendChild( - document.createElement('li') - ) + if (ipArr.length < 1) { + const listItem = list.appendChild( + document.createElement('li') + ) - listItem.innerHTML = localeObj.noFavorites + listItem.innerHTML = localeObj.noFavorites + } + + for (const ip of ipArr) { + const elm = document.createElement('li') + elm.innerHTML = ip + elm.addEventListener('click', () => setIp(ip)) + list.appendChild(elm) + } + + ipList.style.display = 'block' + + const transform = window.getComputedStyle(document.querySelector('#ipList')).transform + const xy = [ transform.split(',')[4], transform.split(',')[5] ] + let newY = (27 * ipArr.length) * window.devicePixelRatio + + if (ipArr.length === 0 || ipArr.length === 1) newY = 0 + + ipList.style.transform = `translate(${xy[0]}px, calc(56vh - ${newY}px)` } - - for (const ip of ipArr) { - const elm = document.createElement('li') - elm.innerHTML = ip - elm.addEventListener('click', () => setIp(ip)) - list.appendChild(elm) - } - - ipList.style.display = 'block' - - const transform = window.getComputedStyle(document.querySelector('#ipList')).transform - const xy = [ transform.split(',')[4], transform.split(',')[5] ] - let newY = (27 * ipArr.length) * window.devicePixelRatio - - if (ipArr.length === 0 || ipArr.length === 1) newY = 0 - - ipList.style.transform = `translate(${xy[0]}px, calc(56vh - ${newY}px)` - } } async function openDownloads() { - const downloads = document.querySelector('#downloadPanel') - const config = await getCfg() + const downloads = document.querySelector('#downloadPanel') + const config = await getCfg() - if (downloads.style.display === 'none') { - downloads.style.removeProperty('display') - } + if (downloads.style.display === 'none') { + downloads.style.removeProperty('display') + } - // Disable the resource download button if a serverFolder path is not set - if (!config.serverFolder) { - document.querySelector('#resourceInstall').disabled = true - document.querySelector('#resourceInstall').classList.add('disabled') - } else { - document.querySelector('#resourceInstall').disabled = false - document.querySelector('#resourceInstall').classList.remove('disabled') - } + // Disable the resource download button if a serverFolder path is not set + if (!config.serverFolder) { + document.querySelector('#resourceInstall').disabled = true + document.querySelector('#resourceInstall').classList.add('disabled') + } else { + document.querySelector('#resourceInstall').disabled = false + document.querySelector('#resourceInstall').classList.remove('disabled') + } } async function closeDownloads() { - const downloads = document.querySelector('#downloadPanel') + const downloads = document.querySelector('#downloadPanel') - downloads.style.display = 'none' + downloads.style.display = 'none' } async function openSettings() { - const settings = document.querySelector('#settingsPanel') - const config = await getCfg() + const settings = document.querySelector('#settingsPanel') + const config = await getCfg() - if (settings.style.display === 'none') { - settings.style.removeProperty('display') - } + if (settings.style.display === 'none') { + settings.style.removeProperty('display') + } - // Fill setting options with what is currently set in config - const killSwitch = document.querySelector('#killswitchOption') - const serverLaunch = document.querySelector('#serverLaunchOption') - const httpsCheckbox = document.querySelector('#httpsOption') + // Fill setting options with what is currently set in config + const killSwitch = document.querySelector('#killswitchOption') + const serverLaunch = document.querySelector('#serverLaunchOption') + const httpsCheckbox = document.querySelector('#httpsOption') - killSwitch.checked = config.enableKillswitch - serverLaunch.checked = config.serverLaunchPanel - httpsCheckbox.checked = config.useHttps + killSwitch.checked = config.enableKillswitch + serverLaunch.checked = config.serverLaunchPanel + httpsCheckbox.checked = config.useHttps - // Load languages - getLanguages() + // Load languages + getLanguages() - // Check for updates - //checkForUpdatesAndShow() + // Check for updates + //checkForUpdatesAndShow() } async function closeSettings() { - const settings = document.querySelector('#settingsPanel') - const config = await getCfg() + const settings = document.querySelector('#settingsPanel') + const config = await getCfg() - settings.style.display = 'none' + settings.style.display = 'none' - // In case we installed the proxy server - if (await proxyIsInstalled() && config.gameexe) { - const playPriv = document.querySelector('#playPrivate') + // In case we installed the proxy server + if (await proxyIsInstalled() && config.gameexe) { + const playPriv = document.querySelector('#playPrivate') - playPriv.classList.remove('disabled') - playPriv.disabled = false - } + playPriv.classList.remove('disabled') + playPriv.disabled = false + } } async function openLogin() { - const login = document.querySelector('#loginPanel') - const ip = document.querySelector('#ip').value - const port = document.querySelector('#port').value - const loginIpDisplay = document.querySelector('#loginPopupServer') - const registerIpDisplay = document.querySelector('#registerPopupServer') + const login = document.querySelector('#loginPanel') + const ip = document.querySelector('#ip').value + const port = document.querySelector('#port').value + const loginIpDisplay = document.querySelector('#loginPopupServer') + const registerIpDisplay = document.querySelector('#registerPopupServer') - const config = await getCfg() - const useHttps = config.useHttps - const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}`; + const config = await getCfg() + const useHttps = config.useHttps + const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` - // Check if we even need to authenticate - try { - const { data } = await axios.get(url + '/authentication/type') + // Check if we even need to authenticate + try { + const { data } = await axios.get(url + '/authentication/type') - if (!data.includes('GCAuthAuthenticationHandler')) { - launchPrivate() - return + if (!data.includes('GCAuthAuthenticationHandler')) { + launchPrivate() + return + } + } catch(e) { + launchPrivate() + return } - } catch(e) { - launchPrivate() - return - } - loginIpDisplay.innerText = ip - registerIpDisplay.innerText = ip + loginIpDisplay.innerText = ip + registerIpDisplay.innerText = ip - if (login.style.display === 'none') { - login.style.removeProperty('display') - } + if (login.style.display === 'none') { + login.style.removeProperty('display') + } } async function closeLogin() { - const login = document.querySelector('#loginPanel') + const login = document.querySelector('#loginPanel') - login.style.display = 'none' + login.style.display = 'none' - setLoginSection() + setLoginSection() } async function closeFirstTimePopup() { - const firstTimePopup = document.querySelector('#firstTimeNotice') - firstTimePopup.style.display = 'none' + const firstTimePopup = document.querySelector('#firstTimeNotice') + firstTimePopup.style.display = 'none' } async function runInstallScript() { - createCmdWindow(`.\\scripts\\install.cmd "${NL_CWD}" true`) + createCmdWindow(`.\\scripts\\install.cmd "${NL_CWD}" true`) - // Create an interval that will check for the proxy server installation finish - const interval = setInterval(async () => { - if (await proxyIsInstalled()) { - clearInterval(interval) - enableButtons() - } - }, 1000) + // Create an interval that will check for the proxy server installation finish + const interval = setInterval(async () => { + if (await proxyIsInstalled()) { + clearInterval(interval) + enableButtons() + } + }, 1000) - closeFirstTimePopup() + closeFirstTimePopup() } async function updateResources() { @@ -373,109 +373,109 @@ async function updateResources() { } async function checkForUpdatesAndShow() { - const updateBtn = document.querySelector('#updateBtn') - const subtitle = document.querySelector('#updateSubtitle') - const url = 'https://github.com/Grasscutters/GrassClipper/releases/latest/download/' - const manifest = await Neutralino.updater.checkForUpdates(url) + const updateBtn = document.querySelector('#updateBtn') + const subtitle = document.querySelector('#updateSubtitle') + const url = 'https://github.com/Grasscutters/GrassClipper/releases/latest/download/' + const manifest = await Neutralino.updater.checkForUpdates(url) - // Version mismatch? Update! - if (manifest?.version !== NL_APPVERSION) { - subtitle.innerHTML = "New update available!" - updateBtn.classList.remove('disabled') - } else { - subtitle.innerHTML = "You are on the latest version! :)" - updateBtn.classList.add('disabled') - } + // Version mismatch? Update! + if (manifest?.version !== NL_APPVERSION) { + subtitle.innerHTML = 'New update available!' + updateBtn.classList.remove('disabled') + } else { + subtitle.innerHTML = 'You are on the latest version! :)' + updateBtn.classList.add('disabled') + } } async function displayServerLaunchSection() { - const serverPanel = document.querySelector('#thirdPanel') - const bottomBtnSection = document.querySelector('#serverPath').parentElement + const serverPanel = document.querySelector('#thirdPanel') + const bottomBtnSection = document.querySelector('#serverPath').parentElement - if (serverPanel.style.display === 'none') { - serverPanel.style.removeProperty('display') - bottomBtnSection.style.removeProperty('display') - } else { - serverPanel.style.display = 'none' - bottomBtnSection.style.display = 'none' - } + if (serverPanel.style.display === 'none') { + serverPanel.style.removeProperty('display') + bottomBtnSection.style.removeProperty('display') + } else { + serverPanel.style.display = 'none' + bottomBtnSection.style.display = 'none' + } } /** * Set the game folder by opening a folder picker */ async function setGameExe() { - const gameExe = await Neutralino.os.showOpenDialog(localeObj.gameFolderDialog, { - filters: [ - { name: 'Executable files', extensions: ['exe'] } - ] - }) + const gameExe = await Neutralino.os.showOpenDialog(localeObj.gameFolderDialog, { + filters: [ + { name: 'Executable files', extensions: ['exe'] } + ] + }) - if (!gameExe[0]) return; + if (!gameExe[0]) return - // Set the folder in our configuration - const config = await getCfg() + // Set the folder in our configuration + const config = await getCfg() - // It's an array of selections, so only get the first one - config.gameexe = gameExe[0].replace(/\//g, '\\') + // It's an array of selections, so only get the first one + config.gameexe = gameExe[0].replace(/\//g, '\\') - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) - // Refresh background and path - setBackgroundImage() - displayGameFolder() - enableButtons() + // Refresh background and path + setBackgroundImage() + displayGameFolder() + enableButtons() } async function setGrasscutterFolder() { - const folder = await Neutralino.os.showOpenDialog(localeObj.grasscutterFileDialog, { - filters: [ - { name: 'Jar files', extensions: ['jar'] } - ] - }) + const folder = await Neutralino.os.showOpenDialog(localeObj.grasscutterFileDialog, { + filters: [ + { name: 'Jar files', extensions: ['jar'] } + ] + }) - if (!folder[0]) return; + if (!folder[0]) return - // Set the folder in our configuration - const config = await getCfg() + // Set the folder in our configuration + const config = await getCfg() - config.serverFolder = folder[0] - Neutralino.storage.setData('config', JSON.stringify(config)) + config.serverFolder = folder[0] + Neutralino.storage.setData('config', JSON.stringify(config)) - displayServerFolder() - enableServerButton() + displayServerFolder() + enableServerButton() } /** * Launch the game with no modifications nor proxy */ async function launchOfficial() { - const config = await getCfg() + const config = await getCfg() - Neutralino.os.execCommand(`"${config.gameexe}"`) + Neutralino.os.execCommand(`"${config.gameexe}"`) } /** * Launch the game with a proxy */ async function launchPrivate() { - const ip = document.getElementById('ip').value || '127.0.0.1' - const port = document.getElementById('port').value || '443' + const ip = document.getElementById('ip').value || '127.0.0.1' + const port = document.getElementById('port').value || '443' - const config = await getCfg() + const config = await getCfg() - console.log('connecting to ' + ip + ':' + port) + console.log('connecting to ' + ip + ':' + port) - // Set the last connect - config.lastConnect = ip - Neutralino.storage.setData('config', JSON.stringify(config)) + // Set the last connect + config.lastConnect = ip + Neutralino.storage.setData('config', JSON.stringify(config)) - // Pass IP and game folder to the private server launcher - createCmdWindow(`.\\scripts\\private_server_launch.cmd ${ip} ${port} ${config.useHttps} "${config.gameexe}" "${NL_CWD}" ${config.enableKillswitch} true`).catch(e => console.log(e)) + // Pass IP and game folder to the private server launcher + createCmdWindow(`.\\scripts\\private_server_launch.cmd ${ip} ${port} ${config.useHttps} "${config.gameexe}" "${NL_CWD}" ${config.enableKillswitch} true`).catch(e => console.log(e)) } async function launchLocalServer() { - const config = await getCfg() + const config = await getCfg() - createCmdWindow(`.\\scripts\\local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e)) + createCmdWindow(`.\\scripts\\local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e)) } diff --git a/resources/js/login.js b/resources/js/login.js index 60188d7..87c0de9 100644 --- a/resources/js/login.js +++ b/resources/js/login.js @@ -2,153 +2,153 @@ * Toggle the login section */ async function setLoginSection() { - const title = document.getElementById('loginSectionTitle'); - const altTitle = document.getElementById('registerSectionTitle'); - const loginSection = document.getElementById('loginPopupContentBody'); - const registerSection = document.getElementById('registerPopupContentBody'); + const title = document.getElementById('loginSectionTitle') + const altTitle = document.getElementById('registerSectionTitle') + const loginSection = document.getElementById('loginPopupContentBody') + const registerSection = document.getElementById('registerPopupContentBody') - title.classList.add('selectedTitle') - altTitle.classList.remove('selectedTitle') + title.classList.add('selectedTitle') + altTitle.classList.remove('selectedTitle') - loginSection.style.removeProperty('display'); - registerSection.style.display = 'none'; + loginSection.style.removeProperty('display') + registerSection.style.display = 'none' } /** * Toggle the register section */ async function setRegisterSection(fromLogin = false) { - const title = document.getElementById('registerSectionTitle'); - const altTitle = document.getElementById('loginSectionTitle'); - const loginSection = document.getElementById('loginPopupContentBody'); - const registerSection = document.getElementById('registerPopupContentBody'); + const title = document.getElementById('registerSectionTitle') + const altTitle = document.getElementById('loginSectionTitle') + const loginSection = document.getElementById('loginPopupContentBody') + const registerSection = document.getElementById('registerPopupContentBody') - title.classList.add('selectedTitle') - altTitle.classList.remove('selectedTitle') + title.classList.add('selectedTitle') + altTitle.classList.remove('selectedTitle') - loginSection.style.display = 'none'; - registerSection.style.removeProperty('display'); + loginSection.style.display = 'none' + registerSection.style.removeProperty('display') - if (fromLogin) { + if (fromLogin) { // Take the values from the login section and put them in the register section - const loginUsername = document.getElementById('loginUsername').value; - const loginPassword = document.getElementById('loginPassword').value; + const loginUsername = document.getElementById('loginUsername').value + const loginPassword = document.getElementById('loginPassword').value - document.getElementById('registerUsername').value = loginUsername; - document.getElementById('registerPassword').value = loginPassword; - } + document.getElementById('registerUsername').value = loginUsername + document.getElementById('registerPassword').value = loginPassword + } } function parseJwt(token) { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace('-', '+').replace('_', '/'); - return JSON.parse(window.atob(base64)); + const base64Url = token.split('.')[1] + const base64 = base64Url.replace('-', '+').replace('_', '/') + return JSON.parse(window.atob(base64)) } /** * Attempt login and launch game */ async function login() { - const username = document.getElementById('loginUsername').value; - const password = document.getElementById('loginPassword').value; - const ip = document.getElementById('ip').value; - const port = document.getElementById('port').value || '443'; - const config = await getCfg(); - const useHttps = config.useHttps; - const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}`; + const username = document.getElementById('loginUsername').value + const password = document.getElementById('loginPassword').value + const ip = document.getElementById('ip').value + const port = document.getElementById('port').value || '443' + const config = await getCfg() + const useHttps = config.useHttps + const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` - const reqBody = { - username, - password, - } + const reqBody = { + username, + password, + } - const { data } = await axios.post(url + '/authentication/login', reqBody) + const { data } = await axios.post(url + '/authentication/login', reqBody) - switch(data.message) { + switch(data.message) { case 'INVALID_ACCOUNT': - displayLoginAlert(localeObj.alertInvalid || 'Invalid username or password', 'error'); - break; + displayLoginAlert(localeObj.alertInvalid || 'Invalid username or password', 'error') + break case 'NO_PASSWORD': - // No account password, create one with change password - displayLoginAlert(localeObj.alertNoPass || 'No password set, please change password', 'warn'); - break; + // No account password, create one with change password + displayLoginAlert(localeObj.alertNoPass || 'No password set, please change password', 'warn') + break case 'UNKNOWN': - // Unknown error, contact server owner - displayLoginAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error'); - break; + // Unknown error, contact server owner + displayLoginAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error') + break case undefined: case null: case 'AUTH_DISABLED': - // Authentication is disabled, we can just connect the user - displayLoginAlert(localeObj.alertAuthNoLogin || 'Authentication is disabled, no need to log in!', 'warn'); - launchPrivate(); - break; + // Authentication is disabled, we can just connect the user + displayLoginAlert(localeObj.alertAuthNoLogin || 'Authentication is disabled, no need to log in!', 'warn') + launchPrivate() + break default: - // Success! Copy the JWT token to their clipboard - const tkData = parseJwt(data.jwt) - await Neutralino.clipboard.writeText(tkData.token) + // Success! Copy the JWT token to their clipboard + const tkData = parseJwt(data.jwt) + await Neutralino.clipboard.writeText(tkData.token) - displayLoginAlert(localeObj.alertLoginSuccess || 'Login successful! Token copied to clipboard. Paste this token into the username field of the game to log in.', 'success', 8000); - launchPrivate() - break; - } + displayLoginAlert(localeObj.alertLoginSuccess || 'Login successful! Token copied to clipboard. Paste this token into the username field of the game to log in.', 'success', 8000) + launchPrivate() + break + } } /** * Attempt registration, do not launch game */ async function register() { - const username = document.getElementById('registerUsername').value; - const password = document.getElementById('registerPassword').value; - const password_confirmation = document.getElementById('registerPasswordConfirm').value; - const ip = document.getElementById('ip').value; - const port = document.getElementById('port').value || '443'; - const config = await getCfg(); - const useHttps = config.useHttps; - const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}`; + const username = document.getElementById('registerUsername').value + const password = document.getElementById('registerPassword').value + const password_confirmation = document.getElementById('registerPasswordConfirm').value + const ip = document.getElementById('ip').value + const port = document.getElementById('port').value || '443' + const config = await getCfg() + const useHttps = config.useHttps + const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` - const reqBody = { - username, - password, - password_confirmation - } + const reqBody = { + username, + password, + password_confirmation + } - const { data } = await axios.post(url + '/authentication/register', reqBody) + const { data } = await axios.post(url + '/authentication/register', reqBody) - switch(data.message) { + switch(data.message) { case 'USERNAME_TAKEN': - // Username is taken - displayRegisterAlert(localeObj.alertUserTaken || 'Username is taken', 'error'); - break; + // Username is taken + displayRegisterAlert(localeObj.alertUserTaken || 'Username is taken', 'error') + break case 'PASSWORD_MISMATCH': - // The password and password confirmation do not match - displayRegisterAlert(localStorage.alertPassMismatch || 'Password and password confirmation do not match', 'error'); - break; + // The password and password confirmation do not match + displayRegisterAlert(localStorage.alertPassMismatch || 'Password and password confirmation do not match', 'error') + break case 'UNKNOWN': - // Unknown error, contact server owner - displayRegisterAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error'); - break; + // Unknown error, contact server owner + displayRegisterAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error') + break case undefined: case null: case 'AUTH_DISABLED': - // Authentication is disabled, we can just connect the user - displayRegisterAlert(localeObj.alertAuthNoRegister || 'Authentication is disabled, no need to register!', 'warn'); - break; + // Authentication is disabled, we can just connect the user + displayRegisterAlert(localeObj.alertAuthNoRegister || 'Authentication is disabled, no need to register!', 'warn') + break default: - // Success!! Bring them to the login screen and auto-input their username - const loginUsername = document.getElementById('loginUsername'); - loginUsername.value = username; + // Success!! Bring them to the login screen and auto-input their username + const loginUsername = document.getElementById('loginUsername') + loginUsername.value = username - setLoginSection(); - displayLoginAlert(localeObj.alertRegisterSuccess || 'Registration successful!', 'success', 5000); - break; - } + setLoginSection() + displayLoginAlert(localeObj.alertRegisterSuccess || 'Registration successful!', 'success', 5000) + break + } } diff --git a/resources/js/onLoad.js b/resources/js/onLoad.js index bc96832..e1942c8 100644 --- a/resources/js/onLoad.js +++ b/resources/js/onLoad.js @@ -3,87 +3,87 @@ * Every autofill, such as backgrounds and the game folder, * should be done here to ensure DOM contents are loaded. */ - document.addEventListener('DOMContentLoaded', async () => { - displayUpdate(); - setBackgroundImage(); - displayGameFolder(); - displayServerFolder(); +document.addEventListener('DOMContentLoaded', async () => { + displayUpdate() + setBackgroundImage() + displayGameFolder() + displayServerFolder() - // Set title version - document.querySelector('#version').innerHTML = NL_APPVERSION + // Set title version + document.querySelector('#version').innerHTML = NL_APPVERSION - const config = await getCfg() - const ipArr = await getFavIps() + const config = await getCfg() + const ipArr = await getFavIps() - if (config.serverLaunchPanel) { - displayServerLaunchSection() - } - - // Set last connect - document.querySelector('#ip').value = config.lastConnect - - if (ipArr.includes(config.lastConnect)) { - document.querySelector('#star').src = 'icons/star_filled.svg' - } - - // Disable private game launch if proxy IP or proxy server is not found - const playPriv = document.querySelector('#playPrivate') - - if (!(await proxyIsInstalled())) { - playPriv.classList.add('disabled') - playPriv.disabled = true - } - - // Exit favorites list and settings panel when clicking outside of it - window.addEventListener("click", function(e) { - const favList = document.querySelector('#ipList') - const settingsPanel = document.querySelector('#settingsPanel') - const downloadPanel = document.querySelector('#downloadPanel') - - // This will close the favorites list no matter what is clicked - if (favList.style.display !== 'none') { - favList.style.display = 'none' - favList.style.transform = '' + if (config.serverLaunchPanel) { + displayServerLaunchSection() } - // This will close the settings panel no matter what is clicked - let checkElm = e.target + // Set last connect + document.querySelector('#ip').value = config.lastConnect - while(checkElm.tagName !== 'BODY') { - if (checkElm.id === 'settingsPanel' + if (ipArr.includes(config.lastConnect)) { + document.querySelector('#star').src = 'icons/star_filled.svg' + } + + // Disable private game launch if proxy IP or proxy server is not found + const playPriv = document.querySelector('#playPrivate') + + if (!(await proxyIsInstalled())) { + playPriv.classList.add('disabled') + playPriv.disabled = true + } + + // Exit favorites list and settings panel when clicking outside of it + window.addEventListener('click', function(e) { + const favList = document.querySelector('#ipList') + const settingsPanel = document.querySelector('#settingsPanel') + const downloadPanel = document.querySelector('#downloadPanel') + + // This will close the favorites list no matter what is clicked + if (favList.style.display !== 'none') { + favList.style.display = 'none' + favList.style.transform = '' + } + + // This will close the settings panel no matter what is clicked + let checkElm = e.target + + while(checkElm.tagName !== 'BODY') { + if (checkElm.id === 'settingsPanel' || checkElm.id === 'settingsBtn') { - return - } + return + } - if (checkElm.id === 'downloadPanel' || + if (checkElm.id === 'downloadPanel' || checkElm.id === 'downloadBtn') { - return - } + return + } - checkElm = checkElm.parentElement - } + checkElm = checkElm.parentElement + } - // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel - if (checkElm.tagName === 'BODY') { - // This will close the settings panel only when something outside of it is clicked - if (settingsPanel.style.display !== 'none') { - settingsPanel.style.display = 'none' - } + // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel + if (checkElm.tagName === 'BODY') { + // This will close the settings panel only when something outside of it is clicked + if (settingsPanel.style.display !== 'none') { + settingsPanel.style.display = 'none' + } - if (downloadPanel.style.display !== 'none') { - downloadPanel.style.display = 'none' - } - } - }); + if (downloadPanel.style.display !== 'none') { + downloadPanel.style.display = 'none' + } + } + }) - // Ensure we do the translation at the very end, after everything else has loaded - await doTranslation() + // Ensure we do the translation at the very end, after everything else has loaded + await doTranslation() - if (!config.gameexe) { - handleGameNotSet() - } + if (!config.gameexe) { + handleGameNotSet() + } - if (!config.serverFolder) { - handleServerNotSet() - } + if (!config.serverFolder) { + handleServerNotSet() + } }) diff --git a/resources/js/options.js b/resources/js/options.js index 58da7f6..a42f899 100644 --- a/resources/js/options.js +++ b/resources/js/options.js @@ -2,54 +2,54 @@ * Toggle the killswitch script */ async function toggleKillSwitch() { - const killSwitch = document.querySelector('#killswitchOption') - const config = await getCfg() + const killSwitch = document.querySelector('#killswitchOption') + const config = await getCfg() - config.enableKillswitch = killSwitch.checked + config.enableKillswitch = killSwitch.checked - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) } /** * Toggles the server launching panel */ async function toggleServerLaunchSection() { - const config = await getCfg() + const config = await getCfg() - displayServerLaunchSection() + displayServerLaunchSection() - // Save setting - config.serverLaunchPanel = !config.serverLaunchPanel - Neutralino.storage.setData('config', JSON.stringify(config)) + // Save setting + config.serverLaunchPanel = !config.serverLaunchPanel + Neutralino.storage.setData('config', JSON.stringify(config)) } /** * Get all languages for the language selector */ async function getLanguages() { - const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json')) - const config = await getCfg() + const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json')) + const config = await getCfg() - // Clear language options - const languageSelect = document.querySelector('#languageSelect') - languageSelect.innerHTML = '' + // Clear language options + const languageSelect = document.querySelector('#languageSelect') + languageSelect.innerHTML = '' - // Load all languages as options - for (const file of languageFiles) { - const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName - const lang = file.entry.split('.json')[0] + // Load all languages as options + for (const file of languageFiles) { + const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName + const lang = file.entry.split('.json')[0] - const option = document.createElement('option') - option.value = lang - option.innerHTML = fullLanguageName + const option = document.createElement('option') + option.value = lang + option.innerHTML = fullLanguageName - // Set language selected to config language - if (lang === config.language) { - option.selected = true - } + // Set language selected to config language + if (lang === config.language) { + option.selected = true + } - document.querySelector('#languageSelect').appendChild(option) - } + document.querySelector('#languageSelect').appendChild(option) + } } /** @@ -58,27 +58,27 @@ async function getLanguages() { * @param {DOMElement} elm */ async function handleLanguageChange(elm) { - const list = elm - const config = await getCfg() + const list = elm + const config = await getCfg() - // Set language in config - config.language = list.value - Neutralino.storage.setData('config', JSON.stringify(config)) + // Set language in config + config.language = list.value + Neutralino.storage.setData('config', JSON.stringify(config)) - // Force refresh of application, no need for restart! - window.location.reload() + // Force refresh of application, no need for restart! + window.location.reload() } /** * Toggle the use of HTTPS */ - async function toggleHttps() { - const httpsCheckbox = document.querySelector('#httpsOption') - const config = await getCfg() +async function toggleHttps() { + const httpsCheckbox = document.querySelector('#httpsOption') + const config = await getCfg() - config.useHttps = httpsCheckbox.checked + config.useHttps = httpsCheckbox.checked - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) } /** @@ -86,29 +86,29 @@ async function handleLanguageChange(elm) { * OR * Remove the current value of the IP input from the favorites list */ - async function setFavorite() { - const ip = document.querySelector('#ip').value - const port = document.querySelector('#port').value || '443' - const ipArr = await getFavIps() +async function setFavorite() { + const ip = document.querySelector('#ip').value + const port = document.querySelector('#port').value || '443' + const ipArr = await getFavIps() - const addr = `${ip}:${port}` + const addr = `${ip}:${port}` - // Set star icon - const star = document.querySelector('#star') + // Set star icon + const star = document.querySelector('#star') - if (star.src.includes('filled') && ip) { - star.src = 'icons/star_empty.svg' + if (star.src.includes('filled') && ip) { + star.src = 'icons/star_empty.svg' - // remove from list - ipArr.splice(ipArr.indexOf(addr), 1) - } else { - star.src = 'icons/star_filled.svg' + // remove from list + ipArr.splice(ipArr.indexOf(addr), 1) + } else { + star.src = 'icons/star_filled.svg' - // add to list - if (ip && !ipArr.includes(addr)) { - ipArr.push(addr) + // add to list + if (ip && !ipArr.includes(addr)) { + ipArr.push(addr) + } } - } - Neutralino.storage.setData('favorites', JSON.stringify(ipArr)) + Neutralino.storage.setData('favorites', JSON.stringify(ipArr)) } diff --git a/resources/js/translation.js b/resources/js/translation.js index dd80b83..47f0eb0 100644 --- a/resources/js/translation.js +++ b/resources/js/translation.js @@ -1,110 +1,110 @@ async function doTranslation() { - const config = await getCfg() + const config = await getCfg() - // See if the localization file exists - const localizations = await filesystem.readDirectory(`${NL_CWD}/languages`) + // See if the localization file exists + const localizations = await filesystem.readDirectory(`${NL_CWD}/languages`) - // Use english if the selected file does not exist - const selectedLanguage = localizations.find(f => f.entry === `${config.language}.json`) + // Use english if the selected file does not exist + const selectedLanguage = localizations.find(f => f.entry === `${config.language}.json`) - // Use english if the selected file does not exist - if (!selectedLanguage) { - config.language = 'en' - } + // Use english if the selected file does not exist + if (!selectedLanguage) { + config.language = 'en' + } - const localization = await filesystem.readFile(`${NL_CWD}/languages/${config.language}.json`) - const engLocale = await filesystem.readFile(`${NL_CWD}/languages/en.json`) - engLocaleObj = JSON.parse(engLocale) - localeObj = JSON.parse(localization) + const localization = await filesystem.readFile(`${NL_CWD}/languages/${config.language}.json`) + const engLocale = await filesystem.readFile(`${NL_CWD}/languages/en.json`) + engLocaleObj = JSON.parse(engLocale) + localeObj = JSON.parse(localization) - const set = (id, localeString) => document.getElementById(id).innerText = localeObj[localeString] || engLocaleObj[localeString] + const set = (id, localeString) => document.getElementById(id).innerText = localeObj[localeString] || engLocaleObj[localeString] - // Begin filling in values - set('titleSection', 'appName') + // Begin filling in values + set('titleSection', 'appName') - const verSpan = document.createElement('span') - verSpan.id = 'version' - verSpan.innerHTML = ` v${NL_APPVERSION}` + const verSpan = document.createElement('span') + verSpan.id = 'version' + verSpan.innerHTML = ` v${NL_APPVERSION}` - document.querySelector('#titleSection').appendChild(verSpan) + document.querySelector('#titleSection').appendChild(verSpan) - // Play buttons - set('playOfficial', 'playOfficial') - set('playPrivate', 'playPrivate') - set('serverLaunch', 'launchLocalServer') + // Play buttons + set('playOfficial', 'playOfficial') + set('playPrivate', 'playPrivate') + set('serverLaunch', 'launchLocalServer') - // File select buttons - set('gameExeSet', 'gameExeSet') - set('grasscutterFileSet', 'grasscutterFileSet') + // File select buttons + set('gameExeSet', 'gameExeSet') + set('grasscutterFileSet', 'grasscutterFileSet') - // Private options - document.querySelector('#ip').placeholder = localeObj.ipPlaceholder - document.querySelector('#port').placeholder = localeObj.portPlaceholder + // Private options + document.querySelector('#ip').placeholder = localeObj.ipPlaceholder + document.querySelector('#port').placeholder = localeObj.portPlaceholder - // Settings - set('fullSettingsTitle', 'settingsTitle') - set('scriptsTitle', 'scriptsSectionTitle') - set('killswitchTitle', 'killswitchOption') - set('killswitchSubtitle', 'killswitchSubtitle') - set('proxyTitle', 'proxyOption') - set('proxyInstall', 'proxyInstallBtn') - set('proxySubtitle', 'proxySubtitle') - set('updateBtn', 'updateOption') - set('updateTitle', 'updateOption') - set('updateSubtitle', 'updateSubtitle') - set('languageTitle', 'languageOption') - set('languageSubtitle', 'languageSubtitle') - set('serverLaunchTitle', 'enableServerLauncherOption') - set('serverSubtitle', 'enableServerLauncherSubtitle') - set('httpsTitle', 'httpsOption') - set('httpsSubtitle', 'httpsSubtitle') + // Settings + set('fullSettingsTitle', 'settingsTitle') + set('scriptsTitle', 'scriptsSectionTitle') + set('killswitchTitle', 'killswitchOption') + set('killswitchSubtitle', 'killswitchSubtitle') + set('proxyTitle', 'proxyOption') + set('proxyInstall', 'proxyInstallBtn') + set('proxySubtitle', 'proxySubtitle') + set('updateBtn', 'updateOption') + set('updateTitle', 'updateOption') + set('updateSubtitle', 'updateSubtitle') + set('languageTitle', 'languageOption') + set('languageSubtitle', 'languageSubtitle') + set('serverLaunchTitle', 'enableServerLauncherOption') + set('serverSubtitle', 'enableServerLauncherSubtitle') + set('httpsTitle', 'httpsOption') + set('httpsSubtitle', 'httpsSubtitle') - // Intro popup - const popup = document.getElementById('firstTimeNotice') - const introSpan = popup.querySelector('span') - const boldIntroSpan = document.createElement('span') + // Intro popup + const popup = document.getElementById('firstTimeNotice') + const introSpan = popup.querySelector('span') + const boldIntroSpan = document.createElement('span') - boldIntroSpan.innerHTML = localeObj.introSen1 + '\n' - boldIntroSpan.classList.add('boldTitle') + boldIntroSpan.innerHTML = localeObj.introSen1 + '\n' + boldIntroSpan.classList.add('boldTitle') - introSpan.appendChild(boldIntroSpan) + introSpan.appendChild(boldIntroSpan) - introSpan.innerHTML += localeObj.introSen2 + '
' - introSpan.innerHTML += localeObj.introSen3 + '
' - introSpan.innerHTML += localeObj.introSen4 + '
' + introSpan.innerHTML += localeObj.introSen2 + '
' + introSpan.innerHTML += localeObj.introSen3 + '
' + introSpan.innerHTML += localeObj.introSen4 + '
' - set('firstTimeInstallBtn', 'proxyInstallBtn') - set('firstTimeDenyBtn', 'proxyInstallDeny') + set('firstTimeInstallBtn', 'proxyInstallBtn') + set('firstTimeDenyBtn', 'proxyInstallDeny') - // Login section - set('loginSectionTitle', 'authLoginTitle') - set('registerSectionTitle', 'authRegisterTitle') - set('loggingInToIndicator', 'loggingInTo') - set('registeringToIndicator', 'registeringFor') - set('loginUsernameIndicator', 'authUsername') - set('loginPasswordIndicator', 'authPassword') - set('registerUsernameIndicator', 'authUsername') - set('registerPasswordIndicator', 'authPassword') - set('registerConfirmIndicator', 'authConfirmPassword') - set('loginPopupContentBodyBtnLogin', 'authLoginBtn') - set('loginPopupContentBodyBtnRegister', 'authRegisterBtn') - set('noLoginBtn', 'launchWithoutAuth') + // Login section + set('loginSectionTitle', 'authLoginTitle') + set('registerSectionTitle', 'authRegisterTitle') + set('loggingInToIndicator', 'loggingInTo') + set('registeringToIndicator', 'registeringFor') + set('loginUsernameIndicator', 'authUsername') + set('loginPasswordIndicator', 'authPassword') + set('registerUsernameIndicator', 'authUsername') + set('registerPasswordIndicator', 'authPassword') + set('registerConfirmIndicator', 'authConfirmPassword') + set('loginPopupContentBodyBtnLogin', 'authLoginBtn') + set('loginPopupContentBodyBtnRegister', 'authRegisterBtn') + set('noLoginBtn', 'launchWithoutAuth') - // Downloads section - set('downloadTitle', 'downloadTitle') - set('grassclipperTitle', 'grassclipperTitle') - set('grasscutterTitle', 'grasscutterTitle') - set('installerTitle', 'installerTitle') - set('installerSubtitle', 'installerSubtitle') - set('downloadStable', 'downloadStable') - set('stableSubtitle', 'stableSubtitle') - set('downloadDev', 'downloadDev') - set('devSubtitle', 'downloadSubtitle') - set('downloadResources', 'downloadResources') - set('devSubtitle', 'devSubtitle') - set('stableInstall', 'stableInstall') - set('devInstall', 'devInstall') + // Downloads section + set('downloadTitle', 'downloadTitle') + set('grassclipperTitle', 'grassclipperTitle') + set('grasscutterTitle', 'grasscutterTitle') + set('installerTitle', 'installerTitle') + set('installerSubtitle', 'installerSubtitle') + set('downloadStable', 'downloadStable') + set('stableSubtitle', 'stableSubtitle') + set('downloadDev', 'downloadDev') + set('devSubtitle', 'downloadSubtitle') + set('downloadResources', 'downloadResources') + set('devSubtitle', 'devSubtitle') + set('stableInstall', 'stableInstall') + set('devInstall', 'devInstall') - // update notification - set('updateNotifText', 'updateNotifText') + // update notification + set('updateNotifText', 'updateNotifText') } \ No newline at end of file diff --git a/resources/js/windowDrag.js b/resources/js/windowDrag.js index b9aa3f5..e8d8704 100644 --- a/resources/js/windowDrag.js +++ b/resources/js/windowDrag.js @@ -1,25 +1,25 @@ // https://stackoverflow.com/questions/67971689/positioning-the-borderless-window-in-neutralino-js // had to use this since the in-built function breaks the close and minimize buttons -let dragging = false, ratio = 1, posX, posY; -let draggable; +let dragging = false, ratio = 1, posX, posY +let draggable document.addEventListener('DOMContentLoaded', async () => { - draggable = document.getElementById('controlBar'); + draggable = document.getElementById('controlBar') - // Listen to hovers - draggable.onmousedown = function (e) { - ratio = window.devicePixelRatio + // Listen to hovers + draggable.onmousedown = function (e) { + ratio = window.devicePixelRatio - posX = e.pageX * ratio, posY = e.pageY * ratio; - dragging = true; - } + posX = e.pageX * ratio, posY = e.pageY * ratio + dragging = true + } - // Patch for monitors with scaling enabled, allows them to detach from the titlebar anywhere - window.onmouseup = function (e) { - dragging = false; - } + // Patch for monitors with scaling enabled, allows them to detach from the titlebar anywhere + window.onmouseup = function (e) { + dragging = false + } - document.onmousemove = function (e) { - if (dragging) Neutralino.window.move(e.screenX * ratio - posX, e.screenY * ratio - posY); - } + document.onmousemove = function (e) { + if (dragging) Neutralino.window.move(e.screenX * ratio - posX, e.screenY * ratio - posY) + } }) \ No newline at end of file From 4141d349f48937fe242f493e75482d616653d24a Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 22:48:03 -0700 Subject: [PATCH 49/50] more auto eslint fixes --- .eslintrc.json | 10 +- resources/js/authAlert.js | 54 ++-- resources/js/gcdownloader.js | 132 ++++----- resources/js/helpers.js | 112 +++---- resources/js/hoverEvt.js | 56 ++-- resources/js/index.js | 552 +++++++++++++++++------------------ resources/js/login.js | 210 ++++++------- resources/js/onLoad.js | 126 ++++---- resources/js/options.js | 110 +++---- resources/js/translation.js | 176 +++++------ resources/js/windowDrag.js | 28 +- 11 files changed, 783 insertions(+), 783 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 064214d..c1cd848 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,13 +9,13 @@ "ecmaVersion": 13 }, "rules": { + "no-undef": 0, + "no-unused-vars": 0, + "no-case-declarations": 0, + "indent": [ "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" + 2 ], "quotes": [ "error", diff --git a/resources/js/authAlert.js b/resources/js/authAlert.js index 9580530..8af7959 100644 --- a/resources/js/authAlert.js +++ b/resources/js/authAlert.js @@ -1,45 +1,45 @@ let alertTimeout, alertCooldown = 3000 async function displayLoginAlert(message, type, cooldown = null) { - displayAlert(message, type, cooldown, 'login') + displayAlert(message, type, cooldown, 'login') } async function displayRegisterAlert(message, type, cooldown = null) { - displayAlert(message, type, cooldown, 'register') + displayAlert(message, type, cooldown, 'register') } function displayAlert(message, type, cooldown, name) { - const elm = document.getElementById(`${name}Alert`) - const text = document.getElementById(`${name}AlertText`) + const elm = document.getElementById(`${name}Alert`) + const text = document.getElementById(`${name}AlertText`) - elm.style.removeProperty('display') + elm.style.removeProperty('display') - // Remove classification classes - elm.classList.remove('error') - elm.classList.remove('success') - elm.classList.remove('warn') + // Remove classification classes + elm.classList.remove('error') + elm.classList.remove('success') + elm.classList.remove('warn') - switch(type) { - case 'error': - elm.classList.add('error') - break + switch(type) { + case 'error': + elm.classList.add('error') + break - case 'success': - elm.classList.add('success') - break + case 'success': + elm.classList.add('success') + break - case 'warn': - default: - elm.classList.add('warn') - break - } + case 'warn': + default: + elm.classList.add('warn') + break + } - text.innerText = message + text.innerText = message - clearTimeout(alertTimeout) + clearTimeout(alertTimeout) - // Disappear after cooldown - alertTimeout = setTimeout(() => { - elm.style.display = 'none' - }, cooldown || alertCooldown) + // Disappear after cooldown + alertTimeout = setTimeout(() => { + elm.style.display = 'none' + }, cooldown || alertCooldown) } \ No newline at end of file diff --git a/resources/js/gcdownloader.js b/resources/js/gcdownloader.js index bcc6e7a..e461cfd 100644 --- a/resources/js/gcdownloader.js +++ b/resources/js/gcdownloader.js @@ -1,102 +1,102 @@ async function clearGCInstallation() { - Neutralino.os.execCommand('del /s /q "./gc"') + Neutralino.os.execCommand('del /s /q "./gc"') } async function setDownloadButtonsToLoading() { - const stableBtn = document.querySelector('#stableInstall') - const devBtn = document.querySelector('#devInstall') + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') - stableBtn.innerText = localeObj.gcScriptRunning || 'Running...' + stableBtn.innerText = localeObj.gcScriptRunning || 'Running...' - devBtn.innerText = localeObj.gcScriptRunning || 'Running...' + devBtn.innerText = localeObj.gcScriptRunning || 'Running...' - // Set btns to disabled - stableBtn.disabled = true - stableBtn.classList.add('disabled') + // Set btns to disabled + stableBtn.disabled = true + stableBtn.classList.add('disabled') - devBtn.disabled = true - devBtn.classList.add('disabled') + devBtn.disabled = true + devBtn.classList.add('disabled') } async function resetDownloadButtons() { - const stableBtn = document.querySelector('#stableInstall') - const devBtn = document.querySelector('#devInstall') + const stableBtn = document.querySelector('#stableInstall') + const devBtn = document.querySelector('#devInstall') - stableBtn.innerText = localeObj.stableInstall || 'Download' - devBtn.innerText = localeObj.devInstall || 'Download' + stableBtn.innerText = localeObj.stableInstall || 'Download' + devBtn.innerText = localeObj.devInstall || 'Download' - // Set btns to enabled - stableBtn.disabled = false - stableBtn.classList.remove('disabled') + // Set btns to enabled + stableBtn.disabled = false + stableBtn.classList.remove('disabled') - devBtn.disabled = false - devBtn.classList.remove('disabled') + devBtn.disabled = false + devBtn.classList.remove('disabled') } async function downloadGC(branch) { - const config = await getCfg() + const config = await getCfg() - // If we are pulling from a new branch, delete the old installation - if (config.grasscutterBranch !== branch) await clearGCInstallation() + // If we are pulling from a new branch, delete the old installation + if (config.grasscutterBranch !== branch) await clearGCInstallation() - // Set current installation in config - config.grasscutterBranch = branch + // Set current installation in config + config.grasscutterBranch = branch - // Set gc path for people with launcher enabled - config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` + // Set gc path for people with launcher enabled + config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar` - // Enable server launcher - config.serverLaunchPanel = true + // Enable server launcher + config.serverLaunchPanel = true - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) - setDownloadButtonsToLoading() + setDownloadButtonsToLoading() - // Keystore for branch (since they can differ) - const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` + // Keystore for branch (since they can differ) + const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12` - // External service that allows un-authed artifact downloading - const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` + // External service that allows un-authed artifact downloading + const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip` - // For data files - const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`) - const dataList = dataFiles.data - .map(file => ({ path: file.path, filename: file.name })) - .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + // For data files + const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`) + const dataList = dataFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) - // For key files - const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`) - const keyList = keyFiles.data - .map(file => ({ path: file.path, filename: file.name })) - .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) + // For key files + const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`) + const keyList = keyFiles.data + .map(file => ({ path: file.path, filename: file.name })) + .map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename })) - const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') + const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\') - // Ensure data and key folders exist + // Ensure data and key folders exist - await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`) - await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`) + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`) + await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`) - // Download data files - for (const o of dataList) { - const folder = 'data' - await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) - } + // Download data files + for (const o of dataList) { + const folder = 'data' + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } - // Download key files - for (const o of keyList) { - const folder = 'keys' - await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) - } + // Download key files + for (const o of keyList) { + const folder = 'keys' + await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`) + } - // Run installer - createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) + // Run installer + createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`) - // Fix buttons - resetDownloadButtons() + // Fix buttons + resetDownloadButtons() - // Display folder after saving config - displayServerFolder() - enableServerButton() - displayServerLaunchSection() + // Display folder after saving config + displayServerFolder() + enableServerButton() + displayServerLaunchSection() } \ No newline at end of file diff --git a/resources/js/helpers.js b/resources/js/helpers.js index a4f514d..8fe28c2 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -4,27 +4,27 @@ * @returns {Promise} */ async function getCfg() { - const defaultConf = { - gameexe: '', - serverFolder: '', - lastConnect: '', - enableKillswitch: false, - serverLaunchPanel: false, - language: 'en', - useHttps: true, - grasscutterBranch: '', - } - const cfgStr = await Neutralino.storage.getData('config').catch(e => { + const defaultConf = { + gameexe: '', + serverFolder: '', + lastConnect: '', + enableKillswitch: false, + serverLaunchPanel: false, + language: 'en', + useHttps: true, + grasscutterBranch: '', + } + const cfgStr = await Neutralino.storage.getData('config').catch(e => { // The data isn't set, so this is our first time opening - Neutralino.storage.setData('config', JSON.stringify(defaultConf)) + Neutralino.storage.setData('config', JSON.stringify(defaultConf)) - // Show the first time notice if there is no config - document.querySelector('#firstTimeNotice').style.display = 'block' - }) + // Show the first time notice if there is no config + document.querySelector('#firstTimeNotice').style.display = 'block' + }) - const config = cfgStr ? JSON.parse(cfgStr) : defaultConf + const config = cfgStr ? JSON.parse(cfgStr) : defaultConf - return config + return config } /** @@ -33,90 +33,90 @@ async function getCfg() { * @returns {Promise} */ async function getFavIps() { - const ipStr = await Neutralino.storage.getData('favorites').catch(e => { + const ipStr = await Neutralino.storage.getData('favorites').catch(e => { // The data isn't set, so this is our first time opening - Neutralino.storage.setData('favorites', JSON.stringify([])) - }) + Neutralino.storage.setData('favorites', JSON.stringify([])) + }) - const ipArr = ipStr ? JSON.parse(ipStr) : [] + const ipArr = ipStr ? JSON.parse(ipStr) : [] - return ipArr + return ipArr } async function proxyIsInstalled() { - // Check if the proxy server is installed - const curDirList = await filesystem.readDirectory(NL_CWD) + // Check if the proxy server is installed + const curDirList = await filesystem.readDirectory(NL_CWD) - if (curDirList.find(f => f.entry === 'ext')) { - const extFiles = await filesystem.readDirectory(NL_CWD + '/ext') + if (curDirList.find(f => f.entry === 'ext')) { + const extFiles = await filesystem.readDirectory(NL_CWD + '/ext') - if (extFiles.find(f => f.entry === 'mitmdump.exe')) { - return true - } + if (extFiles.find(f => f.entry === 'mitmdump.exe')) { + return true } + } - return false + return false } async function checkForUpdates() { - const url = 'https://api.github.com/repos/Grasscutters/GrassClipper/releases/latest' + const url = 'https://api.github.com/repos/Grasscutters/GrassClipper/releases/latest' - const { data } = await axios.get(url) - const latest = data.tag_name + const { data } = await axios.get(url) + const latest = data.tag_name - return latest + return latest } async function displayUpdate() { - const latest = await checkForUpdates() - const versionDisplay = document.querySelector('#newestVersion') - const notif = document.querySelector('#downloadNotif') + const latest = await checkForUpdates() + const versionDisplay = document.querySelector('#newestVersion') + const notif = document.querySelector('#downloadNotif') - if (latest === `v${NL_APPVERSION}`) return + if (latest === `v${NL_APPVERSION}`) return - versionDisplay.innerText = latest + versionDisplay.innerText = latest - notif.classList.add('displayed') + notif.classList.add('displayed') - setTimeout(() => { - notif.classList.remove('displayed') - }, 5000) + setTimeout(() => { + notif.classList.remove('displayed') + }, 5000) } async function openLatestDownload() { - const downloadLink = 'https://github.com/Grasscutters/GrassClipper/releases/latest/' + const downloadLink = 'https://github.com/Grasscutters/GrassClipper/releases/latest/' - Neutralino.os.open(downloadLink) + Neutralino.os.open(downloadLink) } async function openGameFolder() { - const config = await getCfg() - const folder = config.gameexe.match(/.*\\/g, '')[0] + const config = await getCfg() + const folder = config.gameexe.match(/.*\\/g, '')[0] - openInExplorer(folder) + openInExplorer(folder) } async function openGrasscutterFolder() { - const config = await getCfg() - const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0] + const config = await getCfg() + const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0] - openInExplorer(folder) + openInExplorer(folder) } /** * Minimize the window */ function minimizeWin() { - console.log('min') - Neutralino.window.minimize() + console.log('min') + Neutralino.window.minimize() } /** * Close the window */ function closeWin() { - console.log('close') - Neutralino.app.exit() + console.log('close') + Neutralino.app.exit() - window.close() + window.close() } diff --git a/resources/js/hoverEvt.js b/resources/js/hoverEvt.js index af98ea0..47adb2c 100644 --- a/resources/js/hoverEvt.js +++ b/resources/js/hoverEvt.js @@ -1,36 +1,36 @@ document.addEventListener('DOMContentLoaded', async () => { - const firstPanel = document.querySelector('#firstPanel') - const secondPanel = document.querySelector('#secondPanel') - const thirdPanel = document.querySelector('#thirdPanel') + const firstPanel = document.querySelector('#firstPanel') + const secondPanel = document.querySelector('#secondPanel') + const thirdPanel = document.querySelector('#thirdPanel') - // Listen to hovers - firstPanel.addEventListener('mouseover', () => { - secondPanel.classList.add('darken') - thirdPanel.classList.add('darken') - }) + // Listen to hovers + firstPanel.addEventListener('mouseover', () => { + secondPanel.classList.add('darken') + thirdPanel.classList.add('darken') + }) - firstPanel.addEventListener('mouseout', () => { - secondPanel.classList.remove('darken') - thirdPanel.classList.remove('darken') - }) + firstPanel.addEventListener('mouseout', () => { + secondPanel.classList.remove('darken') + thirdPanel.classList.remove('darken') + }) - secondPanel.addEventListener('mouseover', () => { - firstPanel.classList.add('darken') - thirdPanel.classList.add('darken') - }) + secondPanel.addEventListener('mouseover', () => { + firstPanel.classList.add('darken') + thirdPanel.classList.add('darken') + }) - secondPanel.addEventListener('mouseout', () => { - firstPanel.classList.remove('darken') - thirdPanel.classList.remove('darken') - }) + secondPanel.addEventListener('mouseout', () => { + firstPanel.classList.remove('darken') + thirdPanel.classList.remove('darken') + }) - thirdPanel.addEventListener('mouseover', () => { - firstPanel.classList.add('darken') - secondPanel.classList.add('darken') - }) + thirdPanel.addEventListener('mouseover', () => { + firstPanel.classList.add('darken') + secondPanel.classList.add('darken') + }) - thirdPanel.addEventListener('mouseout', () => { - firstPanel.classList.remove('darken') - secondPanel.classList.remove('darken') - }) + thirdPanel.addEventListener('mouseout', () => { + firstPanel.classList.remove('darken') + secondPanel.classList.remove('darken') + }) }) \ No newline at end of file diff --git a/resources/js/index.js b/resources/js/index.js index 822fb67..15523cc 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -3,185 +3,185 @@ Neutralino.init() let localeObj const filesystem = Neutralino.filesystem const createCmdWindow = async (command) => { - Neutralino.os.execCommand(`cmd.exe /c start "" ${command}`, { background: true }) + Neutralino.os.execCommand(`cmd.exe /c start "" ${command}`, { background: true }) } const openInExplorer = async (path) => { - console.log(`explorer.exe "${path}"`) - createCmdWindow(`explorer.exe "${path}"`) + console.log(`explorer.exe "${path}"`) + createCmdWindow(`explorer.exe "${path}"`) } /** * Enable play buttons */ async function enableButtons() { - const offBtn = document.querySelector('#playOfficial') - const privBtn = document.querySelector('#playPrivate') + const offBtn = document.querySelector('#playOfficial') + const privBtn = document.querySelector('#playPrivate') - offBtn.classList.remove('disabled') - offBtn.disabled = false + offBtn.classList.remove('disabled') + offBtn.disabled = false - // Check if the proxy server is installed - if (await proxyIsInstalled()) { - privBtn.classList.remove('disabled') - privBtn.disabled = false - } + // Check if the proxy server is installed + if (await proxyIsInstalled()) { + privBtn.classList.remove('disabled') + privBtn.disabled = false + } } /** * Enable server launch button */ async function enableServerButton() { - const serverBtn = document.querySelector('#serverLaunch') + const serverBtn = document.querySelector('#serverLaunch') - serverBtn.classList.remove('disabled') - serverBtn.disabled = false + serverBtn.classList.remove('disabled') + serverBtn.disabled = false } /** * Disable buttons when the game folder is not set */ async function handleGameNotSet() { - // Set buttons to greyed out and disable - document.querySelector('#gamePath').innerHTML = localeObj.folderNotSet + // Set buttons to greyed out and disable + document.querySelector('#gamePath').innerHTML = localeObj.folderNotSet - // Set official server background to default - document.querySelector('#firstPanel').style.backgroundImage = 'url("../bg/private/default.png")' + // Set official server background to default + document.querySelector('#firstPanel').style.backgroundImage = 'url("../bg/private/default.png")' - const offBtn = document.querySelector('#playOfficial') - const privBtn = document.querySelector('#playPrivate') + const offBtn = document.querySelector('#playOfficial') + const privBtn = document.querySelector('#playPrivate') - offBtn.classList.add('disabled') - offBtn.disabled = true + offBtn.classList.add('disabled') + offBtn.disabled = true - privBtn.classList.add('disabled') - privBtn.disabled = true + privBtn.classList.add('disabled') + privBtn.disabled = true - // TODO show a dialog of sorts + // TODO show a dialog of sorts } async function handleServerNotSet() { - // Set buttons to greyed out and disable - document.querySelector('#serverPath').innerHTML = localeObj.folderNotSet + // Set buttons to greyed out and disable + document.querySelector('#serverPath').innerHTML = localeObj.folderNotSet - // Set official server background to default - // document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")` + // Set official server background to default + // document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")` - const privBtn = document.querySelector('#serverLaunch') + const privBtn = document.querySelector('#serverLaunch') - privBtn.classList.add('disabled') - privBtn.disabled = true + privBtn.classList.add('disabled') + privBtn.disabled = true } /** * Show the game folder under the select button */ async function displayGameFolder() { - const elm = document.querySelector('#gamePath') - const config = await getCfg() + const elm = document.querySelector('#gamePath') + const config = await getCfg() - elm.innerHTML = config.gameexe + elm.innerHTML = config.gameexe } /** * Show the server folder under the select button */ async function displayServerFolder() { - const elm = document.querySelector('#serverPath') - const config = await getCfg() + const elm = document.querySelector('#serverPath') + const config = await getCfg() - elm.innerHTML = config.serverFolder + elm.innerHTML = config.serverFolder } /** * Set the background images of both the private and public sections */ async function setBackgroundImage() { - const config = await getCfg() + const config = await getCfg() - const privImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/private')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) - const privImage = privImages[Math.floor(Math.random() * privImages.length)].entry + const privImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/private')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) + const privImage = privImages[Math.floor(Math.random() * privImages.length)].entry - const servImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/server')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) - const servImage = servImages[Math.floor(Math.random() * servImages.length)].entry + const servImages = (await filesystem.readDirectory(NL_CWD + '/resources/bg/server')).filter(file => file.type === 'FILE' && !file.entry.includes('default')) + const servImage = servImages[Math.floor(Math.random() * servImages.length)].entry - // Set default image, it will change if the bg folder exists - document.querySelector('#firstPanel').style.backgroundImage = 'url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")' + // Set default image, it will change if the bg folder exists + document.querySelector('#firstPanel').style.backgroundImage = 'url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")' - // Set the private background image - document.querySelector('#secondPanel').style.backgroundImage = `url("../bg/private/${privImage}")` + // Set the private background image + document.querySelector('#secondPanel').style.backgroundImage = `url("../bg/private/${privImage}")` - // Set the server background image - document.querySelector('#thirdPanel').style.backgroundImage = `url("../bg/server/${servImage}")` + // Set the server background image + document.querySelector('#thirdPanel').style.backgroundImage = `url("../bg/server/${servImage}")` - return + return - // Check if resources folder exists - const mainDir = await filesystem.readDirectory(NL_CWD) - if (!mainDir.find(dir => dir.entry === 'resources')) { - await filesystem.createDirectory(NL_CWD + '/resources') - } + // Check if resources folder exists + const mainDir = await filesystem.readDirectory(NL_CWD) + if (!mainDir.find(dir => dir.entry === 'resources')) { + await filesystem.createDirectory(NL_CWD + '/resources') + } - // Ensure bg folder exists - const bgDir = await filesystem.readDirectory(NL_CWD + '/resources') - if (!bgDir.find(dir => dir.entry === 'bg')) { - await filesystem.createDirectory(NL_CWD + '/resources/bg') - } + // Ensure bg folder exists + const bgDir = await filesystem.readDirectory(NL_CWD + '/resources') + if (!bgDir.find(dir => dir.entry === 'bg')) { + await filesystem.createDirectory(NL_CWD + '/resources/bg') + } - // Ensure official folder exists - const officialDir = await filesystem.readDirectory(NL_CWD + '/resources/bg') - if (!officialDir.find(dir => dir.entry === 'official')) { - await filesystem.createDirectory(NL_CWD + '/resources/bg/official') - } + // Ensure official folder exists + const officialDir = await filesystem.readDirectory(NL_CWD + '/resources/bg') + if (!officialDir.find(dir => dir.entry === 'official')) { + await filesystem.createDirectory(NL_CWD + '/resources/bg/official') + } - if (config.gameexe) { + if (config.gameexe) { // See if bg folder exists in parent dir - const parentDir = await filesystem.readDirectory(config.gameexe + '/..') + const parentDir = await filesystem.readDirectory(config.gameexe + '/..') - if (parentDir.find(dir => dir.entry === 'bg')) { + if (parentDir.find(dir => dir.entry === 'bg')) { - const officialImages = (await filesystem.readDirectory(config.gameexe + '/../bg')).filter(file => file.type === 'FILE') + const officialImages = (await filesystem.readDirectory(config.gameexe + '/../bg')).filter(file => file.type === 'FILE') - if (officialImages.length > 0) { - for (const bg of officialImages) { - const path = config.gameexe.replace('\\', '/') + '/../bg/' + bg.entry + if (officialImages.length > 0) { + for (const bg of officialImages) { + const path = config.gameexe.replace('\\', '/') + '/../bg/' + bg.entry - // See if the file exists already - const currentBgs = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official/')).filter(file => file.type === 'FILE') + // See if the file exists already + const currentBgs = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official/')).filter(file => file.type === 'FILE') - if (!currentBgs.find(file => file.entry === bg.entry)) { - await filesystem.copyFile(path, NL_CWD + '/resources/bg/official/' + bg.entry).catch(e => { - // TODO: Handle error - }) - } - } - - // Pick one of the images - const localImg = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official')).filter(file => file.type === 'FILE') - const image = localImg[Math.floor(Math.random() * localImg.length)].entry - - // Set background image - document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/official/${image}")` - } + if (!currentBgs.find(file => file.entry === bg.entry)) { + await filesystem.copyFile(path, NL_CWD + '/resources/bg/official/' + bg.entry).catch(e => { + // TODO: Handle error + }) + } } + + // Pick one of the images + const localImg = (await filesystem.readDirectory(NL_CWD + '/resources/bg/official')).filter(file => file.type === 'FILE') + const image = localImg[Math.floor(Math.random() * localImg.length)].entry + + // Set background image + document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/official/${image}")` + } } + } } /** * When an IP is being input, check if it is part of the favorites */ async function handleFavoriteInput() { - const ip = document.querySelector('#ip').value - const port = document.querySelector('#port').value || '443' - const ipArr = await getFavIps() + const ip = document.querySelector('#ip').value + const port = document.querySelector('#port').value || '443' + const ipArr = await getFavIps() - const addr = `${ip}:${port}` + const addr = `${ip}:${port}` - if (!ip || !ipArr.includes(addr)) { - document.querySelector('#star').src = 'icons/star_empty.svg' - } else { - document.querySelector('#star').src = 'icons/star_filled.svg' - } + if (!ip || !ipArr.includes(addr)) { + document.querySelector('#star').src = 'icons/star_empty.svg' + } else { + document.querySelector('#star').src = 'icons/star_filled.svg' + } } /** @@ -190,182 +190,182 @@ async function handleFavoriteInput() { * @param {String} ip */ async function setIp(ip) { - const ipInput = document.querySelector('#ip') - const portInput = document.querySelector('#port') + const ipInput = document.querySelector('#ip') + const portInput = document.querySelector('#port') - const parseIp = ip.split(':')[0] - const parsePort = ip.split(':')[1] + const parseIp = ip.split(':')[0] + const parsePort = ip.split(':')[1] - // Set star - if (ip) { - document.querySelector('#star').src = 'icons/star_filled.svg' - } + // Set star + if (ip) { + document.querySelector('#star').src = 'icons/star_filled.svg' + } - ipInput.value = parseIp - portInput.value = parsePort + ipInput.value = parseIp + portInput.value = parsePort } /** * Create/hide the favorites list */ async function handleFavoriteList() { - const ipArr = await getFavIps() - const ipList = document.querySelector('#ipList') + const ipArr = await getFavIps() + const ipList = document.querySelector('#ipList') - if (ipList.style.display === 'none') { - ipList.innerHTML = '' + if (ipList.style.display === 'none') { + ipList.innerHTML = '' - const list = ipList.appendChild( - document.createElement('ul') - ) + const list = ipList.appendChild( + document.createElement('ul') + ) - if (ipArr.length < 1) { - const listItem = list.appendChild( - document.createElement('li') - ) + if (ipArr.length < 1) { + const listItem = list.appendChild( + document.createElement('li') + ) - listItem.innerHTML = localeObj.noFavorites - } - - for (const ip of ipArr) { - const elm = document.createElement('li') - elm.innerHTML = ip - elm.addEventListener('click', () => setIp(ip)) - list.appendChild(elm) - } - - ipList.style.display = 'block' - - const transform = window.getComputedStyle(document.querySelector('#ipList')).transform - const xy = [ transform.split(',')[4], transform.split(',')[5] ] - let newY = (27 * ipArr.length) * window.devicePixelRatio - - if (ipArr.length === 0 || ipArr.length === 1) newY = 0 - - ipList.style.transform = `translate(${xy[0]}px, calc(56vh - ${newY}px)` + listItem.innerHTML = localeObj.noFavorites } + + for (const ip of ipArr) { + const elm = document.createElement('li') + elm.innerHTML = ip + elm.addEventListener('click', () => setIp(ip)) + list.appendChild(elm) + } + + ipList.style.display = 'block' + + const transform = window.getComputedStyle(document.querySelector('#ipList')).transform + const xy = [ transform.split(',')[4], transform.split(',')[5] ] + let newY = (27 * ipArr.length) * window.devicePixelRatio + + if (ipArr.length === 0 || ipArr.length === 1) newY = 0 + + ipList.style.transform = `translate(${xy[0]}px, calc(56vh - ${newY}px)` + } } async function openDownloads() { - const downloads = document.querySelector('#downloadPanel') - const config = await getCfg() + const downloads = document.querySelector('#downloadPanel') + const config = await getCfg() - if (downloads.style.display === 'none') { - downloads.style.removeProperty('display') - } + if (downloads.style.display === 'none') { + downloads.style.removeProperty('display') + } - // Disable the resource download button if a serverFolder path is not set - if (!config.serverFolder) { - document.querySelector('#resourceInstall').disabled = true - document.querySelector('#resourceInstall').classList.add('disabled') - } else { - document.querySelector('#resourceInstall').disabled = false - document.querySelector('#resourceInstall').classList.remove('disabled') - } + // Disable the resource download button if a serverFolder path is not set + if (!config.serverFolder) { + document.querySelector('#resourceInstall').disabled = true + document.querySelector('#resourceInstall').classList.add('disabled') + } else { + document.querySelector('#resourceInstall').disabled = false + document.querySelector('#resourceInstall').classList.remove('disabled') + } } async function closeDownloads() { - const downloads = document.querySelector('#downloadPanel') + const downloads = document.querySelector('#downloadPanel') - downloads.style.display = 'none' + downloads.style.display = 'none' } async function openSettings() { - const settings = document.querySelector('#settingsPanel') - const config = await getCfg() + const settings = document.querySelector('#settingsPanel') + const config = await getCfg() - if (settings.style.display === 'none') { - settings.style.removeProperty('display') - } + if (settings.style.display === 'none') { + settings.style.removeProperty('display') + } - // Fill setting options with what is currently set in config - const killSwitch = document.querySelector('#killswitchOption') - const serverLaunch = document.querySelector('#serverLaunchOption') - const httpsCheckbox = document.querySelector('#httpsOption') + // Fill setting options with what is currently set in config + const killSwitch = document.querySelector('#killswitchOption') + const serverLaunch = document.querySelector('#serverLaunchOption') + const httpsCheckbox = document.querySelector('#httpsOption') - killSwitch.checked = config.enableKillswitch - serverLaunch.checked = config.serverLaunchPanel - httpsCheckbox.checked = config.useHttps + killSwitch.checked = config.enableKillswitch + serverLaunch.checked = config.serverLaunchPanel + httpsCheckbox.checked = config.useHttps - // Load languages - getLanguages() + // Load languages + getLanguages() - // Check for updates - //checkForUpdatesAndShow() + // Check for updates + //checkForUpdatesAndShow() } async function closeSettings() { - const settings = document.querySelector('#settingsPanel') - const config = await getCfg() + const settings = document.querySelector('#settingsPanel') + const config = await getCfg() - settings.style.display = 'none' + settings.style.display = 'none' - // In case we installed the proxy server - if (await proxyIsInstalled() && config.gameexe) { - const playPriv = document.querySelector('#playPrivate') + // In case we installed the proxy server + if (await proxyIsInstalled() && config.gameexe) { + const playPriv = document.querySelector('#playPrivate') - playPriv.classList.remove('disabled') - playPriv.disabled = false - } + playPriv.classList.remove('disabled') + playPriv.disabled = false + } } async function openLogin() { - const login = document.querySelector('#loginPanel') - const ip = document.querySelector('#ip').value - const port = document.querySelector('#port').value - const loginIpDisplay = document.querySelector('#loginPopupServer') - const registerIpDisplay = document.querySelector('#registerPopupServer') + const login = document.querySelector('#loginPanel') + const ip = document.querySelector('#ip').value + const port = document.querySelector('#port').value + const loginIpDisplay = document.querySelector('#loginPopupServer') + const registerIpDisplay = document.querySelector('#registerPopupServer') - const config = await getCfg() - const useHttps = config.useHttps - const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` + const config = await getCfg() + const useHttps = config.useHttps + const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` - // Check if we even need to authenticate - try { - const { data } = await axios.get(url + '/authentication/type') + // Check if we even need to authenticate + try { + const { data } = await axios.get(url + '/authentication/type') - if (!data.includes('GCAuthAuthenticationHandler')) { - launchPrivate() - return - } - } catch(e) { - launchPrivate() - return + if (!data.includes('GCAuthAuthenticationHandler')) { + launchPrivate() + return } + } catch(e) { + launchPrivate() + return + } - loginIpDisplay.innerText = ip - registerIpDisplay.innerText = ip + loginIpDisplay.innerText = ip + registerIpDisplay.innerText = ip - if (login.style.display === 'none') { - login.style.removeProperty('display') - } + if (login.style.display === 'none') { + login.style.removeProperty('display') + } } async function closeLogin() { - const login = document.querySelector('#loginPanel') + const login = document.querySelector('#loginPanel') - login.style.display = 'none' + login.style.display = 'none' - setLoginSection() + setLoginSection() } async function closeFirstTimePopup() { - const firstTimePopup = document.querySelector('#firstTimeNotice') - firstTimePopup.style.display = 'none' + const firstTimePopup = document.querySelector('#firstTimeNotice') + firstTimePopup.style.display = 'none' } async function runInstallScript() { - createCmdWindow(`.\\scripts\\install.cmd "${NL_CWD}" true`) + createCmdWindow(`.\\scripts\\install.cmd "${NL_CWD}" true`) - // Create an interval that will check for the proxy server installation finish - const interval = setInterval(async () => { - if (await proxyIsInstalled()) { - clearInterval(interval) - enableButtons() - } - }, 1000) + // Create an interval that will check for the proxy server installation finish + const interval = setInterval(async () => { + if (await proxyIsInstalled()) { + clearInterval(interval) + enableButtons() + } + }, 1000) - closeFirstTimePopup() + closeFirstTimePopup() } async function updateResources() { @@ -373,109 +373,109 @@ async function updateResources() { } async function checkForUpdatesAndShow() { - const updateBtn = document.querySelector('#updateBtn') - const subtitle = document.querySelector('#updateSubtitle') - const url = 'https://github.com/Grasscutters/GrassClipper/releases/latest/download/' - const manifest = await Neutralino.updater.checkForUpdates(url) + const updateBtn = document.querySelector('#updateBtn') + const subtitle = document.querySelector('#updateSubtitle') + const url = 'https://github.com/Grasscutters/GrassClipper/releases/latest/download/' + const manifest = await Neutralino.updater.checkForUpdates(url) - // Version mismatch? Update! - if (manifest?.version !== NL_APPVERSION) { - subtitle.innerHTML = 'New update available!' - updateBtn.classList.remove('disabled') - } else { - subtitle.innerHTML = 'You are on the latest version! :)' - updateBtn.classList.add('disabled') - } + // Version mismatch? Update! + if (manifest?.version !== NL_APPVERSION) { + subtitle.innerHTML = 'New update available!' + updateBtn.classList.remove('disabled') + } else { + subtitle.innerHTML = 'You are on the latest version! :)' + updateBtn.classList.add('disabled') + } } async function displayServerLaunchSection() { - const serverPanel = document.querySelector('#thirdPanel') - const bottomBtnSection = document.querySelector('#serverPath').parentElement + const serverPanel = document.querySelector('#thirdPanel') + const bottomBtnSection = document.querySelector('#serverPath').parentElement - if (serverPanel.style.display === 'none') { - serverPanel.style.removeProperty('display') - bottomBtnSection.style.removeProperty('display') - } else { - serverPanel.style.display = 'none' - bottomBtnSection.style.display = 'none' - } + if (serverPanel.style.display === 'none') { + serverPanel.style.removeProperty('display') + bottomBtnSection.style.removeProperty('display') + } else { + serverPanel.style.display = 'none' + bottomBtnSection.style.display = 'none' + } } /** * Set the game folder by opening a folder picker */ async function setGameExe() { - const gameExe = await Neutralino.os.showOpenDialog(localeObj.gameFolderDialog, { - filters: [ - { name: 'Executable files', extensions: ['exe'] } - ] - }) + const gameExe = await Neutralino.os.showOpenDialog(localeObj.gameFolderDialog, { + filters: [ + { name: 'Executable files', extensions: ['exe'] } + ] + }) - if (!gameExe[0]) return + if (!gameExe[0]) return - // Set the folder in our configuration - const config = await getCfg() + // Set the folder in our configuration + const config = await getCfg() - // It's an array of selections, so only get the first one - config.gameexe = gameExe[0].replace(/\//g, '\\') + // It's an array of selections, so only get the first one + config.gameexe = gameExe[0].replace(/\//g, '\\') - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) - // Refresh background and path - setBackgroundImage() - displayGameFolder() - enableButtons() + // Refresh background and path + setBackgroundImage() + displayGameFolder() + enableButtons() } async function setGrasscutterFolder() { - const folder = await Neutralino.os.showOpenDialog(localeObj.grasscutterFileDialog, { - filters: [ - { name: 'Jar files', extensions: ['jar'] } - ] - }) + const folder = await Neutralino.os.showOpenDialog(localeObj.grasscutterFileDialog, { + filters: [ + { name: 'Jar files', extensions: ['jar'] } + ] + }) - if (!folder[0]) return + if (!folder[0]) return - // Set the folder in our configuration - const config = await getCfg() + // Set the folder in our configuration + const config = await getCfg() - config.serverFolder = folder[0] - Neutralino.storage.setData('config', JSON.stringify(config)) + config.serverFolder = folder[0] + Neutralino.storage.setData('config', JSON.stringify(config)) - displayServerFolder() - enableServerButton() + displayServerFolder() + enableServerButton() } /** * Launch the game with no modifications nor proxy */ async function launchOfficial() { - const config = await getCfg() + const config = await getCfg() - Neutralino.os.execCommand(`"${config.gameexe}"`) + Neutralino.os.execCommand(`"${config.gameexe}"`) } /** * Launch the game with a proxy */ async function launchPrivate() { - const ip = document.getElementById('ip').value || '127.0.0.1' - const port = document.getElementById('port').value || '443' + const ip = document.getElementById('ip').value || '127.0.0.1' + const port = document.getElementById('port').value || '443' - const config = await getCfg() + const config = await getCfg() - console.log('connecting to ' + ip + ':' + port) + console.log('connecting to ' + ip + ':' + port) - // Set the last connect - config.lastConnect = ip - Neutralino.storage.setData('config', JSON.stringify(config)) + // Set the last connect + config.lastConnect = ip + Neutralino.storage.setData('config', JSON.stringify(config)) - // Pass IP and game folder to the private server launcher - createCmdWindow(`.\\scripts\\private_server_launch.cmd ${ip} ${port} ${config.useHttps} "${config.gameexe}" "${NL_CWD}" ${config.enableKillswitch} true`).catch(e => console.log(e)) + // Pass IP and game folder to the private server launcher + createCmdWindow(`.\\scripts\\private_server_launch.cmd ${ip} ${port} ${config.useHttps} "${config.gameexe}" "${NL_CWD}" ${config.enableKillswitch} true`).catch(e => console.log(e)) } async function launchLocalServer() { - const config = await getCfg() + const config = await getCfg() - createCmdWindow(`.\\scripts\\local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e)) + createCmdWindow(`.\\scripts\\local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e)) } diff --git a/resources/js/login.js b/resources/js/login.js index 87c0de9..0982456 100644 --- a/resources/js/login.js +++ b/resources/js/login.js @@ -2,153 +2,153 @@ * Toggle the login section */ async function setLoginSection() { - const title = document.getElementById('loginSectionTitle') - const altTitle = document.getElementById('registerSectionTitle') - const loginSection = document.getElementById('loginPopupContentBody') - const registerSection = document.getElementById('registerPopupContentBody') + const title = document.getElementById('loginSectionTitle') + const altTitle = document.getElementById('registerSectionTitle') + const loginSection = document.getElementById('loginPopupContentBody') + const registerSection = document.getElementById('registerPopupContentBody') - title.classList.add('selectedTitle') - altTitle.classList.remove('selectedTitle') + title.classList.add('selectedTitle') + altTitle.classList.remove('selectedTitle') - loginSection.style.removeProperty('display') - registerSection.style.display = 'none' + loginSection.style.removeProperty('display') + registerSection.style.display = 'none' } /** * Toggle the register section */ async function setRegisterSection(fromLogin = false) { - const title = document.getElementById('registerSectionTitle') - const altTitle = document.getElementById('loginSectionTitle') - const loginSection = document.getElementById('loginPopupContentBody') - const registerSection = document.getElementById('registerPopupContentBody') + const title = document.getElementById('registerSectionTitle') + const altTitle = document.getElementById('loginSectionTitle') + const loginSection = document.getElementById('loginPopupContentBody') + const registerSection = document.getElementById('registerPopupContentBody') - title.classList.add('selectedTitle') - altTitle.classList.remove('selectedTitle') + title.classList.add('selectedTitle') + altTitle.classList.remove('selectedTitle') - loginSection.style.display = 'none' - registerSection.style.removeProperty('display') + loginSection.style.display = 'none' + registerSection.style.removeProperty('display') - if (fromLogin) { + if (fromLogin) { // Take the values from the login section and put them in the register section - const loginUsername = document.getElementById('loginUsername').value - const loginPassword = document.getElementById('loginPassword').value + const loginUsername = document.getElementById('loginUsername').value + const loginPassword = document.getElementById('loginPassword').value - document.getElementById('registerUsername').value = loginUsername - document.getElementById('registerPassword').value = loginPassword - } + document.getElementById('registerUsername').value = loginUsername + document.getElementById('registerPassword').value = loginPassword + } } function parseJwt(token) { - const base64Url = token.split('.')[1] - const base64 = base64Url.replace('-', '+').replace('_', '/') - return JSON.parse(window.atob(base64)) + const base64Url = token.split('.')[1] + const base64 = base64Url.replace('-', '+').replace('_', '/') + return JSON.parse(window.atob(base64)) } /** * Attempt login and launch game */ async function login() { - const username = document.getElementById('loginUsername').value - const password = document.getElementById('loginPassword').value - const ip = document.getElementById('ip').value - const port = document.getElementById('port').value || '443' - const config = await getCfg() - const useHttps = config.useHttps - const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` + const username = document.getElementById('loginUsername').value + const password = document.getElementById('loginPassword').value + const ip = document.getElementById('ip').value + const port = document.getElementById('port').value || '443' + const config = await getCfg() + const useHttps = config.useHttps + const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` - const reqBody = { - username, - password, - } + const reqBody = { + username, + password, + } - const { data } = await axios.post(url + '/authentication/login', reqBody) + const { data } = await axios.post(url + '/authentication/login', reqBody) - switch(data.message) { - case 'INVALID_ACCOUNT': - displayLoginAlert(localeObj.alertInvalid || 'Invalid username or password', 'error') - break + switch(data.message) { + case 'INVALID_ACCOUNT': + displayLoginAlert(localeObj.alertInvalid || 'Invalid username or password', 'error') + break - case 'NO_PASSWORD': - // No account password, create one with change password - displayLoginAlert(localeObj.alertNoPass || 'No password set, please change password', 'warn') - break + case 'NO_PASSWORD': + // No account password, create one with change password + displayLoginAlert(localeObj.alertNoPass || 'No password set, please change password', 'warn') + break - case 'UNKNOWN': - // Unknown error, contact server owner - displayLoginAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error') - break + case 'UNKNOWN': + // Unknown error, contact server owner + displayLoginAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error') + break - case undefined: - case null: - case 'AUTH_DISABLED': - // Authentication is disabled, we can just connect the user - displayLoginAlert(localeObj.alertAuthNoLogin || 'Authentication is disabled, no need to log in!', 'warn') - launchPrivate() - break + case undefined: + case null: + case 'AUTH_DISABLED': + // Authentication is disabled, we can just connect the user + displayLoginAlert(localeObj.alertAuthNoLogin || 'Authentication is disabled, no need to log in!', 'warn') + launchPrivate() + break - default: - // Success! Copy the JWT token to their clipboard - const tkData = parseJwt(data.jwt) - await Neutralino.clipboard.writeText(tkData.token) + default: + // Success! Copy the JWT token to their clipboard + const tkData = parseJwt(data.jwt) + await Neutralino.clipboard.writeText(tkData.token) - displayLoginAlert(localeObj.alertLoginSuccess || 'Login successful! Token copied to clipboard. Paste this token into the username field of the game to log in.', 'success', 8000) - launchPrivate() - break - } + displayLoginAlert(localeObj.alertLoginSuccess || 'Login successful! Token copied to clipboard. Paste this token into the username field of the game to log in.', 'success', 8000) + launchPrivate() + break + } } /** * Attempt registration, do not launch game */ async function register() { - const username = document.getElementById('registerUsername').value - const password = document.getElementById('registerPassword').value - const password_confirmation = document.getElementById('registerPasswordConfirm').value - const ip = document.getElementById('ip').value - const port = document.getElementById('port').value || '443' - const config = await getCfg() - const useHttps = config.useHttps - const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` + const username = document.getElementById('registerUsername').value + const password = document.getElementById('registerPassword').value + const password_confirmation = document.getElementById('registerPasswordConfirm').value + const ip = document.getElementById('ip').value + const port = document.getElementById('port').value || '443' + const config = await getCfg() + const useHttps = config.useHttps + const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}` - const reqBody = { - username, - password, - password_confirmation - } + const reqBody = { + username, + password, + password_confirmation + } - const { data } = await axios.post(url + '/authentication/register', reqBody) + const { data } = await axios.post(url + '/authentication/register', reqBody) - switch(data.message) { - case 'USERNAME_TAKEN': - // Username is taken - displayRegisterAlert(localeObj.alertUserTaken || 'Username is taken', 'error') - break + switch(data.message) { + case 'USERNAME_TAKEN': + // Username is taken + displayRegisterAlert(localeObj.alertUserTaken || 'Username is taken', 'error') + break - case 'PASSWORD_MISMATCH': - // The password and password confirmation do not match - displayRegisterAlert(localStorage.alertPassMismatch || 'Password and password confirmation do not match', 'error') - break + case 'PASSWORD_MISMATCH': + // The password and password confirmation do not match + displayRegisterAlert(localStorage.alertPassMismatch || 'Password and password confirmation do not match', 'error') + break - case 'UNKNOWN': - // Unknown error, contact server owner - displayRegisterAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error') - break + case 'UNKNOWN': + // Unknown error, contact server owner + displayRegisterAlert(localeObj.alertUnknown || 'Unknown error, contact server owner', 'error') + break - case undefined: - case null: - case 'AUTH_DISABLED': - // Authentication is disabled, we can just connect the user - displayRegisterAlert(localeObj.alertAuthNoRegister || 'Authentication is disabled, no need to register!', 'warn') - break + case undefined: + case null: + case 'AUTH_DISABLED': + // Authentication is disabled, we can just connect the user + displayRegisterAlert(localeObj.alertAuthNoRegister || 'Authentication is disabled, no need to register!', 'warn') + break - default: - // Success!! Bring them to the login screen and auto-input their username - const loginUsername = document.getElementById('loginUsername') - loginUsername.value = username + default: + // Success!! Bring them to the login screen and auto-input their username + const loginUsername = document.getElementById('loginUsername') + loginUsername.value = username - setLoginSection() - displayLoginAlert(localeObj.alertRegisterSuccess || 'Registration successful!', 'success', 5000) - break - } + setLoginSection() + displayLoginAlert(localeObj.alertRegisterSuccess || 'Registration successful!', 'success', 5000) + break + } } diff --git a/resources/js/onLoad.js b/resources/js/onLoad.js index e1942c8..2065d5e 100644 --- a/resources/js/onLoad.js +++ b/resources/js/onLoad.js @@ -4,86 +4,86 @@ * should be done here to ensure DOM contents are loaded. */ document.addEventListener('DOMContentLoaded', async () => { - displayUpdate() - setBackgroundImage() - displayGameFolder() - displayServerFolder() + displayUpdate() + setBackgroundImage() + displayGameFolder() + displayServerFolder() - // Set title version - document.querySelector('#version').innerHTML = NL_APPVERSION + // Set title version + document.querySelector('#version').innerHTML = NL_APPVERSION - const config = await getCfg() - const ipArr = await getFavIps() + const config = await getCfg() + const ipArr = await getFavIps() - if (config.serverLaunchPanel) { - displayServerLaunchSection() - } + if (config.serverLaunchPanel) { + displayServerLaunchSection() + } - // Set last connect - document.querySelector('#ip').value = config.lastConnect + // Set last connect + document.querySelector('#ip').value = config.lastConnect - if (ipArr.includes(config.lastConnect)) { - document.querySelector('#star').src = 'icons/star_filled.svg' - } + if (ipArr.includes(config.lastConnect)) { + document.querySelector('#star').src = 'icons/star_filled.svg' + } - // Disable private game launch if proxy IP or proxy server is not found - const playPriv = document.querySelector('#playPrivate') + // Disable private game launch if proxy IP or proxy server is not found + const playPriv = document.querySelector('#playPrivate') - if (!(await proxyIsInstalled())) { - playPriv.classList.add('disabled') - playPriv.disabled = true + if (!(await proxyIsInstalled())) { + playPriv.classList.add('disabled') + playPriv.disabled = true + } + + // Exit favorites list and settings panel when clicking outside of it + window.addEventListener('click', function(e) { + const favList = document.querySelector('#ipList') + const settingsPanel = document.querySelector('#settingsPanel') + const downloadPanel = document.querySelector('#downloadPanel') + + // This will close the favorites list no matter what is clicked + if (favList.style.display !== 'none') { + favList.style.display = 'none' + favList.style.transform = '' } - // Exit favorites list and settings panel when clicking outside of it - window.addEventListener('click', function(e) { - const favList = document.querySelector('#ipList') - const settingsPanel = document.querySelector('#settingsPanel') - const downloadPanel = document.querySelector('#downloadPanel') + // This will close the settings panel no matter what is clicked + let checkElm = e.target - // This will close the favorites list no matter what is clicked - if (favList.style.display !== 'none') { - favList.style.display = 'none' - favList.style.transform = '' - } - - // This will close the settings panel no matter what is clicked - let checkElm = e.target - - while(checkElm.tagName !== 'BODY') { - if (checkElm.id === 'settingsPanel' + while(checkElm.tagName !== 'BODY') { + if (checkElm.id === 'settingsPanel' || checkElm.id === 'settingsBtn') { - return - } + return + } - if (checkElm.id === 'downloadPanel' || + if (checkElm.id === 'downloadPanel' || checkElm.id === 'downloadBtn') { - return - } + return + } - checkElm = checkElm.parentElement - } + checkElm = checkElm.parentElement + } - // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel - if (checkElm.tagName === 'BODY') { - // This will close the settings panel only when something outside of it is clicked - if (settingsPanel.style.display !== 'none') { - settingsPanel.style.display = 'none' - } + // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel + if (checkElm.tagName === 'BODY') { + // This will close the settings panel only when something outside of it is clicked + if (settingsPanel.style.display !== 'none') { + settingsPanel.style.display = 'none' + } - if (downloadPanel.style.display !== 'none') { - downloadPanel.style.display = 'none' - } - } - }) + if (downloadPanel.style.display !== 'none') { + downloadPanel.style.display = 'none' + } + } + }) - // Ensure we do the translation at the very end, after everything else has loaded - await doTranslation() + // Ensure we do the translation at the very end, after everything else has loaded + await doTranslation() - if (!config.gameexe) { - handleGameNotSet() - } + if (!config.gameexe) { + handleGameNotSet() + } - if (!config.serverFolder) { - handleServerNotSet() - } + if (!config.serverFolder) { + handleServerNotSet() + } }) diff --git a/resources/js/options.js b/resources/js/options.js index a42f899..5004108 100644 --- a/resources/js/options.js +++ b/resources/js/options.js @@ -2,54 +2,54 @@ * Toggle the killswitch script */ async function toggleKillSwitch() { - const killSwitch = document.querySelector('#killswitchOption') - const config = await getCfg() + const killSwitch = document.querySelector('#killswitchOption') + const config = await getCfg() - config.enableKillswitch = killSwitch.checked + config.enableKillswitch = killSwitch.checked - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) } /** * Toggles the server launching panel */ async function toggleServerLaunchSection() { - const config = await getCfg() + const config = await getCfg() - displayServerLaunchSection() + displayServerLaunchSection() - // Save setting - config.serverLaunchPanel = !config.serverLaunchPanel - Neutralino.storage.setData('config', JSON.stringify(config)) + // Save setting + config.serverLaunchPanel = !config.serverLaunchPanel + Neutralino.storage.setData('config', JSON.stringify(config)) } /** * Get all languages for the language selector */ async function getLanguages() { - const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json')) - const config = await getCfg() + const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json')) + const config = await getCfg() - // Clear language options - const languageSelect = document.querySelector('#languageSelect') - languageSelect.innerHTML = '' + // Clear language options + const languageSelect = document.querySelector('#languageSelect') + languageSelect.innerHTML = '' - // Load all languages as options - for (const file of languageFiles) { - const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName - const lang = file.entry.split('.json')[0] + // Load all languages as options + for (const file of languageFiles) { + const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName + const lang = file.entry.split('.json')[0] - const option = document.createElement('option') - option.value = lang - option.innerHTML = fullLanguageName + const option = document.createElement('option') + option.value = lang + option.innerHTML = fullLanguageName - // Set language selected to config language - if (lang === config.language) { - option.selected = true - } - - document.querySelector('#languageSelect').appendChild(option) + // Set language selected to config language + if (lang === config.language) { + option.selected = true } + + document.querySelector('#languageSelect').appendChild(option) + } } /** @@ -58,27 +58,27 @@ async function getLanguages() { * @param {DOMElement} elm */ async function handleLanguageChange(elm) { - const list = elm - const config = await getCfg() + const list = elm + const config = await getCfg() - // Set language in config - config.language = list.value - Neutralino.storage.setData('config', JSON.stringify(config)) + // Set language in config + config.language = list.value + Neutralino.storage.setData('config', JSON.stringify(config)) - // Force refresh of application, no need for restart! - window.location.reload() + // Force refresh of application, no need for restart! + window.location.reload() } /** * Toggle the use of HTTPS */ async function toggleHttps() { - const httpsCheckbox = document.querySelector('#httpsOption') - const config = await getCfg() + const httpsCheckbox = document.querySelector('#httpsOption') + const config = await getCfg() - config.useHttps = httpsCheckbox.checked + config.useHttps = httpsCheckbox.checked - Neutralino.storage.setData('config', JSON.stringify(config)) + Neutralino.storage.setData('config', JSON.stringify(config)) } /** @@ -87,28 +87,28 @@ async function toggleHttps() { * Remove the current value of the IP input from the favorites list */ async function setFavorite() { - const ip = document.querySelector('#ip').value - const port = document.querySelector('#port').value || '443' - const ipArr = await getFavIps() + const ip = document.querySelector('#ip').value + const port = document.querySelector('#port').value || '443' + const ipArr = await getFavIps() - const addr = `${ip}:${port}` + const addr = `${ip}:${port}` - // Set star icon - const star = document.querySelector('#star') + // Set star icon + const star = document.querySelector('#star') - if (star.src.includes('filled') && ip) { - star.src = 'icons/star_empty.svg' + if (star.src.includes('filled') && ip) { + star.src = 'icons/star_empty.svg' - // remove from list - ipArr.splice(ipArr.indexOf(addr), 1) - } else { - star.src = 'icons/star_filled.svg' + // remove from list + ipArr.splice(ipArr.indexOf(addr), 1) + } else { + star.src = 'icons/star_filled.svg' - // add to list - if (ip && !ipArr.includes(addr)) { - ipArr.push(addr) - } + // add to list + if (ip && !ipArr.includes(addr)) { + ipArr.push(addr) } + } - Neutralino.storage.setData('favorites', JSON.stringify(ipArr)) + Neutralino.storage.setData('favorites', JSON.stringify(ipArr)) } diff --git a/resources/js/translation.js b/resources/js/translation.js index 47f0eb0..dd80b83 100644 --- a/resources/js/translation.js +++ b/resources/js/translation.js @@ -1,110 +1,110 @@ async function doTranslation() { - const config = await getCfg() + const config = await getCfg() - // See if the localization file exists - const localizations = await filesystem.readDirectory(`${NL_CWD}/languages`) + // See if the localization file exists + const localizations = await filesystem.readDirectory(`${NL_CWD}/languages`) - // Use english if the selected file does not exist - const selectedLanguage = localizations.find(f => f.entry === `${config.language}.json`) + // Use english if the selected file does not exist + const selectedLanguage = localizations.find(f => f.entry === `${config.language}.json`) - // Use english if the selected file does not exist - if (!selectedLanguage) { - config.language = 'en' - } + // Use english if the selected file does not exist + if (!selectedLanguage) { + config.language = 'en' + } - const localization = await filesystem.readFile(`${NL_CWD}/languages/${config.language}.json`) - const engLocale = await filesystem.readFile(`${NL_CWD}/languages/en.json`) - engLocaleObj = JSON.parse(engLocale) - localeObj = JSON.parse(localization) + const localization = await filesystem.readFile(`${NL_CWD}/languages/${config.language}.json`) + const engLocale = await filesystem.readFile(`${NL_CWD}/languages/en.json`) + engLocaleObj = JSON.parse(engLocale) + localeObj = JSON.parse(localization) - const set = (id, localeString) => document.getElementById(id).innerText = localeObj[localeString] || engLocaleObj[localeString] + const set = (id, localeString) => document.getElementById(id).innerText = localeObj[localeString] || engLocaleObj[localeString] - // Begin filling in values - set('titleSection', 'appName') + // Begin filling in values + set('titleSection', 'appName') - const verSpan = document.createElement('span') - verSpan.id = 'version' - verSpan.innerHTML = ` v${NL_APPVERSION}` + const verSpan = document.createElement('span') + verSpan.id = 'version' + verSpan.innerHTML = ` v${NL_APPVERSION}` - document.querySelector('#titleSection').appendChild(verSpan) + document.querySelector('#titleSection').appendChild(verSpan) - // Play buttons - set('playOfficial', 'playOfficial') - set('playPrivate', 'playPrivate') - set('serverLaunch', 'launchLocalServer') + // Play buttons + set('playOfficial', 'playOfficial') + set('playPrivate', 'playPrivate') + set('serverLaunch', 'launchLocalServer') - // File select buttons - set('gameExeSet', 'gameExeSet') - set('grasscutterFileSet', 'grasscutterFileSet') + // File select buttons + set('gameExeSet', 'gameExeSet') + set('grasscutterFileSet', 'grasscutterFileSet') - // Private options - document.querySelector('#ip').placeholder = localeObj.ipPlaceholder - document.querySelector('#port').placeholder = localeObj.portPlaceholder + // Private options + document.querySelector('#ip').placeholder = localeObj.ipPlaceholder + document.querySelector('#port').placeholder = localeObj.portPlaceholder - // Settings - set('fullSettingsTitle', 'settingsTitle') - set('scriptsTitle', 'scriptsSectionTitle') - set('killswitchTitle', 'killswitchOption') - set('killswitchSubtitle', 'killswitchSubtitle') - set('proxyTitle', 'proxyOption') - set('proxyInstall', 'proxyInstallBtn') - set('proxySubtitle', 'proxySubtitle') - set('updateBtn', 'updateOption') - set('updateTitle', 'updateOption') - set('updateSubtitle', 'updateSubtitle') - set('languageTitle', 'languageOption') - set('languageSubtitle', 'languageSubtitle') - set('serverLaunchTitle', 'enableServerLauncherOption') - set('serverSubtitle', 'enableServerLauncherSubtitle') - set('httpsTitle', 'httpsOption') - set('httpsSubtitle', 'httpsSubtitle') + // Settings + set('fullSettingsTitle', 'settingsTitle') + set('scriptsTitle', 'scriptsSectionTitle') + set('killswitchTitle', 'killswitchOption') + set('killswitchSubtitle', 'killswitchSubtitle') + set('proxyTitle', 'proxyOption') + set('proxyInstall', 'proxyInstallBtn') + set('proxySubtitle', 'proxySubtitle') + set('updateBtn', 'updateOption') + set('updateTitle', 'updateOption') + set('updateSubtitle', 'updateSubtitle') + set('languageTitle', 'languageOption') + set('languageSubtitle', 'languageSubtitle') + set('serverLaunchTitle', 'enableServerLauncherOption') + set('serverSubtitle', 'enableServerLauncherSubtitle') + set('httpsTitle', 'httpsOption') + set('httpsSubtitle', 'httpsSubtitle') - // Intro popup - const popup = document.getElementById('firstTimeNotice') - const introSpan = popup.querySelector('span') - const boldIntroSpan = document.createElement('span') + // Intro popup + const popup = document.getElementById('firstTimeNotice') + const introSpan = popup.querySelector('span') + const boldIntroSpan = document.createElement('span') - boldIntroSpan.innerHTML = localeObj.introSen1 + '\n' - boldIntroSpan.classList.add('boldTitle') + boldIntroSpan.innerHTML = localeObj.introSen1 + '\n' + boldIntroSpan.classList.add('boldTitle') - introSpan.appendChild(boldIntroSpan) + introSpan.appendChild(boldIntroSpan) - introSpan.innerHTML += localeObj.introSen2 + '
' - introSpan.innerHTML += localeObj.introSen3 + '
' - introSpan.innerHTML += localeObj.introSen4 + '
' + introSpan.innerHTML += localeObj.introSen2 + '
' + introSpan.innerHTML += localeObj.introSen3 + '
' + introSpan.innerHTML += localeObj.introSen4 + '
' - set('firstTimeInstallBtn', 'proxyInstallBtn') - set('firstTimeDenyBtn', 'proxyInstallDeny') + set('firstTimeInstallBtn', 'proxyInstallBtn') + set('firstTimeDenyBtn', 'proxyInstallDeny') - // Login section - set('loginSectionTitle', 'authLoginTitle') - set('registerSectionTitle', 'authRegisterTitle') - set('loggingInToIndicator', 'loggingInTo') - set('registeringToIndicator', 'registeringFor') - set('loginUsernameIndicator', 'authUsername') - set('loginPasswordIndicator', 'authPassword') - set('registerUsernameIndicator', 'authUsername') - set('registerPasswordIndicator', 'authPassword') - set('registerConfirmIndicator', 'authConfirmPassword') - set('loginPopupContentBodyBtnLogin', 'authLoginBtn') - set('loginPopupContentBodyBtnRegister', 'authRegisterBtn') - set('noLoginBtn', 'launchWithoutAuth') + // Login section + set('loginSectionTitle', 'authLoginTitle') + set('registerSectionTitle', 'authRegisterTitle') + set('loggingInToIndicator', 'loggingInTo') + set('registeringToIndicator', 'registeringFor') + set('loginUsernameIndicator', 'authUsername') + set('loginPasswordIndicator', 'authPassword') + set('registerUsernameIndicator', 'authUsername') + set('registerPasswordIndicator', 'authPassword') + set('registerConfirmIndicator', 'authConfirmPassword') + set('loginPopupContentBodyBtnLogin', 'authLoginBtn') + set('loginPopupContentBodyBtnRegister', 'authRegisterBtn') + set('noLoginBtn', 'launchWithoutAuth') - // Downloads section - set('downloadTitle', 'downloadTitle') - set('grassclipperTitle', 'grassclipperTitle') - set('grasscutterTitle', 'grasscutterTitle') - set('installerTitle', 'installerTitle') - set('installerSubtitle', 'installerSubtitle') - set('downloadStable', 'downloadStable') - set('stableSubtitle', 'stableSubtitle') - set('downloadDev', 'downloadDev') - set('devSubtitle', 'downloadSubtitle') - set('downloadResources', 'downloadResources') - set('devSubtitle', 'devSubtitle') - set('stableInstall', 'stableInstall') - set('devInstall', 'devInstall') + // Downloads section + set('downloadTitle', 'downloadTitle') + set('grassclipperTitle', 'grassclipperTitle') + set('grasscutterTitle', 'grasscutterTitle') + set('installerTitle', 'installerTitle') + set('installerSubtitle', 'installerSubtitle') + set('downloadStable', 'downloadStable') + set('stableSubtitle', 'stableSubtitle') + set('downloadDev', 'downloadDev') + set('devSubtitle', 'downloadSubtitle') + set('downloadResources', 'downloadResources') + set('devSubtitle', 'devSubtitle') + set('stableInstall', 'stableInstall') + set('devInstall', 'devInstall') - // update notification - set('updateNotifText', 'updateNotifText') + // update notification + set('updateNotifText', 'updateNotifText') } \ No newline at end of file diff --git a/resources/js/windowDrag.js b/resources/js/windowDrag.js index e8d8704..642b0f3 100644 --- a/resources/js/windowDrag.js +++ b/resources/js/windowDrag.js @@ -4,22 +4,22 @@ let dragging = false, ratio = 1, posX, posY let draggable document.addEventListener('DOMContentLoaded', async () => { - draggable = document.getElementById('controlBar') + draggable = document.getElementById('controlBar') - // Listen to hovers - draggable.onmousedown = function (e) { - ratio = window.devicePixelRatio + // Listen to hovers + draggable.onmousedown = function (e) { + ratio = window.devicePixelRatio - posX = e.pageX * ratio, posY = e.pageY * ratio - dragging = true - } + posX = e.pageX * ratio, posY = e.pageY * ratio + dragging = true + } - // Patch for monitors with scaling enabled, allows them to detach from the titlebar anywhere - window.onmouseup = function (e) { - dragging = false - } + // Patch for monitors with scaling enabled, allows them to detach from the titlebar anywhere + window.onmouseup = function (e) { + dragging = false + } - document.onmousemove = function (e) { - if (dragging) Neutralino.window.move(e.screenX * ratio - posX, e.screenY * ratio - posY) - } + document.onmousemove = function (e) { + if (dragging) Neutralino.window.move(e.screenX * ratio - posX, e.screenY * ratio - posY) + } }) \ No newline at end of file From d63f403a92b961727f73a7a5d041f5febdabe933 Mon Sep 17 00:00:00 2001 From: SpikeHD Date: Mon, 2 May 2022 22:49:22 -0700 Subject: [PATCH 50/50] version bump --- manifest.json | 2 +- neutralino.config.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manifest.json b/manifest.json index 2fc35a4..77d9e27 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { "applicationId": "js.grassclipper.app", - "version": "0.8.7", + "version": "0.9.0", "resourcesURL": "https://github.com/Grasscutters/GrassClipper/releases/latest/download/resources.neu" } \ No newline at end of file diff --git a/neutralino.config.json b/neutralino.config.json index be4549a..0bdb3dd 100644 --- a/neutralino.config.json +++ b/neutralino.config.json @@ -1,6 +1,6 @@ { "applicationId": "js.grassclipper.app", - "version": "0.8.7", + "version": "0.9.0", "defaultMode": "window", "port": 0, "documentRoot": "/resources/", diff --git a/package.json b/package.json index 9c0eb1a..764fed5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grassclipper", - "version": "0.8.7", + "version": "0.9.0", "repository": "https://github.com/Grasscutters/GrassClipper.git", "author": "SpikeHD ", "license": "Apache-2.0",