fix(plugin): allow cold start without ipc precheck

This commit is contained in:
kyasuda
2026-02-24 09:33:13 -08:00
parent 6eda768261
commit 3da9d9e0e0
2 changed files with 53 additions and 41 deletions

View File

@@ -46,12 +46,17 @@ local function is_subminer_process_running()
if is_windows() then if is_windows() then
local image = line:match('^"([^"]+)","') local image = line:match('^"([^"]+)","')
if not image then if not image then
image = line:match("^\"([^\"]+)\"") image = line:match('^"([^"]+)"')
end end
if not image then if not image then
goto continue goto continue
end end
if image == "subminer" or image == "subminer.exe" or image == "subminer.appimage" or image == "subminer.app" then if
image == "subminer"
or image == "subminer.exe"
or image == "subminer.appimage"
or image == "subminer.app"
then
return true return true
end end
if image:find("subminer", 1, true) and not image:find(".lua", 1, true) then if image:find("subminer", 1, true) and not image:find(".lua", 1, true) then
@@ -66,10 +71,21 @@ local function is_subminer_process_running()
goto continue goto continue
end end
local exe = argv0:match("([^/\\]+)$") or argv0 local exe = argv0:match("([^/\\]+)$") or argv0
if exe == "SubMiner" or exe == "SubMiner.AppImage" or exe == "SubMiner.exe" or exe == "subminer" or exe == "subminer.appimage" or exe == "subminer.exe" then if
exe == "SubMiner"
or exe == "SubMiner.AppImage"
or exe == "SubMiner.exe"
or exe == "subminer"
or exe == "subminer.appimage"
or exe == "subminer.exe"
then
return true return true
end end
if exe:find("subminer", 1, true) and exe:find("%.lua", 1, true) == nil and exe:find("%.app", 1, true) == nil then if
exe:find("subminer", 1, true)
and exe:find("%.lua", 1, true) == nil
and exe:find("%.app", 1, true) == nil
then
return true return true
end end
end end
@@ -86,26 +102,6 @@ local function is_subminer_app_running()
return false return false
end end
local function is_subminer_ipc_ready()
if not is_subminer_process_running() then
return false, "SubMiner process not running"
end
if is_windows() then
return true, nil
end
if opts.socket_path ~= default_socket_path() then
return false, "SubMiner socket path mismatch"
end
if not file_exists(default_socket_path()) then
return false, "SubMiner IPC socket missing at /tmp/subminer-socket"
end
return true, nil
end
local function normalize_binary_path_candidate(candidate) local function normalize_binary_path_candidate(candidate)
if type(candidate) ~= "string" then if type(candidate) ~= "string" then
return nil return nil
@@ -797,11 +793,7 @@ local function fix_ass_color(input, fallback)
end end
local function escape_ass_text(text) local function escape_ass_text(text)
return (text or "") return (text or ""):gsub("\\", "\\\\"):gsub("{", "\\{"):gsub("}", "\\}"):gsub("\n", "\\N")
:gsub("\\", "\\\\")
:gsub("{", "\\{")
:gsub("}", "\\}")
:gsub("\n", "\\N")
end end
local function resolve_osd_dimensions() local function resolve_osd_dimensions()
@@ -1234,7 +1226,9 @@ end
local function file_exists(path) local function file_exists(path)
local info = utils.file_info(path) local info = utils.file_info(path)
if not info then return false end if not info then
return false
end
if info.is_dir ~= nil then if info.is_dir ~= nil then
return not info.is_dir return not info.is_dir
end end
@@ -1415,7 +1409,13 @@ local function parse_start_script_message_overrides(...)
local normalized_key = key:lower() local normalized_key = key:lower()
if normalized_key == "backend" then if normalized_key == "backend" then
local backend = value:lower() local backend = value:lower()
if backend == "auto" or backend == "hyprland" or backend == "sway" or backend == "x11" or backend == "macos" then if
backend == "auto"
or backend == "hyprland"
or backend == "sway"
or backend == "x11"
or backend == "macos"
then
overrides.backend = backend overrides.backend = backend
end end
elseif normalized_key == "socket" or normalized_key == "socket_path" then elseif normalized_key == "socket" or normalized_key == "socket_path" then
@@ -1525,14 +1525,6 @@ local function ensure_texthooker_running(callback)
end end
local function start_overlay(overrides) local function start_overlay(overrides)
local socket_ready, reason = is_subminer_ipc_ready()
local process_not_running = reason == "SubMiner process not running"
if not socket_ready and not process_not_running then
subminer_log("warn", "process", "Refusing to start overlay: " .. tostring(reason))
show_osd("SubMiner IPC not set up. Launch mpv with --input-ipc-server=/tmp/subminer-socket")
return
end
if not ensure_binary_available() then if not ensure_binary_available() then
subminer_log("error", "binary", "SubMiner binary not found") subminer_log("error", "binary", "SubMiner binary not found")
show_osd("Error: binary not found") show_osd("Error: binary not found")

View File

@@ -3,6 +3,7 @@ local function run_plugin_scenario(config)
local recorded = { local recorded = {
async_calls = {}, async_calls = {},
sync_calls = {},
script_messages = {}, script_messages = {},
osd = {}, osd = {},
logs = {}, logs = {},
@@ -35,6 +36,7 @@ local function run_plugin_scenario(config)
end end
function mp.command_native(command) function mp.command_native(command)
recorded.sync_calls[#recorded.sync_calls + 1] = command
local args = command.args or {} local args = command.args or {}
if args[1] == "ps" then if args[1] == "ps" then
return { return {
@@ -93,6 +95,9 @@ local function run_plugin_scenario(config)
if config.socket_path then if config.socket_path then
target.socket_path = config.socket_path target.socket_path = config.socket_path
end end
if config.binary_path then
target.binary_path = config.binary_path
end
end end
function utils.file_info(path) function utils.file_info(path)
@@ -168,10 +173,20 @@ local function find_start_call(async_calls)
local args = call.args or {} local args = call.args or {}
for i = 1, #args do for i = 1, #args do
if args[i] == "--start" then if args[i] == "--start" then
return true return call
end end
end end
end end
return nil
end
local function has_sync_command(sync_calls, executable)
for _, call in ipairs(sync_calls) do
local args = call.args or {}
if args[1] == executable then
return true
end
end
return false return false
end end
@@ -180,6 +195,7 @@ local binary_path = "/tmp/subminer-binary"
do do
local recorded, err = run_plugin_scenario({ local recorded, err = run_plugin_scenario({
process_list = "", process_list = "",
binary_path = binary_path,
files = { files = {
[binary_path] = true, [binary_path] = true,
}, },
@@ -187,7 +203,11 @@ do
assert_true(recorded ~= nil, "plugin failed to load for cold-start scenario: " .. tostring(err)) assert_true(recorded ~= nil, "plugin failed to load for cold-start scenario: " .. tostring(err))
assert_true(recorded.script_messages["subminer-start"] ~= nil, "subminer-start script message not registered") assert_true(recorded.script_messages["subminer-start"] ~= nil, "subminer-start script message not registered")
recorded.script_messages["subminer-start"]("texthooker=no") recorded.script_messages["subminer-start"]("texthooker=no")
assert_true(find_start_call(recorded.async_calls), "expected cold-start to invoke --start command when process is absent") assert_true(find_start_call(recorded.async_calls) ~= nil, "expected cold-start to invoke --start command when process is absent")
assert_true(
not has_sync_command(recorded.sync_calls, "ps"),
"expected cold-start start command to avoid synchronous process list scan"
)
end end
print("plugin start gate regression tests: OK") print("plugin start gate regression tests: OK")