Merge pull request #7 from Grasscutters/server_launcher

Server Launcher
This commit is contained in:
SpikeHD 2022-04-22 20:19:34 -07:00 committed by GitHub
commit 4e4bc14f53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 205 additions and 45 deletions

View File

@ -1,5 +1,5 @@
{
"applicationId": "js.grassclipper.app",
"version": "0.4.6",
"version": "0.5.0",
"resourcesURL": "https://github.com/Grasscutters/GrassClipper/releases/latest/download/resources.neu"
}

View File

@ -1,6 +1,6 @@
{
"applicationId": "js.grassclipper.app",
"version": "0.4.6",
"version": "0.5.0",
"defaultMode": "window",
"port": 0,
"documentRoot": "/resources/",

View File

@ -1,6 +1,6 @@
{
"name": "GrassClipper",
"version": "0.4.5",
"version": "0.5.0",
"repository": "https://github.com/Grasscutters/GrassClipper.git",
"author": "SpikeHD <spikegdofficial@gmail.com>",
"license": "Apache-2.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
resources/bg/server/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

View File

@ -56,6 +56,15 @@
Auto updating is temporarily disabled. Check GitHub for the newest release.
</span>
</div>
<div class="settingsRow">
<div class="settingSection">
<span class="settingLabel">Enable Server Launcher</span>
<input type="checkbox" id="serverLaunchOption" onchange="toggleServerLaunchSection()" />
</div>
<span class="settingSubtitle" id="serverSubtitle">
Enable to server launcher tile for launcher a local Grasscutter instance.
</span>
</div>
</div>
</div>
<div id="controlBar">
@ -73,11 +82,11 @@
<img src="icons/close.svg" />
</div>
</div>
<div id="halvesContainer">
<div id="firstHalf">
<div id="panelContainer">
<div id="firstPanel">
<button class="playBtn" id="playOfficial" onclick="launchOfficial()">Play Official</button>
</div>
<div id="secondHalf">
<div id="secondPanel">
<div id="ipList" style="display: none;"></div>
<div id="secondControlContainer">
<div id="serverInput">
@ -88,12 +97,21 @@
<button class="playBtn" id="playPrivate" onclick="launchPrivate()">Play Private</button>
</div>
</div>
<div id="thirdPanel" style="display: none;">
<button class="playBtn" id="serverLaunch" onclick="launchLocalServer()">Launch Local Server</button>
</div>
</div>
<div id="bottomBar">
<div class="bottomSection">
<button class="smolBtn" onclick="setGenshinImpactFolder()">Set "Genshin Impact Game" folder</button>
<span id="genshinPath" style="margin-top: 4px;"></span>
<div>
<button class="smolBtn" onclick="setGenshinImpactFolder()">Set "Genshin Impact Game" folder</button>
<span id="genshinPath" style="margin-top: 4px;"></span>
</div>
<div style="display: none;">
<button class="smolBtn" onclick="setGrassCutterFolder()">Set "GrassCutter" .jar file</button>
<span id="serverPath" style="margin-top: 4px;"></span>
</div>
</div>
</div>
</body>

View File

@ -1,21 +1,36 @@
document.addEventListener('DOMContentLoaded', async () => {
const firstHalf = document.querySelector('#firstHalf')
const secondHalf = document.querySelector('#secondHalf')
const firstPanel = document.querySelector('#firstPanel')
const secondPanel = document.querySelector('#secondPanel')
const thirdPanel = document.querySelector('#thirdPanel')
// Listen to hovers
firstHalf.addEventListener('mouseover', () => {
secondHalf.classList.add('darken')
firstPanel.addEventListener('mouseover', () => {
secondPanel.classList.add('darken')
thirdPanel.classList.add('darken')
})
firstHalf.addEventListener('mouseout', () => {
secondHalf.classList.remove('darken')
firstPanel.addEventListener('mouseout', () => {
secondPanel.classList.remove('darken')
thirdPanel.classList.remove('darken')
})
secondHalf.addEventListener('mouseover', () => {
firstHalf.classList.add('darken')
secondPanel.addEventListener('mouseover', () => {
firstPanel.classList.add('darken')
thirdPanel.classList.add('darken')
})
secondHalf.addEventListener('mouseout', () => {
firstHalf.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('mouseout', () => {
firstPanel.classList.remove('darken')
secondPanel.classList.remove('darken')
})
})

View File

@ -9,6 +9,7 @@ const filesystem = Neutralino.filesystem
document.addEventListener('DOMContentLoaded', async () => {
setBackgroundImage();
displayGenshinFolder();
displayServerFolder();
// Set title version
document.querySelector('#version').innerHTML = NL_APPVERSION
@ -20,6 +21,14 @@ document.addEventListener('DOMContentLoaded', async () => {
handleGenshinFolderNotSet()
}
if (!config.serverFolder) {
handleServerNotSet()
}
if (config.serverLaunchPanel) {
displayServerLaunchSection()
}
// Set last connect
document.querySelector('#ip').value = config.lastConnect
@ -92,8 +101,10 @@ async function getFavIps() {
async function getCfg() {
const defaultConf = {
genshinImpactFolder: '',
serverFolder: '',
lastConnect: '',
enableKillswitch: false
enableKillswitch: false,
serverLaunchPanel: false
}
const cfgStr = await Neutralino.storage.getData('config').catch(e => {
// The data isn't set, so this is our first time opening
@ -125,6 +136,16 @@ async function enableButtons() {
}
}
/**
* Enable server launch button
*/
async function enableServerButton() {
const serverBtn = document.querySelector('#serverLaunch')
serverBtn.classList.remove('disabled')
serverBtn.disabled = false
}
/**
* Disable buttons when the game folder is not set
*/
@ -133,7 +154,7 @@ async function handleGenshinFolderNotSet() {
document.querySelector('#genshinPath').innerHTML = 'Not set'
// Set official server background to default
document.querySelector('#firstHalf').style.backgroundImage = `url("../bg/private/default.png")`
document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")`
const offBtn = document.querySelector('#playOfficial')
const privBtn = document.querySelector('#playPrivate')
@ -147,6 +168,19 @@ async function handleGenshinFolderNotSet() {
// TODO show a dialog of sorts
}
async function handleServerNotSet() {
// Set buttons to greyed out and disable
document.querySelector('#serverPath').innerHTML = 'Not set'
// Set official server background to default
// document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")`
const privBtn = document.querySelector('#serverLaunch')
privBtn.classList.add('disabled')
privBtn.disabled = true
}
async function proxyIsInstalled() {
// Check if the proxy server is installed
const curDirList = await filesystem.readDirectory(NL_CWD)
@ -172,6 +206,16 @@ async function displayGenshinFolder() {
elm.innerHTML = config.genshinImpactFolder
}
/**
* Show the server folder under the select button
*/
async function displayServerFolder() {
const elm = document.querySelector('#serverPath')
const config = await getCfg()
elm.innerHTML = config.serverFolder
}
/**
* Set the background images of both the private and public sections
*/
@ -180,12 +224,18 @@ async function setBackgroundImage() {
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
// Set default image, it will change if the bg folder exists
document.querySelector('#firstHalf').style.backgroundImage = `url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")`
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('#secondHalf').style.backgroundImage = `url("../bg/private/${privImage}")`
document.querySelector('#secondPanel').style.backgroundImage = `url("../bg/private/${privImage}")`
// Set the server background image
document.querySelector('#thirdPanel').style.backgroundImage = `url("../bg/server/${servImage}")`
return
@ -234,7 +284,7 @@ async function setBackgroundImage() {
const image = localImg[Math.floor(Math.random() * localImg.length)].entry
// Set background image
document.querySelector('#firstHalf').style.backgroundImage = `url("../bg/official/${image}")`
document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/official/${image}")`
}
}
}
@ -350,8 +400,10 @@ async function openSettings() {
// Fill setting options with what is currently set in config
const killSwitch = document.querySelector('#killswitchOption')
const serverLaunch = document.querySelector('#serverLaunchOption')
killSwitch.checked = config.enableKillswitch
serverLaunch.checked = config.serverLaunchPanel
// Check for updates
//checkForUpdatesAndShow()
@ -359,11 +411,12 @@ async function openSettings() {
async function closeSettings() {
const settings = document.querySelector('#settingsPanel')
const config = await getCfg()
settings.style.display = 'none'
// In case we installed the proxy server
if (await proxyIsInstalled()) {
if (await proxyIsInstalled() && config.genshinImpactFolder) {
const playPriv = document.querySelector('#playPrivate')
playPriv.classList.remove('disabled')
@ -411,6 +464,29 @@ async function checkForUpdatesAndShow() {
}
}
async function displayServerLaunchSection() {
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'
}
}
async function toggleServerLaunchSection() {
const config = await getCfg()
displayServerLaunchSection()
// Save setting
config.serverLaunchPanel = !config.serverLaunchPanel
Neutralino.storage.setData('config', JSON.stringify(config))
}
/**
* Set the game folder by opening a folder picker
*/
@ -439,6 +515,23 @@ async function setGenshinImpactFolder() {
enableButtons()
}
async function setGrassCutterFolder() {
const folder = await Neutralino.os.showOpenDialog('Select GrassCutter server jar', {
filters: [
{ name: 'Jar files', extensions: ['jar'] }
]
})
// Set the folder in our configuration
const config = await getCfg()
config.serverFolder = folder
Neutralino.storage.setData('config', JSON.stringify(config))
displayServerFolder()
enableServerButton()
}
/**
* Get the name of the game executable
*
@ -482,6 +575,12 @@ async function launchPrivate() {
Neutralino.os.execCommand(`${NL_CWD}/scripts/private_server_launch.cmd ${ip} "${config.genshinImpactFolder}/${await getGenshinExecName()}" "${NL_CWD}" ${config.enableKillswitch}`).catch(e => console.log(e))
}
async function launchLocalServer() {
const config = await getCfg()
Neutralino.os.execCommand(`${NL_CWD}/scripts/local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e))
}
/**
* Minimize the window
*/

View File

@ -50,7 +50,7 @@ body {
}
#settingsPanel {
width: 30%;
width: 35%;
height: 60%;
}
@ -65,7 +65,7 @@ body {
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px 20%;
padding: 10px 10%;
}
.settingsRow {
@ -104,7 +104,7 @@ body {
#settingsClose {
display: inline-block;
margin-left: 65%;
margin-left: 70%;
transition: filter 0.1s ease-in-out;
}
@ -281,17 +281,29 @@ body {
.bottomSection {
display: flex;
flex-direction: column;
flex-direction: row;
height: 100%;
width: 100%;
background: #141414;
justify-content: space-evenly;
}
#genshinPath {
.bottomSection div {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #141414;
margin: 4px;
height: 10%;
}
#genshinPath, #serverPath {
color: white;
font-size: 14px;
}
#halvesContainer {
#panelContainer {
width: 100%;
height: 100%;
position: relative;
@ -299,7 +311,7 @@ body {
display: flex;
}
#firstHalf, #secondHalf {
#firstPanel, #secondPanel, #thirdPanel {
display: flex;
justify-content: center;
width: 100%;
@ -309,19 +321,22 @@ body {
transition: width 0.2s ease-in-out, filter 0.2s ease-in-out;
}
#firstHalf:hover, #secondHalf:hover {
#firstPanel:hover, #secondPanel:hover, #thirdPanel:hover {
width: calc(100% + 150px);
}
#firstHalf {
#firstPanel, #secondPanel {
border-right: 6px solid #141414;
}
#firstPanel {
background-position: -340px;
}
/* Move the first official button to the position on the png */
#firstHalf button {
position: relative;
transform: translate(140px, 500px);
#firstPanel button, #secondPanel button, #thirdPanel button {
display: block;
/* transform: translate(140px, 500px); */
width: 300px;
height: 60px;
}
@ -330,13 +345,7 @@ body {
display: block;
}
#secondHalf button {
display: block;
width: 300px;
height: 60px;
}
#secondHalf input {
#secondPanel input {
margin-bottom: 4px;
height: 20px;
background: white;
@ -348,7 +357,7 @@ body {
transition: border-bottom 0.1s ease-in-out;
}
#secondHalf input:focus {
#secondPanel input:focus {
outline: none;
border-bottom: 2px solid #ffc61e;
}
@ -356,9 +365,14 @@ body {
/* Move the second private button the near-bottom */
#secondControlContainer {
position: relative;
transform: translate(115px, 456px);
/* transform: translate(115px, 456px); */
width: 300px;
height: 60px;
margin-top: calc(68vh - 40px) !important;
}
#secondControlContainer, #firstPanel button, #thirdPanel button {
margin-top: 68vh;
}
#serverInput input, #serverInput img{

View File

@ -0,0 +1,14 @@
@echo off
set GRASSCUTTER_JAR=%1
set GRASSCUTTER_JAR=%GRASSCUTTER_JAR:"=%
:: Ensure admin
>nul 2>&1 reg query "HKU\S-1-5-19" || (
set params = %*:"="""%
cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 "%1"", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && exit /B )
)
echo Starting local Grasscutter server...
start /b java -jar %GRASSCUTTER_JAR%