diff --git a/ticketmachine.lua b/ticketmachine.lua index 20df990..647932c 100644 --- a/ticketmachine.lua +++ b/ticketmachine.lua @@ -1,6 +1,6 @@ local CURRENT_STATION_CODE = 'Ticket-Machine' local API_BASE = 'https://ticket.fse-media.group/api' -local VERSION = 'v1.5.22' +local VERSION = 'v1.5.23' local UPDATE_CHECK_INTERVAL = 5 -- ########################### @@ -562,10 +562,6 @@ local function issueTicketFromPeripheral(fromNameEnArg, toNameEnArg, apiType, ri if type(dev) ~= 'table' then return false, '', 'peripheral_unavailable' end - local fn = dev.issueTicket - if type(fn) ~= 'function' then - return false, '', 'unsupported_method' - end local function normalizeIssuedTicketId(id) if id == nil then return '' end @@ -582,25 +578,107 @@ local function issueTicketFromPeripheral(fromNameEnArg, toNameEnArg, apiType, ri return s end - local function tryIssue(...) - local okCall, r1, r2, r3 = pcall(fn, ...) - if not (okCall and peripheralCallSucceeded(r1)) then - return false, '', okCall and 'issue_failed' or 'issue_call_failed' - end - local issuedId = extractPeripheralId(r2, r3, r1, fallbackTicketId) - local normalizedId = normalizeIssuedTicketId(issuedId) - if #normalizedId == 0 then - return false, '', 'invalid_ticket_id' - end - return true, normalizedId, 'issueTicket' + local fallbackId = normalizeIssuedTicketId(fallbackTicketId) + local typeCandidates = { tostring(apiType or 'local') } + if apiType == 'limited_express' then + table.insert(typeCandidates, 'Express') + table.insert(typeCandidates, 'Limited Express') + elseif apiType == 'single' then + table.insert(typeCandidates, 'Single') + else + table.insert(typeCandidates, 'Local') + table.insert(typeCandidates, 'Ordinary') end - local okIssue, ticketId, issueErr = tryIssue(fromNameEnArg, toNameEnArg, apiType, rides, cost, startStationArg, terminalStationArg, fromNameCnUArg, toNameCnUArg) - if okIssue then - return true, ticketId, 'issueTicket' + local function buildIssuePayload(typeValue) + return { + ticket_id = fallbackId, + id = fallbackId, + start_station = tostring(startStationArg or ''), + terminal_station = tostring(terminalStationArg or ''), + start_station_id = tostring(startStationArg or ''), + terminal_station_id = tostring(terminalStationArg or ''), + start_name_en = tostring(fromNameEnArg or ''), + terminal_name_en = tostring(toNameEnArg or ''), + start_name = tostring(fromNameCnUArg or ''), + terminal_name = tostring(toNameCnUArg or ''), + fromNameCnU = tostring(fromNameCnUArg or ''), + toNameCnU = tostring(toNameCnUArg or ''), + rides = tonumber(rides) or 1, + trips = tonumber(rides) or 1, + trips_total = tonumber(rides) or 1, + trips_remaining = tonumber(rides) or 1, + cost = tonumber(cost) or 0, + train_type = tostring(apiType or 'local'), + type = tostring(typeValue or apiType or 'local') + } end - return tryIssue(fromNameEnArg, toNameEnArg, apiType, rides, cost, startStationArg, terminalStationArg) + local variants = {} + local seenVariantKey = {} + local function addVariant(methodName, args) + local parts = { methodName } + for i = 1, #args do + parts[#parts + 1] = tostring(args[i]) + end + local key = table.concat(parts, '\31') + if not seenVariantKey[key] then + seenVariantKey[key] = true + variants[#variants + 1] = { method = methodName, args = args } + end + end + + for _, typeValue in ipairs(typeCandidates) do + local payload = buildIssuePayload(typeValue) + addVariant('issueTicket', { + tostring(fromNameEnArg or ''), + tostring(toNameEnArg or ''), + typeValue, + tonumber(rides) or 1, + tonumber(cost) or 0, + tostring(startStationArg or ''), + tostring(terminalStationArg or ''), + tostring(fromNameCnUArg or ''), + tostring(toNameCnUArg or '') + }) + addVariant('issueTicket', { + tostring(fromNameEnArg or ''), + tostring(toNameEnArg or ''), + typeValue, + tonumber(rides) or 1, + tonumber(cost) or 0, + tostring(startStationArg or ''), + tostring(terminalStationArg or '') + }) + addVariant('issueTicketData', { payload }) + addVariant('writeTicketData', { payload }) + end + + local lastError = 'unsupported_method' + for _, variant in ipairs(variants) do + local fn = dev[variant.method] + if type(fn) == 'function' then + local okCall, r1, r2, r3 = pcall(fn, table.unpack(variant.args)) + if okCall and peripheralCallSucceeded(r1) then + local payloadArg = type(variant.args[1]) == 'table' and variant.args[1] or nil + local issuedId = extractPeripheralId(r2, r3, r1, payloadArg and payloadArg.ticket_id, payloadArg and payloadArg.id, fallbackId) + local normalizedId = normalizeIssuedTicketId(issuedId) + if #normalizedId > 0 then + return true, normalizedId, variant.method + end + lastError = 'invalid_ticket_id' + else + local detail = extractPeripheralId(r1, r2, r3) + if okCall then + lastError = variant.method .. ':' .. tostring(detail ~= '' and detail or 'issue_failed') + else + lastError = variant.method .. ':' .. tostring(r1 or 'issue_call_failed') + end + end + end + end + + return false, '', lastError end -- ###########################