GrassClipper/resources/js/index.js

435 lines
12 KiB
JavaScript
Raw Normal View History

2022-04-20 01:12:56 +00:00
Neutralino.init();
2022-04-21 08:20:41 +00:00
/**
* Every autofill, such as backgrounds and the game folder,
* should be done here to ensure DOM contents are loaded.
*/
2022-04-20 01:12:56 +00:00
document.addEventListener('DOMContentLoaded', async () => {
setBackgroundImage();
displayGenshinFolder();
const config = await getCfg()
2022-04-21 05:43:32 +00:00
const ipArr = await getFavIps()
if (!config.genshinImpactFolder) {
handleGenshinFolderNotSet()
}
2022-04-21 01:43:19 +00:00
// Set last connect
document.querySelector('#ip').value = config.lastConnect
2022-04-21 05:43:32 +00:00
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')
const curDirList = await Neutralino.filesystem.readDirectory(NL_CWD)
if (!curDirList.find(f => f.entry === 'ext')) {
playPriv.classList.add('disabled')
playPriv.disabled = true
}
const extFiles = await Neutralino.filesystem.readDirectory(NL_CWD + '/ext')
if (!extFiles.find(f => f.entry === 'mitmdump.exe')) {
playPriv.classList.add('disabled')
playPriv.disabled = true
}
// Exit favorites list and settings panel when clicking outside of it
2022-04-21 21:53:53 +00:00
window.addEventListener("click", function(e) {
const favList = document.querySelector('#ipList')
2022-04-21 21:53:53 +00:00
const settingsPanel = document.querySelector('#settingsPanel')
// This will close the favorites list no matter what is clicked
if (favList.style.display !== 'none') {
favList.style.display = 'none'
favList.style.transform = ''
}
2022-04-21 21:53:53 +00:00
// This will close the settings panel no matter what is clicked
let settingCheckElm = e.target
while(settingCheckElm.tagName !== 'BODY') {
if (settingCheckElm.id === 'settingsPanel'
|| settingCheckElm.id === 'settingsBtn') {
return
}
settingCheckElm = settingCheckElm.parentElement
}
// We travelled through the parents, so if we are at the body, we clicked outside of the settings panel
if (settingCheckElm.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'
}
}
});
2022-04-20 01:12:56 +00:00
})
2022-04-21 08:20:41 +00:00
/**
* Get the list of favorite IPs
*
* @returns {Promise<string[]>}
*/
2022-04-21 05:43:32 +00:00
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([]))
})
const ipArr = ipStr ? JSON.parse(ipStr) : []
return ipArr
}
2022-04-21 08:20:41 +00:00
/**
* Get configuration
*
* @returns {Promise<string>}
*/
2022-04-20 01:12:56 +00:00
async function getCfg() {
2022-04-21 10:51:58 +00:00
const defaultConf = {
genshinImpactFolder: '',
lastConnect: '',
enableKillswitch: false
}
2022-04-20 04:45:34 +00:00
const cfgStr = await Neutralino.storage.getData('config').catch(e => {
2022-04-20 01:12:56 +00:00
// The data isn't set, so this is our first time opening
2022-04-21 10:51:58 +00:00
Neutralino.storage.setData('config', JSON.stringify(defaultConf))
// Show the first time notice if there is no config
document.querySelector('#firstTimeNotice').style.display = 'block'
2022-04-20 04:45:34 +00:00
})
2022-04-21 10:51:58 +00:00
const config = cfgStr ? JSON.parse(cfgStr) : defaultConf
2022-04-20 04:45:34 +00:00
return config
}
2022-04-21 08:20:41 +00:00
/**
* Enable play buttons
*/
async function enableButtons() {
const offBtn = document.querySelector('#playOfficial')
const privBtn = document.querySelector('#playPrivate')
offBtn.classList.remove('disabled')
offBtn.disabled = false
privBtn.classList.remove('disabled')
privBtn.disabled = false
}
2022-04-21 08:20:41 +00:00
/**
* Disable buttons when the game folder is not set
*/
async function handleGenshinFolderNotSet() {
// Set buttons to greyed out and disable
document.querySelector('#genshinPath').innerHTML = 'Not set'
// Set official server background to default
document.querySelector('#firstHalf').style.backgroundImage = `url("../bg/private/default.png")`
const offBtn = document.querySelector('#playOfficial')
const privBtn = document.querySelector('#playPrivate')
offBtn.classList.add('disabled')
offBtn.disabled = true
privBtn.classList.add('disabled')
privBtn.disabled = true
// TODO show a dialog of sorts
2022-04-20 01:12:56 +00:00
}
2022-04-21 08:20:41 +00:00
/**
* Show the game folder under the select button
*/
2022-04-20 01:12:56 +00:00
async function displayGenshinFolder() {
const elm = document.querySelector('#genshinPath')
const config = await getCfg()
elm.innerHTML = config.genshinImpactFolder
}
2022-04-21 08:20:41 +00:00
/**
* Set the background images of both the private and public sections
*/
2022-04-20 01:12:56 +00:00
async function setBackgroundImage() {
const config = await getCfg()
2022-04-20 01:40:05 +00:00
// Check if resources folder exists
const mainDir = await Neutralino.filesystem.readDirectory(NL_CWD)
if (!mainDir.find(dir => dir.entry === 'resources')) {
await Neutralino.filesystem.createDirectory(NL_CWD + '/resources')
}
// Ensure bg folder exists
const bgDir = await Neutralino.filesystem.readDirectory(NL_CWD + '/resources')
if (!bgDir.find(dir => dir.entry === 'bg')) {
await Neutralino.filesystem.createDirectory(NL_CWD + '/resources/bg')
}
// Ensure official folder exists
const officialDir = await Neutralino.filesystem.readDirectory(NL_CWD + '/resources/bg')
if (!officialDir.find(dir => dir.entry === 'official')) {
2022-04-20 23:27:40 +00:00
await Neutralino.filesystem.createDirectory(NL_CWD + '/resources/bg/official')
2022-04-20 01:40:05 +00:00
}
if (config.genshinImpactFolder) {
2022-04-21 05:06:56 +00:00
const officialImages = (await Neutralino.filesystem.readDirectory(config.genshinImpactFolder + '/../bg')).filter(file => file.type === 'FILE')
if (officialImages.length > 0) {
for (const bg of officialImages) {
2022-04-21 05:06:56 +00:00
const path = config.genshinImpactFolder.replace('\\', '/') + '/../bg/' + bg.entry
// See if the file exists already
const currentBgs = (await Neutralino.filesystem.readDirectory(NL_CWD + '/resources/bg/official/')).filter(file => file.type === 'FILE')
if (!currentBgs.find(file => file.entry === bg.entry)) {
await Neutralino.filesystem.copyFile(path, NL_CWD + '/resources/bg/official/' + bg.entry).catch(e => {
// TODO: Handle error
})
}
}
2022-04-21 05:06:56 +00:00
// Pick one of the images
const localImg = (await Neutralino.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('#firstHalf').style.backgroundImage = `url("../bg/official/${image}")`
} else {
// Set default image
document.querySelector('#firstHalf').style.backgroundImage = `url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")`
2022-04-21 05:06:56 +00:00
}
2022-04-20 01:12:56 +00:00
}
const privImages = (await Neutralino.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
2022-04-20 01:12:56 +00:00
// Set the background image
document.querySelector('#secondHalf').style.backgroundImage = `url("../bg/private/${privImage}")`
2022-04-20 01:12:56 +00:00
}
2022-04-21 08:20:41 +00:00
/**
* When an IP is being input, check if it is part of the favorites
*/
2022-04-21 05:26:25 +00:00
async function handleFavoriteInput() {
2022-04-21 05:43:32 +00:00
const ip = document.querySelector('#ip').value
const ipArr = await getFavIps()
if (!ip || !ipArr.includes(ip)) {
document.querySelector('#star').src = 'icons/star_empty.svg'
} else {
document.querySelector('#star').src = 'icons/star_filled.svg'
}
}
2022-04-21 08:20:41 +00:00
/**
* Set the IP input value
*
* @param {String} ip
*/
2022-04-21 06:12:15 +00:00
async function setIp(ip) {
const ipInput = document.querySelector('#ip')
// Set star
if (ip) {
document.querySelector('#star').src = 'icons/star_filled.svg'
}
2022-04-21 06:12:15 +00:00
ipInput.value = ip
}
2022-04-21 08:20:41 +00:00
/**
* Create/hide the favorites list
*/
2022-04-21 06:04:20 +00:00
async function handleFavoriteList() {
const ipArr = await getFavIps()
const ipList = document.querySelector('#ipList')
if (ipList.style.display === 'none') {
ipList.innerHTML = ''
const list = ipList.appendChild(
document.createElement('ul')
)
2022-04-21 06:17:50 +00:00
if (ipArr.length < 1) {
const listItem = list.appendChild(
document.createElement('li')
)
listItem.innerHTML = 'No favorites set'
}
2022-04-21 06:04:20 +00:00
for (const ip of ipArr) {
const elm = document.createElement('li')
elm.innerHTML = ip
2022-04-21 06:12:15 +00:00
elm.addEventListener('click', () => setIp(ip))
2022-04-21 06:04:20 +00:00
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 = parseInt(xy[1].replace(')', '')) - (27 * ipArr.length)
if (ipArr.length === 0) newY -= 27
ipList.style.transform = `translate(${xy[0]}px, ${newY}px)`
2022-04-21 06:04:20 +00:00
}
}
2022-04-21 08:20:41 +00:00
/**
* Add the current value of the IP input to the favorites list
* OR
* Remove the current value of the IP input from the favorites list
*/
2022-04-21 05:43:32 +00:00
async function setFavorite() {
const ip = document.querySelector('#ip').value
const ipArr = await getFavIps()
// Set star icon
const star = document.querySelector('#star')
if (star.src.includes('filled') && ip) {
star.src = 'icons/star_empty.svg'
// remove from list
ipArr.splice(ipArr.indexOf(ip), 1)
} else {
star.src = 'icons/star_filled.svg'
// add to list
if (ip && !ipArr.includes(ip)) {
ipArr.push(ip)
}
}
Neutralino.storage.setData('favorites', JSON.stringify(ipArr))
2022-04-21 05:26:25 +00:00
}
2022-04-21 21:53:53 +00:00
async function openSettings() {
const settings = document.querySelector('#settingsPanel')
2022-04-21 22:15:52 +00:00
const config = await getCfg()
2022-04-21 21:53:53 +00:00
if (settings.style.display === 'none') {
settings.style.removeProperty('display')
}
2022-04-21 22:15:52 +00:00
// Fill setting options with what is currently set in config
const killSwitch = document.querySelector('#killswitchOption')
killSwitch.checked = config.enableKillswitch
}
2022-04-21 22:33:14 +00:00
async function closeSettings() {
const settings = document.querySelector('#settingsPanel')
settings.style.display = 'none'
}
2022-04-21 22:15:52 +00:00
async function toggleKillSwitch() {
const killSwitch = document.querySelector('#killswitchOption')
const config = await getCfg()
config.enableKillswitch = killSwitch.checked
Neutralino.storage.setData('config', JSON.stringify(config))
2022-04-21 21:53:53 +00:00
}
async function closeFirstTimePopup() {
const firstTimePopup = document.querySelector('#firstTimeNotice')
firstTimePopup.style.display = 'none'
}
async function runInstallScript() {
Neutralino.os.execCommand(`${NL_CWD}/scripts/install.cmd "${NL_CWD}"`)
closeFirstTimePopup()
}
2022-04-21 08:20:41 +00:00
/**
* Set the game folder by opening a folder picker
*/
2022-04-20 01:12:56 +00:00
async function setGenshinImpactFolder() {
2022-04-21 05:06:56 +00:00
const folder = await Neutralino.os.showFolderDialog('Select Genshin Impact Game folder')
2022-04-20 01:12:56 +00:00
// Set the folder in our configuration
const config = await getCfg()
2022-04-20 01:12:56 +00:00
config.genshinImpactFolder = folder
Neutralino.storage.setData('config', JSON.stringify(config))
2022-04-20 01:40:05 +00:00
2022-04-20 05:31:23 +00:00
// Refresh background and path
2022-04-20 01:40:05 +00:00
setBackgroundImage()
2022-04-20 05:31:23 +00:00
displayGenshinFolder()
enableButtons()
2022-04-20 01:12:56 +00:00
}
2022-04-20 01:21:29 +00:00
2022-04-21 08:20:41 +00:00
/**
* Get the name of the game executable
*
* @returns {Promise<String>}
*/
2022-04-20 04:55:25 +00:00
async function getGenshinExecName() {
// Scan genshin dir
const config = await getCfg()
2022-04-21 05:06:56 +00:00
const genshinDir = await Neutralino.filesystem.readDirectory(config.genshinImpactFolder)
2022-04-20 04:55:25 +00:00
// Find the executable
const genshinExec = genshinDir.find(file => file.entry.endsWith('.exe'))
return genshinExec.entry
}
2022-04-21 08:20:41 +00:00
/**
* Launch the game with no modifications nor proxy
*/
2022-04-20 01:21:29 +00:00
async function launchOfficial() {
const config = await getCfg()
2022-04-21 05:06:56 +00:00
Neutralino.os.execCommand(config.genshinImpactFolder + '/' + await getGenshinExecName())
2022-04-20 01:40:05 +00:00
}
2022-04-21 08:20:41 +00:00
/**
* Launch the game with a proxy
*/
2022-04-20 01:40:05 +00:00
async function launchPrivate() {
2022-04-20 03:33:34 +00:00
const ip = document.getElementById('ip').value || 'localhost'
2022-04-20 01:40:05 +00:00
const config = await getCfg()
2022-04-20 03:33:34 +00:00
console.log('connecting to ' + ip)
2022-04-21 01:43:19 +00:00
// Set the last connect
config.lastConnect = ip
Neutralino.storage.setData('config', JSON.stringify(config))
2022-04-20 03:02:04 +00:00
// Pass IP and game folder to the private server launcher
2022-04-21 22:23:52 +00:00
Neutralino.os.execCommand(`${NL_CWD}/scripts/private_server_launch.cmd ${ip} "${config.genshinImpactFolder}/${await getGenshinExecName()}" "${NL_CWD}" ${config.enableKillswitch}`).catch(e => console.log(e))
2022-04-21 00:44:17 +00:00
}
2022-04-21 08:20:41 +00:00
/**
* Minimize the window
*/
2022-04-21 00:44:17 +00:00
function minimizeWin() {
2022-04-21 01:16:36 +00:00
console.log('min')
2022-04-21 00:44:17 +00:00
Neutralino.window.minimize()
}
2022-04-21 08:20:41 +00:00
/**
* Close the window
*/
2022-04-21 00:44:17 +00:00
function closeWin() {
2022-04-21 01:16:36 +00:00
console.log('close')
2022-04-21 00:44:17 +00:00
Neutralino.app.exit()
2022-04-20 01:21:29 +00:00
}