Advertisement
NuAoA

Untitled

Mar 23rd, 2014
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.06 KB | None | 0 0
  1. --[[
  2. Inventory Tracker by NuAoA
  3. Description:
  4.     Scans an attached inventory for a change in its contents.
  5.  
  6. ]]--
  7.  
  8. local comp_faces = {"Front","Back","Left","Right","Top","Bottom"}
  9. local inv -- used to attach
  10. local lastInv = {}
  11. local HubComputerID = 57
  12.  
  13.  
  14. function attachModem()
  15.     for i=1,#comp_faces do
  16.         if peripheral.isPresent(string.lower(comp_faces[i])) and peripheral.getType(string.lower(comp_faces[i])) == "modem" then
  17.             if rednet.isOpen(string.lower(comp_faces[i])) then
  18.                 return true
  19.             else
  20.                 rednet.open(string.lower(comp_faces[i]))               
  21.                 return true
  22.             end
  23.         end
  24.     end    
  25.     return false
  26. end
  27.  
  28. function attachInventory()
  29.     local face = nil
  30.     local function checkGetAllStacks()
  31.         local p = peripheral.wrap(face)
  32.         local _ = p.getAllStacks() -- this will throw a error if the function does not exist.
  33.     end
  34.     for i=1,#comp_faces do
  35.         if peripheral.isPresent(string.lower(comp_faces[i])) and peripheral.getType(string.lower(comp_faces[i])) ~= "modem" then
  36.             face = string.lower(comp_faces[i])
  37.             if pcall(checkGetAllStacks) then
  38.                 inv = peripheral.wrap(string.lower(comp_faces[i]))
  39.                 if peripheral.getType(string.lower(comp_faces[i])) == "me_interface" then
  40.                     inv.isMe = true
  41.                 end
  42.                 return true,peripheral.getType(string.lower(comp_faces[i]))
  43.             end        
  44.         end
  45.     end    
  46.     return false
  47. end
  48.  
  49. function startup()
  50.     term.clear()
  51.     print("Booting Inventory Tracker")
  52.     local isModem = attachModem()
  53.     print("Locating modem... "..tostring(isModem))
  54.     local isInv,invType = attachInventory()
  55.     print("Locating inventory... "..tostring(isInv))
  56.     print("")
  57.     if isInv then
  58.         print("Inventory name: "..tostring(invType))
  59.     end
  60.     if isInv and isModem then
  61.         term.clear()
  62.         term.setCursorPos(1,1)
  63.         print(invType)
  64.         lastInv = getInv()
  65.     else
  66.         print()
  67.         print("This program requires a wireless modem and a adjacent inventory/me_interface")
  68.         print()
  69.         print()
  70.         term.write("Press any key to reboot")
  71.         os.pullEventRaw("key")
  72.         sleep(1)
  73.         os.reboot()
  74.     end
  75. end
  76.  
  77. --make a duplicate of a table.
  78. function deepcopy(orig)
  79.     local orig_type = type(orig)
  80.     local copy
  81.     if orig_type == 'table' then
  82.         copy = {}
  83.         for orig_key, orig_value in next, orig, nil do
  84.             copy[deepcopy(orig_key)] = deepcopy(orig_value)
  85.         end
  86.         setmetatable(copy, deepcopy(getmetatable(orig)))
  87.     else -- number, string, boolean, etc
  88.         copy = orig
  89.     end
  90.     return copy
  91. end
  92.  
  93. function uniqueToID(unique,...)
  94.     if type(unique) ~= "number" or unique == nil then
  95.         if unique == nil then error("[uniqueToID] nil passed to function!",2) end
  96.         error("[uniqueToID] invalid type passed to function! "..type(unique),2)
  97.     end
  98.     local Dam = math.floor(unique/2^15)
  99.     local ID = unique%(2^15)
  100.     if arg[1] then return ID..":"..Dam else return ID,Dam end
  101. end
  102.  
  103. -- converts a ID,dam to a unique number
  104. function IDtoUnique(ID,...)
  105.     if type(ID) == "string" then
  106.         if string.match(ID,"%d+:%d+") then
  107.             return tonumber(string.match(ID,"(%d+):%d+")) +(2^15)*tonumber(string.match(ID,"%d+:(%d+)"))
  108.         else
  109.             error("[IDtoUnique] Invalid string passed to function. "..ID,2)
  110.         end
  111.     elseif ID == nil or arg[1] == nil then
  112.         term.clear()
  113.         print(ID)
  114.         print(arg[1])
  115.         error("[IDtoUnique] Invalid arguments passed to function.",2)
  116.     else
  117.         return ID+arg[1]*2^15
  118.     end
  119. end
  120.  
  121. function formatTable(tab)
  122.     -- will format a getAllStacks table into a more usefull format of the form:
  123.     -- table[uniqueID][name] = qty
  124.     local retTab = {}  
  125.     for slot,v in pairs(tab) do
  126.         local retTab2 = {}
  127.         local uniqueID = IDtoUnique(v.id,v.dmg)
  128.         if retTab[uniqueID] ~= nil and retTab[uniqueID][v.name] ~= nil then
  129.             retTab[uniqueID][v.name] = retTab[uniqueID][v.name] + v.qty
  130.         elseif retTab[uniqueID] ~= nil then
  131.             retTab[uniqueID][v.name] = v.qty
  132.         else
  133.             retTab2[v.name] = v.qty
  134.             retTab[uniqueID] = retTab2
  135.         end
  136.     end
  137.     return deepcopy(retTab)
  138. end
  139.  
  140. -- returns the contents of
  141. function getInv()
  142.     if inv.isMe then return formatTable(inv.getAvailableItems())
  143.     else return formatTable(inv.getAllStacks()) end
  144. end
  145.  
  146. function compareInv(curr,last)
  147.     --Compares tables curr and last for differences.
  148.     --returns a table of items that have been removed.
  149.     local foundChange = false
  150.     local changeTab = {}
  151.     --check if item or qty of item was removed
  152.     for uniqueID,tab1 in pairs(last) do
  153.         for name,qty in pairs(tab1) do
  154.             if curr[uniqueID] == nil or curr[uniqueID][name] == nil then
  155.                 foundChange = true
  156.                 local tab = {}
  157.                 tab.name = name
  158.                 tab.id,tab.dmg = uniqueToID(uniqueID)
  159.                 tab.qty = -1*qty
  160.                 table.insert(changeTab,deepcopy(tab))
  161.                 --item does not exist
  162.             elseif curr[uniqueID][name] ~= last[uniqueID][name] then
  163.                 foundChange = true
  164.                 local tab = {}
  165.                 tab.name = name
  166.                 tab.id,tab.dmg = uniqueToID(uniqueID)
  167.                 tab.qty = curr[uniqueID][name] - last[uniqueID][name]
  168.                 table.insert(changeTab,deepcopy(tab))
  169.                 --qty change
  170.             end
  171.         end
  172.     end
  173.     --check if new item was inserted
  174.     for uniqueID,tab1 in pairs(curr) do
  175.         for name,qty in pairs(tab1) do
  176.             if last[uniqueID] == nil or last[uniqueID][name] == nil then
  177.                 foundChange = true
  178.                 local tab = {}
  179.                 tab.name = name
  180.                 tab.id,tab.dmg = uniqueToID(uniqueID)
  181.                 tab.qty = qty
  182.                 table.insert(changeTab,deepcopy(tab))
  183.                 --item does not exist
  184.             end
  185.         end
  186.     end
  187.     return foundChange,deepcopy(changeTab)
  188. end
  189.  
  190. function checkChange()
  191.     local invTemp = getInv()
  192.     local change,tab = compareInv(invTemp,lastInv)
  193.     lastInv = deepcopy(invTemp)
  194.     if change then return true,tab
  195.     else return false,nil end
  196. end
  197.  
  198. function listener()
  199.     while true do
  200.         local ID,mess,dist = rednet.receive()
  201.         if ID == HubComputerID then
  202.             if mess == "scan" then
  203.                 local isChange,tab = checkChange()
  204.                 if isChange then                   
  205.                     rednet.send(HubComputerID,textutils.serialize(tab))
  206.                 end
  207.             end
  208.         end
  209.     end
  210. end
  211. function antiHack()
  212.     local pullEvent = os.pullEvent
  213.     os.pullEvent = os.pullEventRaw
  214.     while true do
  215.         local event,side = os.pullEventRaw("terminate")      
  216.         sleep(0)       
  217.         --userInput("terminate command")
  218.     end            
  219. end
  220. startup()
  221. parallel.waitForAny(listener,antiHack)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement