From 8bbde6c44b408624c905c6d482f9871b2f8f9f7a Mon Sep 17 00:00:00 2001 From: ubq323 Date: Mon, 2 Jan 2023 17:35:01 +0000 Subject: shop2 --- shop2.lua | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 shop2.lua diff --git a/shop2.lua b/shop2.lua new file mode 100644 index 0000000..cb1b453 --- /dev/null +++ b/shop2.lua @@ -0,0 +1,196 @@ +local key=assert(settings.get"krist.pkey","please set private key") + +-- ac.kst +local OURNAME = "ac" +local ITEMS = {} +local function i(adr,itname,hname,price) + ITEMS[adr]={itname=itname,hname=hname,price=price,adr=adr} +end +i("dmn","minecraft:diamond","Diamond",5) +i("blz","minecraft:blaze_rod","Blaze Rod",10) +i("ely","minecraft:elytra","Elytra",200) +i=nil + + +local chest = peripheral.wrap"back" +local function take_stock() + -- if you do this in parallel, you avoid having to wait 1 tick for each + -- slot of the chest. which is probably good. + local out = {} + local fns = {} + for i=1,chest.size() do + fns[i] = function() out[i] = chest.getItemDetail(i) end + end + parallel.waitForAll(unpack(fns)) + return out +end + + +local sres =textutils.unserializeJSON( http.post("https://krist.dev/ws/start","privatekey="..key).readAll()) +assert(sres.ok,"not ok") + +local ws = assert(http.websocket(sres.url)) +local nextid = 0 +local our_addr = "???" + +local function sendws(t) + t.id = nextid + nextid = nextid + 1 + return ws.send(textutils.serializeJSON(t)) +end + +sendws{type="me"} + +local function parsemeta(m) + local out = {} + for s in string.gmatch(m..";","(.-);") do + local k,v = s:match"^(.-)=(.-)$" + if k==nil then + out.recipient = s + else + out[k]=v + end + end + return out +end + +-- XXX +local function stock_amt(item) + local out = 0 + for i=1,16 do + local x = turtle.getItemDetail(i) + if x and x.name == ITEM then out = out + x.count end + end + return out +end + +-- XXX +local function give(amt) + amt = amt or 1 + -- assumes that we have at least amt in stock already + for i=1,16 do + local x = turtle.getItemDetail(i) + if x and x.name == ITEM then + local a = math.min(amt,x.count) + turtle.select(i) + turtle.drop(a) + amt = amt - a + if amt <= 0 then break end + end + end +end + +local function proctrans(tr) + if tr.to ~= our_addr then return end + if tr.type ~= "transfer" then return end + if tr.sent_name ~= OURNAME then return end + local meta = parsemeta(tr.metadata) + local function tell(msg) if meta.username then chatbox.tell(meta.username,msg) end end + local function refund() if meta['return'] then sendws { type="make_transaction", to=meta['return'], amount=tr.value } end end + + local mtn = tr.sent_metaname + + + local remainder = tr.value % PRICE + if remainder ~= 0 then + tell("i can only give you a whole number of items. make sure the amount you gave me is a multiple of "..PRICE) + refund() + else + local in_stock = stock_amt() + if in_stock == 0 then + tell("we are out of stock! please yell at ubq323 about this") + refund() + else + local to_give = math.floor(tr.value / PRICE) + if to_give > in_stock then + tell("i don't have that many items in stock, sorry") + refund() + else + give(to_give) + tell("thank you!!! :3") + end + end + end +end + +local function run_shop() + while true do + msgtxt = assert(ws.receive(),"ws error") + msg = textutils.unserializeJSON(msgtxt) + if msg.type == "response" and msg.responding_to_type == "me" then + our_addr = msg.address.address + end + if msg.type == "event" and msg.event == "transaction" then + proctrans(msg.transaction) + end + end +end + +local function run_topdisp() + + local mtop = peripheral.wrap"top" + mtop.setPaletteColor(colors.cyan,0x00FFFF) + while true do + mtop.setTextScale(5) + mtop.setTextColor(colors.cyan) + mtop.setCursorPos(1,1) + mtop.write"DIAMONDS" + + os.sleep(0.75) + mtop.clear() + os.sleep(0.25) + + mtop.setTextScale(4) + mtop.setTextColor(colors.white) + mtop.setCursorPos(1,1) + mtop.write("5KST EACH") + + os.sleep(0.75) + mtop.clear() + os.sleep(0.25) + end +end + +local function run_sidedisp() + local m = peripheral.wrap("left") + local function printseq(q) + for _,v in ipairs(q) do + if type(v) == "number" then + m.setTextColor(v) + elseif type(v) == "table" then + m.setCursorPos(v[1],v[2]) + else -- str + m.write(v) + end + end + end + while true do + local sa = stock_amt() + m.clear() + printseq { + {7,1}, colors.orange, "UBQ323", {3,2}, "DIAMOND STORE", + {9,3}, "!!!", + {1,5}, colors.white, "stock: ", colors.yellow, ""..sa, + {1,6}, colors.white, "price: ", colors.yellow, ""..PRICE, colors.white, "kst/item" + } + if sa > 0 then + printseq { + {2,8}, colors.blue, "/pay d@ac.kst "..PRICE, + {2,9}, colors.gray, "(or a multiple",{6,10}," of "..PRICE..")", + } + else + printseq { + {3,8}, colors.red, "out of stock!", + {2,9}, "please come back",{7,10},"soon." + } + + end + os.sleep(2) + + end +end + +print(pcall(parallel.waitForAny,run_shop, run_topdisp, run_sidedisp)) +print("hi") +peripheral.call("top","clear") +peripheral.call("left","clear") -- cgit v1.2.3