Henry_Du
|
a6d9b6c418
|
fix(server): 修复 serve-static 不接受数组 root、改为按请求逐个挂载,避免启动时 TypeError: root path must be a string
上一轮把 getBeepAudioDirs() 这个数组直接塞进 express.static(),
但 serve-static 签名要求 root 必须是字符串,会在 app 启动注册
中间件时直接抛错(甚至在接收请求前)。
修复方式:
- /media/audio/general 和 /media/audio/beep 改为动态中间件:
请求进来时再依次对每个目录调用一次 express.static(root, {fallthrough})
- 单目录的 music/voice/line/station/temp 保留 express.static
但统一包一层 String(xxx || '') 保证就算路径解析异常也是空
字符串而不是 undefined
- 后备的 7 条 app.get(':path(*)') 路由不变,仍然负责 sendBinaryFile /
sendBinaryFileFromCandidates 兜底(含 range、Content-Length 等头)
客户端 bump v1.0.102 -> v1.0.103
|
2026-08-17 15:44:38 +08:00 |
|
Henry_Du
|
5c462a4d09
|
fix(server): 改用 Express 5 + path-to-regexp v7 兼容的通配写法,避免路由启动崩溃
Express 5 内置的 path-to-regexp v7 不再支持裸 '*',也不支持
自定义正则 '.*'(会报 Missing parameter name)。Express 5
官方兼容的单段全通写是 ':name(*)',并且路由注册会在 app 启动
第一时间完成(出错会直接崩)。
同时为了兼容旧 URL 行为,保留 express.static 前置挂载 +
显式 app.get 后备两条路径,因为 Audio 模块可能需要带
Cache-Control / Range / Content-Type 等头的 custom sendBinaryFile
处理(例如 station 动态裁剪音频),所以不能直接用 static 替代。
修复 7 条路由:
/media/audio/general/:path(*)
/media/audio/beep/:path(*)
/media/audio/music/:path(*)
/media/audio/voice/:path(*)
/media/audio/line/:path(*)
/media/audio/station/:path(*)
/media/temp/:path(*)
参数解码加 decodeURIComponent(),兼容中文/空格文件名。
客户端 bump v1.0.101 -> v1.0.102
|
2026-08-17 15:41:36 +08:00 |
|
Henry_Du
|
fc66e43379
|
fix: 修复新版 path-to-regexp 不兼容 '*' 通配符导致启动崩溃
新版 express/router 依赖的 path-to-regexp 不再接受裸 '*' 路径语法,
改为命名通配参数 :relPath(.*),并同步把 req.params[0] 改为
req.params.relPath。涉及 7 条 /media/* 静态路由:
- /media/audio/general/*
- /media/audio/beep/*
- /media/audio/music/*
- /media/audio/voice/*
- /media/audio/line/*
- /media/audio/station/*
- /media/temp/*
客户端版本号 bump v1.0.100 -> v1.0.101
|
2026-08-17 15:38:41 +08:00 |
|
Henry_Du
|
4c7d94f2c9
|
feat(A1+B1): 引入站台多主机识别、音频线缆分组互斥令牌、本地Modem仲裁、线缆分组管理WebUI
服务端 A1 改动(CloudServer/server.js):
- stations 改为 nodes[] 多连接存储,同站台名的多台 CC 主机归入同一组(纯 stationName 精确分组)
- 新增 getStationMaster():hasStationPeripheral + lastSeen 加权选 Master,音频只下发给 Master
- 新增 audioCableGroups 数据结构(持久化到 server-data.json)
- 新增 acquireCableToken/releaseCableToken:同线缆组全局互斥,高优先级发送 audio_preempt 抢占
- 新增 7 路由 REST API:/api/audio-cable-groups CRUD + 批量/单个站台成员管理 + PUT /stations/:name/cable-group 直接改组
- sendAudioControl 给同站组所有节点全量下发(stop/状态同步)
- init_state / state_update 携带 audioCableGroups 给前端
- WS close 自动 removeStationWs 清理节点 + 释放令牌
客户端 B1 改动(station_broadcast.lua v1.0.99):
- Peripherals 新增 wiredModems 扫描(排除无线),自动 rednet.open
- 新增 LocalBus 命名空间:
- station_hello 每 10s 广播 + 30s 超时清理邻居
- 同站台名自动组 stationGroup,按 hasStationPeripheral + nodeId 升序选 Master
- 新增 Utils.isLocalStationMaster(),所有列车上报(arrival/approaching/alert/departure/schedule_sync)仅 Master 执行,彻底解决重复广播
- acquireLocalToken:audio_probe -> 80ms 收响应 -> 必要时 audio_preempt 抢占 -> token_grant
- 令牌持有期间每 2s 广播 audio_playing 心跳,30s 超时自动判死回收
- Audio.playerLoop 在 playItem 前获取本地令牌,失败则跳过该音频
- Audio.stop() 自动释放本地令牌
- WS 新增下行处理:audio_preempt / cable_token_denied / station_group_state
- station_identity.cfg 支持 audio_cable_group= 字段,saveStationIdentity 写回
- Network.register/heartbeat 携带 cableGroup 供服务端回填分组
Web 管理端(CloudServer/public/cablemanager.html,单文件无外部依赖):
- 极简硬边风格,对齐 listmanager.html 配色和字体
- 分组网格卡片:色标/名称/描述/成员数/当前令牌持有者 + 编辑删除
- 新增/编辑 Modal:名称+描述+8色预设色板+自定义#RRGGBB
- 分组详情双栏 Dual List:左栏全部站台(搜索+在线状态+在其他组标签)/ 右栏成员,中间批量添加移除按钮
- 顶部快捷操作:站台下拉+组下拉+确认,直接 PUT /stations/:name/cable-group
- WebSocket 监听 state_update 实时刷新,Toast 提示反馈
|
2026-08-17 15:32:20 +08:00 |
|
Henry_Du
|
6ac05d3a84
|
feat(server): 实施 A1 方案 - 多连接存储、站台分组 Master 选举、audioCableGroup 互斥令牌机制
- stations 存储改造:stations[name] = { name, code, platform, audioCableGroup, version, lastSeen, nodes: [] } 结构,每个 node 含 ws/hasStationPeripheral/stationPeripheralSide/hasBlockReader/hasCreateTarget/identityMode/nodeId/wsId/connectedAt
- 新增 audioCableGroups:{ id, name, color, description, stationNames: [] } 分组,及 audioCableTokens 互斥令牌 Map(cableGroupId -> { holderStationName, holderAudioId, holderPriority, acquiredAt, cancelToken })
- 新增核心函数:upsertStationNode(按 wsId 去重更新 node、聚合计时表级 schedule)、removeStationWs(WS 关闭时清理 node + 释放令牌 + 下发 group_state)、getStationMaster(hasStationPeripheral=1000加权 + lastSeen小数加权 两轮选举 OPEN ws)、getAllStationConnections、getGroupKeyForStation(纯 stationName 分组,不再 code@@platform)、acquireCableToken(无持者直给/同 holder 更新/高优先级 audio_preempt + 200ms 延迟抢占/低优先级拒绝+denied 消息)、releaseCableToken
- 发送策略改造:sendAudioControl 遍历组内所有节点 ws 全发(同名站同步 stop 等指令);sendAudioBufferToStation/sendLiveWavChunksToStation 只发送 master ws,发送前后 acquire/release token,durationSec 后 setTimeout 延迟释放,audio_start 消息新增 cableGroupId 字段
- enqueueStationAudioQueue 增加 cableGrp 兜底释放;loadData 兼容旧 stations 单值结构导入 nodes=[] 数组新结构 + audioCableGroups 双向回填;saveData 剥离 nodes 中 ws 对象后保存,新增 audioCableGroups 字段持久化
- WS 层改造:wss close 事件调用 removeStationWs;console_connect init_state 增加 audioCableGroups 数组;handleStationRegister/handleHeartbeat/handleScheduleSync 改为调用 upsertStationNode;station_register_ack 返回 nodeId/audioCableGroup
- broadcastUpdate state_update 增加 audioCableGroups 字段;新增 WS 下行 audio_preempt / cable_token_granted / cable_token_denied / station_group_state 四种消息类型
- getStationGroups 完全重写:按 stationName 精确分组,返回 members/nodes 数组(每个 node 带 nodeId/wsId/online/isMaster/connectedAt/lastSeen/hasStationPeripheral/hasBlockReader/hasCreateTarget/identityMode/tickRate/memberTags),增加 masterNodeId、audioCableGroup{id,name,color}、cableGroupId 字段;resolveStationGroup memberNames 返回 nodeId 列表
- REST API 新增 9 个路由:GET/POST/PUT/DELETE /api/audio-cable-groups,POST /api/audio-cable-groups/:id/stations(批量加站台,含 prev cableGroup 自动清理)、DELETE /api/audio-cable-groups/:id/stations/:stationName、PUT /api/stations/:name/cable-group(stations.audioCableGroup 与 group.stationNames 双向同步),stations DELETE 自动同步 cable group 清理
- 兼容性:旧 stations[name].ws 统一改为 getStationMaster(name).ws;TTS、HLS、temp-broadcast、音乐播放、version 管理等功能不受破坏;Lua 客户端版本号提升至 v1.0.99
|
2026-08-17 15:15:23 +08:00 |
|
Henry_Du
|
55f0312314
|
feat(audio): 支持斜杠格式的车站编号和模糊搜索匹配
- 修改TTS音频导入逻辑,保留编号中的斜杠(/)格式(如 CH-01/CE-12),自动创建子目录
- 移除generator.html中单文件和批量导入时的斜杠转横杠逻辑
- 新增sanitizeStationCode和ensureDirForFile辅助函数,确保路径安全
- 重写findFileCaseInsensitive,支持递归子目录搜索与末尾段模糊匹配
- 新增listAllFilesRecursive和resolveAudioPathWithFuzzy工具函数
- 修改getPlaybackAudioByBaseName/findWavByBaseName支持模糊搜索查找
- 修改resolveManagedPath允许子路径访问,getManagedFiles递归扫描子目录
- 媒体路由从:file参数改为通配符/*形式,safeRelativeToBase确保路径安全
- 升级版本号至v1.0.98
|
2026-08-17 14:54:21 +08:00 |
|
Henry_Du
|
ae213a84a1
|
feat: 从机站台吸附识别与时刻表自动同步 v1.0.73
- Lua端: 新增定期外设重扫描(PERIPHERAL_SCAN_INTERVAL=15s),支持热插拔站台方块
- Lua端: 新增定期身份同步,站台外设热插/热拔时自动刷新身份并重新register
- Lua端: 新增独立的schedule sync coroutine与station_schedule_sync消息类型(SCHEDULE_SYNC_INTERVAL=10s)
- Lua端: 扩展heartbeat携带hasStationPeripheral/stationPeripheralSide/hasBlockReader/hasCreateTarget/identityMode/upcomingTrains/currentTrain等字段
- 从机若吸附有站台方块(train_station外设),则自动进入主机逻辑: 识别到发、停靠列车检测,数据通过WS推送到服务器
- server端: 新增assignDeviceFields工具函数统一写入设备字段与时刻表
- server端: 新增handleScheduleSync处理station_schedule_sync消息,数据写入stations[name]并broadcast
- server端: 扩展handleHeartbeat与handleStationRegister,均调用assignDeviceFields存储设备状态和时刻表摘要
- server端: 扩展getStationGroups分组视图,新增hostCount/slaveCount/hasAnyStationPeripheral/upcomingTrains/currentTrain/members详细信息
- 时刻表合并: 同一站台组多节点的upcomingTrains按trainName@@dest@@platform去重合并; currentTrain优先主机数据
- 版本升级: v1.0.72 -> v1.0.73
|
2026-08-16 13:33:10 +08:00 |
|
Henry_Du
|
ae96c86288
|
feat: departure广播新增下一站播报 + 客户端预解析station code
|
2026-08-16 13:01:32 +08:00 |
|
Henry_Du
|
32b2c8ce9d
|
fix: 终点站到达时下一站广播播放异常 + getNextStation 不回绕起点
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
|
2026-08-16 12:41:19 +08:00 |
|
Henry_Du
|
34d9ed00d6
|
fix: 解决自动更新无限重启循环 + 终点站列车不显示在预测列表
1. CloudServer: publishStationUpdate 发布时同步 Gitea 最新脚本到本地副本
- 新增 fetchGiteaScript() 一次下载全文
- 发布更新时将 Gitea 脚本内容写入 stationScriptPath
- 保证 targetVersion 与 /downloads/station_broadcast.lua 内容版本一致
2. 客户端 AutoUpdate.apply: 下载后校验版本一致性
- 从下载内容正则提取 APP_VERSION_TEXT
- 若 downloadedVersion ~= targetVersion 则中止更新,防止 reboot loop
- 写入错误日志便于排查
3. 预测显示: 在站列车(尤其终点站)强制插入 upcomingTrains 列表头部
- CRN 可能从 TrainStops 提前移除终点站列车
- 使用 normalizeUpcomingKey 去重避免重复条目
- 固定 ETA=0,确保 CURREN T TRAIN 对应列车能在 UPCOMING 中可见
版本号 v1.0.68 -> v1.0.69
|
2026-08-16 12:32:11 +08:00 |
|
Henry_Du
|
af00d57e68
|
feat: 发布更新时优先使用远程 Gitea 仓库的版本号
|
2026-08-16 11:54:29 +08:00 |
|
Henry_Du
|
b74eb252e3
|
feat: 在后端增加解析远程 Gitea 最新版本号的接口并展示在前端
|
2026-08-16 11:40:47 +08:00 |
|
Henry_Du
|
d8eee041c8
|
feat: 明确音频优先级,优化发车音频触发时机
- 到达与发车最高优先级(3),其次是进站预告(2),然后是延误警告(1),最低为背景音乐(0)
- 将发车音乐的触发时机从固定时间改为动态计算(音频时长+1.5秒补偿),确保音频结束时列车刚好发车
- 拆分 handleTrainApproaching 与 handleTrainAlert 逻辑,解耦进站与延误的优先级
- 版本号提升至 v1.0.59
|
2026-08-04 13:00:04 +08:00 |
|
Henry_Du
|
aa10f0ebe1
|
chore(server): 屏蔽 HLS RTMP 推流失败的错误日志
由于当前环境未配置 RTMP 服务器,当 ffmpeg 尝试推送音频流到 127.0.0.1:1935 时会一直报错 `Connection refused` 从而导致控制台刷屏。
现将该错误日志注释屏蔽,使控制台保持清爽。
|
2026-08-03 12:35:16 +08:00 |
|
Henry_Du
|
a36b21cfaf
|
fix(server): 完善列车接近音频的处理与日志记录
新增列车接近音频入队和构建失败的日志输出
调整音频任务优先级为1,中断模式改为ifLower
修复音频构建为空时的静默失败问题
|
2026-08-03 10:22:04 +08:00 |
|
Henry_Du
|
101d392840
|
fix(CloudServer/server): 修复列车接近处理的ch序列遗漏的站台编号参数
|
2026-08-03 09:59:58 +08:00 |
|
Henry_Du
|
b2888c6c88
|
chore(安装脚本与文档): 修改安装脚本下载源并新增教程视频
将install_station_broadcast.lua中的旧下载地址替换为gitea仓库的https新源,同时新增FSE铁路广播系统教程视频文件
|
2026-08-02 21:24:57 +08:00 |
|
Henry_Du
|
aef63ca444
|
fix: install updater alongside startup script
Download the update helper during install and expose it from the cloud server so new hosts can run manual updates immediately.
|
2026-08-02 21:20:28 +08:00 |
|
Henry_Du
|
10d15dfddc
|
feat: add station auto update publishing
Publish the latest station script from the console so online hosts download and reboot immediately while offline hosts update on their next load.
|
2026-08-02 20:04:55 +08:00 |
|
Henry_Du
|
906594008a
|
fix: remove ch-min from delay announcement
|
2026-08-02 19:06:20 +08:00 |
|
Henry_Du
|
39dc446958
|
功能(站点广播): 实现延误与停运列车的双语广播功能
添加所有中日文广播所需的音频资源文件
将应用版本更新至v1.0.37
修复列车状态原因映射逻辑,补充广播所需的缺失字段
实现根据延误、停运状态生成对应双语广播序列的逻辑
更新测试脚本以适配区块阅读器并正确解析CRN的NBT数据
添加示例NBT转储文件作为参考
|
2026-08-02 18:50:49 +08:00 |
|
Henry_Du
|
f922ace154
|
fix: trigger approaching broadcast under 30 seconds
|
2026-08-02 17:42:49 +08:00 |
|
Henry_Du
|
712d8bb84d
|
fix: Ensure platform is stripped of non-digit chars for audio file matching
|
2026-08-02 11:52:27 +08:00 |
|
Henry_Du
|
ef75671527
|
feat: Add train pre-arrival broadcast via CRN create_target
|
2026-08-02 11:37:41 +08:00 |
|
Henry_Du
|
ac8405e300
|
fix: use pcall to uncapped AUDIO_VOLUME for HQ speakers while keeping 3.0 fallback for vanilla speakers
|
2026-08-02 08:53:49 +08:00 |
|
Henry_Du
|
832658ad58
|
feat: apply 5x volume boost to all FFmpeg audio processing (broadcast sequences, HLS, DFPWM) to maximize loudness
|
2026-08-02 08:50:28 +08:00 |
|
Henry_Du
|
90c108b1d7
|
Update: remove ja-xl and ch-line from train arrival broadcast sequence
|
2026-08-01 23:05:39 +08:00 |
|
Henry_Du
|
4b3bd91023
|
Fix: implement case-insensitive file matching for broadcast audio sequences to fix missing uppercase line and station names
|
2026-08-01 22:54:10 +08:00 |
|
Henry_Du
|
2fae7305f6
|
Fix: use filter_complex for sequence concatenation to fix sample rate mismatch causing speed up and noise
|
2026-08-01 22:46:23 +08:00 |
|
Henry_Du
|
e009f05a61
|
Fix: use wav-stream-live for train arrivals and departures to fix CC client audio playback
|
2026-08-01 22:34:29 +08:00 |
|
Henry_Du
|
81f58b58bb
|
Fix: Lua client config screen overwritten by logs, and fix temp broadcast preview URL
|
2026-08-01 22:15:59 +08:00 |
|
Henry_Du
|
5c78b20163
|
Fix: include audioLineDir and audioVoiceDir when building broadcast sequence
|
2026-08-01 22:09:40 +08:00 |
|
Henry_Du
|
1043d46fb8
|
Fix: correctly setup line audio directory, routing, and upload handling
|
2026-08-01 18:41:29 +08:00 |
|
Henry_Du
|
495b3cedb9
|
Fix: save line audio to voice directory instead of beep
|
2026-08-01 18:30:59 +08:00 |
|
Henry_Du
|
2741b2d321
|
Revert TTS generation to backend with fixed local proxy 127.0.0.1:7890
|
2026-08-01 18:25:50 +08:00 |
|
Henry_Du
|
c76538e4bd
|
feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions
|
2026-08-01 17:58:20 +08:00 |
|
Henry_Du
|
a516976e35
|
Revert "feat: use pure direct connection to official api.fish.audio without any forced proxies"
This reverts commit 3ecae7b0bc.
|
2026-08-01 17:57:00 +08:00 |
|
Henry_Du
|
3ecae7b0bc
|
feat: use pure direct connection to official api.fish.audio without any forced proxies
|
2026-08-01 17:55:30 +08:00 |
|
Henry_Du
|
b8aee4d766
|
fix: revert to server proxy logic and add resilient fallback for win32 to prevent 500 errors
|
2026-08-01 17:51:08 +08:00 |
|
Henry_Du
|
038662c15e
|
Revert "feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions"
This reverts commit dedb37e22b.
|
2026-08-01 17:49:57 +08:00 |
|
Henry_Du
|
dedb37e22b
|
feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions
|
2026-08-01 17:45:48 +08:00 |
|
Henry_Du
|
1b6a2b7e33
|
feat: switch Fish Audio API endpoint to user's custom proxy domain (fishaudio.fse-media.group)
|
2026-08-01 17:42:24 +08:00 |
|
Henry_Du
|
7bfff51919
|
revert: switch back to direct Fish Audio API due to Vercel IP block
|
2026-08-01 17:37:52 +08:00 |
|
Henry_Du
|
f4c22cb713
|
feat: switch Fish Audio API endpoint to Vercel proxy to resolve ETIMEDOUT issues on server
|
2026-08-01 17:34:55 +08:00 |
|
Henry_Du
|
52ecdc8a16
|
Revert "fix: remove hardcoded windows proxy fallback that causes 500 error when proxy is unavailable"
This reverts commit 62ecf5642b.
|
2026-08-01 16:00:00 +08:00 |
|
Henry_Du
|
62ecf5642b
|
fix: remove hardcoded windows proxy fallback that causes 500 error when proxy is unavailable
|
2026-08-01 15:57:30 +08:00 |
|
Henry_Du
|
6150050f69
|
revert: move TTS generation back to server-side due to CORS issues
|
2026-08-01 12:01:38 +08:00 |
|
Henry_Du
|
6f122c7a2c
|
feat: add FISH_AUDIO_BASE env support for reverse proxy
|
2026-08-01 11:59:15 +08:00 |
|
Henry_Du
|
e3a88acf9b
|
Revert "feat: migrate TTS generation to frontend to utilize local browser proxy"
This reverts commit 5e600bb75d.
|
2026-08-01 11:58:20 +08:00 |
|
Henry_Du
|
5e600bb75d
|
feat: migrate TTS generation to frontend to utilize local browser proxy
|
2026-08-01 11:55:31 +08:00 |
|