From cae616dc7cdc5cd99cbf04ceb172fe03939f659a Mon Sep 17 00:00:00 2001 From: arcattack Date: Mon, 20 Jul 2026 22:27:12 -0500 Subject: [PATCH] join_lan.bat: pin the operator's LAN IP (auto-discovery was unreliable) Field report: LAN auto-discovery (BT_RELAY=auto) didn't work -- a joiner had to hand-set BT_RELAY=10.0.0.46:1500 to reach the console every time. - players/join_lan.bat: BT_RELAY=auto -> BT_RELAY=10.0.0.46:1500 (the operator PC's LAN IP), with a comment on updating it if the IP changes. - tools/btoperator.py: the export now DETECTS the operator PC's LAN IP (UDP default-route probe, no packet sent) and stamps BT_RELAY=:port into the generated join_lan.bat instead of "auto" -- so regeneration keeps it correct and doesn't revert to the broken auto-discovery. Verified: detects 10.0.0.46 here. Co-Authored-By: Claude Opus 4.8 --- players/join_lan.bat | 7 +++++-- tools/btoperator.py | 32 +++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/players/join_lan.bat b/players/join_lan.bat index 297adbb..949f84d 100644 --- a/players/join_lan.bat +++ b/players/join_lan.bat @@ -1,10 +1,13 @@ @echo off -rem BT411 -- join the operator's LAN game (auto-discovers). +rem BT411 -- join the operator's LAN game. +rem BT_RELAY = the operator PC's LAN IP + console port (auto-discovery was +rem unreliable on this network, so it is pinned). If the operator's IP changes, +rem update the address below (find it on the operator PC with `ipconfig`). rem Joining over the INTERNET? Use join.bat instead. cd /d %~dp0 if not exist "build\Release\btl4.exe" goto badpath if not exist "content\OPERATOR.EGG" goto badpath -set BT_RELAY=auto +set BT_RELAY=10.0.0.46:1500 set BT_LOG=join.log set BT_START_INSIDE=1 set BT_DEV_GAUGES=1 diff --git a/tools/btoperator.py b/tools/btoperator.py index 28600e3..8de9535 100644 --- a/tools/btoperator.py +++ b/tools/btoperator.py @@ -751,6 +751,24 @@ class Operator(QMainWindow): if problems and not self._confirm_problems(problems, "Export anyway?"): return host = self.f_public.text().strip() or "YOUR.RELAY.HOST" + + # LAN bat address: auto-discovery (BT_RELAY=auto) proved unreliable on + # some networks (field report 2026-07-20: a joiner had to hand-set + # BT_RELAY=:1500), so pin THIS operator PC's LAN IP. + # The UDP connect picks the default-route interface without sending a + # packet; falls back to "auto" only if detection fails. + def _detect_lan_ip(): + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + s.connect(("8.8.8.8", 1)) + ip = s.getsockname()[0] + except Exception: + ip = "" + finally: + s.close() + return ip if (ip and not ip.startswith("127.")) else "" + out_dir = QFileDialog.getExistingDirectory( self, "Export player launch scripts to…", REPO) if not out_dir: @@ -810,13 +828,21 @@ class Operator(QMainWindow): % (host, self.f_port.value()), "..\\build\\Release\\btl4.exe -egg %s -net 1501\n" % egg_name, net_tail)) + lan_ip = _detect_lan_ip() + lan_relay = ("%s:%d" % (lan_ip, self.f_port.value())) if lan_ip else "auto" + lan_hdr = ( + ("rem BT411 -- join the operator's LAN game.\n" + "rem BT_RELAY = the operator PC's LAN IP + console port. If that IP\n" + "rem changes, update it below (operator PC: run `ipconfig`).\n") + if lan_ip else + "rem BT411 -- join the operator's LAN game (auto-discovers).\n") with open(os.path.join(out_dir, "join_lan.bat"), "w", newline="\r\n") as f: f.write(guarded( - "rem BT411 -- join the operator's LAN game (auto-discovers).\n" + lan_hdr + "rem Joining over the INTERNET? Use join.bat instead.\n", - "set BT_RELAY=auto\nset BT_LOG=join.log\n" - "set BT_START_INSIDE=1\nset BT_DEV_GAUGES=1\n", + "set BT_RELAY=%s\nset BT_LOG=join.log\n" + "set BT_START_INSIDE=1\nset BT_DEV_GAUGES=1\n" % lan_relay, "..\\build\\Release\\btl4.exe -egg %s -net 1501\n" % egg_name, net_tail)) with open(os.path.join(out_dir, "play_solo.bat"), "w",