JereTheJuggler

inventoryManipulator.lua

Nov 20th, 2021 (edited)
620
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.08 KB | None | 0 0
  1. if os.pullEvent == nil then os.pullEvent = nil end
  2. table.contains = function(self,value)
  3.     for _, v in ipairs(self) do
  4.         if v == value then
  5.             return true
  6.         end
  7.     end
  8.     return false
  9. end
  10.  
  11. List = {
  12.     new=function(self,t)
  13.         local list = t or {}
  14.         setmetatable(list,self)
  15.         self.__index = self
  16.         return list
  17.     end,
  18.     insert=table.insert,
  19.     remove=table.remove,
  20.     contains=table.contains
  21. }
  22.  
  23. ItemList={
  24.     new=function(self,data)
  25.         local ob = {
  26.             names={},
  27.             tags={}
  28.         }
  29.         setmetatable(ob,self)
  30.         self.__index = self
  31.         if data ~= nil then
  32.             if data.names ~= nil then
  33.                 for _,name in ipairs(data.names) do
  34.                     ob.names[name] = true
  35.                 end
  36.             end
  37.             if data.tags ~= nil then
  38.                 for _,tag in ipairs(data.tags) do
  39.                     ob.tags[tag] = true
  40.                 end
  41.             end
  42.         end
  43.         return ob
  44.     end,
  45.     addName=function(self,name)
  46.         if not self:hasName(name) then self.names[name] = true return true end
  47.         return false
  48.     end,
  49.     addTag=function(self,tag)
  50.         if not self:hasTag(tag) then self.tags[tag] = true return true end
  51.         return false
  52.     end,
  53.     removeName=function(self,name)
  54.         if self:hasName(name) then self.names[name] = nil return true end
  55.         return false
  56.     end,
  57.     removeTag=function(self,tag)
  58.         if self:hasTag(tag) then self.tags[tag] = nil return true end
  59.         return false
  60.     end,
  61.     hasName=function(self,name)
  62.         return self.names[name] ~= nil
  63.     end,
  64.     hasTag=function(self,tag)
  65.         return self.tags[tag] ~= nil
  66.     end,
  67.     getSaveData=function(self)
  68.         local ob = {
  69.             names={},
  70.             tags={}
  71.         }
  72.         for name,_ in pairs(self.names) do table.insert(ob.names,name) end
  73.         for tag,_ in pairs(self.tags) do table.insert(ob.tags,tag) end
  74.         return ob
  75.     end
  76. }
  77.  
  78. PlayerList={
  79.     list={},
  80.     addPlayer=function(name)
  81.         if PlayerList.list[name] == nil then
  82.             local p = Player:new(name)
  83.             PlayerList.list[name] = p
  84.             if p.stored == nil then
  85.                 print("stored is nil")
  86.                 os.pullEvent("key")
  87.             end
  88.             p:loadSaveData()
  89.         end
  90.     end,
  91.     getNames=function()
  92.         local names = {}
  93.         for name,_ in pairs(PlayerList.list) do
  94.             table.insert(names,name)
  95.         end
  96.         return names
  97.     end,
  98.     hasPlayer=function(name)
  99.         return PlayerList.list[name] ~= nil
  100.     end,
  101.     getPlayer=function(name)
  102.         return PlayerList.list[name]
  103.     end
  104. }
  105.  
  106. Player={
  107.     new=function(self,name)
  108.         local ob = {
  109.             name=name,
  110.             managingEnabled=true,
  111.             enablingItem=nil,
  112.             stored=ItemList:new(),
  113.             trashed=ItemList:new()
  114.         }
  115.         setmetatable(ob,self)
  116.         self.__index = self
  117.         return ob
  118.     end,
  119.     getSaveFilename=function(self)
  120.         return self.name..".config"
  121.     end,
  122.     writeSaveData=function(self)
  123.         local data = textutils.serialize({
  124.             enablingItem=self.enablingItem,
  125.             stored=self.stored:getSaveData(),
  126.             trashed=self.trashed:getSaveData()
  127.         })
  128.         local h = fs.open(self:getSaveFilename(),"w")
  129.         h.write(data)
  130.         h.close()
  131.     end,
  132.     loadSaveData=function(self)
  133.         local fname = self:getSaveFilename()
  134.         if fs.exists(fname) then
  135.             local h = fs.open(fname,"r")
  136.             local text = h.readAll()
  137.             h.close()
  138.             local data = textutils.unserialize(text)
  139.             if data.enablingItem ~= nil then
  140.                 self.enablingItem = data.enablingItem
  141.             else
  142.                 self.enablingItem = nil
  143.             end
  144.             if data.stored ~= nil then
  145.                 self.stored=ItemList:new(data.stored)
  146.             else
  147.                 self.stored=ItemList:new()
  148.             end
  149.             if data.trashed ~= nil then
  150.                 self.trashed=ItemList:new(data.trashed)
  151.             else
  152.                 self.trashed=ItemList:new()
  153.             end
  154.         else
  155.             self.enablingItem = nil
  156.             self.stored = ItemList:new()
  157.             self.trashed = ItemList:new()
  158.         end
  159.     end,
  160.     setEnablingItem=function(self,name)
  161.         if self.enablingItem == nil or self.enablingItem ~= name then
  162.             self.enablingItem = name
  163.             self:writeSaveData()
  164.         end
  165.     end,
  166.     addStoredName=function(self,name)
  167.         if self.stored:addName(name) then self:writeSaveData() end
  168.     end,
  169.     addStoredTag=function(self,tag)
  170.         if self.stored:addTag(tag) then self:writeSaveData() end
  171.     end,
  172.     addTrashedName=function(self,name)
  173.         if self.trashed:addName(name) then self:writeSaveData() end
  174.     end,
  175.     addTrashedTag=function(self,tag)
  176.         if self.trashed:addTag(tag) then self:writeSaveData() end
  177.     end,
  178.     removeStoredName=function(self,name)
  179.         if self.stored:removeName(name) then self:writeSaveData() end
  180.     end,
  181.     removeStoredTag=function(self,tag)
  182.         if self.stored:removeTag(tag) then self:writeSaveData() end
  183.     end,
  184.     removeTrashedName=function(self,name)
  185.         if self.trashed:removeName(name) then self:writeSaveData() end
  186.     end,
  187.     removeTrashedTag=function(self,tag)
  188.         if self.trashed:removeTag(tag) then self:writeSaveData() end
  189.     end,
  190.     removeStoredItem=function(self,item)
  191.         local needsSave = self.stored:removeName(item.name)
  192.         if item.tags ~= nil then
  193.             for _,tag in ipairs(item.tags) do
  194.                 if self.stored:removeTag(tag) then needsSave = true end
  195.             end
  196.         end
  197.         if needsSave then self:writeSaveData() end
  198.     end,
  199.     removeTrashedItem=function(self,item)
  200.         local needsSave = self.trashed:removeName(item.name)
  201.         if item.tags ~= nil then
  202.             for _,tag in ipairs(item.tags) do
  203.                 if self.trashed:removeTag(tag) then needsSave = true end
  204.             end
  205.         end
  206.         if needsSave then self:writeSaveData() end
  207.     end,
  208.     shouldStore=function(self,item)
  209.         if self.stored:hasName(item.name) then return true end
  210.         if item.tags ~= nil then
  211.             for _,tag in ipairs(item.tags) do
  212.                 if self.stored:hasTag(tag) then return true end
  213.             end
  214.         end
  215.         return false
  216.     end,
  217.     shouldTrash=function(self,item)
  218.         if self.trashed:hasName(item.name) then return true end
  219.         if item.tags ~= nil then
  220.             for _,tag in ipairs(item.tags) do
  221.                 if self.trashed:hasTag(tag) then return true end
  222.             end
  223.         end
  224.         return false
  225.     end
  226. }
  227.  
  228. InventoryList={
  229.     list={},
  230.     hasInventory=function(name)
  231.         return InventoryList.list[name] ~= nil
  232.     end,
  233.     addInventory=function(name)
  234.         if not InventoryList.hasInventory(name) then
  235.             InventoryList.list[name] = Inventory:new(name)
  236.         end
  237.     end,
  238.     getInventoryForPlayer=function(playerName)
  239.         for _,inv in pairs(InventoryList.list) do
  240.             if inv:safeGetOwner() == playerName then return inv end
  241.         end
  242.         return nil
  243.     end
  244. }
  245.  
  246. Inventory={
  247.     new=function(self,name)
  248.         local inv = peripheral.wrap(name)
  249.         inv.name = name
  250.         setmetatable(inv,self)
  251.         self.__index = self
  252.         return inv
  253.     end,
  254.     scan=function(self)
  255.         local playerName = self:safeGetOwner()
  256.  
  257.         if playerName == nil then return end
  258.  
  259.         if not PlayerList.hasPlayer(playerName) then
  260.             PlayerList.addPlayer(playerName)
  261.         end
  262.         local player = PlayerList.getPlayer(playerName)
  263.  
  264.         --prevent scanning if inventory's player does not have an enabling item set
  265.         if player.enablingItem == nil then return end
  266.  
  267.         --prevent modifying inventory if player is currently being configured
  268.         --allow scan to continue to look for whether or not the player is holding their enabling item
  269.         local readonly = CommandLine.currentPlayer ~= nil and CommandLine.currentPlayer.name == player.name
  270.  
  271.         local items = nil
  272.         if not pcall(function() items = self.getItems() end) then return end
  273.         local foundEnabler = false
  274.         for slot,item in pairs(items) do
  275.             if item.name == player.enablingItem then
  276.                 player.managingEnabled = true
  277.                 foundEnabler = true
  278.             end
  279.             if player.managingEnabled and not readonly then
  280.                 if player:shouldStore(item) then
  281.                     self.removeItemFromPlayer("UP",item.count,slot,item.name)
  282.                 elseif player:shouldTrash(item) then
  283.                     self.removeItemFromPlayer("DOWN",item.count,slot,item.name)
  284.                 end
  285.             end
  286.         end
  287.         if not foundEnabler then
  288.             player.managingEnabled = false
  289.         end
  290.     end,
  291.     safeGetOwner=function(self)
  292.         local owner = nil
  293.         pcall(function() owner = self.getOwner() end)
  294.         return owner
  295.     end
  296. }
  297.  
  298. Peripherals={
  299.     sideNames = {front=true,back=true,left=true,right=true,top=true,bottom=true},
  300.     findInventories=function()
  301.         for _,name in ipairs(peripheral.getNames()) do
  302.             if Peripherals.sideNames[name] == nil then
  303.                 local peripType = peripheral.getType(name)
  304.                 if peripType == "inventoryManager" then
  305.                     if not InventoryList.hasInventory(name) then
  306.                         InventoryList.addInventory(name)
  307.                     end
  308.                 end
  309.             end
  310.         end
  311.     end,
  312.     findModem=function()
  313.         for _,name in ipairs(peripheral.getNames()) do
  314.             if Peripherals.sideNames[name] == nil then
  315.                 local peripType = peripheral.getType(name)
  316.                 if peripType == "modem" then
  317.                     local p = peripheral.wrap(name)
  318.                     if p.isWireless() then
  319.                         rednet.open(name)
  320.                         return
  321.                     end
  322.                 end
  323.             end
  324.         end
  325.     end
  326. }
  327.  
  328. CommandLine={
  329.     instructionColor=colors.lightBlue,
  330.     errorColor=colors.red,
  331.     valueColor=colors.yellow,
  332.  
  333.     currentPlayer=nil,
  334.     currentOperation=nil,
  335.  
  336.     setEnablingItemText = "Set My Enabler Item",
  337.     addStoredItemText = "Add Stored Item",
  338.     addTrashedItemText = "Add Trashed Item",
  339.     removeStoredItemText = "Remove Stored Item",
  340.     removeTrashedItemText = "Remove Trashed Item",
  341.     switchPlayerText = "Log Out",
  342.  
  343.     clear=function(self)
  344.         term.clear()
  345.         term.setCursorPos(1,1)
  346.         if self.currentPlayer ~= nil then
  347.             term.write("Current User: ")
  348.             term.setTextColor(colors.yellow)
  349.             self:printValue(self.currentPlayer.name)
  350.             term.setTextColor(colors.white)
  351.             if self.currentOperation ~= nil then
  352.                 term.write("Current Operation: ")
  353.                 term.setTextColor(colors.yellow)
  354.                 self:printValue(self.currentOperation)
  355.                 term.setTextColor(colors.white)
  356.             end
  357.             print()
  358.         end
  359.     end,
  360.     print=function(self,text)
  361.         if type(text) == "table" then
  362.             if text.color ~= nil then
  363.                 local originalColor = term.getTextColor()
  364.                 if text.color ~= nil then
  365.                     term.setTextColor(text.color)
  366.                 end
  367.                 for _,line in ipairs(text) do
  368.                     self:print(line)
  369.                 end
  370.                 term.setTextColor(originalColor)
  371.             else
  372.                 for _,line in ipairs(text) do
  373.                     self:print(line)
  374.                 end
  375.             end
  376.         else
  377.             print(text)
  378.         end
  379.     end,
  380.     printValue=function(self,text)
  381.         term.setTextColor(colors.yellow)
  382.         self:print(text)
  383.         term.setTextColor(colors.white)
  384.     end,
  385.     instruction=function(self,text)
  386.         term.setTextColor(colors.lightBlue)
  387.         self:print(text)
  388.         term.setTextColor(colors.white)
  389.     end,
  390.     error=function(self,text)
  391.         term.setTextColor(colors.red)
  392.         self:print(text)
  393.         term.setTextColor(colors.white)
  394.     end,
  395.  
  396.     promptOperation=function(self)
  397.         local actions = {
  398.             self.setEnablingItemText,
  399.             self.addStoredItemText,
  400.             self.removeStoredItemText,
  401.             self.addTrashedItemText,
  402.             self.removeTrashedItemText,
  403.             self.switchPlayerText
  404.         }
  405.         while true do
  406.             self.currentOperation = nil
  407.             if self.currentPlayer == nil then
  408.                 self:setPlayer()
  409.             else
  410.                 local cancelled, selection = self:promptSelection("What would you like to do?",actions,false)
  411.                 local action = actions[selection]
  412.                 if action == self.switchPlayerText then
  413.                     self.currentPlayer = nil
  414.                 else
  415.                     self.currentOperation = action
  416.                     if action == self.setEnablingItemText then
  417.                         self:setEnablingItem()
  418.                     elseif action == self.addStoredItemText then
  419.                         self:addStoredItem()
  420.                     elseif action == self.removeStoredItemText then
  421.                         self:removeStoredItem()
  422.                     elseif action == self.addTrashedItemText then
  423.                         self:addTrashedItem()
  424.                     elseif action == self.removeTrashedItemText then
  425.                         self:removeTrashedItem()
  426.                     end
  427.                 end
  428.             end
  429.         end
  430.     end,
  431.     promptSelection=function(self,instructionText,options,canCancel)
  432.         if canCancel == nil then canCancel = true end
  433.         while true do
  434.             self:clear()
  435.             self:instruction(instructionText)
  436.             for i,option in ipairs(options) do
  437.                 print(i..") "..option)
  438.             end
  439.             if canCancel then
  440.                 self:error((#options+1)..") Cancel")
  441.             end
  442.             print()
  443.             local input = tonumber(read())
  444.             if input ~= nil then
  445.                 input = math.floor(input)
  446.                 if canCancel and input == #options + 1 then
  447.                     return true, nil
  448.                 end
  449.                 if input > 0 and input <= #options then
  450.                     return false, input
  451.                 end
  452.             end
  453.         end
  454.     end,
  455.     promptYesNo=function(self,instructionText)
  456.         while true do
  457.             self:clear()
  458.             self:instruction(instructionText)
  459.             term.write("1) ")
  460.             term.setTextColor(colors.lime)
  461.             print("Yes")
  462.             term.setTextColor(colors.white)
  463.             term.write("2) ")
  464.             term.setTextColor(colors.red)
  465.             print("No")
  466.             term.setTextColor(colors.white)
  467.             print()
  468.             local input = tonumber(read())
  469.             if input ~= nil then
  470.                 if input == 1 then return true end
  471.                 if input == 2 then return false end
  472.             end
  473.         end
  474.     end,
  475.     promptCancelOrRetry=function(self,errorText)
  476.         self:clear()
  477.         self:error(errorText)
  478.         print()
  479.         self:instruction({"Press X to cancel","Press any other key to try again"})
  480.         local _,key = os.pullEvent("key")
  481.         if key == keys.x then return false end
  482.         return true
  483.     end,
  484.     promptNameOrTags=function(self,heldItem,instruction)
  485.         local options = {
  486.             "Name \""..heldItem.name.."\""
  487.         }
  488.         for _,tag in ipairs(heldItem.tags) do
  489.             table.insert(options,"Tag \""..tag.."\"")
  490.         end
  491.         local cancelled, selection = self:promptSelection(instruction,options)
  492.         if cancelled then return nil, nil end
  493.         if selection == 1 then return heldItem.name, nil end
  494.         return nil, heldItem.tags[selection-1]
  495.     end,
  496.  
  497.     confirmHeldItem=function(self,heldItem,question)
  498.         return self:promptYesNo({
  499.             {color=colors.white,"The current user is holding this item:"},
  500.             {color=self.valueColor,self.getItemDisplayName(heldItem)},
  501.             "",
  502.             question
  503.         })
  504.     end,
  505.  
  506.     getHeldItem=function(self)
  507.         if self.currentPlayer == nil then return nil end
  508.         while true do
  509.             local inv = InventoryList.getInventoryForPlayer(self.currentPlayer.name)
  510.             if inv ~= nil then
  511.                 local heldItem = nil
  512.                 if not pcall(function() heldItem = inv.getItemInHand() end) then
  513.                     if not self:promptCancelOrRetry({"The inventory for the current user is not","available at this time"}) then
  514.                         return nil
  515.                     end
  516.                 elseif heldItem == nil or heldItem.name == nil or heldItem.count == 0 then
  517.                     if not self:promptCancelOrRetry({"You are not currently holding any items"}) then
  518.                         return nil
  519.                     end
  520.                 else
  521.                     return heldItem
  522.                 end
  523.             else
  524.                 if not self:promptCancelOrRetry({"An inventory with a memory card for the current","user could not be found"}) then
  525.                     return nil
  526.                 end
  527.             end
  528.         end
  529.     end,
  530.     getItemDisplayName=function(item)
  531.         return string.sub(item.displayName,2,string.len(item.displayName)-1)
  532.     end,
  533.  
  534.     setPlayer=function(self)
  535.         self.currentPlayer = nil
  536.         local names = PlayerList.getNames()
  537.         if #names == 0 then
  538.             self:error("No player memory cards have been found")
  539.             sleep(10)
  540.             return
  541.         end
  542.         table.insert(names,"Refresh List")
  543.         local cancelled, selection = self:promptSelection({
  544.             "Please select a player to modify",
  545.             {color=self.valueColor,
  546.                 "Note: Inventory management will be disabled for",
  547.                 "      the selected user until they are logged out"
  548.             }
  549.         },names,false)
  550.         if selection == #names then return end
  551.         self.currentPlayer = PlayerList.getPlayer(names[selection])
  552.     end,
  553.     setEnablingItem=function(self)
  554.         local heldItem = self:getHeldItem()
  555.         if heldItem == nil then return end
  556.         if self:confirmHeldItem(heldItem,"Do you want to set that item as the enabling item?") then
  557.             self.currentPlayer:setEnablingItem(heldItem.name)
  558.         end
  559.     end,
  560.     addStoredItem=function(self)
  561.         local heldItem = self:getHeldItem()
  562.         if heldItem == nil then return end
  563.         if heldItem.tags == nil then
  564.             if self:confirmHeldItem(heldItem,"Do you want to automatically store that item?") then
  565.                 self.currentPlayer:addStoredName(heldItem.name)
  566.             end
  567.         else
  568.             local name, tag = self:promptNameOrTags(heldItem,"Store items with...")
  569.             if name ~= nil then
  570.                 self.currentPlayer:addStoredName(name)
  571.             elseif tag ~= nil then
  572.                 self.currentPlayer:addStoredTag(tag)
  573.             end
  574.         end
  575.     end,
  576.     addTrashedItem=function(self)
  577.         local heldItem = self:getHeldItem()
  578.         if heldItem == nil then return end
  579.         if heldItem.tags == nil then
  580.             if self:confirmHeldItem(heldItem,"Do you want to automatically trash that item?") then
  581.                 self.currentPlayer:addTrashedName(heldItem.name)
  582.             end
  583.         else
  584.             local name, tag = self:promptNameOrTags(heldItem,"Trash items with...")
  585.             if name ~= nil then
  586.                 self.currentPlayer:addTrashedName(name)
  587.             elseif tag ~= nil then
  588.                 self.currentPlayer:addTrashedTag(tag)
  589.             end
  590.         end
  591.     end,
  592.     removeStoredItem=function(self)
  593.         local heldItem = self:getHeldItem()
  594.         if heldItem == nil then return end
  595.         if self:confirmHeldItem(heldItem,"Do you want to stop storing that item?") then
  596.             self.currentPlayer:removeStoredItem(heldItem)
  597.         end
  598.     end,
  599.     removeTrashedItem=function(self)
  600.         local heldItem = self:getHeldItem()
  601.         if heldItem == nil then return end
  602.         if self:confirmHeldItem(heldItem,"Do you want to stop storing that item?") then
  603.             self.currentPlayer:removeTrashedItem(heldItem)
  604.         end
  605.     end
  606. }
  607.  
  608. function run()
  609.     parallel.waitForAny(function()
  610.         --rednet
  611.         Peripherals.findModem()
  612.         while true do
  613.             local senderId, message, protocol = rednet.receive()
  614.  
  615.         end
  616.     end,function()
  617.         --inventory managing function
  618.         while true do
  619.             Peripherals.findInventories()
  620.             for _,inv in pairs(InventoryList.list) do
  621.                 inv:scan()
  622.             end
  623.             sleep(5)
  624.         end
  625.     end,function()
  626.         --command line function
  627.         CommandLine:promptOperation()
  628.     end)
  629. end
  630. run()
Add Comment
Please, Sign In to add comment