Files
ykxmz/_build/patch_watch_relay.py
T
xmz7891 b705216e4a ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞
- 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀?
鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException
- 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴?
鏈嶅姟鍣ㄧ
- 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級
- 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯
- 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺?
鏂囨。
- 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
2026-10-06 19:01:05 +08:00

232 lines
8.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""让 RemoteClient 支持中转(跨网络)。
改动很小,因为把"怎么传字节"抽成了 Transport:
SocketTransport —— 原来的局域网直连
RelayTransport —— 走中转服务器
RemoteClient 里协议相关的代码(readLoop / call / awaitReply / send)
一行都不用动。
新增 connectViaRelay(baseUrl, code, token, listener, timeout):
和原有 connect(host, port, ...) 走同一套握手流程。
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
CLIENT = ROOT / "android" / "src" / "com" / "lanremote" / "watch" / "RemoteClient.java"
JSON = ROOT / "android" / "src" / "com" / "lanremote" / "watch" / "Json.java"
# ---------------- 1. Json.escape ----------------
JSON_ANCHOR = " public static String write(Object value) {"
JSON_NEW = ''' /**
* 把字符串转义成能安全塞进 JSON 字符串字面量的形式。
* 只处理引号、反斜杠和控制字符 —— 中文不用转,JSON 本身是 UTF-8。
*/
public static String escape(String text) {
if (text == null) {
return "";
}
StringBuilder out = new StringBuilder(text.length() + 16);
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
switch (ch) {
case '"':
out.append("\\\\\\"");
break;
case '\\\\':
out.append("\\\\\\\\");
break;
case '\\n':
out.append("\\\\n");
break;
case '\\r':
out.append("\\\\r");
break;
case '\\t':
out.append("\\\\t");
break;
default:
if (ch < 0x20) {
out.append(String.format("\\\\u%04x", (int) ch));
} else {
out.append(ch);
}
break;
}
}
return out.toString();
}
''' + JSON_ANCHOR
# ---------------- 2. RemoteClient ----------------
FIELD_OLD = ''' private Socket socket;
private BufferedReader reader;'''
FIELD_NEW = ''' /**
* 传输层。局域网直连时是 SocketTransport,跨网络时是 RelayTransport。
* 抽出来之后协议逻辑完全不用管数据是走 TCP 还是走中转的 HTTPS。
*/
private Transport transport;
private BufferedReader reader;'''
CONNECTED_OLD = ''' public boolean isConnected() {
return running && socket != null && !socket.isClosed();
}'''
CONNECTED_NEW = ''' public boolean isConnected() {
return running && transport != null && !transport.isClosed();
}
/** 当前传输方式的描述,界面上用来显示"直连"还是"经中转"。 */
public String transportName() {
if (transport == null) {
return "";
}
return transport instanceof RelayTransport ? "中转" : "直连";
}
public RelayTransport relayTransport() {
return transport instanceof RelayTransport
? (RelayTransport) transport : null;
}'''
CONNECT_OLD = ''' Socket sock = new Socket();
sock.connect(new InetSocketAddress(host, port), timeoutMs);
sock.setSoTimeout(0);
sock.setTcpNoDelay(true);
this.socket = sock;
this.reader = new BufferedReader(new InputStreamReader(sock.getInputStream(), UTF8), 8192);
this.writer = sock.getOutputStream();
Thread thread = new Thread(new Runnable() {'''
CONNECT_NEW = ''' Socket sock = new Socket();
sock.connect(new InetSocketAddress(host, port), timeoutMs);
sock.setSoTimeout(0);
sock.setTcpNoDelay(true);
return startTransport(new Transport.SocketTransport(sock), code, token,
listener, timeoutMs);
}
/**
* 经中转服务器连接(跨网络)。
*
* 手表没法直连电脑(两边都在 NAT 后面),所以两边都主动连出去,
* 由中转按配对码把两条连接对上。中转只转发字节、不认识协议内容,
* 所以电脑那边的配对和令牌校验照样生效。
*/
public Map<String, Object> connectViaRelay(String baseUrl, String code,
String token, Listener listener,
int timeoutMs) throws IOException {
close();
RelayTransport relay = new RelayTransport(baseUrl, code, deviceName);
if (!relay.attach()) {
String reason = relay.getLastError();
relay.close();
throw new IOException(reason == null || reason.isEmpty()
? "连不上中转服务器" : reason);
}
return startTransport(relay, code, token, listener, timeoutMs);
}
/** 握手 + 起读取线程。局域网和中转共用这一段。 */
private Map<String, Object> startTransport(Transport channel, String code,
String token, Listener listener,
int timeoutMs) throws IOException {
this.listener = listener;
this.running = true;
this.replies.clear();
this.transport = channel;
this.reader = new BufferedReader(
new InputStreamReader(channel.input(), UTF8), 8192);
this.writer = channel.output();
Thread thread = new Thread(new Runnable() {'''
CLOSE_OLD = ''' public void close() {
running = false;
try {
if (socket != null) {
socket.close();
}
} catch (IOException ignored) {
// 关闭时的异常无需处理
}
socket = null;
reader = null;
writer = null;
replies.clear();
}'''
CLOSE_NEW = ''' public void close() {
running = false;
try {
if (transport != null) {
transport.close();
}
} catch (Exception ignored) {
// 关闭时的异常无需处理
}
transport = null;
reader = null;
writer = null;
replies.clear();
}'''
def main() -> int:
ok = True
# ---- Json.escape ----
text = JSON.read_text(encoding="utf-8")
if "public static String escape(" in text:
print(" Json.escape 已存在")
elif JSON_ANCHOR not in text:
print(" [失败] Json 锚点没找到")
ok = False
else:
text = text.replace(JSON_ANCHOR, JSON_NEW, 1)
JSON.write_text(text, encoding="utf-8")
print(" Json.escape 已加")
# ---- RemoteClient ----
text = CLIENT.read_text(encoding="utf-8")
if "connectViaRelay" in text:
print(" RemoteClient 已经改过")
else:
for old, new, tag in ((FIELD_OLD, FIELD_NEW, "字段换成 Transport"),
(CONNECTED_OLD, CONNECTED_NEW, "isConnected 用 Transport"),
(CONNECT_OLD, CONNECT_NEW, "connect 拆出 startTransport + connectViaRelay"),
(CLOSE_OLD, CLOSE_NEW, "close 关 Transport")):
if old not in text:
print(f" [失败] {tag} —— 锚点没找到")
ok = False
continue
text = text.replace(old, new, 1)
print(f" {tag}")
CLIENT.write_text(text, encoding="utf-8")
# 检查还有没有裸用 socket 的地方
text = CLIENT.read_text(encoding="utf-8")
leftovers = [line.strip() for line in text.splitlines()
if "socket" in line and "Transport" not in line
and "Socket" not in line and "//" not in line]
if leftovers:
print(f" [注意] 还有裸用 socket 的行:{leftovers}")
else:
print(" 没有残留的裸 socket 引用")
return 0 if ok else 1
if __name__ == "__main__":
sys.exit(main())