From 00ac2d7d6fa34fea9dd17fbda22c175a66ad1f88 Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Sun, 29 Mar 2026 01:32:37 -0400 Subject: [PATCH] fix: prefer wired modems in findModem() to prevent wireless/wired mismatch WebBridge.findModem() iterated _G.device with pairs() which has non-deterministic order. On computers with both wired and wireless modems, it could return the wireless modem while the manager uses a wired modem - messages never cross the wired/wireless boundary. Now uses two-pass iteration: first looks for wired modems, then falls back to any modem. Peripheral scan fallback also prefers wired. Backward-compatible: boolean arg (preferWireless) still works. --- apis/webbridge.lua | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/apis/webbridge.lua b/apis/webbridge.lua index 390a29c..c22b72c 100644 --- a/apis/webbridge.lua +++ b/apis/webbridge.lua @@ -170,29 +170,57 @@ end --- Find a modem peripheral. -- Prefers the Opus device registry, falls back to peripheral scan. --- @param preferWireless boolean|nil If true, prefer wireless modem +-- By default prefers wired modems (for reliable LAN communication). +-- @param opts table|boolean|nil Options table { preferWireless = bool }, +-- or legacy boolean (true = prefer wireless) -- @return table|nil Modem peripheral handle -- @return string|nil Peripheral name/side -function WebBridge.findModem(preferWireless) +function WebBridge.findModem(opts) + -- Legacy support: boolean arg means preferWireless + if type(opts) == 'boolean' then + opts = { preferWireless = opts } + end + opts = opts or {} + -- Try Opus device registry first if _G.device then - if preferWireless and _G.device.wireless_modem then + if opts.preferWireless and _G.device.wireless_modem then return _G.device.wireless_modem, 'wireless_modem' end - -- Find any modem in device registry + + -- Two-pass: prefer wired modems first, then any modem + -- (pairs() order is non-deterministic; without two passes, + -- a wireless modem might be returned even when wired is available) + local fallback, fallbackName for name, dev in pairs(_G.device) do - if dev.type == 'modem' or dev.type == 'wireless_modem' or dev.type == 'wired_modem' then + if dev.type == 'wired_modem' then return dev, name + elseif dev.type == 'modem' or dev.type == 'wireless_modem' then + if not fallback then + fallback, fallbackName = dev, name + end end end + if fallback then + return fallback, fallbackName + end end - -- Fallback: scan peripherals + -- Fallback: scan peripherals (prefer wired) + local wirelessDev, wirelessName for _, name in ipairs(peripheral.getNames()) do if peripheral.getType(name) == 'modem' then - return peripheral.wrap(name), name + local dev = peripheral.wrap(name) + if dev.isWireless and not dev.isWireless() then + return dev, name -- wired modem found + elseif not wirelessDev then + wirelessDev, wirelessName = dev, name + end end end + if wirelessDev then + return wirelessDev, wirelessName + end return nil end