# -*- coding: utf-8 -*- """DiscoveryCore.java:加上 requestSelfCheck(用真实注释做锚点)。""" from __future__ import annotations import sys from pathlib import Path CORE = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\android\src" r"\com\lanremote\watch\DiscoveryCore.java") CONST_OLD = ' private static final String REPLY_MAGIC = "LANREMOTE_REPLY";\n' CONST_NEW = (' private static final String REPLY_MAGIC = "LANREMOTE_REPLY";\n' ' private static final String SELFCHECK_MAGIC = "LANREMOTE_SELFCHECK";\n' ' private static final String ACK_MAGIC = "LANREMOTE_ACK";\n') ANCHOR = ' /** 对扫描到的地址做一次单播发现,拿到电脑名和真实端口。 */' NEW = ''' /** * 请电脑打开「网络自检」。 * * 走 UDP 广播是有意的:连不上的典型原因就是 TCP 被防火墙拦了, * 而 UDP 广播往往仍然通(那正是「能搜到但连不上」的原因)。 * 所以只要能广播出去,就能让电脑把自检窗口弹出来。 * * @return 电脑名;没有回应返回 null */ public static String requestSelfCheck(String extraBroadcast, int timeoutMs) { DatagramSocket socket = null; try { socket = new DatagramSocket(); socket.setBroadcast(true); socket.setSoTimeout(500); byte[] payload = ("{\\"lanremote\\":\\"" + SELFCHECK_MAGIC + "\\",\\"proto\\":1}").getBytes("UTF-8"); List targets = new ArrayList(); targets.add("255.255.255.255"); if (extraBroadcast != null && extraBroadcast.length() > 0) { targets.add(extraBroadcast); } // 连发三轮,丢一两个包也能到 for (int round = 0; round < 3; round++) { for (String target : targets) { try { socket.send(new DatagramPacket(payload, payload.length, InetAddress.getByName(target), PORT)); } catch (Exception ignored) { // 某个广播地址不被允许时跳过 } } try { Thread.sleep(120); } catch (InterruptedException stop) { Thread.currentThread().interrupt(); break; } } long deadline = System.currentTimeMillis() + timeoutMs; byte[] buffer = new byte[2048]; while (System.currentTimeMillis() < deadline) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); try { socket.receive(packet); } catch (SocketTimeoutException timeout) { continue; } catch (Exception broken) { break; } String text = new String(packet.getData(), 0, packet.getLength(), "UTF-8"); if (text.indexOf(ACK_MAGIC) < 0) { continue; } try { Map obj = Json.parseObject(text); String name = Json.str(obj, "name", ""); if (name != null && name.length() > 0) { return name; } } catch (Exception ignored) { // 解析失败就用来源 IP } return packet.getAddress().getHostAddress(); } } catch (Exception ignored) { // 网络不可用 } finally { if (socket != null) { socket.close(); } } return null; } /** 对扫描到的地址做一次单播发现,拿到电脑名和真实端口。 */''' def main() -> int: text = CORE.read_text(encoding="utf-8") ok = True for old, new, tag in ((CONST_OLD, CONST_NEW, "常量"), (ANCHOR, NEW, "方法")): if old not in text: print(f" [失败] {tag} 锚点未匹配") ok = False else: text = text.replace(old, new, 1) print(f" {tag}: OK") if ok: CORE.write_text(text, encoding="utf-8") return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())