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=<lan-ip>: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 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-20 22:27:12 -05:00
co-authored by Claude Opus 4.8
parent 9f0a7c52df
commit cae616dc7c
2 changed files with 34 additions and 5 deletions
+29 -3
View File
@@ -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=<operator-lan-ip>: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",