Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Inventory Tracker by NuAoA
- Description:
- Scans an attached inventory for a change in its contents.
- ]]--
- local comp_faces = {"Front","Back","Left","Right","Top","Bottom"}
- local inv -- used to attach
- local lastInv = {}
- local HubComputerID = 57
- function attachModem()
- for i=1,#comp_faces do
- if peripheral.isPresent(string.lower(comp_faces[i])) and peripheral.getType(string.lower(comp_faces[i])) == "modem" then
- if rednet.isOpen(string.lower(comp_faces[i])) then
- return true
- else
- rednet.open(string.lower(comp_faces[i]))
- return true
- end
- end
- end
- return false
- end
- function attachInventory()
- local face = nil
- local function checkGetAllStacks()
- local p = peripheral.wrap(face)
- local _ = p.getAllStacks() -- this will throw a error if the function does not exist.
- end
- for i=1,#comp_faces do
- if peripheral.isPresent(string.lower(comp_faces[i])) and peripheral.getType(string.lower(comp_faces[i])) ~= "modem" then
- face = string.lower(comp_faces[i])
- if pcall(checkGetAllStacks) then
- inv = peripheral.wrap(string.lower(comp_faces[i]))
- if peripheral.getType(string.lower(comp_faces[i])) == "me_interface" then
- inv.isMe = true
- end
- return true,peripheral.getType(string.lower(comp_faces[i]))
- end
- end
- end
- return false
- end
- function startup()
- term.clear()
- print("Booting Inventory Tracker")
- local isModem = attachModem()
- print("Locating modem... "..tostring(isModem))
- local isInv,invType = attachInventory()
- print("Locating inventory... "..tostring(isInv))
- print("")
- if isInv then
- print("Inventory name: "..tostring(invType))
- end
- if isInv and isModem then
- term.clear()
- term.setCursorPos(1,1)
- print(invType)
- lastInv = getInv()
- else
- print()
- print("This program requires a wireless modem and a adjacent inventory/me_interface")
- print()
- print()
- term.write("Press any key to reboot")
- os.pullEventRaw("key")
- sleep(1)
- os.reboot()
- end
- end
- --make a duplicate of a table.
- function deepcopy(orig)
- local orig_type = type(orig)
- local copy
- if orig_type == 'table' then
- copy = {}
- for orig_key, orig_value in next, orig, nil do
- copy[deepcopy(orig_key)] = deepcopy(orig_value)
- end
- setmetatable(copy, deepcopy(getmetatable(orig)))
- else -- number, string, boolean, etc
- copy = orig
- end
- return copy
- end
- function uniqueToID(unique,...)
- if type(unique) ~= "number" or unique == nil then
- if unique == nil then error("[uniqueToID] nil passed to function!",2) end
- error("[uniqueToID] invalid type passed to function! "..type(unique),2)
- end
- local Dam = math.floor(unique/2^15)
- local ID = unique%(2^15)
- if arg[1] then return ID..":"..Dam else return ID,Dam end
- end
- -- converts a ID,dam to a unique number
- function IDtoUnique(ID,...)
- if type(ID) == "string" then
- if string.match(ID,"%d+:%d+") then
- return tonumber(string.match(ID,"(%d+):%d+")) +(2^15)*tonumber(string.match(ID,"%d+:(%d+)"))
- else
- error("[IDtoUnique] Invalid string passed to function. "..ID,2)
- end
- elseif ID == nil or arg[1] == nil then
- term.clear()
- print(ID)
- print(arg[1])
- error("[IDtoUnique] Invalid arguments passed to function.",2)
- else
- return ID+arg[1]*2^15
- end
- end
- function formatTable(tab)
- -- will format a getAllStacks table into a more usefull format of the form:
- -- table[uniqueID][name] = qty
- local retTab = {}
- for slot,v in pairs(tab) do
- local retTab2 = {}
- local uniqueID = IDtoUnique(v.id,v.dmg)
- if retTab[uniqueID] ~= nil and retTab[uniqueID][v.name] ~= nil then
- retTab[uniqueID][v.name] = retTab[uniqueID][v.name] + v.qty
- elseif retTab[uniqueID] ~= nil then
- retTab[uniqueID][v.name] = v.qty
- else
- retTab2[v.name] = v.qty
- retTab[uniqueID] = retTab2
- end
- end
- return deepcopy(retTab)
- end
- -- returns the contents of
- function getInv()
- if inv.isMe then return formatTable(inv.getAvailableItems())
- else return formatTable(inv.getAllStacks()) end
- end
- function compareInv(curr,last)
- --Compares tables curr and last for differences.
- --returns a table of items that have been removed.
- local foundChange = false
- local changeTab = {}
- --check if item or qty of item was removed
- for uniqueID,tab1 in pairs(last) do
- for name,qty in pairs(tab1) do
- if curr[uniqueID] == nil or curr[uniqueID][name] == nil then
- foundChange = true
- local tab = {}
- tab.name = name
- tab.id,tab.dmg = uniqueToID(uniqueID)
- tab.qty = -1*qty
- table.insert(changeTab,deepcopy(tab))
- --item does not exist
- elseif curr[uniqueID][name] ~= last[uniqueID][name] then
- foundChange = true
- local tab = {}
- tab.name = name
- tab.id,tab.dmg = uniqueToID(uniqueID)
- tab.qty = curr[uniqueID][name] - last[uniqueID][name]
- table.insert(changeTab,deepcopy(tab))
- --qty change
- end
- end
- end
- --check if new item was inserted
- for uniqueID,tab1 in pairs(curr) do
- for name,qty in pairs(tab1) do
- if last[uniqueID] == nil or last[uniqueID][name] == nil then
- foundChange = true
- local tab = {}
- tab.name = name
- tab.id,tab.dmg = uniqueToID(uniqueID)
- tab.qty = qty
- table.insert(changeTab,deepcopy(tab))
- --item does not exist
- end
- end
- end
- return foundChange,deepcopy(changeTab)
- end
- function checkChange()
- local invTemp = getInv()
- local change,tab = compareInv(invTemp,lastInv)
- lastInv = deepcopy(invTemp)
- if change then return true,tab
- else return false,nil end
- end
- function listener()
- while true do
- local ID,mess,dist = rednet.receive()
- if ID == HubComputerID then
- if mess == "scan" then
- local isChange,tab = checkChange()
- if isChange then
- rednet.send(HubComputerID,textutils.serialize(tab))
- end
- end
- end
- end
- end
- function antiHack()
- local pullEvent = os.pullEvent
- os.pullEvent = os.pullEventRaw
- while true do
- local event,side = os.pullEventRaw("terminate")
- sleep(0)
- --userInput("terminate command")
- end
- end
- startup()
- parallel.waitForAny(listener,antiHack)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement