Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- CC BY-SA License
- Copyright (c) 2020 ipeni
- reusers may distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator. This license allows for commercial use. If you remix, adapt, or build upon the material, you must license the modified material under identical terms.
- --]]
- disk = nil
- monitor = nil
- modem = nil
- wiredModem = nil
- monitorSide = nil
- itemPrices = {}
- t = nil
- currentUser = nil
- playerBalance = 0
- cart = 0
- cost = 0
- items = {}
- function checkForFloppy()
- while true do
- local e, s, sC, rC, m, dist = os.pullEvent()
- if e == "disk" and not fs.exists("disk/user.txt") then
- currentUser = {}
- local newUser = generateId()
- write("Creating User File...")
- userFile = fs.open("disk/user.txt", "w")
- print("writing to balances file...")
- --Create user file on inserted disk
- userFile.writeLine(newUser)
- userFile.close()
- --Read balances file and initialized newly created user
- balances = fs.open("balances.txt", "r")
- serialized = textutils.unserialise(balances.readAll())
- balances.close()
- serialized[newUser] = 0
- --Open balances file in write mode and insert the new data
- balances = fs.open("balances.txt", "w")
- balances.write(textutils.serialise(serialized))
- balances.close()
- write("User file created.")
- reDrawItems(true)
- elseif e == "disk" and fs.exists("disk/user.txt") then
- userfile = fs.open("disk/user.txt", "r")
- user = userfile.readAll()
- balances = fs.open("balances.txt", "r")
- balTable = textutils.unserialise(balances.readAll())
- playerBalance = balTable[user]
- currentUser = user
- reDrawItems(true)
- elseif e == "disk_eject" then
- write("Thanks for shopping, come again")
- --Reset all store parameters
- currentUser = nil
- playerBalance = 0
- cart = 0
- activePage = 1
- reDrawItems(true)
- end
- end
- end
- --Generates new User ID, not impossible for duplicated but unlikely, if it becomes problematic we can add an extra character or add a check to regenerate until its unique
- function generateId()
- local random = math.random
- local template = "xxxxxxxx"
- local id =
- string.gsub(
- template,
- "[xy]",
- function(c)
- write("Checking User Card...")
- local v = (c == "x") and random(0, 0xf) or random(8, 0xb)
- sleep(0.5)
- return string.format("%x", v)
- end
- )
- return id
- end
- --Waits for messaged from the ATM
- function listenForBalanceUpdate()
- while true do
- local e, s, sC, rC, m, dist = os.pullEvent("modem_message")
- if m["request"] == "balance_update" then
- print("updating balance for " .. m["user"])
- file = fs.open("balances.txt", "r")
- balances = textutils.unserialise(file.readAll())
- balances[m["user"]] = tonumber(balances[m["user"]]) + tonumber(m["balance"])
- newBalances = fs.open("balances.txt", "w")
- newBalances.write(textutils.serialize(balances))
- newBalances.close()
- end
- end
- end
- function write(str)
- monitor.clear()
- monitor.setCursorPos(1, 1)
- monitor.write(str)
- end
- function listenForTouch()
- while true do
- local e, p1 = t:handleEvents(os.pullEvent())
- if e == "button_click" and t.buttonList[p1].func ~= nil then
- t.buttonList[p1].func()
- end
- end
- end
- function init()
- if not fs.exists("balances.txt") then
- file = fs.open("balances.txt", "w")
- file.writeLine("{}")
- file.close()
- end
- parallel.waitForAll(checkForFloppy, listenForBalanceUpdate, listenForNewItems, listenForTouch, readCommands)
- end
- function initializePeripherals()
- print("Initializing...")
- if not fs.exists("buttons.lua") then
- shell.run("pastebin", "get", "pFHeia96", "buttons.lua")
- os.loadAPI("./buttons.lua")
- else
- os.loadAPI("./buttons.lua")
- end
- for k,v in ipairs(peripheral.getNames()) do
- type = peripheral.getType(v)
- if type == "monitor" then
- monitor = peripheral.wrap(v)
- monitor.setTextScale(0.75)
- monitor.write("Please Insert User disk")
- monitorSide = v
- t = buttons.new(monitorSide)
- elseif type == "modem" then
- tempModem = peripheral.wrap(v)
- if tempModem.isWireless() then
- modem = peripheral.wrap(v)
- modem.open(404)
- else
- wiredModem = peripheral.wrap(v)
- modemNames = wiredModem.getNamesRemote()
- for x,y in ipairs(modemNames) do
- if y:match("drive",1,true) then
- disk = peripheral.wrap(y)
- break
- end
- end
- end
- end
- end
- if modem == nil or disk == nil then
- print("please connect a modem and disk drive to this computer")
- sleep(3)
- initializePeripherals()
- elseif monitor == nil then
- print("please connect a monitor to this computer")
- sleep(3)
- initializePeripherals()
- elseif modem ~= nil and monitor ~= nil and disk ~= nil then
- init()
- end
- end
- function updateCartLabel(oldName, value, operator, stock)
- if cart > stock or cart + value > stock and operator == "add" then
- return false
- end
- if operator == "subtract" and cart - value >= 0 then
- t:rename(oldName, "Cart: " .. cart - value)
- cart = cart - value
- t:draw()
- return true
- elseif operator == "add" and cart <= 64 and cart + value <= 64 then
- t:rename(oldName, "Cart: " .. cart + value)
- cart = cart + value
- t:draw()
- return true
- end
- return false
- end
- function updateCostLabel(oldName, itemName)
- cost = cart * itemPrices[itemName]
- t:rename(oldName, "Cost: " .. cost)
- t:draw()
- end
- function sendPurchase(item, amount, stock)
- if playerBalance < amount then
- monitor.clear()
- monitor.setCursorPos(1, 1)
- write("Not enought funds, please deposit at the ATM, redirecting...")
- cart = 0
- sleep(3)
- reDrawItems()
- return
- else
- modem.transmit(420, 404, {request = "get_item", name = item, amount = amount})
- cart = 0
- items[item]["count"] = stock - amount
- file = fs.open("balances.txt", "r")
- balances = textutils.unserialise(file.readAll())
- user = tostring(currentUser)
- balances[user] = tonumber(balances[user]) - (tonumber(amount) * itemPrices[item])
- playerBalance = balances[user]
- newBalances = fs.open("balances.txt", "w")
- newBalances.write(textutils.serialize(balances))
- newBalances.close()
- monitor.clear()
- monitor.setCursorPos(1, 1)
- monitor.write("Thank you for your purchase")
- sleep(2)
- reDrawItems()
- end
- end
- function openProductPage(name)
- stock = items[name]["count"]
- local x, y = monitor.getSize()
- xmin = math.ceil(x / 2 - 5)
- xmax = math.ceil((x / 2) + 5)
- ymin = math.ceil(y / 3)
- ymax = math.ceil((y / 3) + 2)
- t = buttons.new(monitorSide)
- t:add(name .. " - Stock: " .. stock .. " - Price: " .. itemPrices[name], nil, x - x + 1, ymin, x - 1, ymax, colors.black, colors.white)
- t:add(
- "Purchase",
- function()
- sendPurchase(name, cart, stock)
- end,
- x / 5 * 2 + 1,
- y - 6,
- x / 5 * 3,
- y - 1,
- colors.green,
- colors.black
- )
- cost = cart * itemPrices[name]
- t:add("Cart: " .. cart, nil, x - x + 1, ymin + 3, x - 1, ymax + 3, colors.black, colors.white)
- t:add("Cost: " .. cost, nil, x - x + 1, ymin + 6, x - 1, ymax + 6, colors.black, colors.white)
- t:add(
- "+1",
- function()
- if updateCartLabel("Cart: " .. cart, 1, "add", stock) then
- updateCostLabel("Cost: " .. cost, name)
- end
- end,
- math.ceil(x / 3 - 5),
- math.ceil(ymin + 10),
- math.ceil(x / 3 + 5),
- math.ceil(ymax + 10),
- colors.green,
- colors.black
- )
- t:add(
- "+5",
- function()
- if updateCartLabel("Cart: " .. cart, 5, "add", stock) then
- updateCostLabel("Cost: " .. cost, name)
- end
- end,
- math.ceil(x / 3 - 5),
- math.ceil(ymin + 13),
- math.ceil(x / 3 + 5),
- math.ceil(ymax + 13),
- colors.blue,
- colors.black
- )
- t:add(
- "+10",
- function()
- if updateCartLabel("Cart: " .. cart, 10, "add", stock) then
- updateCostLabel("Cost: " .. cost, name)
- end
- end,
- math.ceil(x / 3 - 5),
- math.ceil(ymin + 16),
- math.ceil(x / 3 + 5),
- math.ceil(ymax + 16),
- colors.green,
- colors.black
- )
- t:add(
- "-1",
- function()
- if updateCartLabel("Cart: " .. cart, 1, "subtract", stock) then
- updateCostLabel("Cost: " .. cost, name)
- end
- end,
- math.ceil((x / 3) * 2 - 5),
- math.ceil(ymin + 10),
- math.ceil((x / 3) * 2 + 5),
- math.ceil(ymax + 10),
- colors.green,
- colors.black
- )
- t:add(
- "-5",
- function()
- if updateCartLabel("Cart: " .. cart, 5, "subtract", stock) then
- updateCostLabel("Cost: " .. cost, name)
- end
- end,
- math.ceil((x / 3) * 2 - 5),
- math.ceil(ymin + 13),
- math.ceil((x / 3) * 2 + 5),
- math.ceil(ymax + 13),
- colors.blue,
- colors.black
- )
- t:add(
- "-10",
- function()
- if updateCartLabel("Cart: " .. cart, 10, "subtract", stock) then
- updateCostLabel("Cost: " .. cost, name)
- end
- end,
- math.ceil((x / 3) * 2 - 5),
- math.ceil(ymin + 16),
- math.ceil((x / 3) * 2 + 5),
- math.ceil(ymax + 16),
- colors.green,
- colors.black
- )
- t:add(
- "back",
- function()
- reDrawItems()
- end,
- 1,
- 1,
- 10,
- 3,
- colors.red,
- colors.white
- )
- t:add("Balance: " .. playerBalance, nil, x - 20, 1, x - 1, 10, colors.green, colors.black)
- t:draw()
- end
- activePage = 1
- pageCount = 1
- pages = {}
- function reDrawItems(reload)
- reload = reload or false
- if items == nil or t == nil or tablelength(items) < 1 then
- write("items or monitor yet to be initialized")
- return
- end
- if currentUser == nil then
- write("Please insert your user card...")
- return
- end
- t = buttons.new(monitorSide)
- if reload then
- pages = {}
- index = 0
- page = 1
- pages[page] = {}
- tempItems = {}
- for k, v in pairs(items) do
- name = ""
- if string.find(k, ":") then
- name = string.match(tostring(k), ":(.*)")
- else
- name = k
- end
- table.insert(tempItems, {name = name})
- pages[page] = tempItems
- if 20 / index == 1 then
- tempItems = {}
- index = 0
- page = page + 1
- pageCount = page
- else
- index = index + 1
- end
- end
- end
- column = 20
- row = 1
- columnTwo = 1
- indexTwo = 0
- for k, v in ipairs(pages[activePage]) do
- t:add(
- v.name,
- function()
- openProductPage(v.name)
- end,
- column - 18,
- row * 3 - 1,
- column - 2,
- row * 3,
- colors.red,
- colors.lime
- )
- if 6 / indexTwo == 1 then
- column = (columnTwo + 1) * 20
- columnTwo = columnTwo + 1
- row = 1
- indexTwo = 0
- else
- indexTwo = indexTwo + 1
- row = row + 1
- end
- end
- local x, y = monitor.getSize()
- if activePage + 1 <= pageCount then
- t:add(
- "Next ->",
- function()
- if activePage + 1 <= pageCount then
- activePage = activePage + 1
- end
- reDrawItems()
- end,
- 2,
- 30,
- 15,
- 35,
- colors.red,
- colors.green
- )
- end
- if activePage - 1 >= 1 then
- t:add(
- "Back <-",
- function()
- if activePage + 1 >= 1 then
- activePage = activePage - 1
- end
- reDrawItems()
- end,
- 20,
- 30,
- 35,
- 35,
- colors.red,
- colors.green
- )
- end
- t:draw()
- end
- function listenForNewItems()
- if tablelength(items) < 1 then
- sendRebootToTurtles()
- sleep(3)
- sendFileToTurtles("turtles.lua")
- end
- while true do
- local e, s, sC, rC, m, dist = os.pullEvent("modem_message")
- if(m["request"] == "init") then
- pricesFile = nil
- if not fs.exists("prices.txt") then
- pricesFile = fs.open("prices.txt", "w")
- pricesFile.writeLine("{}")
- pricesFile.close()
- end
- pricesFile = fs.open("prices.txt", "r")
- prices = textutils.unserialise(pricesFile.readAll())
- for k,v in pairs(m["data"]) do
- items[k] = v
- if(prices[k] == nil) then
- prices[k] = 1
- end
- end
- pricesFile = fs.open("prices.txt", "w")
- newPrices = textutils.serialise(prices)
- itemPrices = prices
- pricesFile.write(newPrices)
- pricesFile.close()
- reDrawItems(true)
- elseif m["request"] == "balance_request" then
- local balancesFile = fs.open("balances.txt", "r")
- local balances = textutils.unserialise(balancesFile.readAll())
- balancesFile.close()
- local balance = balances[m["user"]]
- modem.transmit(6969,404, { request = "balance_transmission", balance = balance})
- end
- end
- end
- function readCommands()
- while true do
- if itemPrices == nil then
- return
- end
- print("Waiting for command")
- sInput = read()
- if sInput == "changePrice" then
- print("Type an item name...")
- sInput = read()
- matches = {}
- for k,v in pairs(itemPrices) do
- if k:match(sInput,1, true) then
- table.insert(matches, k)
- end
- end
- length = tablelength(matches)
- if length == 0 then
- print("no matches")
- elseif length == 1 then
- print("what would you like to set the price to?")
- sInput = read()
- name = matches[1]
- itemPrices[name] = tonumber(sInput)
- savePrices(itemPrices)
- else
- for k,v in ipairs(matches) do
- print(k..": Matched "..v)
- end
- print("please select 1 by index provided")
- sInput = read()
- name = matches[tonumber(sInput)]
- print("what would you like to set the price to?")
- sInput = read()
- itemPrices[name] = tonumber(sInput)
- savePrices(itemPrices)
- end
- sleep(2)
- elseif sInput == "help" then
- print("Available commands are changePrice, sendReboot, and sendFile")
- sleep(2)
- elseif sInput == "sendFile" then
- print("Please provide file name..")
- sInput = read()
- sendFileToTurtles(sInput)
- sleep(2)
- elseif sInput == "sendReboot" then
- print("Rebooting turtles...")
- sendRebootToTurtles()
- print("Please send the turtles a file onces reboot has completed")
- sleep(2)
- end
- end
- end
- function sendFileToTurtles(fileName)
- if not fs.exists("turtles.lua") then
- shell.run("pastebin","get","7JRHhjUe","turtles.lua")
- end
- data = {}
- data["request_name"] = "slave"
- file = fs.open(fileName, "r")
- data["file"] = file.readAll()
- modem.transmit(420, 69, data)
- end
- function sendRebootToTurtles()
- data = {}
- data["request"] = "reboot"
- modem.transmit(420,69,data)
- end
- function savePrices(prices)
- newPrices = textutils.serialise(prices)
- file = fs.open("prices.txt", "w")
- file.write(newPrices)
- file.close()
- end
- function tablelength(T)
- local count = 0
- for _ in pairs(T) do count = count + 1 end
- return count
- end
- initializePeripherals()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement