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.
This commit is contained in:
MayaTheShy
2026-03-29 01:32:37 -04:00
parent caf82ba81d
commit 00ac2d7d6f

View File

@@ -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