summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-01-02 17:35:01 +0000
committerubq323 <ubq323@ubq323.website>2023-01-02 17:35:01 +0000
commit8bbde6c44b408624c905c6d482f9871b2f8f9f7a (patch)
tree41ef71276aa2931eb35ee0f4511e3f090dac4481
parent8be94cdcbf6d72732509a6fb32b64fa4d62cc0ce (diff)
shop2
-rw-r--r--shop2.lua196
1 files changed, 196 insertions, 0 deletions
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")