From 432b82eae9ccb465f6db83915065f74e2be7386d Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sun, 2 Aug 2026 16:48:42 +0800 Subject: [PATCH] feat: prefer CRN display ETA text when available --- station_broadcast.lua | 50 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/station_broadcast.lua b/station_broadcast.lua index 04c3361..ab542b1 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -2,7 +2,7 @@ -- ============================================================================ -- 1. Configuration & Constants -- ============================================================================ -local APP_VERSION_TEXT = "v1.0.30" +local APP_VERSION_TEXT = "v1.0.31" local CONFIG = { CLOUD_URL = "ws://stabadmin.fse-media.group", @@ -2331,6 +2331,7 @@ function Main.loop() while true do local now = os.epoch("utc") local newUpcoming = {} + local etaByText = {} local dbg = { hasBR = Peripherals.blockReader ~= nil, hasCT = Peripherals.createTarget ~= nil, @@ -2339,6 +2340,47 @@ function Main.loop() tickRate = State.tickRate or 20 } + -- Prefer CRN's own ETA display text (create_target) when available. + -- This avoids drift when TPS fluctuates, while still using NBT for delay/status. + if Peripherals.createTarget then + local okLines, lines = pcall(Peripherals.createTarget.dump) + if okLines and type(lines) == "table" then + for _, lineText in pairs(lines) do + if lineText and lineText ~= "" and lineText:match("[%w%?%[]") then + local cleanLine = string.gsub(lineText, "%s*%(?%+%s*%d+.-%)?", "") + local platform, etaStr, tName, dest + platform, etaStr, tName, dest = string.match(cleanLine, "^(%d+)%s+(.-)%s+(%[.-%][^%s]*)%s+(.*)$") + if not tName then + platform, etaStr, tName, dest = string.match(cleanLine, "^([^%s]+)%s+(.-)%s+(%[.-%][^%s]*)%s+(.*)$") + end + if not tName then + platform, etaStr, tName, dest = string.match(cleanLine, "^([^%s]+)%s+(.-)%s+([^%s]+)%s+(.*)$") + end + if tName and etaStr then + local etaSeconds = -1 + local isNow = string.find(etaStr, "现在") or string.find(etaStr, "0") + if isNow then + etaSeconds = 0 + else + local num, unit = string.match(etaStr, "(%d+)%s*(.*)") + if num then + num = tonumber(num) + if string.find(unit, "秒") or string.find(unit, "s") or string.find(unit, "sec") or (unit == "??" and num > 10) then + etaSeconds = num + else + etaSeconds = num * 60 + end + end + end + if dest then + etaByText[tName .. "_" .. dest] = etaSeconds + end + end + end + end + end + end + -- Check Block Reader (Advanced Peripherals) first for precise ETA and Delay if Peripherals.blockReader then local ok, data = pcall(Peripherals.blockReader.getBlockData) @@ -2413,6 +2455,11 @@ function Main.loop() local etaTicks = realArrival - currentTick local etaSeconds = math.floor(etaTicks / (State.tickRate or 20)) if etaSeconds < 0 then etaSeconds = 0 end + local announceKey = trainName .. "_" .. destination + local textEta = etaByText[announceKey] + if type(textEta) == "number" and textEta >= 0 then + etaSeconds = textEta + end -- Calculate Delay in minutes local delayTicks = realArrival - scheduledArrival @@ -2430,7 +2477,6 @@ function Main.loop() }) if etaSeconds >= 0 and etaSeconds <= 45 then - local announceKey = trainName .. "_" .. destination if not State.announcedApproaching[announceKey] then State.announcedApproaching[announceKey] = now Utils.log("INFO", string.format("Train Approaching: %s (ETA: %ds, Delay: %dm)", trainName, etaSeconds, delayMinutes))