fix(client): 优化停站时间获取,并在列车停站时禁用进站预告
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` 触发逻辑,彻底解决列车停站时倒秒导致的重复播报。
This commit is contained in:
+24
-39
@@ -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,16 +778,16 @@ 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 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)
|
||||
|
||||
Utils.log("DEBUG", string.format(" [%d] SCAN '%s': '%s' (Code: %s)", i, k, entryText, tostring(entryCode)))
|
||||
Utils.log("DEBUG", string.format(" [%d] SCAN STATION: '%s' (Code: %s)", i, entryText, tostring(entryCode)))
|
||||
|
||||
local isMatch = (target == entryText)
|
||||
or (targetCode and entryCode and targetCode == entryCode)
|
||||
@@ -796,17 +796,13 @@ function Utils.getStopTime(schedule, stationName)
|
||||
or Utils.isFuzzyMatch(target, entryText)
|
||||
|
||||
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
|
||||
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
|
||||
if entry.instruction and (entry.instruction.id == "create:station" or entry.instruction.id == "create:destination") then
|
||||
isOtherStation = true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
if checkIsStation(entry, 0) then break end
|
||||
if isOtherStation then break end
|
||||
|
||||
local s = findTimeInConditions(entry.conditions)
|
||||
if s then
|
||||
@@ -887,11 +874,11 @@ 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 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)
|
||||
@@ -902,15 +889,11 @@ function Utils.getNextStation(schedule, currentStationName)
|
||||
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 return true end
|
||||
elseif type(v) == "table" then
|
||||
if scanRecursive(v, depth + 1) then return true end
|
||||
if isMatch then isStationEntry = true end
|
||||
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]
|
||||
|
||||
Reference in New Issue
Block a user