Refactor launcher profiles and port automation
This commit is contained in:
@@ -16,42 +16,97 @@ function normalizeNullableText(value){
|
||||
return nextValue.length > 0 ? nextValue : null
|
||||
}
|
||||
|
||||
function normalizeBoolean(value){
|
||||
return value === true
|
||||
}
|
||||
|
||||
function normalizePositiveInteger(value, fallback, minimum = 1){
|
||||
const parsed = Number.parseInt(String(value ?? ''), 10)
|
||||
if(Number.isFinite(parsed) && parsed >= minimum){
|
||||
return parsed
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
function deriveFeatureFlags(rawProfile){
|
||||
const legacyKind = normalizeText(rawProfile?.kind)
|
||||
|
||||
let modsEnabled = normalizeBoolean(rawProfile?.modsEnabled)
|
||||
let pluginsEnabled = normalizeBoolean(rawProfile?.pluginsEnabled)
|
||||
let serverEnabled = normalizeBoolean(rawProfile?.serverEnabled)
|
||||
|
||||
if(legacyKind === 'modpack'){
|
||||
modsEnabled = true
|
||||
} else if(legacyKind === 'server-pack'){
|
||||
pluginsEnabled = true
|
||||
serverEnabled = true
|
||||
}
|
||||
|
||||
if(pluginsEnabled){
|
||||
serverEnabled = true
|
||||
}
|
||||
|
||||
return {
|
||||
modsEnabled,
|
||||
pluginsEnabled,
|
||||
serverEnabled
|
||||
}
|
||||
}
|
||||
|
||||
function deriveLegacyKind(flags){
|
||||
if(flags.serverEnabled){
|
||||
return 'server-pack'
|
||||
}
|
||||
if(flags.modsEnabled){
|
||||
return 'modpack'
|
||||
}
|
||||
return 'map'
|
||||
}
|
||||
|
||||
function resolveLegacyServerJar(rawProfile){
|
||||
const directValue = normalizeNullableText(rawProfile?.serverJarUrl)
|
||||
if(directValue != null){
|
||||
return directValue
|
||||
}
|
||||
|
||||
const legacyBundle = normalizeNullableText(rawProfile?.serverBundleUrl)
|
||||
if(legacyBundle != null && legacyBundle.toLowerCase().endsWith('.jar')){
|
||||
return legacyBundle
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function toStoredProfile(rawProfile){
|
||||
const kind = normalizeText(rawProfile.kind) || 'modpack'
|
||||
const flags = deriveFeatureFlags(rawProfile)
|
||||
const storedProfile = {
|
||||
id: normalizeText(rawProfile.id),
|
||||
name: normalizeText(rawProfile.name),
|
||||
kind,
|
||||
kind: deriveLegacyKind(flags),
|
||||
description: normalizeText(rawProfile.description),
|
||||
details: normalizeText(rawProfile.details),
|
||||
distributionUrl: normalizeNullableText(rawProfile.distributionUrl),
|
||||
defaultServerAddress: normalizeText(rawProfile.defaultServerAddress),
|
||||
allowCustomServerAddress: rawProfile.allowCustomServerAddress === true,
|
||||
modsEnabled: flags.modsEnabled,
|
||||
pluginsEnabled: flags.pluginsEnabled,
|
||||
serverEnabled: flags.serverEnabled,
|
||||
worldArchiveUrl: normalizeNullableText(rawProfile.worldArchiveUrl),
|
||||
worldDirectoryName: normalizeNullableText(rawProfile.worldDirectoryName),
|
||||
serverBundleUrl: normalizeNullableText(rawProfile.serverBundleUrl),
|
||||
serverJarUrl: resolveLegacyServerJar(rawProfile),
|
||||
serverDirectoryName: normalizeText(rawProfile.serverDirectoryName) || 'server',
|
||||
serverLaunchCommand: normalizeNullableText(rawProfile.serverLaunchCommand),
|
||||
serverWorkingDirectory: normalizeNullableText(rawProfile.serverWorkingDirectory),
|
||||
serverPort: Number.isFinite(Number(rawProfile.serverPort)) ? Number(rawProfile.serverPort) : 25565,
|
||||
tunnelCommand: normalizeNullableText(rawProfile.tunnelCommand),
|
||||
tunnelAddressRegex: normalizeNullableText(rawProfile.tunnelAddressRegex),
|
||||
serverMemoryMb: normalizePositiveInteger(rawProfile.serverMemoryMb, 4096, 512),
|
||||
serverMaxPlayers: normalizePositiveInteger(rawProfile.serverMaxPlayers, 20, 1),
|
||||
serverWhitelistEnabled: normalizeBoolean(rawProfile.serverWhitelistEnabled),
|
||||
artwork: normalizeText(rawProfile.artwork)
|
||||
}
|
||||
|
||||
if(kind !== 'map'){
|
||||
storedProfile.worldArchiveUrl = null
|
||||
storedProfile.worldDirectoryName = null
|
||||
}
|
||||
|
||||
if(kind !== 'server-pack'){
|
||||
storedProfile.serverBundleUrl = null
|
||||
if(!storedProfile.serverEnabled){
|
||||
storedProfile.serverJarUrl = null
|
||||
storedProfile.serverDirectoryName = 'server'
|
||||
storedProfile.serverLaunchCommand = null
|
||||
storedProfile.serverWorkingDirectory = null
|
||||
storedProfile.serverPort = 25565
|
||||
storedProfile.tunnelCommand = null
|
||||
storedProfile.tunnelAddressRegex = null
|
||||
storedProfile.serverMemoryMb = 4096
|
||||
storedProfile.serverMaxPlayers = 20
|
||||
storedProfile.serverWhitelistEnabled = false
|
||||
}
|
||||
|
||||
return storedProfile
|
||||
@@ -66,21 +121,19 @@ function normalizeProfile(rawProfile, sourceType = 'catalog'){
|
||||
launchIssues.push('distribution URL이 필요합니다.')
|
||||
}
|
||||
|
||||
if(storedProfile.kind === 'map'){
|
||||
if(storedProfile.worldArchiveUrl == null){
|
||||
launchIssues.push('맵 ZIP 또는 로컬 월드 경로가 필요합니다.')
|
||||
}
|
||||
if(storedProfile.worldDirectoryName == null){
|
||||
launchIssues.push('월드 폴더 이름이 필요합니다.')
|
||||
}
|
||||
if(storedProfile.worldArchiveUrl == null){
|
||||
launchIssues.push('맵 ZIP 또는 로컬 월드 경로가 필요합니다.')
|
||||
}
|
||||
if(storedProfile.worldDirectoryName == null){
|
||||
launchIssues.push('월드 폴더 이름이 필요합니다.')
|
||||
}
|
||||
|
||||
if(storedProfile.kind === 'server-pack' && storedProfile.serverBundleUrl == null){
|
||||
hostIssues.push('로컬 호스팅을 하려면 서버 번들 ZIP 또는 디렉터리 경로가 필요합니다.')
|
||||
if(storedProfile.serverEnabled && storedProfile.serverJarUrl == null){
|
||||
hostIssues.push('로컬 서버를 시작하려면 버킷 JAR 업로드가 필요합니다.')
|
||||
}
|
||||
|
||||
const launchReady = launchIssues.length === 0
|
||||
const hostReady = storedProfile.kind === 'server-pack' ? hostIssues.length === 0 : false
|
||||
const hostReady = storedProfile.serverEnabled ? hostIssues.length === 0 : false
|
||||
|
||||
return {
|
||||
...storedProfile,
|
||||
@@ -147,7 +200,7 @@ exports.getInstalledProfiles = async function(){
|
||||
const catalog = await exports.loadCatalog()
|
||||
const installedProfiles = ConfigManager.getInstalledLibraryProfiles()
|
||||
|
||||
return installedProfiles.map((installedProfile) => {
|
||||
const mergedProfiles = installedProfiles.map((installedProfile) => {
|
||||
const latestProfile = catalog.profiles.find((profile) => profile.id === installedProfile.id)
|
||||
return latestProfile != null
|
||||
? {
|
||||
@@ -157,6 +210,11 @@ exports.getInstalledProfiles = async function(){
|
||||
}
|
||||
: installedProfile
|
||||
})
|
||||
|
||||
ConfigManager.setInstalledLibraryProfiles(mergedProfiles)
|
||||
ConfigManager.save()
|
||||
|
||||
return mergedProfiles
|
||||
}
|
||||
|
||||
exports.installProfile = async function(profileId){
|
||||
@@ -214,10 +272,6 @@ exports.resolveServerAddress = function(profile){
|
||||
return manualAddress
|
||||
}
|
||||
|
||||
if(typeof profile.defaultServerAddress === 'string' && profile.defaultServerAddress.length > 0){
|
||||
return profile.defaultServerAddress
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -226,6 +280,14 @@ exports.setServerAddressOverride = function(profileId, address){
|
||||
ConfigManager.save()
|
||||
}
|
||||
|
||||
exports.shouldHostLocally = function(profile){
|
||||
if(profile == null || profile.serverEnabled !== true){
|
||||
return false
|
||||
}
|
||||
|
||||
return exports.resolveServerAddress(profile) == null
|
||||
}
|
||||
|
||||
exports.applyConfiguredProfile = function(){
|
||||
const selectedProfile = exports.getSelectedProfileSync()
|
||||
const distributionUrl = selectedProfile?.distributionUrl ?? DEFAULT_REMOTE_DISTRO_URL
|
||||
|
||||
Reference in New Issue
Block a user