refactor(station_broadcast): 清理冗余代码与注释,移除无用文件并更新gitignore

- 清理station_broadcast.lua中的冗余注释、废弃代码块,移除无用的节分隔注释
- 删除不再使用的austream.lua文件
- 更新.gitignore,新增临时文件与转储文件的忽略规则
This commit is contained in:
2026-08-02 22:03:06 +08:00
parent 59865138c7
commit 6964e7a47d
4 changed files with 49 additions and 3986 deletions
+43 -110
View File
@@ -1,7 +1,5 @@
-- ============================================================================
-- 1. Configuration & Constants
-- ============================================================================
local APP_VERSION_TEXT = "v1.0.46"
local CONFIG = {
@@ -34,9 +32,9 @@ local COLORS = {
SUCCESS = colors.green
}
-- ============================================================================
-- 2. State Management
-- ============================================================================
local State = {
ws = nil,
stationName = "Unknown",
@@ -60,9 +58,9 @@ local State = {
updateInProgress = false
}
-- ============================================================================
-- 3. Peripherals Setup
-- ============================================================================
local Peripherals = {}
function Peripherals.isTrainStationPeripheral(name)
@@ -80,9 +78,6 @@ function Peripherals.isTrainStationPeripheral(name)
return false
end
-- Create Wiki documents the station peripheral by its methods rather than a
-- guaranteed fixed type string. Match on the core method set so attached
-- stations are still detected across integration/version differences.
return type(wrapped.getStationName) == "function"
and type(wrapped.isTrainPresent) == "function"
and type(wrapped.getTrainName) == "function"
@@ -90,7 +85,6 @@ function Peripherals.isTrainStationPeripheral(name)
end
function Peripherals.init()
-- Station Peripheral: prefer direct sides, then fall back to any discovered peripheral name.
local station = nil
local stationSide = nil
local checkedNames = {}
@@ -115,7 +109,7 @@ function Peripherals.init()
Peripherals.station = station
State.hasStationPeripheral = station ~= nil
State.stationPeripheralSide = stationSide
-- monitors
local monitors = { peripheral.find("monitor") }
if #monitors > 0 then
Peripherals.primaryMonitor = monitors[1]
@@ -125,14 +119,13 @@ function Peripherals.init()
Peripherals.primaryMonitor = nil
State.hasPrimaryMonitor = false
end
-- Speakers
Peripherals.speakers = { peripheral.find("speaker") }
-- Create Target Block (CRN)
Peripherals.createTarget = peripheral.find("create_target")
if Peripherals.createTarget then
pcall(Peripherals.createTarget.resize, 80, 10)
end
-- Block Reader (Advanced Peripherals)
local blockReader = nil
local typeCandidates = { "blockReader", "block_reader", "arBlockReader", "advancedperipherals:block_reader" }
for _, t in ipairs(typeCandidates) do
@@ -154,9 +147,9 @@ function Peripherals.init()
Peripherals.blockReader = blockReader
end
-- ============================================================================
-- 4. Utility Functions
-- ============================================================================
local Utils = {}
function Utils.log(level, message)
@@ -165,8 +158,7 @@ function Utils.log(level, message)
local entry = { level = level, text = entryText }
table.insert(State.logs, 1, entry)
if #State.logs > 100 then table.remove(State.logs) end
-- If user is scrolling history, increment offset to stay on same items
if State.logScrollOffset > 0 then
State.logScrollOffset = math.min(State.logScrollOffset + 1, math.max(0, #State.logs - 1))
end
@@ -546,7 +538,7 @@ function Utils.getStationCode(name)
end
if code then
return tostring(code):lower() -- Always return lowercase for consistent comparison
return tostring(code):lower()
end
return nil
end
@@ -570,7 +562,6 @@ function Utils.isSameTrain(id1, id2)
if not id1 or not id2 then return false end
if id1 == id2 then return true end
-- Consist Car Match: "CK 1 01" vs "CK 1 02"
local function getConsist(id)
local clean = id:gsub("^%[.-%]%s*", "")
local p = {}
@@ -587,27 +578,26 @@ function Utils.isSameTrain(id1, id2)
local c2 = getConsist(id2)
if c1 == c2 then return true end
-- Fuzzy match: remove type prefix and compare content
local _, name1, num1 = Utils.parseTrainId(id1)
local _, name2, num2 = Utils.parseTrainId(id2)
-- If both have numbers, compare name and number
if num1 ~= "" and num2 ~= "" then
return name1 == name2 and num1 == num2
end
-- Fallback to comparing just the main content/name
return name1 == name2
end
function Utils.parseTrainId(trainId)
if not trainId then return "unknown", "" end
-- Generic match: [Type]Content
local typeStr, content = trainId:match("^%[(.-)%](.+)$")
if typeStr then
-- Check for Express types
if typeStr == "Ltd.Exp" or typeStr == "Express" then
local name, num = content:match("^(.+) No%.(%d+)$")
@@ -628,7 +618,6 @@ end
function Utils.getDestination(schedule)
if not schedule then return "Unknown" end
-- Handle both wrapped and unwrapped schedule structure
local entries = schedule.entries or (type(schedule) == "table" and schedule)
if not entries or type(entries) ~= "table" then return "Unknown" end
@@ -692,7 +681,7 @@ function Utils.isFuzzyMatch(str, pattern)
if str == pattern then return true end
-- 1. Handle Create Mod Wildcards (*)
-- 1. Handle Create Mod Wildcards
if pattern:find("*") then
local p = pattern:gsub("([%^%$%(%)%%%.%[%]%+%-%?])", "%%%1")
p = p:gsub("%%%*", ".*")
@@ -705,7 +694,6 @@ function Utils.isFuzzyMatch(str, pattern)
local b2 = Utils.getBaseName(pattern)
if b1 ~= "" and b2 ~= "" then
if b1 == b2 then return true end
-- Substring match for base names
if #b1 >= 4 and #b2 >= 4 then
if b1:find(b2, 1, true) or b2:find(b1, 1, true) then
return true
@@ -954,9 +942,9 @@ function Utils.getNextStation(schedule, currentStationName)
return nil
end
-- ============================================================================
-- 5. Audio System
-- ============================================================================
local Audio = {}
function Audio.createStream()
@@ -1573,7 +1561,6 @@ function Audio.playDfpwmItem(item)
local playSeq = State.interruptSeq
local source = item.audioData
-- Support both static string data and streaming functions
if type(source) == "table" and source.read then
source = source.read
end
@@ -1644,7 +1631,7 @@ function Audio.playWavStreamItem(item)
local playSeq = State.interruptSeq
-- Ensure all speakers are completely empty and synced before starting the new stream
if not waitForNativeSpeakersEmpty(Peripherals.speakers, playSeq) then
return
end
@@ -1789,11 +1776,11 @@ function Utils.getChineseNumberAudio(val)
end
return seq
else
-- Handle Alphanumeric (e.g., "1A", "2B")
-- Handle Alphanumeric
local digit, letter = tostring(val):match("^(%d+)([a-zA-Z])$")
if digit and letter then
local seq = Utils.getChineseNumberAudio(digit)
table.insert(seq, letter:upper()) -- e.g. "A", "B"
table.insert(seq, letter:upper())
return seq
end
return {tostring(val)}
@@ -1811,7 +1798,7 @@ function Utils.getStationAudio(code, langPrefix)
end
end
end
-- Fallback to hardcoded pattern
return langPrefix .. code
end
@@ -2012,7 +1999,6 @@ function Network.register()
end
function Network.syncFiles()
-- Sync only config file (list.txt) periodically
while true do
local resp = http.get(CONFIG.API_URL .. "/list.txt")
if not resp then
@@ -2194,7 +2180,7 @@ function Network.messageLoop()
elseif event == "websocket_closed" then
Utils.log("WARN", "WS Closed")
State.ws = nil
State.audioRx = nil -- Clear partial download
State.audioRx = nil
os.sleep(5)
end
end
@@ -2216,9 +2202,9 @@ function Network.heartbeat()
end
end
-- ============================================================================
-- 7. Display System
-- ============================================================================
local Display = {}
function Display.render()
@@ -2410,9 +2396,9 @@ function Display.renderTerminal()
end
end
-- ============================================================================
-- 7.5 Input Handling
-- ============================================================================
local Input = {}
function Input.listener()
@@ -2443,13 +2429,13 @@ function Input.listener()
Display.renderTerminal()
Display.render()
elseif event == "monitor_touch" and param1 == monitorName then
-- Simple touch to scroll: top half of log area scrolls up, bottom half scrolls down
local _, monH = Peripherals.primaryMonitor.getSize()
local y = param3
if y >= monH - 3 then
if y == monH - 3 then -- Top line of log area
if y == monH - 3 then
State.logScrollOffset = math.min(State.logScrollOffset + 1, math.max(0, #State.logs - 3))
elseif y == monH then -- Bottom line of log area
elseif y == monH then
State.logScrollOffset = math.max(0, State.logScrollOffset - 1)
end
Display.renderTerminal()
@@ -2484,9 +2470,9 @@ function Input.listener()
end
end
-- ============================================================================
-- 8. Main Logic
-- ============================================================================
local Main = {}
State.announcedApproaching = {}
State.announcedAlerts = {}
@@ -2510,52 +2496,7 @@ local function isPendingAlertReady(key, now)
return (now - firstSeen) >= (tonumber(CONFIG.ALERT_CONFIRM_MS) or 60000)
end
local function parseEtaText(etaStr)
etaStr = tostring(etaStr or "")
if etaStr == "" then return -1 end
if string.find(etaStr, "现在", 1, true)
or string.find(etaStr, "到达", 1, true)
or string.find(etaStr, "^0+$")
then
return 0
end
local mm, ss = string.match(etaStr, "(%d+)%s*:%s*(%d+)")
if mm and ss then
return tonumber(mm) * 60 + tonumber(ss)
end
local min, sec = string.match(etaStr, "(%d+)%s*分.-(%d+)%s*秒")
if min and sec then
return tonumber(min) * 60 + tonumber(sec)
end
local secOnly = string.match(etaStr, "(%d+)%s*秒")
if secOnly then
return tonumber(secOnly)
end
local minOnly = string.match(etaStr, "(%d+)%s*分")
if minOnly then
return tonumber(minOnly) * 60
end
local num, unit = string.match(etaStr, "(%d+)%s*(.*)")
if num then
num = tonumber(num)
unit = tostring(unit or ""):lower()
if unit == "" then
return num
end
if string.find(unit, "秒", 1, true) or string.find(unit, "s", 1, true) or string.find(unit, "sec", 1, true) or (unit == "??" and num > 10) then
return num
end
return num * 60
end
return -1
end
local function normalizeUpcomingKey(trainName, destination)
local function clean(value)
@@ -2624,8 +2565,7 @@ function Main.loop()
local etaTextByKey = {}
local delayTextByKey = {}
-- Read CRN text ETA only for display wording.
-- Timing decisions and numeric ETA still come from NBT.
-- ETA come from NBT.
if Peripherals.createTarget then
local okLines, lines = pcall(Peripherals.createTarget.dump)
if okLines and type(lines) == "table" then
@@ -2657,11 +2597,10 @@ function Main.loop()
end
end
-- Check Block Reader (Advanced Peripherals) first for precise ETA and Delay
if Peripherals.blockReader then
local ok, data = pcall(Peripherals.blockReader.getBlockData)
if ok and data and data.TrainStops then
-- Real-time interpolation: estimate actual tick rate (TPS) from CRN refreshes
if not State.lastRefreshed or State.lastRefreshed ~= data.LastRefreshed then
if State.lastRefreshed and State.lastRefreshedEpoch then
local deltaTicks = (data.LastRefreshed or 0) - (State.lastRefreshed or 0)
@@ -2711,8 +2650,7 @@ function Main.loop()
if cancelled then
reason = "cancelled"
end
-- Calculate ETA in seconds using interpolated currentTick
local scheduledArrival = pickEarlierTick(st.ScheduledArrival, st.ScheduledDeparture)
local realArrival = pickEarlierTick(st.RealTimeArrival, st.RealTimeDeparture)
local etaTicks = realArrival - currentTick
@@ -2720,8 +2658,7 @@ function Main.loop()
if etaSeconds < 0 then etaSeconds = 0 end
local announceKey = normalizeUpcomingKey(trainName, destination)
local etaLabel = buildEtaLabel(etaSeconds, etaTextByKey[announceKey])
-- Calculate Delay in minutes
local delayTicks = realArrival - scheduledArrival
local delayMinutes = math.floor(delayTicks / ((State.tickRate or 20) * 60))
if delayMinutes < 0 then delayMinutes = 0 end
@@ -2811,7 +2748,6 @@ function Main.loop()
end
end
-- Try CC:C Bridge Display Link (Legacy Text Parsing) if Block Reader is not available
if not Peripherals.blockReader and Peripherals.createTarget then
local lines = Peripherals.createTarget.dump()
local seenAlertKeys = {}
@@ -2825,7 +2761,6 @@ function Main.loop()
local delayMatch = string.match(lineText, "%+%s*(%d+)")
local delay = tonumber(delayMatch) or 0
-- 从文本中移除延误相关的字眼,防止干扰后续的正则表达式匹配
local cleanLine = string.gsub(lineText, "%s*%(?%+%s*%d+.-%)?", "")
local platform, etaStr, tName, dest
@@ -2839,8 +2774,7 @@ function Main.loop()
if tName and etaStr then
local announceKey = tName .. "_" .. dest
-- 将 ETA 转换为秒数进行精准判断
local etaSeconds = -1
local isNow = string.find(etaStr, "现在") or string.find(etaStr, "0")
@@ -2850,7 +2784,7 @@ function Main.loop()
local num, unit = string.match(etaStr, "(%d+)%s*(.*)")
if num then
num = tonumber(num)
-- 如果单位包含秒的字眼,或者是乱码但数值>10(如 45 ??, 30 ??),则认为是秒
if string.find(unit, "秒") or string.find(unit, "s") or string.find(unit, "sec") or (unit == "??" and num > 10) then
etaSeconds = num
else
@@ -2893,7 +2827,6 @@ function Main.loop()
end
end
-- 触发逻辑:当 ETA 已经明确不大于45秒,且之前没有播报过
if etaSeconds >= 0 and etaSeconds <= 45 then
seenApproachKeys[announceKey] = true
local pending = State.pendingApproaching[announceKey]
@@ -2942,7 +2875,7 @@ function Main.loop()
end
end
-- Update Upcoming Trains globally for the monitor
State.upcomingTrains = newUpcoming
if not Peripherals.station then
@@ -3016,9 +2949,9 @@ function Main.loop()
end
end
-- ============================================================================
-- 9. Bootstrap
-- ============================================================================
AutoUpdate.checkOnBoot()
Peripherals.init()
Utils.ensureSlaveIdentityConfigured()