refactor(peripheral): 移除tm_gpu外设支持并清理冗余代码

删除gate.lua与ticketmachine.lua中所有与tm_gpu相关的代码逻辑,移除冗余的table.pack兼容函数与事件重写代码,简化外设发现与终端处理流程,同步更新两个文件的版本号。
This commit is contained in:
2026-07-31 11:22:21 +08:00
parent 9c7e99633b
commit d685dee2a4
2 changed files with 8 additions and 433 deletions
+4 -217
View File
@@ -1,7 +1,7 @@
local DEFAULT_SERVER_BASE = "https://ticket.fse-media.group" local DEFAULT_SERVER_BASE = "https://ticket.fse-media.group"
local DEFAULT_SERVER_PATH = "/api/tickets/check" local DEFAULT_SERVER_PATH = "/api/tickets/check"
local GATE_OPEN_SECONDS = 2 local GATE_OPEN_SECONDS = 2
local VERSION = "v1.5.29" local VERSION = "v1.5.27"
local VERSION_CHECK_INTERVAL = 5 local VERSION_CHECK_INTERVAL = 5
local serverURL = nil local serverURL = nil
@@ -88,11 +88,9 @@ end
local nativeTerm = (term and type(term.current) == "function" and term.current()) or term local nativeTerm = (term and type(term.current) == "function" and term.current()) or term
local monitor = peripheral.find("monitor") local monitor = peripheral.find("monitor")
local tmGpu = peripheral.find("tm_gpu")
local speaker = peripheral.find("speaker") local speaker = peripheral.find("speaker")
local inspection = peripheral.find("ticket_inspection_machine") local inspection = peripheral.find("ticket_inspection_machine")
local monitorSide = nil local monitorSide = nil
local tmGpuSide = nil
local serverConnected = nil local serverConnected = nil
local isUpdating = false local isUpdating = false
@@ -172,219 +170,15 @@ local function setServerConnected(ok)
serverLastChangeTs = os.epoch("utc") serverLastChangeTs = os.epoch("utc")
end end
local GPU_CHAR_WIDTH = 4
local GPU_CHAR_HEIGHT = 6
local GPU_COLOR_MAP = {
[colors.white] = 0xFFFFFFFF,
[colors.orange] = 0xFFFFA500,
[colors.magenta] = 0xFFFF00FF,
[colors.lightBlue] = 0xFF66CCFF,
[colors.yellow] = 0xFFFFFF00,
[colors.lime] = 0xFF00FF00,
[colors.pink] = 0xFFFFB6C1,
[colors.gray] = 0xFF808080,
[colors.lightGray] = 0xFFD3D3D3,
[colors.cyan] = 0xFF00FFFF,
[colors.purple] = 0xFF800080,
[colors.blue] = 0xFF0000FF,
[colors.brown] = 0xFF8B4513,
[colors.green] = 0xFF008000,
[colors.red] = 0xFFFF0000,
[colors.black] = 0xFF000000,
}
local function ccColorToARGB(col)
return GPU_COLOR_MAP[col] or GPU_COLOR_MAP[colors.white]
end
local function isTmGpu(dev)
return type(dev) == "table"
and type(dev.getSize) == "function"
and type(dev.drawText) == "function"
and type(dev.fill) == "function"
and type(dev.sync) == "function"
end
local function scanForTmGpu()
if not peripheral or type(peripheral.getNames) ~= "function" or type(peripheral.wrap) ~= "function" then
return nil, nil
end
local names = peripheral.getNames() or {}
for _, name in ipairs(names) do
local okWrap, dev = pcall(peripheral.wrap, name)
if okWrap and isTmGpu(dev) then
return dev, name
end
end
return nil, nil
end
local function buildTmGpuTerm(dev)
local gpuTerm = {
kind = "tm_gpu",
device = dev,
cursorX = 1,
cursorY = 1,
textColor = colors.white,
backgroundColor = colors.black,
width = 1,
height = 1,
pixelWidth = 0,
pixelHeight = 0,
resolutionConfigured = false,
}
local function syncSize()
if type(gpuTerm.device.refreshSize) == "function" then
pcall(gpuTerm.device.refreshSize)
end
for _ = 1, 3 do
local size = pack(pcall(gpuTerm.device.getSize))
local px = tonumber(size[2]) or 0
local py = tonumber(size[3]) or 0
if size[1] and px > 0 and py > 0 then
if not gpuTerm.resolutionConfigured and type(gpuTerm.device.setSize) == "function" then
gpuTerm.resolutionConfigured = true
local resolution = tonumber(size[6]) or 0
if resolution > 0 and resolution < 32 then
pcall(gpuTerm.device.setSize, 32)
os.sleep(0)
size = pack(pcall(gpuTerm.device.getSize))
px = tonumber(size[2]) or px
py = tonumber(size[3]) or py
end
end
gpuTerm.pixelWidth = px
gpuTerm.pixelHeight = py
gpuTerm.width = math.max(1, math.floor(px / GPU_CHAR_WIDTH))
gpuTerm.height = math.max(1, math.floor(py / GPU_CHAR_HEIGHT))
return gpuTerm.width, gpuTerm.height
end
os.sleep(0)
end
if gpuTerm.pixelWidth <= 0 then gpuTerm.pixelWidth = 64 end
if gpuTerm.pixelHeight <= 0 then gpuTerm.pixelHeight = 32 end
gpuTerm.width = math.max(1, math.floor(gpuTerm.pixelWidth / GPU_CHAR_WIDTH))
gpuTerm.height = math.max(1, math.floor(gpuTerm.pixelHeight / GPU_CHAR_HEIGHT))
return gpuTerm.width, gpuTerm.height
end
function gpuTerm.getSize()
return syncSize()
end
function gpuTerm.setCursorPos(x, y)
gpuTerm.cursorX = math.max(1, math.floor(tonumber(x) or 1))
gpuTerm.cursorY = math.max(1, math.floor(tonumber(y) or 1))
end
function gpuTerm.setTextColor(col)
gpuTerm.textColor = GPU_COLOR_MAP[col] and col or colors.white
end
function gpuTerm.setBackgroundColor(col)
gpuTerm.backgroundColor = GPU_COLOR_MAP[col] and col or colors.black
end
function gpuTerm.clear()
syncSize()
pcall(gpuTerm.device.fill, ccColorToARGB(gpuTerm.backgroundColor))
gpuTerm.cursorX = 1
gpuTerm.cursorY = 1
end
function gpuTerm.write(text)
text = tostring(text or "")
if #text == 0 then return end
local width, height = syncSize()
local originalLen = #text
local x = gpuTerm.cursorX
local y = gpuTerm.cursorY
if y < 1 or y > height or x > width then
gpuTerm.cursorX = x + originalLen
return
end
if x < 1 then
local shift = 1 - x
if shift >= #text then
gpuTerm.cursorX = x + originalLen
return
end
text = text:sub(shift + 1)
x = 1
end
local visible = text:sub(1, math.max(0, width - x + 1))
if #visible > 0 then
local px = ((x - 1) * GPU_CHAR_WIDTH) + 1
local py = ((y - 1) * GPU_CHAR_HEIGHT) + 1
local bg = ccColorToARGB(gpuTerm.backgroundColor)
local fg = ccColorToARGB(gpuTerm.textColor)
pcall(gpuTerm.device.filledRectangle, px, py, #visible * GPU_CHAR_WIDTH, GPU_CHAR_HEIGHT, bg)
pcall(gpuTerm.device.drawText, px, py, visible, fg, bg, 1, 0)
end
gpuTerm.cursorX = gpuTerm.cursorX + originalLen
end
function gpuTerm.sync()
pcall(gpuTerm.device.sync)
end
return gpuTerm
end
local termDev = nativeTerm local termDev = nativeTerm
if peripheral and type(peripheral.getName) == "function" then if peripheral and type(peripheral.getName) == "function" and monitor then
if tmGpu then pcall(function() monitorSide = peripheral.getName(monitor) end)
pcall(function() tmGpuSide = peripheral.getName(tmGpu) end)
end
if monitor then
pcall(function() monitorSide = peripheral.getName(monitor) end)
end
end end
local function refreshDisplayTarget() local function refreshDisplayTarget()
local nextGpu = nil
local nextGpuSide = tmGpuSide
local nextMonitor = nil local nextMonitor = nil
local nextMonitorSide = monitorSide local nextMonitorSide = monitorSide
if peripheral then if peripheral then
if nextGpuSide and type(peripheral.isPresent) == "function" and peripheral.isPresent(nextGpuSide) and type(peripheral.wrap) == "function" then
local okWrap, wrapped = pcall(peripheral.wrap, nextGpuSide)
if okWrap and isTmGpu(wrapped) then
nextGpu = wrapped
end
end
if not nextGpu and type(peripheral.find) == "function" then
local foundGpuName = nil
local foundGpu = peripheral.find("tm_gpu", function(name, wrapped)
if isTmGpu(wrapped) then
foundGpuName = name
nextGpu = wrapped
return true
end
end)
if foundGpu and isTmGpu(foundGpu) then
nextGpu = foundGpu
nextGpuSide = foundGpuName
else
nextGpuSide = nil
end
end
if not nextGpu then
local dev, name = scanForTmGpu()
if dev then
nextGpu = dev
nextGpuSide = name
end
end
if nextMonitorSide and type(peripheral.isPresent) == "function" and peripheral.isPresent(nextMonitorSide) and type(peripheral.wrap) == "function" then if nextMonitorSide and type(peripheral.isPresent) == "function" and peripheral.isPresent(nextMonitorSide) and type(peripheral.wrap) == "function" then
local okWrap, wrapped = pcall(peripheral.wrap, nextMonitorSide) local okWrap, wrapped = pcall(peripheral.wrap, nextMonitorSide)
if okWrap and wrapped then if okWrap and wrapped then
@@ -406,13 +200,9 @@ local function refreshDisplayTarget()
end end
end end
end end
tmGpu = nextGpu
tmGpuSide = nextGpuSide
monitor = nextMonitor monitor = nextMonitor
monitorSide = nextMonitorSide monitorSide = nextMonitorSide
if tmGpu then if monitor then
termDev = buildTmGpuTerm(tmGpu)
elseif monitor then
pcall(monitor.setTextScale, 0.5) pcall(monitor.setTextScale, 0.5)
termDev = monitor termDev = monitor
else else
@@ -497,9 +287,6 @@ local function draw(statusLine1, statusLine2, statusColor)
termDev.setCursorPos(1, h) termDev.setCursorPos(1, h)
termDev.setTextColor(colors.gray) termDev.setTextColor(colors.gray)
termDev.write(string.rep(" ", w)) termDev.write(string.rep(" ", w))
if type(termDev.sync) == "function" then
termDev.sync()
end
end end
local function pulseLeftRedstone(seconds) local function pulseLeftRedstone(seconds)
+4 -216
View File
@@ -1,12 +1,8 @@
local CURRENT_STATION_CODE = 'Ticket-Machine' local CURRENT_STATION_CODE = 'Ticket-Machine'
local API_BASE = 'https://ticket.fse-media.group/api' local API_BASE = 'https://ticket.fse-media.group/api'
local VERSION = 'v1.5.27' local VERSION = 'v1.5.25'
local UPDATE_CHECK_INTERVAL = 5 local UPDATE_CHECK_INTERVAL = 5
local pack = table.pack or function(...)
return { n = select('#', ...), ... }
end
-- ########################### -- ###########################
-- Core HTTP & JSON Utilities -- Core HTTP & JSON Utilities
-- ########################### -- ###########################
@@ -344,172 +340,13 @@ local function reportIssue(errMsg, detail)
postJSONResult(url, payload) postJSONResult(url, payload)
end end
local GPU_CHAR_WIDTH = 4
local GPU_CHAR_HEIGHT = 6
local GPU_COLOR_MAP = {
[colors.white] = 0xFFFFFFFF,
[colors.orange] = 0xFFFFA500,
[colors.magenta] = 0xFFFF00FF,
[colors.lightBlue] = 0xFF66CCFF,
[colors.yellow] = 0xFFFFFF00,
[colors.lime] = 0xFF00FF00,
[colors.pink] = 0xFFFFB6C1,
[colors.gray] = 0xFF808080,
[colors.lightGray] = 0xFFD3D3D3,
[colors.cyan] = 0xFF00FFFF,
[colors.purple] = 0xFF800080,
[colors.blue] = 0xFF0000FF,
[colors.brown] = 0xFF8B4513,
[colors.green] = 0xFF008000,
[colors.red] = 0xFFFF0000,
[colors.black] = 0xFF000000,
}
local function ccColorToARGB(col)
return GPU_COLOR_MAP[col] or GPU_COLOR_MAP[colors.white]
end
local function isTmGpu(dev)
return type(dev) == 'table'
and type(dev.getSize) == 'function'
and type(dev.drawText) == 'function'
and type(dev.fill) == 'function'
and type(dev.sync) == 'function'
end
local function buildTmGpuTerm(dev)
local gpuTerm = {
kind = 'tm_gpu',
device = dev,
cursorX = 1,
cursorY = 1,
textColor = colors.white,
backgroundColor = colors.black,
width = 1,
height = 1,
pixelWidth = 0,
pixelHeight = 0,
resolutionConfigured = false,
}
local function syncSize()
if type(gpuTerm.device.refreshSize) == 'function' then
pcall(gpuTerm.device.refreshSize)
end
for _ = 1, 3 do
local size = pack(pcall(gpuTerm.device.getSize))
local px = tonumber(size[2]) or 0
local py = tonumber(size[3]) or 0
if size[1] and px > 0 and py > 0 then
if not gpuTerm.resolutionConfigured and type(gpuTerm.device.setSize) == 'function' then
gpuTerm.resolutionConfigured = true
local resolution = tonumber(size[6]) or 0
if resolution > 0 and resolution < 32 then
pcall(gpuTerm.device.setSize, 32)
os.sleep(0)
size = pack(pcall(gpuTerm.device.getSize))
px = tonumber(size[2]) or px
py = tonumber(size[3]) or py
end
end
gpuTerm.pixelWidth = px
gpuTerm.pixelHeight = py
gpuTerm.width = math.max(1, math.floor(px / GPU_CHAR_WIDTH))
gpuTerm.height = math.max(1, math.floor(py / GPU_CHAR_HEIGHT))
return gpuTerm.width, gpuTerm.height
end
os.sleep(0)
end
if gpuTerm.pixelWidth <= 0 then gpuTerm.pixelWidth = 64 end
if gpuTerm.pixelHeight <= 0 then gpuTerm.pixelHeight = 32 end
gpuTerm.width = math.max(1, math.floor(gpuTerm.pixelWidth / GPU_CHAR_WIDTH))
gpuTerm.height = math.max(1, math.floor(gpuTerm.pixelHeight / GPU_CHAR_HEIGHT))
return gpuTerm.width, gpuTerm.height
end
function gpuTerm.getSize()
return syncSize()
end
function gpuTerm.setCursorPos(x, y)
gpuTerm.cursorX = math.max(1, math.floor(tonumber(x) or 1))
gpuTerm.cursorY = math.max(1, math.floor(tonumber(y) or 1))
end
function gpuTerm.setTextColor(col)
gpuTerm.textColor = GPU_COLOR_MAP[col] and col or colors.white
end
function gpuTerm.setBackgroundColor(col)
gpuTerm.backgroundColor = GPU_COLOR_MAP[col] and col or colors.black
end
function gpuTerm.clear()
syncSize()
pcall(gpuTerm.device.fill, ccColorToARGB(gpuTerm.backgroundColor))
gpuTerm.cursorX = 1
gpuTerm.cursorY = 1
pcall(gpuTerm.device.sync)
end
function gpuTerm.write(text)
text = tostring(text or '')
if #text == 0 then return end
local width, height = syncSize()
local originalLen = #text
local x = gpuTerm.cursorX
local y = gpuTerm.cursorY
if y < 1 or y > height or x > width then
gpuTerm.cursorX = x + originalLen
return
end
if x < 1 then
local shift = 1 - x
if shift >= #text then
gpuTerm.cursorX = x + originalLen
return
end
text = text:sub(shift + 1)
x = 1
end
local visible = text:sub(1, math.max(0, width - x + 1))
if #visible > 0 then
local px = ((x - 1) * GPU_CHAR_WIDTH) + 1
local py = ((y - 1) * GPU_CHAR_HEIGHT) + 1
local bg = ccColorToARGB(gpuTerm.backgroundColor)
local fg = ccColorToARGB(gpuTerm.textColor)
pcall(gpuTerm.device.filledRectangle, px, py, #visible * GPU_CHAR_WIDTH, GPU_CHAR_HEIGHT, bg)
pcall(gpuTerm.device.drawText, px, py, visible, fg, bg, 1, 0)
pcall(gpuTerm.device.sync)
end
gpuTerm.cursorX = gpuTerm.cursorX + originalLen
end
function gpuTerm.sync()
pcall(gpuTerm.device.sync)
end
return gpuTerm
end
-- ########################### -- ###########################
-- Peripheral discovery -- Peripheral discovery
-- ########################### -- ###########################
local SIDE_PRIORITY = { top = 1, bottom = 2, left = 3, right = 4, front = 5, back = 6 } local SIDE_PRIORITY = { top = 1, bottom = 2, left = 3, right = 4, front = 5, back = 6 }
local REDSTONE_SIDES = { 'right', 'left', 'top', 'bottom', 'front', 'back' } local REDSTONE_SIDES = { 'right', 'left', 'top', 'bottom', 'front', 'back' }
local nativeTerm = (term and type(term.current) == 'function' and term.current()) or term
local monitor = nil local monitor = nil
local monitorName = nil local monitorName = nil
local tmGpu = nil
local tmGpuName = nil
local ticketVendingMachine = nil local ticketVendingMachine = nil
local ticketVendingMachineName = nil local ticketVendingMachineName = nil
local speaker = nil local speaker = nil
@@ -566,48 +403,23 @@ local function findPeripheralByType(typeName)
return nil, nil return nil, nil
end end
local function scanForTmGpu() local termDev = term
if not peripheral or type(peripheral.getNames) ~= 'function' or type(peripheral.wrap) ~= 'function' then
return nil, nil
end
local names = peripheral.getNames() or {}
table.sort(names, comparePeripheralName)
for _, name in ipairs(names) do
local okWrap, dev = pcall(peripheral.wrap, name)
if okWrap and isTmGpu(dev) then
return dev, name
end
end
return nil, nil
end
local termDev = nativeTerm or term
local w, h = termDev.getSize() local w, h = termDev.getSize()
local function refreshDevices() local function refreshDevices()
local prevSignature = table.concat({ local prevSignature = table.concat({
tostring(monitorName or ''), tostring(monitorName or ''),
tostring(tmGpuName or ''),
tostring(ticketVendingMachineName or ''), tostring(ticketVendingMachineName or ''),
tostring(speakerName or '') tostring(speakerName or '')
}, '|') }, '|')
monitor, monitorName = findPeripheralByType('monitor') monitor, monitorName = findPeripheralByType('monitor')
tmGpu, tmGpuName = findPeripheralByType('tm_gpu')
if not isTmGpu(tmGpu) then
tmGpu, tmGpuName = scanForTmGpu()
end
ticketVendingMachine, ticketVendingMachineName = findPeripheralByType('ticket_vending_machine') ticketVendingMachine, ticketVendingMachineName = findPeripheralByType('ticket_vending_machine')
speaker, speakerName = findPeripheralByType('speaker') speaker, speakerName = findPeripheralByType('speaker')
if tmGpu and isTmGpu(tmGpu) then termDev = monitor or term
termDev = buildTmGpuTerm(tmGpu) if monitor then pcall(monitor.setTextScale, 0.5) end
else
termDev = monitor or nativeTerm or term
if monitor then pcall(monitor.setTextScale, 0.5) end
end
w, h = termDev.getSize() w, h = termDev.getSize()
local nextSignature = table.concat({ local nextSignature = table.concat({
tostring(monitorName or ''), tostring(monitorName or ''),
tostring(tmGpuName or ''),
tostring(ticketVendingMachineName or ''), tostring(ticketVendingMachineName or ''),
tostring(speakerName or '') tostring(speakerName or '')
}, '|') }, '|')
@@ -618,30 +430,6 @@ end
refreshDevices() refreshDevices()
local nativePullEvent = os.pullEvent
local function pullEventCompat(filter)
while true do
local ev = pack(nativePullEvent())
local eventName = ev[1]
if eventName == 'tm_monitor_touch' then
local px = tonumber(ev[3]) or 1
local py = tonumber(ev[4]) or 1
ev[1] = 'monitor_touch'
ev[2] = tostring(ev[2] or tmGpuName or '')
ev[3] = math.max(1, math.floor((px - 1) / GPU_CHAR_WIDTH) + 1)
ev[4] = math.max(1, math.floor((py - 1) / GPU_CHAR_HEIGHT) + 1)
eventName = ev[1]
end
if not filter or filter == eventName then
return table.unpack(ev, 1, ev.n or #ev)
end
end
end
os.pullEvent = pullEventCompat
local function saveCardIssueSnapshot(cardData) local function saveCardIssueSnapshot(cardData)
pcall(function() pcall(function()
ensureDir('logs/last_card_issue.json') ensureDir('logs/last_card_issue.json')