From 810dff3f0e17495990fec5eec7556ded97034adc Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sat, 1 Aug 2026 11:23:55 +0800 Subject: [PATCH] feat: update station broadcast logic --- station_broadcast.lua | 110 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/station_broadcast.lua b/station_broadcast.lua index 13a78ef..4260ba1 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -170,7 +170,7 @@ function Utils.loadStationIdentity() return data end -function Utils.saveStationIdentity(stationCode, stationPlatform) +function Utils.saveStationIdentity(stationCode, stationPlatform, departureBeep) local handle = fs.open(CONFIG.STATION_IDENTITY_FILE, "w") if not handle then return false @@ -179,6 +179,7 @@ function Utils.saveStationIdentity(stationCode, stationPlatform) "# Station identity cache / override", "station_code=" .. Utils.trim(stationCode or ""), "station_platform=" .. Utils.trim(stationPlatform or ""), + "departure_beep=" .. Utils.trim(departureBeep or "fc1"), "" }, "\n")) handle.close() @@ -226,7 +227,7 @@ function Utils.promptSlaveIdentity() term.write("Press any key to retry...") os.pullEvent("key") else - local ok = Utils.saveStationIdentity(stationCode, stationPlatform) + local ok = Utils.saveStationIdentity(stationCode, stationPlatform, nil) if ok then term.setCursorPos(1, 10) term.setTextColor(colors.green) @@ -311,10 +312,16 @@ function Utils.resolveStationIdentity() identityMode = "manual-fallback" end + local departureBeep = manual.departure_beep + if not departureBeep or departureBeep == "" then + departureBeep = "fc1" + end + return { stationName = stationName, stationCode = stationCode or "UNK", stationPlatform = tostring(stationPlatform or "1"), + departureBeep = departureBeep, mode = identityMode } end @@ -338,7 +345,7 @@ function Utils.syncStationIdentityFromPeripheral() return false end - local ok = Utils.saveStationIdentity(stationCode, stationPlatform) + local ok = Utils.saveStationIdentity(stationCode, stationPlatform, identity.departureBeep) if ok then Utils.log("INFO", "Synced station_identity.cfg from physical station: " .. stationCode .. " / P" .. stationPlatform) return true @@ -352,6 +359,7 @@ function Utils.refreshStationIdentity() State.stationName = identity.stationName State.stationCode = identity.stationCode State.stationPlatform = identity.stationPlatform + State.departureBeep = identity.departureBeep State.stationIdentityMode = identity.mode end @@ -712,6 +720,71 @@ function Utils.getStopTime(schedule, stationName) return nil end +function Utils.getNextStation(schedule, currentStationName) + if not schedule or not schedule.entries or not currentStationName then return nil end + + local target = tostring(currentStationName):lower():match("^%s*(.-)%s*$") + if target == "" then return nil end + + local targetCode = Utils.getStationCode(target) + local targetBase = Utils.getBaseName(target) + local targetAlpha = target:gsub("[^%w%d]", "") + + local maxIdx = 0 + for k, _ in pairs(schedule.entries) do + if type(k) == "number" and k > maxIdx then maxIdx = k end + end + + local matchFoundIndex = nil + + 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) + + if isMatch then return true end + elseif type(v) == "table" then + if scanRecursive(v, depth + 1) then return true end + end + end + return false + end + + if scanRecursive(entry, 0) then + matchFoundIndex = i + break + end + end + end + + if matchFoundIndex then + for i = matchFoundIndex + 1, maxIdx do + local entry = schedule.entries[i] + if entry and entry.instruction then + local inst = entry.instruction + if inst.id == "create:station" then + return (inst.data and inst.data.text) or inst.text + end + end + end + end + + return nil +end + -- ============================================================================ -- 5. Audio System -- ============================================================================ @@ -2027,6 +2100,7 @@ function Main.loop() local id = Peripherals.station.getTrainName() local schedule = Peripherals.station.getSchedule() local dest = Utils.getDestination(schedule) + local nextStation = Utils.getNextStation(schedule, State.stationName) local now = os.epoch("utc") / 1000 local stationTime = Utils.getStopTime(schedule, State.stationName) or 60 @@ -2035,10 +2109,38 @@ function Main.loop() trainType = Utils.parseTrainId(id), schedule = schedule, dest = dest, + nextStation = nextStation, arrivalTime = now, departureTime = now + stationTime, - platform = Utils.getPlatformNumber(State.stationName, "1") + platform = Utils.getPlatformNumber(State.stationName, "1"), + departureSent = false } + + Network.send({ + type = "train_arrival", + stationName = State.stationName, + stationCode = State.stationCode, + stationPlatform = State.stationPlatform, + trainId = id, + destination = dest, + nextStation = nextStation, + departureTime = State.currentTrain.departureTime + }) + else + local now = os.epoch("utc") / 1000 + if not State.currentTrain.departureSent and (State.currentTrain.departureTime - now) <= 10 then + State.currentTrain.departureSent = true + Network.send({ + type = "train_departure", + stationName = State.stationName, + stationCode = State.stationCode, + stationPlatform = State.stationPlatform, + trainId = State.currentTrain.id, + destination = State.currentTrain.dest, + nextStation = State.currentTrain.nextStation, + departureBeep = State.departureBeep + }) + end end else if State.currentTrain then