slabOS/libcredit_mobile.lua
2025-06-06 04:14:34 +00:00

137 lines
4.3 KiB
Lua

local M = {}
local modem = peripheral.wrap("back")
local SERVER_CHANNEL = 43
local function sendRequestAndWaitForReply(messageTable, replyHandler, timeout)
timeout = timeout or 5
local replyChannel = math.random(1000, 9999)
modem.open(replyChannel)
messageTable.replyChannel = replyChannel
local jsonMessage = textutils.serialiseJSON(messageTable)
modem.transmit(SERVER_CHANNEL, replyChannel, jsonMessage)
local startTime = os.clock()
local replyReceived = false
while os.clock() - startTime < timeout do
local event, side, channel, receivedReplyChannel, message, distance = os.pullEvent("modem_message")
if event == "modem_message" and channel == replyChannel then
local success, parsedReply = pcall(textutils.unserialiseJSON, message)
if success and type(parsedReply) == "table" then
replyHandler(parsedReply)
replyReceived = true
break
end
end
end
modem.close(replyChannel)
return replyReceived
end
function M.createAccount(username, associatedDevice, callback)
if type(username) ~= "string" or #username == 0 then
error("Username must be a non-empty string.", 2)
end
if type(callback) ~= "function" then
error("Callback must be a function.", 2)
end
if associatedDevice and type(associatedDevice) ~= "number" then
error("Associated device must be a number if provided.", 2)
end
local message = {
type = "createAccount",
user = username
}
if associatedDevice then
message.associatedDevice = associatedDevice
end
return sendRequestAndWaitForReply(message, function(reply)
if reply.type == "accountCreationConfirmation" and reply.user == username then
if reply.status == "success" then
print("Account '" .. username .. "' created successfully. New credit: " .. tostring(reply.newCredit))
callback(true, reply.newCredit)
else
print("Account creation failed for '" .. username .. "'. Reason: " .. tostring(reply.reason))
callback(false, reply.reason)
end
else
print("Unexpected reply for createAccount request: " .. textutils.serialiseJSON(reply))
callback(false, "unexpected_reply")
end
end)
end
function M.getCredit(username, callback)
local message = {
type = "getCredit",
user = username
}
return sendRequestAndWaitForReply(message, function(reply)
if reply.type == "creditResponse" and reply.user == username then
callback(reply.credit)
else
callback(nil)
end
end)
end
function M.addTransaction(username, amount, vendor, vendor_account, callback, timeout)
if type(amount) ~= "number" or amount <= 0 then
error("Amount must be a positive number.", 2)
end
if type(username) ~= "string" or #username == 0 then
error("Username must be a non-empty string.", 2)
end
if type(vendor) ~= "string" or #vendor == 0 then
error("Vendor must be a non-empty string.", 2)
end
if type(vendor_account) ~= "string" or #vendor_account == 0 then
error("Vendor account must be a non-empty string.", 2)
end
if type(callback) ~= "function" then
error("Callback must be a function.", 2)
end
if timeout and (type(timeout) ~= "number" or timeout <= 0) then
error("Timeout must be a positive number if provided.", 2)
end
local message = {
type = "addTransaction",
user = username,
amount = amount,
vendor = vendor,
vendor_account = vendor_account
}
return sendRequestAndWaitForReply(message, function(reply)
if reply.type == "transactionCompleted" and reply.transaction_id then
if reply.status == "success" then
callback(true, reply.newCredit)
elseif reply.status == "failed" then
callback(false, reply.reason)
elseif reply.status == "cancelled" then
callback(false, "cancelled")
else
callback(false, "unknown_status")
end
else
callback(false, "unexpected_reply")
end
end, timeout)
end
return M