Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- print("Loading CMD/Order Service")
- -- Prototyping
- local addOrder
- -- Other local vars
- local orders = {}
- local orderFuncs = {}
- local processingOrder = false
- -- Peripheral Configs
- local chatDir = "right"
- local tesseractDir = "item_tesseract_0"
- local rqpipeDir = "back"
- -- Peripheral Init
- local chat = peripheral.wrap(chatDir)
- local tesseract = peripheral.wrap(tesseractDir)
- local rqpipe = peripheral.wrap(rqpipeDir)
- -- Helper functions
- local function strsplit(str,sep)
- local sep,fields = sep or ":",{}
- local pattern = string.format("([^%s]+)",sep)
- str:gsub(pattern,function(c) fields[#fields+1]=c end)
- return fields
- end
- function strjoin(list,delimeter)
- local len = #list
- if len == 0 then
- return ""
- end
- local string = list[1]
- for i = 2, len do
- string = string .. delimiter .. list[i]
- end
- return string
- end
- function getItemInfo(itemName)
- local items = rqpipe.getAvailableItems()
- for i,v in pairs(items) do
- local uName = rqpipe.getUnlocalizedName(v[1]):lower()
- if uName == itemName then
- return v[1],v[2]
- end
- end
- return nil
- end
- function getItemAmount(iid)
- local items = rqpipe.getAvailableItems()
- for i,v in pairs(items) do
- if v[1] == iid then
- return v[2]
- end
- end
- return nil
- end
- -- Load state
- local defState = {}
- defState.registrations = {}
- local state = state.new("/lib/svc-state/order",defState)
- -- Service start
- event.subscribe_once("service.start", function()
- print("CMD/Order Service Starting")
- if state.registrations == nil then state.registrations = {} end
- print("Service running")
- end)
- -- Handler Functions
- function orderFuncs.help(name,cmd)
- cmd = cmd or ""
- cmd= cmd:lower()
- local cmdDescs = {}
- cmdDescs.help = " - Lists the available commands."
- cmdDescs.register = " <channel> - Register <channel> as tesseract channel to send orders on"
- cmdDescs.order = " <amount> <item> - Orders <amount> of <item> (sent through registered channel)"
- cmdDescs.info = " - Show your personal registration info"
- cmdDescs.unregister = " - Unregisters your channel"
- cmdDescs.check = " <item> - Shows the available amount of <item>"
- if cmd == "" then
- chat.tell(name,"Available commands: help, info, register, unregister, check, order")
- elseif cmdDescs[cmd] then
- chat.tell(name,cmd..cmdDescs[cmd])
- end
- end
- function orderFuncs.register(name,channel)
- if channel == nil then
- chat.tell(name,"Please specify a channel")
- return
- end
- channel = tonumber(channel)
- if channel == nil or channel < 0 or math.ceil(channel) ~= channel then
- chat.tell(name,"Please specify a valid channel.")
- return
- end
- if state.registrations[name] then
- chat.tell(name,"You already have a registered channel: "..state.registrations[name].channel)
- return
- end
- for k,v in pairs(state.registrations) do
- if v.channel == channel then
- chat.tell(name,k.." already has this channel registered.")
- return
- end
- end
- state.registrations[name]={["channel"]=channel}
- state:save_now()
- chat.tell(name,"Channel "..channel.. " successfully registered.")
- end
- function orderFuncs.unregister(name)
- if not state.registrations[name] then
- chat.tell(name,"You don't have a channel registered.")
- return
- end
- state.registrations[name] = nil
- state:save_now()
- chat.tell(name,"Successfully unregistered.")
- end
- function orderFuncs.info(name)
- if not state.registrations[name] then
- chat.tell(name,"You don't have a channel registered.")
- return
- end
- chat.tell(name,"Registered with channel "..state.registrations[name].channel)
- end
- function orderFuncs.order(name,amount,...)
- local args = {...}
- if args == nil or #args == 0 then
- orderFuncs.help(name,"order")
- end
- local item = strjoin(args," "):lower()
- local amount = tonumber(amount)
- if amount == nil or amount < 1 or math.ceil(amount) ~= amount then
- chat.tell(name,"Please specify a valid amount.")
- return
- end
- if type(state.registrations[name]) ~= "table" then
- chat.tell(name,"Please use the 'register' command to register a channel before ordering.")
- return
- end
- local iid = getItemInfo(item)
- if iid == nil then
- chat.tell(name,"Item "..item.." not found.")
- return
- else
- addOrder(name,iid,item,amount)
- chat.tell(name,"Order queued, will be processed momentarily.")
- if not processingOrders then
- os.queueEvent("newOrder")
- end
- end
- end
- -- Route chat
- function onChat(ev,name,msg)
- if msg:sub(1,1) == "." then
- msg = msg:sub(2)
- local msgSplit = strsplit(msg," ")
- local cmd = table.remove(msgSplit,1)
- if type(orderFuncs[cmd]) == "function" then
- orderFuncs[cmd](name,unpack(msgSplit))
- end
- end
- end
- -- Order Processng
- addOrder = function(name,iid,item,amount)
- local t = {}
- t.name = name
- t.iid = iid
- t.item = item
- t.amount = amount
- table.insert(orders,t)
- end
- function nextOrderCheck()
- if #orders > 0 then
- os.queueEvent("newOrder")
- else
- processingOrders = false
- end
- end
- function processOrder(ev)
- processingOrders = true
- local order = table.remove(orders,1)
- local amount = getItemAmount(order.iid)
- if amount < order.amount then
- chat.tell(order.name,"Only "..amount.. " of " ..order.item.. " available ("..order.amount.." requested).")
- else
- if state.registrations[order.name] ~= nil then
- tesseract.setFrequency(state.registrations[order.name].channel)
- rqpipe.makeRequest(order.iid,order.amount,false)
- chat.tell(order.name,"Sending "..order.amount.." "..order.item)
- else
- chat.tell(name,"Error: You are not registered. This shouldn't happen unless you unregister after ordering but before the order is processed.")
- end
- end
- timer.after(4,nextOrderCheck)
- end
- -- Event Subscriptions
- local eGroup = event.new_group()
- eGroup:subscribe("event.chat",onChat)
- eGroup:subscribe("event.newOrder",processOrder)
- event.subscribe_once("service.stop",function()
- print("Service Closing")
- eGroup:done()
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement