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

@@ -12,12 +12,14 @@ npm run admin
- `http://127.0.0.1:8787`
## 현재 1차 구현 범위
## 현재 구현 범위
- 프로필 추가 / 수정 / 삭제 / 복제
- `modpack`, `map`, `server-pack` 종류별 입력 폼
- `맵` 기본 + `모드`, `플러그인`, `서버` 체크 조합
- `distribution.json` 업로드 / 새로 만들기 / 직접 편집
- 맵 ZIP, 서버 번들 ZIP 업로드
- 월드 ZIP 업로드
- 서버용 버킷 JAR 업로드
- 서버 포트 / 메모리 / 최대 인원수 / 화이트리스트 설정
- 저장 시 아래 두 파일을 동시에 갱신
- `admin/data/catalog.json`
- `app/assets/launcher/catalog.json`
@@ -28,11 +30,8 @@ npm run admin
- `JSON 편집` 버튼으로 현재 연결된 로컬 `distribution.json` 수정 가능
- `새로 만들기` 버튼으로 샘플 템플릿에서 새 `distribution.json` 생성 가능
- 저장된 distribution 파일은 아래에 생성됩니다.
- `admin/data/distributions/`
- 접속주소 필드는 관리자 사이트에서 다루지 않습니다. 런처 내부 접속 흐름과 분리해서 프로필 자료만 관리합니다.
## 업로드 동작
업로드 버튼으로 올린 파일은 아래에 저장됩니다.
@@ -43,15 +42,14 @@ npm run admin
예:
- `admin/data/uploads/1715000000000-my-pack.zip`
이 방식은 로컬 테스트에는 바로 쓸 수 있습니다.
- `admin/data/uploads/1715000000000-paper.jar`
## 주의
- 접속 주소는 관리자 사이트에서 다루지 않습니다.
- 접속 주소는 사용자가 런처 라이브러리에서 직접 입력합니다.
- 지금 1차 버전은 로컬 운영용입니다.
- 기본 서버 바인딩은 `127.0.0.1` 이라 같은 PC에서만 접속됩니다.
- 외부에서 쓰는 공개 관리자 사이트로 만들려면 인증과 공개 URL 저장 방식을 추가해야 합니다.
## 추천 운영 방식

View File

