docs: 참고 대상의 제작자·저장소·서버 주소를 문서에서 제거
Some checks failed
build / build (push) Has been cancelled

코드와 산출물 jar 에는 애초에 외부 서버 주소가 없었으나(rendezvous 기본값이
빈 문자열), 설계 문서에 참고 대상의 제작자명과 저장소 경로가 남아 있었다.
기술적 관찰 사실은 설계 판단의 근거로 필요하므로 유지하되 "기존 구현" 으로
중립화했다.

더불어 이 프로젝트가 남의 인프라에 얹혀 가지 않는다는 점을 README 에 명시했다.
rendezvous 는 빈 값으로 시작해 사용자가 직접 띄운 서버만 쓰며, 유일하게 남는
외부 호출인 STUN 기본값도 제거하는 방법을 함께 적었다.

검증: 작업 트리와 양쪽 산출물 jar 전수 검색 0건, 테스트 57개 전부 통과.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-09-28 11:33:14 +09:00
parent bacc2e91d3
commit 40b8894a98
2 changed files with 27 additions and 7 deletions

View File

@@ -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 의 시그널링 서버 항목 참고).