Refactor launcher profiles and port automation
Some checks failed
Build / release (macos-latest) (push) Has been cancelled
Build / release (ubuntu-latest) (push) Has been cancelled
Build / release (windows-latest) (push) Has been cancelled
Windows Smoke Test / windows-smoke (push) Has been cancelled

This commit is contained in:
2026-05-05 21:52:17 +09:00
parent e266387784
commit 9786cfe031
22 changed files with 1558 additions and 798 deletions

View File

@@ -14,8 +14,6 @@ const LAUNCHER_CATALOG_PATH = path.join(PROJECT_ROOT, 'app', 'assets', 'launcher
const PUBLIC_DIR = path.join(__dirname, 'public')
const SAMPLE_DISTRIBUTION_PATH = path.join(PROJECT_ROOT, 'docs', 'sample_distribution.json')
const PROFILE_KINDS = new Set(['modpack', 'map', 'server-pack'])
function normalizeText(value){
return typeof value === 'string' ? value.trim() : ''
}
@@ -34,6 +32,18 @@ function normalizePort(value){
return 25565
}
function normalizePositiveInteger(value, fallback, minimum = 1){
const parsed = Number.parseInt(String(value ?? ''), 10)
if(Number.isFinite(parsed) && parsed >= minimum){
return parsed
}
return fallback
}
function normalizeBoolean(value){
return value === true
}
function resolveSafeProjectPath(relativePath){
const resolvedPath = path.resolve(PROJECT_ROOT, relativePath)
if(!resolvedPath.startsWith(PROJECT_ROOT + path.sep) && resolvedPath !== PROJECT_ROOT){
@@ -53,30 +63,72 @@ function createDistributionFileName(profileId){
return `${safeId.length > 0 ? safeId : 'distribution'}.distribution.json`
}
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 normalizeServerJarSource(rawProfile){
const directValue = normalizeText(rawProfile?.serverJarUrl)
if(directValue.length > 0){
return directValue
}
const legacyBundle = normalizeText(rawProfile?.serverBundleUrl)
if(legacyBundle.toLowerCase().endsWith('.jar')){
return legacyBundle
}
return ''
}
function sanitizeProfile(rawProfile, index){
const kind = PROFILE_KINDS.has(rawProfile?.kind) ? rawProfile.kind : 'modpack'
const {
modsEnabled,
pluginsEnabled,
serverEnabled
} = deriveFeatureFlags(rawProfile)
const sanitized = {
id: normalizeText(rawProfile?.id) || `profile-${index + 1}`,
name: normalizeText(rawProfile?.name) || `새 프로필 ${index + 1}`,
kind,
description: normalizeText(rawProfile?.description),
details: normalizeMultilineText(rawProfile?.details),
distributionUrl: normalizeText(rawProfile?.distributionUrl)
distributionUrl: normalizeText(rawProfile?.distributionUrl),
modsEnabled,
pluginsEnabled,
serverEnabled,
worldArchiveUrl: normalizeText(rawProfile?.worldArchiveUrl),
worldDirectoryName: normalizeText(rawProfile?.worldDirectoryName)
}
if(kind === 'map'){
sanitized.worldArchiveUrl = normalizeText(rawProfile?.worldArchiveUrl)
sanitized.worldDirectoryName = normalizeText(rawProfile?.worldDirectoryName)
}
if(kind === 'server-pack'){
sanitized.serverBundleUrl = normalizeText(rawProfile?.serverBundleUrl)
if(serverEnabled){
sanitized.serverJarUrl = normalizeServerJarSource(rawProfile)
sanitized.serverDirectoryName = normalizeText(rawProfile?.serverDirectoryName) || `${sanitized.id}-server`
sanitized.serverLaunchCommand = normalizeText(rawProfile?.serverLaunchCommand)
sanitized.serverWorkingDirectory = normalizeText(rawProfile?.serverWorkingDirectory)
sanitized.serverPort = normalizePort(rawProfile?.serverPort)
sanitized.tunnelCommand = normalizeText(rawProfile?.tunnelCommand)
sanitized.tunnelAddressRegex = normalizeText(rawProfile?.tunnelAddressRegex)
sanitized.serverMemoryMb = normalizePositiveInteger(rawProfile?.serverMemoryMb, 4096, 512)
sanitized.serverMaxPlayers = normalizePositiveInteger(rawProfile?.serverMaxPlayers, 20, 1)
sanitized.serverWhitelistEnabled = normalizeBoolean(rawProfile?.serverWhitelistEnabled)
}
if(normalizeText(rawProfile?.artwork).length > 0){