From fdbcfa3b9b7d057fd7f73056ce5b59279e9f09b9 Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Mon, 3 Aug 2026 12:20:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(client):=20=E4=BC=98=E5=8C=96=E5=81=9C?= =?UTF-8?q?=E7=AB=99=E6=97=B6=E9=97=B4=E8=8E=B7=E5=8F=96=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E5=9C=A8=E5=88=97=E8=BD=A6=E5=81=9C=E7=AB=99=E6=97=B6=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E8=BF=9B=E7=AB=99=E9=A2=84=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 修复 `Utils.getStopTime` 和 `Utils.getNextStation` 会误匹配“非车站指令”(如修改最高速度等指令)中的文本的问题,现在仅在 `instruction.id == create:station` 或 `create:destination` 的条目中扫描,保证了 CC 电脑从 `create:track_station` 获取到的时刻表信息(包括计算出的停站时间)100% 准确。 2. 修复显示器(Display Board / NBT)在列车停站后依然显示“离站倒计时 ETA”,导致触发 `train_approaching` 的问题:如果当前列车已经在站内(`State.currentTrain` 存在且匹配),将强制忽略该列车的 `train_approaching` 触发逻辑,彻底解决列车停站时倒秒导致的重复播报。 --- station_broadcast.lua | 101 ++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/station_broadcast.lua b/station_broadcast.lua index 8f0155a..932544f 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -1,6 +1,6 @@ -- 1. Configuration & Constants -local APP_VERSION_TEXT = "v1.0.54" +local APP_VERSION_TEXT = "v1.0.55" local CONFIG = { CLOUD_URL = "ws://stabadmin.fse-media.group", @@ -778,35 +778,31 @@ function Utils.getStopTime(schedule, stationName) for i = 1, maxIdx do local entry = schedule.entries[i] if entry then - local function scanRecursive(obj, depth) - if depth > 5 or not obj then return false end - for k, v in pairs(obj) do - if type(v) == "string" then - local entryText = v:lower() - local entryCode = Utils.getStationCode(entryText) - local entryAlpha = entryText:gsub("[^%w%d]", "") - local entryBase = Utils.getBaseName(entryText) - - Utils.log("DEBUG", string.format(" [%d] SCAN '%s': '%s' (Code: %s)", i, k, entryText, tostring(entryCode))) + local isStationEntry = false + if entry.instruction and (entry.instruction.id == "create:station" or entry.instruction.id == "create:destination") then + local text = (entry.instruction.data and entry.instruction.data.text) or entry.instruction.text + if type(text) == "string" then + local entryText = text:lower() + local entryCode = Utils.getStationCode(entryText) + local entryAlpha = entryText:gsub("[^%w%d]", "") + local entryBase = Utils.getBaseName(entryText) - local isMatch = (target == entryText) - or (targetCode and entryCode and targetCode == entryCode) - or (targetAlpha ~= "" and entryAlpha ~= "" and (targetAlpha == entryAlpha or targetAlpha:find(entryAlpha, 1, true) or entryAlpha:find(targetAlpha, 1, true))) - or (targetBase ~= "" and entryBase ~= "" and (targetBase == entryBase or targetBase:find(entryBase, 1, true) or entryBase:find(targetBase, 1, true))) - or Utils.isFuzzyMatch(target, entryText) + Utils.log("DEBUG", string.format(" [%d] SCAN STATION: '%s' (Code: %s)", i, entryText, tostring(entryCode))) - if isMatch then - Utils.log("DEBUG", string.format(" >>> MATCH FOUND AT ENTRY %d (via field '%s')", i, k)) - return true - end - elseif type(v) == "table" then - if scanRecursive(v, depth + 1) then return true end + local isMatch = (target == entryText) + or (targetCode and entryCode and targetCode == entryCode) + or (targetAlpha ~= "" and entryAlpha ~= "" and (targetAlpha == entryAlpha or targetAlpha:find(entryAlpha, 1, true) or entryAlpha:find(targetAlpha, 1, true))) + or (targetBase ~= "" and entryBase ~= "" and (targetBase == entryBase or targetBase:find(entryBase, 1, true) or entryBase:find(targetBase, 1, true))) + or Utils.isFuzzyMatch(target, entryText) + + if isMatch then + Utils.log("DEBUG", string.format(" >>> MATCH FOUND AT ENTRY %d", i)) + isStationEntry = true end end - return false end - if scanRecursive(entry, 0) then + if isStationEntry then matchFoundIndex = i local s = findTimeInConditions(entry.conditions) if s then @@ -833,19 +829,10 @@ function Utils.getStopTime(schedule, stationName) local entry = schedule.entries[i] if entry then local isOtherStation = false - local function checkIsStation(obj, depth) - if depth > 2 or not obj then return false end - for k, v in pairs(obj) do - if type(v) == "string" then - local lk = tostring(k):lower() - if lk:find("text") or lk:find("station") or lk:find("destination") then return true end - elseif type(v) == "table" then - if checkIsStation(v, depth + 1) then return true end - end - end - return false + if entry.instruction and (entry.instruction.id == "create:station" or entry.instruction.id == "create:destination") then + isOtherStation = true end - if checkIsStation(entry, 0) then break end + if isOtherStation then break end local s = findTimeInConditions(entry.conditions) if s then @@ -887,30 +874,26 @@ function Utils.getNextStation(schedule, currentStationName) for i = 1, maxIdx do local entry = schedule.entries[i] if entry then - local function scanRecursive(obj, depth) - if depth > 5 or not obj then return false end - for k, v in pairs(obj) do - if type(v) == "string" then - local entryText = v:lower() - local entryCode = Utils.getStationCode(entryText) - local entryAlpha = entryText:gsub("[^%w%d]", "") - local entryBase = Utils.getBaseName(entryText) - - local isMatch = (target == entryText) - or (targetCode and entryCode and targetCode == entryCode) - or (targetAlpha ~= "" and entryAlpha ~= "" and (targetAlpha == entryAlpha or targetAlpha:find(entryAlpha, 1, true) or entryAlpha:find(targetAlpha, 1, true))) - or (targetBase ~= "" and entryBase ~= "" and (targetBase == entryBase or targetBase:find(entryBase, 1, true) or entryBase:find(targetBase, 1, true))) - or Utils.isFuzzyMatch(target, entryText) + local isStationEntry = false + if entry.instruction and (entry.instruction.id == "create:station" or entry.instruction.id == "create:destination") then + local text = (entry.instruction.data and entry.instruction.data.text) or entry.instruction.text + if type(text) == "string" then + local entryText = text:lower() + local entryCode = Utils.getStationCode(entryText) + local entryAlpha = entryText:gsub("[^%w%d]", "") + local entryBase = Utils.getBaseName(entryText) - if isMatch then return true end - elseif type(v) == "table" then - if scanRecursive(v, depth + 1) then return true end - end + local isMatch = (target == entryText) + or (targetCode and entryCode and targetCode == entryCode) + or (targetAlpha ~= "" and entryAlpha ~= "" and (targetAlpha == entryAlpha or targetAlpha:find(entryAlpha, 1, true) or entryAlpha:find(targetAlpha, 1, true))) + or (targetBase ~= "" and entryBase ~= "" and (targetBase == entryBase or targetBase:find(entryBase, 1, true) or entryBase:find(targetBase, 1, true))) + or Utils.isFuzzyMatch(target, entryText) + + if isMatch then isStationEntry = true end end - return false end - if scanRecursive(entry, 0) then + if isStationEntry then matchFoundIndex = i break end @@ -2751,7 +2734,8 @@ function Main.loop() end end - if etaSeconds > 0 and etaSeconds <= 45 then + local isAtStation = State.currentTrain and State.currentTrain.id == trainName and State.currentTrain.dest == destination + if not isAtStation and etaSeconds > 0 and etaSeconds <= 45 then if not seenApproachKeys[announceKey] then seenApproachKeys[announceKey] = true local pending = State.pendingApproaching[announceKey] @@ -2888,7 +2872,8 @@ function Main.loop() end end - if etaSeconds > 0 and etaSeconds <= 45 then + local isAtStation = State.currentTrain and State.currentTrain.id == tName and State.currentTrain.dest == dest + if not isAtStation and etaSeconds > 0 and etaSeconds <= 45 then if not seenApproachKeys[announceKey] then seenApproachKeys[announceKey] = true local pending = State.pendingApproaching[announceKey]