diff --git a/main.lua b/main.lua index 29f1e803..eb47215f 100644 --- a/main.lua +++ b/main.lua @@ -263,6 +263,11 @@ function love.load(args) -- of each flashing their own cmd.exe window (#606). No-op elsewhere. require("src.core.HostShell").hideHostConsole() + -- Hang gen1tls on love.system before mods boot. Android already has tls* + -- from JNI; this is the desktop half. No DLL / no FFI is fine -- ws:// + -- rooms still work, wss:// just won't. + pcall(function() require("src.net.Gen1Tls").install() end) + -- NX fused mounts are unreliable for the blue|yellow cache overlay: wrap -- the love loaders once so every generated-asset read falls back to the -- versioned save-dir copy. Never installed on desktop/Android/iOS. diff --git a/src/mods/LegacyCompat.lua b/src/mods/LegacyCompat.lua index 0f8a1cf2..05f5a3b6 100644 --- a/src/mods/LegacyCompat.lua +++ b/src/mods/LegacyCompat.lua @@ -662,7 +662,13 @@ end local function systemShim(ctx) local function real() return _G.love and _G.love.system or nil end - return { + -- tls* comes from the engine (Android JNI, or desktop gen1tls hung on + -- love.system at boot). Forward those; keep clipboard / openURL stubbed. + local TLS = { + tlsOpen = true, tlsStatus = true, tlsSend = true, + tlsReceive = true, tlsError = true, tlsClose = true, + } + local shim = { getOS = function() local sys = real() return sys and sys.getOS and sys.getOS() or "Unknown" @@ -697,6 +703,13 @@ local function systemShim(ctx) return false end, } + return setmetatable(shim, { + __index = function(_, key) + if not TLS[key] then return nil end + local sys = real() + return sys and sys[key] + end, + }) end local function eventShim(ctx) diff --git a/src/net/Gen1Tls.lua b/src/net/Gen1Tls.lua new file mode 100644 index 00000000..3d9a33e9 Binary files /dev/null and b/src/net/Gen1Tls.lua differ diff --git a/tests/modkit/cases/sandbox.lua b/tests/modkit/cases/sandbox.lua index 4c7aba9b..27133e15 100644 --- a/tests/modkit/cases/sandbox.lua +++ b/tests/modkit/cases/sandbox.lua @@ -62,6 +62,9 @@ local PROBE = [[ out.assignGarbage = attempt(function() love.mousemoved = 7 end) out.powerInfo = type(love.system.getPowerInfo) out.openUrl = love.system.openURL("https://example.com") + -- tls* is forwarded from the real love.system when the engine hung it + -- (Gen1Tls / Android JNI); without that it's just nil, not an error. + out.tlsOpenType = type(love.system.tlsOpen) out.eventQuit = love.event.quit() out.popen = select(1, io.popen("ls")) @@ -200,6 +203,8 @@ T.check(out.loveAssign ~= false, "a mod cannot replace a love module table: " .. tostring(out.loveAssign)) T.eq(out.powerInfo, "function", "love.system reads through to the same information mod.device exposes") +T.check(out.tlsOpenType == "function" or out.tlsOpenType == "nil", + "tls* is readable through the system shim (nil until the engine hangs it)") -- a wrapped callback has to land on the real table or the wrap never fires T.eq(type(installedMouseMoved), "function",