fix(client): 过滤非车站指令并修复列车停站后重复播报进站预告的问题

1. 新增 `isStationDestination` 过滤器,在通过显示屏(Create Target)读取时刻表时,
   自动忽略包含“速度”、“重命名”、“时刻表”、“等待”、“卸载”等关键字的非车站指令,
   防止将这些指令当作车站并错误触发进站预告。
2. 修复显示屏读取到的负数 ETA 被错误解析为正数的问题(增加可选负号匹配)。
3. 将触发进站预告的条件从 `etaSeconds >= 0` 修改为 `etaSeconds > 0`。
   这样当列车完全停站(ETA=0或负数)时,将不再触发进站预告,彻底解决停站时间
   超过冷却期后导致的重复播报“进站预告”的问题。
This commit is contained in:
2026-08-03 12:04:13 +08:00
parent 439ed9ea3c
commit f846004091
+41 -8
View File
@@ -1,6 +1,6 @@
-- 1. Configuration & Constants
local APP_VERSION_TEXT = "v1.0.52"
local APP_VERSION_TEXT = "v1.0.53"
local CONFIG = {
CLOUD_URL = "ws://stabadmin.fse-media.group",
@@ -2713,7 +2713,7 @@ function Main.loop()
end
end
if etaSeconds >= 0 and etaSeconds <= 45 then
if etaSeconds > 0 and etaSeconds <= 45 then
if not seenApproachKeys[announceKey] then
seenApproachKeys[announceKey] = true
local pending = State.pendingApproaching[announceKey]
@@ -2768,6 +2768,37 @@ function Main.loop()
local seenAlertKeys = {}
local seenApproachKeys = {}
local function isStationDestination(destName)
if not destName then return false end
local blacklist = {
"速度", "speed",
"名称", "rename", "重命名",
"时刻表", "schedule",
"区段", "section",
"卸", "unload",
"装", "load",
"等待", "wait",
"条件", "condition",
"动力", "powered",
"物品", "item",
"流体", "fluid",
"玩家", "player",
"时间", "time",
"抛弃", "discard",
"限制", "limit",
"货物", "cargo",
"无载", "unloaded",
"空载", "empty"
}
local lowerDest = string.lower(destName)
for _, word in ipairs(blacklist) do
if string.find(lowerDest, word, 1, true) then
return false
end
end
return true
end
cleanupTimestampMap(State.announcedApproaching, now, tonumber(CONFIG.APPROACHING_COOLDOWN_MS) or 120000)
cleanupTimestampMap(State.announcedAlerts, now, tonumber(CONFIG.ALERT_COOLDOWN_MS) or 300000)
@@ -2787,7 +2818,7 @@ function Main.loop()
platform, etaStr, tName, dest = string.match(cleanLine, "^([^%s]+)%s+(.-)%s+([^%s]+)%s+(.*)$")
end
if tName and etaStr then
if tName and etaStr and isStationDestination(dest) then
local announceKey = normalizeUpcomingKey(tName, dest)
local etaSeconds = -1
@@ -2796,13 +2827,15 @@ function Main.loop()
if isNow then
etaSeconds = 0
else
local mm, ss = string.match(etaStr, "^(%d+)%s*:%s*(%d+)%s*$")
local sign_mm, mm, ss = string.match(etaStr, "^%s*(%-?)%s*(%d+)%s*:%s*(%d+)%s*$")
if mm and ss then
etaSeconds = tonumber(mm) * 60 + tonumber(ss)
if sign_mm == "-" then etaSeconds = -etaSeconds end
else
local num, unit = string.match(etaStr, "(%d+)%s*(.*)")
local sign, num, unit = string.match(etaStr, "^%s*(%-?)%s*(%d+)%s*(.*)")
if num then
num = tonumber(num)
if sign == "-" then num = -num end
if string.find(unit, "秒") or string.find(unit, "s") or string.find(unit, "sec") or (unit == "??" and num > 10) then
etaSeconds = num
@@ -2819,8 +2852,8 @@ function Main.loop()
platform = platform or State.stationPlatform or "1",
eta = etaSeconds >= 0 and etaSeconds or 0,
etaLabel = buildEtaLabel(etaSeconds >= 0 and etaSeconds or 0, {
value = string.match(etaStr, "(%d+)"),
unit = string.match(etaStr, "%d+%s*(.*)")
value = string.match(etaStr, "(%-?%d+)"),
unit = string.match(etaStr, "%-?%d+%s*(.*)")
}),
delay = delay,
cancelled = false,
@@ -2847,7 +2880,7 @@ function Main.loop()
end
end
if etaSeconds >= 0 and etaSeconds <= 45 then
if etaSeconds > 0 and etaSeconds <= 45 then
if not seenApproachKeys[announceKey] then
seenApproachKeys[announceKey] = true
local pending = State.pendingApproaching[announceKey]