fix(crn): 修复CRN聚合站(如「千叶」)在CC中文环境下变????导致校正匹配失败引发终点站广播漏播
- 新增 extractAlphaNumCodes / hasSharedAlphaNumCode: 提取并比对字母数字代码(CB-03,CE-09等), 在中文变问号乱码环境下仍可通过代码完成跨源匹配 - looksLikeValidDestinationText: 放宽校验, 若问号超过50%但仍存在有效字母数字代码(如「????CB-03 6」)时不直接判为无效——保留代码供后续 hasSharedAlphaNumCode 匹配 - tryCorrectUpcomingEntryWithCurrentTrain: 1) 新增 etaSeconds 形参用于识别在站列车(eta≤0.5s), 据此触发校正 2) 新增 nearbyPlatform 条件: 站台号数字差≤1 时也进入校正候选 3) 新增 sharedCodeDest / sharedCodeTrain: 即使车次/站台全不匹配, 只要 dest 或 id 含有与权威值相同的字母数字代码即可触发 4) 新增兜底触发: (dest或id无效且eta=0) | (双无效且相邻站台) —— 专门覆盖CRN聚合名????这种彻底无代码的场景 5) 新增校正分支: 只要 sharedCodeTrain/sharedCodeDest 命中且 (etaAtStation|samePlatform|invalid) 即直接覆盖原值, 无需 fuzzy match 再次通过 - checkIsAtStationWithCurrentTrain: 1) 无 sameTrain 时用 hasSharedAlphaNumCode 二次匹配车次 2) 若车次/目的地双乱码 + 站台相邻, 也视为同车 3) 乱码目的地分支新增 hasSharedAlphaNumCode 成功即判停靠成功 - BlockReader/CreateTarget 两处预校正均移至 etaSeconds 计算之后, 并将 eta 传入函数, 确保看门条件里的 etaAtStation 可生效 - 全局校正循环也传入 entry.eta 版本升级至 v1.0.72
This commit is contained in:
+123
-39
@@ -1,6 +1,6 @@
|
||||
|
||||
-- 1. Configuration & Constants
|
||||
local APP_VERSION_TEXT = "v1.0.71"
|
||||
local APP_VERSION_TEXT = "v1.0.72"
|
||||
|
||||
local CONFIG = {
|
||||
CLOUD_URL = "ws://stabadmin.fse-media.group",
|
||||
@@ -3042,6 +3042,45 @@ local function isStationDestination(destName)
|
||||
return true
|
||||
end
|
||||
|
||||
local function extractAlphaNumCodes(text)
|
||||
if not text then return {} end
|
||||
local s = tostring(text)
|
||||
local codes = {}
|
||||
for code in string.gmatch(s, "[%a%d]+%-[%a%d]+") do
|
||||
codes[code] = true
|
||||
end
|
||||
for code in string.gmatch(s, "%a+%d+") do
|
||||
codes[code] = true
|
||||
end
|
||||
for code in string.gmatch(s, "%d+") do
|
||||
codes[code] = true
|
||||
end
|
||||
local list = {}
|
||||
for k, _ in pairs(codes) do
|
||||
table.insert(list, k)
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
local function hasSharedAlphaNumCode(a, b)
|
||||
local codes1 = extractAlphaNumCodes(a)
|
||||
local codes2 = extractAlphaNumCodes(b)
|
||||
if #codes1 == 0 or #codes2 == 0 then return false end
|
||||
for _, c1 in ipairs(codes1) do
|
||||
for _, c2 in ipairs(codes2) do
|
||||
if c1 == c2 then return true end
|
||||
local lc1, lc2 = string.lower(c1), string.lower(c2)
|
||||
if lc1 == lc2 then return true end
|
||||
if #lc1 >= 3 and #lc2 >= 3 then
|
||||
if string.find(lc1, lc2, 1, true) or string.find(lc2, lc1, 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function looksLikeValidDestinationText(text)
|
||||
if not text then return false end
|
||||
local s = tostring(text)
|
||||
@@ -3053,7 +3092,10 @@ local function looksLikeValidDestinationText(text)
|
||||
local c = string.sub(s, i, i)
|
||||
if c == "?" then questionMarkCount = questionMarkCount + 1 end
|
||||
end
|
||||
if #s > 0 and questionMarkCount / #s >= 0.5 then return false end
|
||||
if #s > 0 and questionMarkCount / #s >= 0.5 then
|
||||
local codes = extractAlphaNumCodes(s)
|
||||
if #codes == 0 then return false end
|
||||
end
|
||||
local hasRealChar = false
|
||||
for i = 1, #s do
|
||||
local b = string.byte(s, i)
|
||||
@@ -3066,7 +3108,7 @@ local function looksLikeValidDestinationText(text)
|
||||
return isStationDestination(s)
|
||||
end
|
||||
|
||||
local function tryCorrectUpcomingEntryWithCurrentTrain(entry)
|
||||
local function tryCorrectUpcomingEntryWithCurrentTrain(entry, etaSeconds)
|
||||
if not State.currentTrain or not entry then return entry end
|
||||
local ctId = State.currentTrain.id
|
||||
local ctDest = State.currentTrain.dest
|
||||
@@ -3077,7 +3119,29 @@ local function tryCorrectUpcomingEntryWithCurrentTrain(entry)
|
||||
if ctId and entry.trainName then
|
||||
sameTrain = Utils.isSameTrain(ctId, entry.trainName)
|
||||
end
|
||||
if not sameTrain and not samePlatform then return entry end
|
||||
|
||||
local platformNum = tonumber((string.gsub(entryPlatform, "%D", "")))
|
||||
local ctPlatformNum = tonumber((string.gsub(ctPlatform, "%D", "")))
|
||||
local nearbyPlatform = false
|
||||
if platformNum and ctPlatformNum then
|
||||
nearbyPlatform = (math.abs(platformNum - ctPlatformNum) <= 1)
|
||||
end
|
||||
|
||||
local sharedCodeDest = hasSharedAlphaNumCode(entry.dest, ctDest)
|
||||
local sharedCodeTrain = hasSharedAlphaNumCode(entry.trainName, ctId)
|
||||
|
||||
local etaAtStation = (type(etaSeconds) == "number" and etaSeconds <= 0.5)
|
||||
local destInvalid = not looksLikeValidDestinationText(entry.dest)
|
||||
local idInvalid = not looksLikeValidDestinationText(entry.trainName)
|
||||
|
||||
local shouldCorrect = samePlatform or sameTrain
|
||||
or (sharedCodeDest and (nearbyPlatform or etaAtStation))
|
||||
or (sharedCodeTrain and (nearbyPlatform or etaAtStation))
|
||||
or ((destInvalid or idInvalid) and etaAtStation)
|
||||
or (destInvalid and idInvalid and nearbyPlatform)
|
||||
|
||||
if not shouldCorrect then return entry end
|
||||
|
||||
local validId = looksLikeValidDestinationText(entry.trainName)
|
||||
local validDest = looksLikeValidDestinationText(entry.dest)
|
||||
|
||||
@@ -3085,19 +3149,25 @@ local function tryCorrectUpcomingEntryWithCurrentTrain(entry)
|
||||
entry.trainName = ctId
|
||||
end
|
||||
if sameTrain and ctId and ctId ~= "" and tostring(entry.trainName or "") ~= tostring(ctId) then
|
||||
if Utils.isFuzzyMatch(entry.trainName or "", ctId) or not validId then
|
||||
if Utils.isFuzzyMatch(entry.trainName or "", ctId) or not validId or sharedCodeTrain then
|
||||
entry.trainName = ctId
|
||||
end
|
||||
end
|
||||
if ctId and ctId ~= "" and tostring(entry.trainName or "") ~= tostring(ctId) and sharedCodeTrain and (etaAtStation or samePlatform or idInvalid) then
|
||||
entry.trainName = ctId
|
||||
end
|
||||
|
||||
if not validDest and ctDest and ctDest ~= "" then
|
||||
entry.dest = ctDest
|
||||
end
|
||||
if (sameTrain or samePlatform) and ctDest and ctDest ~= "" and tostring(entry.dest or "") ~= tostring(ctDest) then
|
||||
if Utils.isFuzzyMatch(entry.dest or "", ctDest) or not validDest then
|
||||
if (sameTrain or samePlatform or sharedCodeDest) and ctDest and ctDest ~= "" and tostring(entry.dest or "") ~= tostring(ctDest) then
|
||||
if Utils.isFuzzyMatch(entry.dest or "", ctDest) or not validDest or sharedCodeDest or etaAtStation then
|
||||
entry.dest = ctDest
|
||||
end
|
||||
end
|
||||
if ctDest and ctDest ~= "" and tostring(entry.dest or "") ~= tostring(ctDest) and sharedCodeDest and (etaAtStation or samePlatform or destInvalid) then
|
||||
entry.dest = ctDest
|
||||
end
|
||||
|
||||
return entry
|
||||
end
|
||||
@@ -3125,6 +3195,16 @@ local function checkIsAtStationWithCurrentTrain(trainName, destination, platform
|
||||
end
|
||||
end
|
||||
end
|
||||
if not sameTrain and hasSharedAlphaNumCode(trainName, ctId) then
|
||||
sameTrain = true
|
||||
end
|
||||
if not sameTrain and (not looksLikeValidDestinationText(trainName)) and (not looksLikeValidDestinationText(destination)) then
|
||||
local pNum = tonumber((string.gsub(trainPlatform, "%D", "")))
|
||||
local ctPNum = tonumber((string.gsub(ctPlatform, "%D", "")))
|
||||
if pNum and ctPNum and math.abs(pNum - ctPNum) <= 1 then
|
||||
sameTrain = true
|
||||
end
|
||||
end
|
||||
if sameTrain then
|
||||
local entryIdValid = looksLikeValidDestinationText(trainName)
|
||||
if entryIdValid then
|
||||
@@ -3136,6 +3216,9 @@ local function checkIsAtStationWithCurrentTrain(trainName, destination, platform
|
||||
if not looksLikeValidDestinationText(destination) then
|
||||
return true
|
||||
end
|
||||
if hasSharedAlphaNumCode(destination, ctDest) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
@@ -3223,20 +3306,6 @@ function Main.loop()
|
||||
platform = State.stationPlatform or "1"
|
||||
end
|
||||
|
||||
local preCorrected = tryCorrectUpcomingEntryWithCurrentTrain({
|
||||
trainName = trainName,
|
||||
dest = destination,
|
||||
platform = platform
|
||||
})
|
||||
if preCorrected then
|
||||
if preCorrected.trainName and tostring(preCorrected.trainName) ~= tostring(trainName) then
|
||||
trainName = preCorrected.trainName
|
||||
end
|
||||
if preCorrected.dest and tostring(preCorrected.dest) ~= tostring(destination) then
|
||||
destination = preCorrected.dest
|
||||
end
|
||||
end
|
||||
|
||||
if isStationDestination(destination) then
|
||||
local cancelled = false
|
||||
local reason = nil
|
||||
@@ -3261,6 +3330,21 @@ function Main.loop()
|
||||
local etaTicks = realArrival - currentTick
|
||||
local etaSeconds = etaTicks / (State.tickRate or 20)
|
||||
if etaSeconds < 0 then etaSeconds = 0 end
|
||||
|
||||
local preCorrected = tryCorrectUpcomingEntryWithCurrentTrain({
|
||||
trainName = trainName,
|
||||
dest = destination,
|
||||
platform = platform
|
||||
}, etaSeconds)
|
||||
if preCorrected then
|
||||
if preCorrected.trainName and tostring(preCorrected.trainName) ~= tostring(trainName) then
|
||||
trainName = preCorrected.trainName
|
||||
end
|
||||
if preCorrected.dest and tostring(preCorrected.dest) ~= tostring(destination) then
|
||||
destination = preCorrected.dest
|
||||
end
|
||||
end
|
||||
|
||||
local announceKey = normalizeUpcomingKey(trainName, destination)
|
||||
local etaLabel = buildEtaLabel(etaSeconds, etaTextByKey[announceKey])
|
||||
|
||||
@@ -3383,24 +3467,7 @@ function Main.loop()
|
||||
platform, etaStr, tName, dest = string.match(cleanLine, "^([^%s]+)%s+(.-)%s+([^%s]+)%s+(.*)$")
|
||||
end
|
||||
|
||||
local entryPlatform = platform or State.stationPlatform or "1"
|
||||
local preCorrectedCT = tryCorrectUpcomingEntryWithCurrentTrain({
|
||||
trainName = tName or "",
|
||||
dest = dest or "",
|
||||
platform = entryPlatform
|
||||
})
|
||||
if preCorrectedCT then
|
||||
if preCorrectedCT.trainName and tostring(preCorrectedCT.trainName) ~= tostring(tName or "") then
|
||||
tName = preCorrectedCT.trainName
|
||||
end
|
||||
if preCorrectedCT.dest and tostring(preCorrectedCT.dest) ~= tostring(dest or "") then
|
||||
dest = preCorrectedCT.dest
|
||||
end
|
||||
end
|
||||
|
||||
if tName and etaStr and isStationDestination(dest) then
|
||||
local announceKey = normalizeUpcomingKey(tName, dest)
|
||||
|
||||
local etaSeconds = -1
|
||||
local isNow = string.find(etaStr, "现在")
|
||||
|
||||
@@ -3426,6 +3493,23 @@ function Main.loop()
|
||||
end
|
||||
end
|
||||
|
||||
local entryPlatform = platform or State.stationPlatform or "1"
|
||||
local preCorrectedCT = tryCorrectUpcomingEntryWithCurrentTrain({
|
||||
trainName = tName or "",
|
||||
dest = dest or "",
|
||||
platform = entryPlatform
|
||||
}, etaSeconds >= 0 and etaSeconds or 0)
|
||||
if preCorrectedCT then
|
||||
if preCorrectedCT.trainName and tostring(preCorrectedCT.trainName) ~= tostring(tName or "") then
|
||||
tName = preCorrectedCT.trainName
|
||||
end
|
||||
if preCorrectedCT.dest and tostring(preCorrectedCT.dest) ~= tostring(dest or "") then
|
||||
dest = preCorrectedCT.dest
|
||||
end
|
||||
end
|
||||
|
||||
local announceKey = normalizeUpcomingKey(tName, dest)
|
||||
|
||||
table.insert(newUpcoming, {
|
||||
trainName = tName,
|
||||
dest = dest,
|
||||
@@ -3511,7 +3595,7 @@ function Main.loop()
|
||||
|
||||
|
||||
for _, entry in ipairs(newUpcoming) do
|
||||
tryCorrectUpcomingEntryWithCurrentTrain(entry)
|
||||
tryCorrectUpcomingEntryWithCurrentTrain(entry, entry.eta)
|
||||
end
|
||||
|
||||
State.upcomingTrains = newUpcoming
|
||||
|
||||
Reference in New Issue
Block a user