From 32b2c8ce9daa38b822a354faca498fa40ffa276d Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sun, 16 Aug 2026 12:41:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BB=88=E7=82=B9=E7=AB=99=E5=88=B0?= =?UTF-8?q?=E8=BE=BE=E6=97=B6=E4=B8=8B=E4=B8=80=E7=AB=99=E5=B9=BF=E6=92=AD?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E5=BC=82=E5=B8=B8=20+=20getNextStation=20?= =?UTF-8?q?=E4=B8=8D=E5=9B=9E=E7=BB=95=E8=B5=B7=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Utils.getNextStation: 移除终点站回绕到起点的逻辑(非环线) - 此前当前站是 END 时会从 schedule.entries 开头再找,把起点当下一站 - 修复后在终点站返回 nil,明确表示无后续站 2. 服务端 handleTrainArrival: 智能区分普通站/终点站广播序列 - 新增 hasNextStation / finalNextCode 判断:只有当下一站有效时 才在 seq 中插入 ch-nextsta + ch- 片段 - 终点站(finalNextCode 为 null):直接删除 nextsta 和下一站代码, 仅保留 站台-站台-线路-方向-终点站-警示 片段 - 避免 ch-UNK 等无效资源或回绕起点站名被播放 3. 日志增强:arrival 处理时额外打印 nextStation 和 nextCode, 便于快速确认服务端是否收到正确的下一站信息 版本号 v1.0.69 -> v1.0.70 --- CloudServer/server.js | 24 +++++-- station_broadcast.lua | 146 +++++++++++++++++++++++++++++------------- 2 files changed, 117 insertions(+), 53 deletions(-) diff --git a/CloudServer/server.js b/CloudServer/server.js index efc4936..2501e6e 100644 --- a/CloudServer/server.js +++ b/CloudServer/server.js @@ -2139,7 +2139,10 @@ function handleTrainArrival(ws, data) { const lineCode = data.lineCode || (stationCode ? stationCode.split('-')[0] : 'UNK'); const destCode = data.destCode || getStationCodeFromName(data.destination) || 'UNK'; - const nextCode = data.nextCode || getStationCodeFromName(data.nextStation) || 'UNK'; + const nextStationRaw = data.nextStation ? String(data.nextStation).trim() : ''; + const nextCodeRaw = data.nextCode ? String(data.nextCode).trim() : (nextStationRaw ? getStationCodeFromName(nextStationRaw) : ''); + const hasNextStation = nextStationRaw && nextStationRaw !== '' && nextCodeRaw && nextCodeRaw !== 'UNK' && nextCodeRaw !== ''; + const finalNextCode = hasNextStation ? nextCodeRaw : null; const existingIndex = activeTrains.findIndex(t => t.trainId === trainId); const trainData = { @@ -2155,7 +2158,7 @@ function handleTrainArrival(ws, data) { activeTrains.push(trainData); } - log('INFO', `Train ${trainId} arrived at ${stationName}. Broadcasting...`); + log('INFO', `Train ${trainId} arrived at ${stationName}. Broadcasting... nextStation=${nextStationRaw || '(none/terminal)'} nextCode=${finalNextCode || '(none)'}`); saveData(); broadcastUpdate(); @@ -2173,11 +2176,18 @@ function handleTrainArrival(ws, data) { })); // Broadcast Audio Logic - const seq = [ - 'ksts', - `ja-${finalPlatform}`, 'ja-zt', `ja-${lineCode}`, `ja-${destCode}`, 'ja-to', 'ja-nextsta', `ja-${nextCode}`, 'ja-warn', - `ch-${finalPlatform}`, 'ch-zt', `ch-${lineCode}`, 'ch-to', `ch-${destCode}`, 'ch-nextsta', `ch-${nextCode}`, 'ch-warn' - ]; + const seq = ['ksts']; + if (finalNextCode) { + seq.push( + `ja-${finalPlatform}`, 'ja-zt', `ja-${lineCode}`, `ja-${destCode}`, 'ja-to', 'ja-nextsta', `ja-${finalNextCode}`, 'ja-warn', + `ch-${finalPlatform}`, 'ch-zt', `ch-${lineCode}`, 'ch-to', `ch-${destCode}`, 'ch-nextsta', `ch-${finalNextCode}`, 'ch-warn' + ); + } else { + seq.push( + `ja-${finalPlatform}`, 'ja-zt', `ja-${lineCode}`, `ja-${destCode}`, 'ja-warn', + `ch-${finalPlatform}`, 'ch-zt', `ch-${lineCode}`, 'ch-to', `ch-${destCode}`, 'ch-warn' + ); + } enqueueHlsPush(stationName, seq); diff --git a/station_broadcast.lua b/station_broadcast.lua index d52a197..7dc64ac 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -1,6 +1,6 @@ -- 1. Configuration & Constants -local APP_VERSION_TEXT = "v1.0.69" +local APP_VERSION_TEXT = "v1.0.70" local CONFIG = { CLOUD_URL = "ws://stabadmin.fse-media.group", @@ -975,7 +975,6 @@ function Utils.getNextStation(schedule, currentStationName) end if matchFoundIndex then - -- Search forward for i = matchFoundIndex + 1, maxIdx do local entry = schedule.entries[i] if entry and entry.instruction then @@ -985,16 +984,6 @@ function Utils.getNextStation(schedule, currentStationName) end end end - -- Loop around to beginning - for i = 1, matchFoundIndex - 1 do - local entry = schedule.entries[i] - if entry and entry.instruction then - local inst = entry.instruction - if inst.id == "create:station" or inst.id == "create:destination" then - return (inst.data and inst.data.text) or inst.text - end - end - end end return nil @@ -3053,6 +3042,99 @@ local function isStationDestination(destName) return true end +local function looksLikeValidDestinationText(text) + if not text then return false end + local s = tostring(text) + if s == "" then return false end + local lower = string.lower(s) + if lower == "unknown" then return false end + local questionMarkCount = 0 + for i = 1, #s do + 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 + local hasRealChar = false + for i = 1, #s do + local b = string.byte(s, i) + if b and b >= 48 and b <= 57 then hasRealChar = true break end + if b and b >= 65 and b <= 90 then hasRealChar = true break end + if b and b >= 97 and b <= 122 then hasRealChar = true break end + if b and b >= 128 then hasRealChar = true break end + end + if not hasRealChar then return false end + return isStationDestination(s) +end + +local function tryCorrectUpcomingEntryWithCurrentTrain(entry) + if not State.currentTrain or not entry then return entry end + local ctId = State.currentTrain.id + local ctDest = State.currentTrain.dest + local ctPlatform = tostring(State.stationPlatform or State.currentTrain.platform or "1") + local entryPlatform = tostring(entry.platform or "1") + local samePlatform = (entryPlatform == ctPlatform) + local sameTrain = false + if ctId and entry.trainName then + sameTrain = Utils.isSameTrain(ctId, entry.trainName) + end + if not sameTrain and not samePlatform then return entry end + local validId = looksLikeValidDestinationText(entry.trainName) + local validDest = looksLikeValidDestinationText(entry.dest) + if not validId and ctId and ctId ~= "" then + entry.trainName = ctId + end + if not validDest and ctDest and ctDest ~= "" then + entry.dest = ctDest + elseif sameTrain and ctDest and ctDest ~= "" then + if not Utils.isFuzzyMatch(entry.dest or "", ctDest) then + local entryDestValid = looksLikeValidDestinationText(entry.dest) + if not entryDestValid then + entry.dest = ctDest + end + end + end + return entry +end + +local function checkIsAtStationWithCurrentTrain(trainName, destination, platform) + if not State.currentTrain then return false end + local ctId = State.currentTrain.id + local ctDest = State.currentTrain.dest + local ctPlatform = tostring(State.stationPlatform or State.currentTrain.platform or "1") + local trainPlatform = tostring(platform or "1") + if trainPlatform == ctPlatform then + return true + end + local sameTrain = false + if ctId and trainName then + if ctId == trainName then + sameTrain = true + else + local validCT = looksLikeValidDestinationText(ctId) + local validEntry = looksLikeValidDestinationText(trainName) + if validCT and validEntry then + sameTrain = Utils.isSameTrain(ctId, trainName) + elseif (not validEntry) and validCT then + sameTrain = Utils.isFuzzyMatch(ctDest or "", destination or "") + end + end + end + if sameTrain then + local entryIdValid = looksLikeValidDestinationText(trainName) + if entryIdValid then + return true + else + if Utils.isFuzzyMatch(ctDest or "", destination or "") then + return true + end + if not looksLikeValidDestinationText(destination) then + return true + end + end + end + return false +end + function Main.loop() while true do local now = os.epoch("utc") @@ -3204,23 +3286,7 @@ function Main.loop() end end - local isAtStation = false - local trainPlatform = tostring(platform or State.stationPlatform or "1") - local currentPlatform = tostring(State.stationPlatform or "1") - - if State.currentTrain then - if trainPlatform == currentPlatform then - isAtStation = true - elseif State.currentTrain.id == trainName then - if trainName == "???" or trainName == "Unknown" or trainName == "" then - if Utils.isFuzzyMatch(State.currentTrain.dest, destination) then - isAtStation = true - end - else - isAtStation = true - end - end - end + local isAtStation = checkIsAtStationWithCurrentTrain(trainName, destination, platform) if not isAtStation and etaSeconds > 0 and etaSeconds <= 45 then if not seenApproachKeys[announceKey] then seenApproachKeys[announceKey] = true @@ -3358,23 +3424,7 @@ function Main.loop() end end - local isAtStation = false - local trainPlatform = tostring(platform or State.stationPlatform or "1") - local currentPlatform = tostring(State.stationPlatform or "1") - - if State.currentTrain then - if trainPlatform == currentPlatform then - isAtStation = true - elseif State.currentTrain.id == tName then - if tName == "???" or tName == "Unknown" or tName == "" then - if Utils.isFuzzyMatch(State.currentTrain.dest, dest) then - isAtStation = true - end - else - isAtStation = true - end - end - end + local isAtStation = checkIsAtStationWithCurrentTrain(tName, dest, platform or State.stationPlatform or "1") if not isAtStation and etaSeconds > 0 and etaSeconds <= 45 then if not seenApproachKeys[announceKey] then seenApproachKeys[announceKey] = true @@ -3424,6 +3474,10 @@ function Main.loop() end + for _, entry in ipairs(newUpcoming) do + tryCorrectUpcomingEntryWithCurrentTrain(entry) + end + State.upcomingTrains = newUpcoming if not Peripherals.station then