@@ -14,36 +14,33 @@
"version": 1,
"profiles": [
{
"id": "my-modpack",
"name": "My Modpack",
"kind": "modpack",
"id": "my-map-profile",
"name": "My Map Profile",
"description": "설명",
"details": "설치 페이지 상세 패널에 표시할 긴 설명",
"distributionUrl": "admin/data/distributions/my-modpack.distribution.json"
},
{
"id": "my-map",
"name": "My Map",
"kind": "map",
"description": "싱글플레이 월드",
"details": "월드와 플레이 방식에 대한 상세 설명",
"distributionUrl": "admin/data/distributions/my-map.distribution.json",
"modsEnabled": true,
"pluginsEnabled": false,
"serverEnabled": false,
"distributionUrl": "admin/data/distributions/my-map-profile.distribution.json",
"worldArchiveUrl": "https://example.com/worlds/my-map.zip",
"worldDirectoryName": "My Map"
},
{
"id": "my-server-pack",
"name": "My Server Pack",
"kind": "server-pack",
"description": "클라이언트 + 로컬 서버 번들",
"details": "서버 실행 방법, 권장 인원, 접속 방식 등 상세 설명",
"distributionUrl": "admin/data/distributions/my-server-pack.distribution.json",
"serverBundleUrl": "https://example.com/serverpacks/my-server-pack.zip",
"serverDirectoryName": "my-server-pack",
"serverLaunchCommand": "java -jar server.jar nogui",
"id": "my-plugin-server-profile",
"name": "My Plugin Server Profile",
"description": "플러그인 서버 포함 프로필",
"details": "주소가 없으면 로컬 서버를 실행하고, 주소가 있으면 해당 서버로 접속합니다.",
"modsEnabled": false,
"pluginsEnabled": true,
"serverEnabled": true,
"distributionUrl": "admin/data/distributions/my-plugin-server-profile.distribution.json",
"worldArchiveUrl": "https://example.com/worlds/plugin-map.zip",
"worldDirectoryName": "Plugin Map",
"serverJarUrl": "https://example.com/server/paper.jar",
"serverPort": 25565,
"tunnelCommand": "playit-cli --port ${port}",
"tunnelAddressRegex": "([a-zA-Z0-9.-]+:\\d+)"
"serverMemoryMb": 4096,
"serverMaxPlayers": 20,
"serverWhitelistEnabled": false
}
]
}
@@ -53,46 +50,36 @@
- `id`: 내부 식별자
- `name`: 라이브러리/설치 페이지 표시 이름
- `kind`: `modpack`, `map`, `server-pack`
- `description`: 표시 설명
- `details`: 설치 페이지 상세 패널에 표시할 긴 설명
- `distributionUrl`: Helios distribution.json URL 또는 로컬 경로. 관리자 사이트에서 직접 만들거나 업로드 가능
- `worldArchiveUrl`: `kind: map` 일 때 사용할 월드 ZIP 또는 로컬 경로
- `worldDirectoryName`: 게임 `saves/` 아래에 설치될 월드 폴더 이름
- `serverBundleUrl`: `kind: server-pack` 일 때 사용할 서버 ZIP 또는 로컬 디렉터리/경로
- `serverDirectoryName`: 서버 번들이 풀릴 하위 디렉터리 이름
- `serverLaunchCommand`: 로컬 서버 실행 명령. 비워두면 `start.sh`, `start.bat`, `server.jar` 순으로 추론
- `serverWorkingDirectory`: 실제 실행할 작업 디렉터리. 서버 루트 기준 상대 경로
- `modsEnabled`: 모드 기능 사용 여부
- `pluginsEnabled`: 플러그인 기능 사용 여부. 켜면 서버도 같이 사용
- `serverEnabled`: 서버 기능 사용 여부
- `distributionUrl`: Helios distribution.json URL 또는 로컬 경로
- `worldArchiveUrl`: 월드 ZIP 또는 로컬 경로
- `worldDirectoryName`: 게임 `saves/` 아래와 로컬 서버 `world/`에 사용할 월드 폴더 이름
- `serverJarUrl`: 로컬 서버 실행에 사용할 버킷 JAR 경로 또는 URL
- `serverPort`: 로컬 서버 포트
- `tunnelCommand`: 선택형 터널 명령. `${port}`, `${serverDir}` 치환 가능
- `tunnelAddressRegex`: 터널 stdout 에서 공개 주소를 추출할 정규식
- `serverMemoryMb`: 로컬 서버 최대 메모리(MB)
- `serverMaxPlayers`: 로컬 서버 최대 인원수
- `serverWhitelistEnabled`: 로컬 서버 화이트리스트 사용 여부
## 런처가 계산하는 상태
아래 값들은 런처가 내부적으로 계산하는 상태라 파일에 직접 넣지 않아도 됩니다.
- `launchReady`: 실행에 필요한 필드가 모두 있는지 여부
- `hostReady`: `server-pack` 이 로컬 호스팅 가능한지 여부
- `hostReady`: 서버 기능 프로필이 로컬 호스팅 가능한지 여부
판정 기준:
- `modpack`: `distributionUrl` 필요
- `map`: `distributionUrl`, `worldArchiveUrl`, `worldDirectoryName` 필요
- `server-pack`: 클라이언트 실행은 `distributionUrl`, 로컬 호스팅은 추가로 `serverBundleUrl` 필요
- 공통 실행: `distributionUrl`, `worldArchiveUrl`, `worldDirectoryName`
- 로컬 서버 실행 추가 조건: `serverEnabled=true` 이고 `serverJarUrl` 존재
## 현재 구현 범위
- `modpack`: 지원
- `map`: 월드 ZIP 사전 다운로드, `saves/` 설치, `--quickPlaySingleplayer` 실행 지원
- `server-pack`: distribution 기반 클라이언트 + 수동 주소 입력 자동 접속 + 로컬 서버 실행 + 선택형 터널 명령 지원
## 네트워크 참고
포트포워딩 없이 외부 사용자가 접속하려면 런처 단독으로는 부족합니다.
필요한 것 중 하나:
- 별도 중계 서버
- 터널링 도구
- VPN/NAT traversal 백엔드
현재 구현은 그 중 `터널 명령 실행기`를 연결할 수 있는 자리까지만 제공합니다.
- 맵 기반 싱글플레이 실행
- 맵 + 모드 클라이언트 실행
- 서버 기능 프로필의 직접 주소 입력 접속
- 서버 기능 프로필의 로컬 버킷 JAR 실행
- 자동 포트 개방 상태 표시