코드와 산출물 jar 에는 애초에 외부 서버 주소가 없었으나(rendezvous 기본값이 빈 문자열), 설계 문서에 참고 대상의 제작자명과 저장소 경로가 남아 있었다. 기술적 관찰 사실은 설계 판단의 근거로 필요하므로 유지하되 "기존 구현" 으로 중립화했다. 더불어 이 프로젝트가 남의 인프라에 얹혀 가지 않는다는 점을 README 에 명시했다. rendezvous 는 빈 값으로 시작해 사용자가 직접 띄운 서버만 쓰며, 유일하게 남는 외부 호출인 STUN 기본값도 제거하는 방법을 함께 적었다. 검증: 작업 트리와 양쪽 산출물 jar 전수 검색 0건, 테스트 57개 전부 통과. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -15,8 +15,12 @@
|
||||
|
||||
## 2. "jar 하나로 모든 버전" 이 왜 어려운가
|
||||
|
||||
기존 P2P 모드들(참고 대상: `KITE2459/kfcudp-instant-p2p`)은 Stonecutter 로 17개 버전을
|
||||
각각 빌드한다. 게을러서가 아니라, 마인크래프트 클래스를 참조하면 그 방법밖에 없기 때문이다.
|
||||
기존에 배포되는 P2P 모드들은 Stonecutter 로 17개 버전을 각각 빌드한다. 게을러서가 아니라,
|
||||
마인크래프트 클래스를 참조하면 그 방법밖에 없기 때문이다.
|
||||
|
||||
> 이 문서에서 "기존 구현" 이라고 적은 것은 착수 전 조사 단계에서 살펴본 배포본 한 종을
|
||||
> 가리킨다. 설계 판단의 근거를 남기기 위해 관찰한 사실만 적었고, 제작자·저장소·서버 주소는
|
||||
> 적지 않는다. 코드를 가져오지 않았고 그들의 인프라에 접속하지도 않는다.
|
||||
|
||||
결정적인 단절이 2026년에 생겼다. **마인크래프트 26.1부터 코드가 비난독화되면서 Fabric 의
|
||||
Yarn/intermediary 매핑이 폐지됐다.**
|
||||
@@ -79,7 +83,7 @@ GUI 코드가 한 줄도 필요 없다.
|
||||
### 얻은 것
|
||||
|
||||
- 버전별 빌드 17개 → 1개
|
||||
- Stonecutter 조건부 주석 (참고 모드의 `RoomListScreen.java` 한 파일에만 96개) → 0개
|
||||
- Stonecutter 조건부 주석 (기존 구현은 GUI 한 파일에만 96개) → 0개
|
||||
- 믹스인 14개 → 0개. 다른 모드와 충돌할 지점도 함께 사라졌다.
|
||||
- Fabric Loom·매핑·마인크래프트 jar 다운로드 없음 → 빌드가 몇 초로 끝나고 CI 매트릭스도 1칸
|
||||
- 게임 API 를 안 건드리므로 새 마인크래프트 버전이 나와도 할 일이 없다
|
||||
@@ -105,7 +109,7 @@ GUI 코드가 한 줄도 필요 없다.
|
||||
| NAT traversal | 직접 구현 | libwebrtc 내장 (검증 충분) |
|
||||
|
||||
**순수 자바 QUIC을 선택했다.** 크기가 42배 차이 나고, 아키텍처 제약이 사라지는 것이 결정적이다.
|
||||
참고 모드의 WebRTC 빌드는 `linux-aarch64` 를 번들에서 빠뜨려서 ARM 리눅스에서 아예 실패하는데,
|
||||
기존 구현의 WebRTC 빌드는 `linux-aarch64` 를 번들에서 빠뜨려서 ARM 리눅스에서 아예 실패하는데,
|
||||
네이티브가 없으면 그런 실수를 할 여지 자체가 없다. "jar 하나로 모든 버전" 목표와도 맞는다.
|
||||
QUIC 은 암호화·혼잡제어·다중화를 프로토콜 한 겹에서 주므로 DTLS+SCTP+ICE 조합보다 얇다.
|
||||
|
||||
@@ -144,7 +148,7 @@ siphash 뿐이고 모두 순수 자바다. 클래스 파일 major 55 = Java 11
|
||||
때문이다. 최악의 대기가 600ms 인 대신 구현이 훨씬 단순하다.
|
||||
`P2PSocket.awaitPath` 에 이 판단을 적어 두었고, 갈아타기는 아래 남은 과제로 넘겼다.
|
||||
|
||||
참고 모드는 이걸 다르게 풀었다. 1차는 TURN 후보를 아예 만들지 않고, 실패하면 2차에 릴레이를
|
||||
기존 구현은 이걸 다르게 풀었다. 1차는 TURN 후보를 아예 만들지 않고, 실패하면 2차에 릴레이를
|
||||
허용해 재협상한다. 목적은 같지만 세션을 두 번 만들고, 양쪽이 같은 단계로 맞춰야 해서
|
||||
"조인자의 OFFER 재협상 횟수로 호스트가 단계를 유추" 하는 조율이 들어간다. 유예 방식은
|
||||
세션 하나로 끝난다.
|
||||
@@ -224,7 +228,7 @@ JDK 안에서 끝내면 그 변수가 사라진다.
|
||||
2. **실제 NAT 뒤에서의 홀펀칭 성공률 측정.** 같은 기기 안 테스트에는 NAT 가 없다. 대칭 NAT·
|
||||
CGNAT 비율에 따라 중계 의존도가 결정되므로 숫자를 봐야 다음 판단을 할 수 있다.
|
||||
3. **시그널링 TLS.** 지금은 평문 TCP 라 이 경로를 장악한 중간자가 인증서 지문을 바꿔칠 수
|
||||
있다. 참고 모드도 같은 약점을 갖고 있다(기본 `ws://`). TLS 를 씌우거나 초대코드에서
|
||||
있다. 기존 구현도 같은 약점을 갖고 있다(기본 `ws://`). TLS 를 씌우거나 초대코드에서
|
||||
파생한 키로 시그널링 메시지를 인증하면 된다. 후자가 서버 인증서 없이 되므로 더 맞을 수 있다.
|
||||
4. **중계 → 직결 승격.** 4절에서 미룬 것. 중계로 먼저 붙여 대기를 0 으로 만들고, 홀펀칭이
|
||||
성공하면 조용히 갈아탄다. QUIC 의 연결 마이그레이션(CID 유지)을 쓰면 재핸드셰이크 없이
|
||||
@@ -254,4 +258,8 @@ JDK 안에서 끝내면 그 변수가 사라진다.
|
||||
- [NAT Traversal — iroh](https://docs.iroh.computer/concepts/nat-traversal) — 중계 우선 + 직결 승격, 성공률
|
||||
- [How Tailscale is improving NAT traversal](https://tailscale.com/blog/nat-traversal-improvements-pt-1) — DERP 폴백 모델
|
||||
- [Kwik](https://github.com/ptrd/kwik) — 순수 자바 QUIC
|
||||
- 참고 구현: `KITE2459/kfcudp-instant-p2p` (CC0) — 문제 정의와 UX 를 참고했다. 코드는 가져오지 않았다.
|
||||
|
||||
이 목록 외에, 착수 전 조사 단계에서 배포 중인 P2P 모드 한 종을 분석해 문제 정의와 UX 를
|
||||
참고했다. 본문에서 "기존 구현" 이라고 쓴 것이 그것이다. 제작자·저장소·서버 주소는 의도적으로
|
||||
적지 않는다. 코드를 가져오지 않았고, 그들의 시그널링·STUN·TURN 서버를 쓰지도 않는다 —
|
||||
이 프로젝트는 사용자가 직접 띄운 서버만 사용한다(README 의 시그널링 서버 항목 참고).
|
||||
|
||||
Reference in New Issue
Block a user