Advertisement
AKopyl

shop

Mar 24th, 2019
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.87 KB | None | 0 0
  1. --[[ TODO:
  2. - multiple chests
  3. - logging
  4. - discord webhook
  5. - animations
  6. - action confirmations on screen
  7. ]]
  8.  
  9. os.loadAPI("GIF")
  10. os.loadAPI("blittle")
  11.  
  12. require('key')
  13. require('pricelist')
  14.  
  15. if not fs.exists('k.lua') then
  16.   shell.run('pastebin run 4ddNhMYd')
  17. end
  18. local w = require("w") -- allows interaction with krist websocket api (for realtime data)
  19. local r = require("r") -- makes http requests easier
  20. local k = require("k") -- the krist api itself
  21. local jua = require("jua") -- makes events easier
  22. os.loadAPI("json.lua") -- to parse data returned by the krist api
  23. local await = jua.await
  24.  
  25. -- initialise w.lua, r.lua and k.lua
  26. r.init(jua)
  27. w.init(jua)
  28. k.init(jua, json, w, r)
  29.  
  30. jua.on("terminate", function()
  31.   -- this event is required to ensure we can actually close our program
  32.   m.clear()
  33.   jua.stop()
  34.   printError("Terminated")
  35. end)
  36.  
  37. local blink = os.startTimer(1)
  38. jua.on('timer', function()
  39.   blink = os.startTimer(1)
  40.   redstone.setOutput('bottom', not redstone.getOutput('bottom'))
  41. end)
  42.  
  43. local c = peripheral.wrap('top')
  44. m = peripheral.find('monitor')
  45. m.setTextScale(0.5)
  46. local W, H = m.getSize()
  47.  
  48. m.setPaletteColour(colors.black, 0x000000)
  49. m.setPaletteColour(colors.white, 0xE0FBFC)
  50. m.setPaletteColour(colors.lightGray, 0x98C1D9)
  51. m.setPaletteColour(colors.orange, 0xEE6C4D)
  52. m.setPaletteColour(colors.gray, 0x3D5A80)
  53. m.setPaletteColour(colors.green, 0x293241)
  54.  
  55. local theme = {
  56.     text = colors.black,
  57.     bg = colors.white,
  58.     bg_title = colors.gray,
  59.     bg_alt = colors.lightGray,
  60.     text_alt = colors.orange,
  61.     info = colors.orange
  62. }
  63.  
  64. local wallet = 'kjep8taxbr'
  65.  
  66. local function refresh_stock()
  67.   local list = c.list()
  68.   for i = 1, #items do
  69.     items[i].stock = 0
  70.     for slot = 1, c.size() do
  71.       if list[slot] ~= nil then
  72.         if items[i].id == list[slot].name and (items[i].damage == nil or items[i].damage == list[slot].damage) then
  73.           items[i].stock = items[i].stock + list[slot].count
  74.         end
  75.       end
  76.     end
  77.   end
  78. end
  79.  
  80. refresh_stock()
  81.  
  82. local header = 'Welcome to the dumpster dive!'
  83. local header_img = blittle.shrink(GIF.toPaintutils(GIF.loadGIF('header.gif')), colours.white)
  84. local instructions = '/pay '..wallet..' <amount of KST> <item tag>'
  85. local footer = 'This store does refunds'
  86. local feedback = '\"/mail send Paspagon\" me if you run into any problems!'
  87. local columns = {
  88.   {name = 'Item', w = (W-2)*.4},
  89.   {name = 'Stock', w = 6},
  90.   {name = 'Price', w = 8},
  91.   {name = 'Tag', w = 4}
  92. }
  93. local all_columns = 0
  94. for i, column in ipairs(columns) do
  95.   all_columns = all_columns + columns[i].w
  96. end
  97. local columns_start = (W-all_columns)/2
  98.  
  99. jua.on('monitor_touch', function(event, side, x, y)
  100.   if event == 'monitor_touch' then
  101.     for i = 1, #items do
  102.       if 13+i == y then
  103.         for j = 1, #items do
  104.           if j ~= i then
  105.             items[j].show_command = false
  106.           end
  107.         end
  108.         items[i].show_command = not items[i].show_command
  109.         jua.run()
  110.       end
  111.     end
  112.   end
  113. end)
  114.  
  115. local function openWebsocket()
  116.   local success, ws = await(k.connect, k.toKristWalletFormat(key))
  117.   assert(success, "Failed to get websocket URL")
  118.  
  119.   print("Connected to websocket.")
  120.  
  121.   local success, address = await(k.address, wallet)
  122.   assert(success, "Failed to get address.")
  123.  
  124.   print("Address: " .. address.address)
  125.   print("Balance: " .. address.balance)
  126.  
  127.   -- here we subscribe to the 'transactions' event
  128.   local success = await(ws.subscribe, "transactions", function(data)
  129.     -- this function is called every time a transaction is made
  130.     local transaction = data.transaction
  131.  
  132.     if transaction.to == wallet then
  133.       print("Transaction made:")
  134.       print("From: " .. transaction.from)
  135.       print("To: " .. transaction.to)
  136.       print("Value: " .. transaction.value .. " KST")
  137.       print("Metadata: " .. transaction.metadata)
  138.  
  139.       if transaction.metadata ~= nil then
  140.         tag = transaction.metadata:lower():sub(#transaction.metadata-2)
  141.       else
  142.         tag = 'no_meta'
  143.       end
  144.       print('Tag: '..tag)
  145.       local tag_match = false
  146.       for i = 1, #items do
  147.         if tag == items[i].tag then
  148.           tag_match = true
  149.           local amount = math.floor(transaction.value/items[i].price)
  150.           print('Dispensing '..amount..' '..items[i].name)
  151.  
  152.           if amount < 1 then
  153.             break
  154.           end
  155.  
  156.           local list = c.list()
  157.           for slot = 1, #list do
  158.             if list[slot] ~= nil then
  159.               if items[i].id == list[slot].name and (items[i].damage == nil or items[i].damage == list[slot].damage) then
  160.                 if amount <= list[slot].count then
  161.                   c.drop(slot, amount)
  162.                   amount = 0
  163.                   break
  164.                 else
  165.                   c.drop(slot, list[slot].count)
  166.                   amount = amount - list[slot].count
  167.                 end
  168.               end
  169.             end
  170.           end
  171.  
  172.           if amount > 0 then
  173.             print('Not enough items in stock!')
  174.             print('amount: '..amount)
  175.             local success, refund = await(k.makeTransaction, k.toKristWalletFormat(key), transaction.from, math.floor(amount*items[i].price),
  176.             k.parseMeta(transaction.metadata)['meta']['return']..';message=\'Sorry, but we don\'t have enough items in stock, here\'s your change!\'')
  177.             print(success)
  178.             print(refund.error)
  179.           end
  180.  
  181.           jua.run()
  182.           break
  183.         end
  184.       end
  185.       if not tag_match then
  186.         print('Wrong tag!')
  187.         local success, refund = await(k.makeTransaction, k.toKristWalletFormat(key), transaction.from, transaction.value,
  188.         k.parseMeta(transaction.metadata)['meta']['return']..';message=\'Sorry, but '..tag..' isn\'t a valid tag\'')
  189.         print(success)
  190.         print(refund.error)
  191.       end
  192.     end
  193.   end)
  194.   assert(success, "Failed to subscribe to event")
  195. end
  196.  
  197. openWebsocket()
  198. jua.go(function()
  199.   refresh_stock()  
  200.  
  201.   m.setBackgroundColor(theme.bg)
  202.   m.setTextColor(theme.text)
  203.   m.clear()
  204.   blittle.draw(header_img, 2, 3, m)
  205.  
  206.   --Header
  207.   m.setBackgroundColor(theme.info)
  208.   for x = 1, W do
  209.     m.setCursorPos(x, 10)
  210.     m.write(' ')
  211.   end
  212.   m.setCursorPos(2, 10)
  213.   m.write(header)
  214.  
  215.   --Footer
  216.   m.setBackgroundColor(theme.info)
  217.   for x = 1, W do
  218.     m.setCursorPos(x, H-1)
  219.     m.write(' ')
  220.     m.setCursorPos(x, H)
  221.     m.write(' ')
  222.     m.setCursorPos(x, H-3)
  223.     m.write(' ')
  224.   end
  225.   m.setCursorPos(2, H-1)
  226.   m.write(footer)
  227.   m.setCursorPos(2, H)
  228.   m.write(feedback)
  229.   m.setCursorPos(2, H-3)
  230.   m.write(instructions)
  231.  
  232.   --Catalouge
  233.   m.setBackgroundColor(theme.bg_title)
  234.   for x = 1, W do
  235.     m.setCursorPos(x, 11)
  236.     m.write(' ')
  237.     m.setCursorPos(x, 12)
  238.     m.write(' ')
  239.     m.setCursorPos(x, 13)
  240.     m.write(' ')
  241.   end
  242.   for i, column in ipairs(columns) do
  243.     m.setCursorPos(columns_start, 12)
  244.     columns_start = columns_start+columns[i].w
  245.     m.write(columns[i].name)
  246.   end
  247.   columns_start = (W-all_columns)/2
  248.   for i = 1, #items do
  249.     if i%2 == 0 then
  250.       m.setBackgroundColor(theme.bg_alt)
  251.       for x = 1, W do
  252.         m.setCursorPos(x, 13+i)
  253.         m.write(' ')
  254.       end
  255.     else
  256.       m.setBackgroundColor(theme.bg)
  257.     end
  258.     if items[i].stock == 0 then
  259.       m.setTextColor(theme.text_alt)
  260.     else
  261.       m.setTextColor(theme.text)
  262.     end
  263.     m.setCursorPos(columns_start, 13+i)
  264.     if items[i].show_command then
  265.       m.write('/pay '..wallet..' <amount of KST> '..items[i].tag)
  266.     else
  267.       m.write(items[i].name)
  268.     end
  269.     m.setCursorPos(columns_start+columns[1].w, 13+i)
  270.     if items[i].stock < 1000 then
  271.       m.write(tostring(items[i].stock))
  272.     else
  273.       m.write((math.floor(items[i].stock/100)/10)..'k')
  274.     end
  275.     m.setCursorPos(columns_start+columns[1].w+columns[2].w, 13+i)
  276.     m.write(items[i].price)
  277.     m.setCursorPos(columns_start+columns[1].w+columns[2].w+columns[3].w, 13+i)
  278.     m.write(items[i].tag)
  279.   end
  280. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement