Refactor launcher profiles and port automation
This commit is contained in:
@@ -5,8 +5,7 @@
|
||||
// Requirements
|
||||
const { URL } = require('url')
|
||||
const {
|
||||
MojangRestAPI,
|
||||
getServerStatus
|
||||
MojangRestAPI
|
||||
} = require('helios-core/mojang')
|
||||
const {
|
||||
RestResponseStatus,
|
||||
@@ -32,7 +31,9 @@ const {
|
||||
const AuthManager = require('./assets/js/authmanager')
|
||||
const CatalogManager = require('./assets/js/catalogmanager')
|
||||
const DiscordWrapper = require('./assets/js/discordwrapper')
|
||||
const PortManager = require('./assets/js/portmanager')
|
||||
const ProcessBuilder = require('./assets/js/processbuilder')
|
||||
const ServerRuntime = require('./assets/js/serverruntime')
|
||||
|
||||
// Launch Elements
|
||||
const launch_content = document.getElementById('launch_content')
|
||||
@@ -47,6 +48,7 @@ const avatarContainer = document.getElementById('avatarContainer')
|
||||
const accountMenu = document.getElementById('accountMenu')
|
||||
const accountMenuName = document.getElementById('accountMenuName')
|
||||
const accountMenuLogoutButton = document.getElementById('accountMenuLogoutButton')
|
||||
const portStatusTooltip = document.getElementById('portStatusTooltip')
|
||||
|
||||
const loggerLanding = LoggerUtil.getLogger('Landing')
|
||||
|
||||
@@ -188,7 +190,7 @@ function refreshSelectedProfileButton(){
|
||||
}
|
||||
|
||||
function isSelectedMapReady(profile){
|
||||
if(profile == null || profile.kind !== 'map'){
|
||||
if(profile == null || profile.serverEnabled === true){
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -200,6 +202,24 @@ function isSelectedMapReady(profile){
|
||||
)
|
||||
}
|
||||
|
||||
function updateLandingStatusDisplay(label, value, tone, tooltip, fade = false){
|
||||
const applyValues = () => {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = label
|
||||
document.getElementById('player_count').innerHTML = value
|
||||
document.getElementById('player_count').dataset.tone = tone
|
||||
portStatusTooltip.textContent = tooltip
|
||||
}
|
||||
|
||||
if(fade){
|
||||
$('#server_status_wrapper').fadeOut(250, () => {
|
||||
applyValues()
|
||||
$('#server_status_wrapper').fadeIn(500)
|
||||
})
|
||||
} else {
|
||||
applyValues()
|
||||
}
|
||||
}
|
||||
|
||||
// Bind launch button
|
||||
document.getElementById('launch_button').addEventListener('click', async e => {
|
||||
loggerLanding.info('Launching game..')
|
||||
@@ -394,70 +414,45 @@ const refreshServerStatus = async (fade = false) => {
|
||||
|
||||
let pLabel = Lang.queryJS('landing.profileStatus.label')
|
||||
let pVal = Lang.queryJS('landing.selectedProfile.noSelection')
|
||||
let pTone = 'info'
|
||||
let tooltip = '라이브러리에서 실행할 프로필을 먼저 선택하세요.'
|
||||
|
||||
if(selectedProfile == null){
|
||||
if(fade){
|
||||
$('#server_status_wrapper').fadeOut(250, () => {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = pLabel
|
||||
document.getElementById('player_count').innerHTML = pVal
|
||||
$('#server_status_wrapper').fadeIn(500)
|
||||
})
|
||||
} else {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = pLabel
|
||||
document.getElementById('player_count').innerHTML = pVal
|
||||
}
|
||||
updateLandingStatusDisplay(pLabel, pVal, pTone, tooltip, fade)
|
||||
return
|
||||
}
|
||||
|
||||
if(selectedProfile.kind === 'map'){
|
||||
if(selectedProfile.serverEnabled !== true){
|
||||
pLabel = Lang.queryJS('landing.mapStatus.label')
|
||||
pVal = isSelectedMapReady(selectedProfile)
|
||||
? Lang.queryJS('landing.mapStatus.ready')
|
||||
: Lang.queryJS('landing.mapStatus.notReady')
|
||||
|
||||
if(fade){
|
||||
$('#server_status_wrapper').fadeOut(250, () => {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = pLabel
|
||||
document.getElementById('player_count').innerHTML = pVal
|
||||
$('#server_status_wrapper').fadeIn(500)
|
||||
})
|
||||
} else {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = pLabel
|
||||
document.getElementById('player_count').innerHTML = pVal
|
||||
}
|
||||
pTone = selectedProfile.launchReady ? 'success' : 'error'
|
||||
tooltip = selectedProfile.launchReady
|
||||
? '이 프로필은 맵 실행 준비가 끝났습니다.'
|
||||
: (selectedProfile.launchIssues?.join(' / ') || '맵 실행 준비가 아직 끝나지 않았습니다.')
|
||||
updateLandingStatusDisplay(pLabel, pVal, pTone, tooltip, fade)
|
||||
return
|
||||
}
|
||||
|
||||
pLabel = Lang.queryJS('landing.serverStatus.server')
|
||||
pVal = Lang.queryJS('landing.serverStatus.offline')
|
||||
|
||||
try {
|
||||
const distro = await DistroAPI.getDistribution()
|
||||
const serv = distro?.getServerById(ConfigManager.getSelectedServer())
|
||||
?? (typeof distro?.getMainServer === 'function' ? distro.getMainServer() : null)
|
||||
if(serv == null){
|
||||
throw new Error('No server available for selected profile.')
|
||||
}
|
||||
|
||||
const servStat = await getServerStatus(47, serv.hostname, serv.port)
|
||||
pLabel = Lang.queryJS('landing.serverStatus.players')
|
||||
pVal = servStat.players.online + '/' + servStat.players.max
|
||||
|
||||
pLabel = Lang.queryJS('landing.portStatus.label')
|
||||
const portState = await PortManager.ensurePortAvailability(selectedProfile)
|
||||
pVal = portState.summary
|
||||
pTone = portState.tone
|
||||
tooltip = selectedProfile.hostIssues?.length > 0
|
||||
? `${portState.message} / ${selectedProfile.hostIssues.join(' / ')}`
|
||||
: portState.message
|
||||
} catch (err) {
|
||||
loggerLanding.warn('Unable to refresh server status, assuming offline.')
|
||||
loggerLanding.warn('Unable to refresh port status.')
|
||||
loggerLanding.debug(err)
|
||||
pLabel = Lang.queryJS('landing.portStatus.label')
|
||||
pVal = Lang.queryJS('landing.portStatus.failed')
|
||||
pTone = 'error'
|
||||
tooltip = err instanceof Error ? err.message : '자동 포트 개방 상태를 확인하지 못했습니다.'
|
||||
}
|
||||
if(fade){
|
||||
$('#server_status_wrapper').fadeOut(250, () => {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = pLabel
|
||||
document.getElementById('player_count').innerHTML = pVal
|
||||
$('#server_status_wrapper').fadeIn(500)
|
||||
})
|
||||
} else {
|
||||
document.getElementById('landingPlayerLabel').innerHTML = pLabel
|
||||
document.getElementById('player_count').innerHTML = pVal
|
||||
}
|
||||
|
||||
|
||||
updateLandingStatusDisplay(pLabel, pVal, pTone, tooltip, fade)
|
||||
}
|
||||
|
||||
refreshMojangStatuses()
|
||||
@@ -468,6 +463,10 @@ let mojangStatusListener = setInterval(() => refreshMojangStatuses(true), 60*60*
|
||||
// Set refresh rate to once every 5 minutes.
|
||||
let serverStatusListener = setInterval(() => refreshServerStatus(true), 300000)
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
PortManager.cleanupAll().catch(() => {})
|
||||
})
|
||||
|
||||
/**
|
||||
* Shows an error overlay, toggles off the launch area.
|
||||
*
|
||||
@@ -747,10 +746,34 @@ async function dlAsync(login = true) {
|
||||
|
||||
if(login) {
|
||||
const authUser = ConfigManager.getSelectedAccount()
|
||||
const selectedProfile = CatalogManager.getSelectedProfileSync()
|
||||
loggerLaunchSuite.info(`Sending selected account (${authUser.displayName}) to ProcessBuilder.`)
|
||||
let pb = new ProcessBuilder(serv, versionData, modLoaderData, authUser, remote.app.getVersion())
|
||||
setLaunchDetails(Lang.queryJS('landing.dlAsync.launchingGame'))
|
||||
|
||||
if(selectedProfile?.serverEnabled === true && CatalogManager.shouldHostLocally(selectedProfile)){
|
||||
if(!selectedProfile.hostReady){
|
||||
showLaunchFailure(
|
||||
Lang.queryJS('landing.localServer.missingJarTitle'),
|
||||
Lang.queryJS('landing.localServer.missingJarText')
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
setLaunchDetails(Lang.queryJS('landing.localServer.starting'))
|
||||
try {
|
||||
await ServerRuntime.startHostedProfile(selectedProfile)
|
||||
refreshServerStatus(true)
|
||||
} catch (error) {
|
||||
loggerLaunchSuite.error('Failed to start local server.', error)
|
||||
showLaunchFailure(
|
||||
Lang.queryJS('landing.localServer.failureTitle'),
|
||||
error instanceof Error ? error.message : Lang.queryJS('landing.localServer.failureText')
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// const SERVER_JOINED_REGEX = /\[.+\]: \[CHAT\] [a-zA-Z0-9_]{1,16} joined the game/
|
||||
const SERVER_JOINED_REGEX = new RegExp(`\\[.+\\]: \\[CHAT\\] ${authUser.displayName} joined the game`)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user