mirror of
https://github.com/Grasscutters/GrassClipper.git
synced 2024-11-16 04:45:34 +00:00
eslint changes
This commit is contained in:
parent
f0210cdbfe
commit
eae6cc087b
29
.eslintrc.json
Normal file
29
.eslintrc.json
Normal file
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
@ -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()
|
||||
}
|
@ -3,28 +3,28 @@
|
||||
*
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
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<string[]>}
|
||||
*/
|
||||
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()
|
||||
}
|
||||
|
@ -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')
|
||||
})
|
||||
})
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
})
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 + '<br>'
|
||||
introSpan.innerHTML += localeObj.introSen3 + '<br>'
|
||||
introSpan.innerHTML += localeObj.introSen4 + '<br>'
|
||||
introSpan.innerHTML += localeObj.introSen2 + '<br>'
|
||||
introSpan.innerHTML += localeObj.introSen3 + '<br>'
|
||||
introSpan.innerHTML += localeObj.introSen4 + '<br>'
|
||||
|
||||
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')
|
||||
}
|
@ -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)
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue
Block a user