From 40b8894a982369bb63b94601fe483bf478d48072 Mon Sep 17 00:00:00 2001 From: EJClaw Date: Mon, 28 Sep 2026 11:33:14 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=EC=B0=B8=EA=B3=A0=20=EB=8C=80=EC=83=81?= =?UTF-8?q?=EC=9D=98=20=EC=A0=9C=EC=9E=91=EC=9E=90=C2=B7=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EC=86=8C=C2=B7=EC=84=9C=EB=B2=84=20=EC=A3=BC=EC=86=8C=EB=A5=BC?= =?UTF-8?q?=20=EB=AC=B8=EC=84=9C=EC=97=90=EC=84=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 코드와 산출물 jar 에는 애초에 외부 서버 주소가 없었으나(rendezvous 기본값이 빈 문자열), 설계 문서에 참고 대상의 제작자명과 저장소 경로가 남아 있었다. 기술적 관찰 사실은 설계 판단의 근거로 필요하므로 유지하되 "기존 구현" 으로 중립화했다. 더불어 이 프로젝트가 남의 인프라에 얹혀 가지 않는다는 점을 README 에 명시했다. rendezvous 는 빈 값으로 시작해 사용자가 직접 띄운 서버만 쓰며, 유일하게 남는 외부 호출인 STUN 기본값도 제거하는 방법을 함께 적었다. 검증: 작업 트리와 양쪽 산출물 jar 전수 검색 0건, 테스트 57개 전부 통과. Co-Authored-By: Claude Opus 4.7 --- README.md | 12 ++++++++++++ docs/DESIGN.md | 22 +++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0552aa6..6a85397 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,18 @@ java -jar mc_p2p_mod-<버전>-rendezvous.jar 25580 40000-40100 서버를 띄웠으면 게임에서 `http://127.0.0.1:25585` 를 열고 주소를 넣고 저장한다. 예: `p2p.example.com:25580` +### 외부 서버를 쓰지 않는다 + +이 모드에는 **다른 사람의 시그널링·중계 서버 주소가 기본값으로 들어 있지 않다.** `rendezvous` +는 비어 있는 상태로 시작하고, 사용자가 직접 띄운 서버를 넣어야 비로소 동작한다. 남의 인프라에 +얹혀 가는 구성을 아예 만들 수 없게 한 것이다. + +남는 외부 호출은 `stun` 기본값 하나뿐이다(`stun.l.google.com:19302`). 공인 주소를 알아내는 데만 +쓰이고 게임 트래픽은 지나가지 않는다. 그래도 완전히 없애고 싶으면 두 가지 방법이 있다. + +- 같은 공유기 안에서만 쓸 거라면 `stun` 을 빈 값으로 둔다. 외부 호출이 0 이 된다. +- 인터넷을 넘어야 하면 직접 띄운 STUN 서버(coturn 등)를 적는다. + --- ## 방 만들기 (호스트) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 4a472c3..f7b1c18 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -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 의 시그널링 서버 항목 참고).