From 75c4242365f66d6dea9f43dc50cf28c9d7dfd599 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Sat, 23 May 2026 17:10:49 +0900 Subject: [PATCH] feat: send Login Disconnect with custom message on blocked join Previously a blocked join just dropped the socket, so the MC client showed 'Internal Exception: SocketException: Connection reset'. Now when next_state=2 (login), the proxy sends a proper Login Disconnect (0x00) packet containing a JSON chat component, and the client displays the message on its disconnect screen. - block_message added to config (default Korean message); editable in Settings UI as a textarea - build_login_disconnect() encodes (varint length)+(0x00)+(JSON str) - Status/ping (next_state=1) still silently dropped so the proxy presence is not announced to scanners - Backward-compat: load_config() backfills block_message on old files --- README.md | 2 +- api/config_io.py | 7 +++++- api/routes/config.py | 1 + frontend/src/pages/Settings.jsx | 17 +++++++++++++ frontend/src/styles.css | 12 +++++++-- proxy/config.py | 1 + proxy/main.py | 43 +++++++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1746c5c..d1e46d7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## 기능 - 마인크래프트 핸드셰이크 패킷에서 클라이언트가 입력한 server address 파싱 -- 허용 도메인 화이트리스트 매칭, 불일치 시 즉시 연결 종료 +- 허용 도메인 화이트리스트 매칭, 불일치 시 Login Disconnect 패킷으로 차단 사유(커스텀 가능) 표시 후 연결 종료 - 통과한 연결은 백엔드 MC 서버로 투명 TCP 중계 (Fabric / Paper / Spigot / NeoForge 등 서버 종류 무관) - 설정 파일(`data/config.json`) 변경을 프록시가 자동 감지해 hot reload (재시작 불필요) diff --git a/api/config_io.py b/api/config_io.py index 07593a8..87b5551 100644 --- a/api/config_io.py +++ b/api/config_io.py @@ -21,6 +21,7 @@ DEFAULT_CONFIG = { "allowed_domains": [ {"domain": "mc.tkrmagid.kr", "enabled": True, "note": "메인 도메인"} ], + "block_message": "이 서버는 허용된 도메인에서만 접속 가능합니다.", } _lock = threading.Lock() @@ -33,7 +34,11 @@ def load_config() -> dict: return json.loads(json.dumps(DEFAULT_CONFIG)) with _lock: with CONFIG_PATH.open("r", encoding="utf-8") as f: - return json.load(f) + cfg = json.load(f) + # 구버전 설정 파일 호환: 누락된 최상위 키는 기본값으로 채워준다 + if "block_message" not in cfg: + cfg["block_message"] = DEFAULT_CONFIG["block_message"] + return cfg def save_config(cfg: dict) -> None: diff --git a/api/routes/config.py b/api/routes/config.py index d640e3f..c563f53 100644 --- a/api/routes/config.py +++ b/api/routes/config.py @@ -29,6 +29,7 @@ class FullConfig(BaseModel): proxy: ProxyConfig backend: BackendConfig allowed_domains: list[DomainEntry] + block_message: str = "이 서버는 허용된 도메인에서만 접속 가능합니다." @router.get("/config") diff --git a/frontend/src/pages/Settings.jsx b/frontend/src/pages/Settings.jsx index af47c56..ca52695 100644 --- a/frontend/src/pages/Settings.jsx +++ b/frontend/src/pages/Settings.jsx @@ -51,6 +51,23 @@ export default function Settings() { 프록시 활성화 +
+

차단 메시지

+