Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local localDir = shell.resolve("")
- local configPath = localDir.."/settings.config"
- local listsFolder = localDir.."/lists"
- if not fs.exists(listsFolder) then fs.makeDir(listsFolder) end
- local controller = nil
- local trashCan = nil
- local modem = nil
- local clients = {
- -- [playerName]={
- -- chestAddress=[address],
- -- chest=[wrappedPlayerChest],
- -- active=[active],
- -- dumpList={
- -- [itemDisplayName]=true,
- -- ...
- -- },
- -- trashList={
- -- [itemDisplayName]=true,
- -- ...
- -- }
- -- },
- -- ...
- }
- local drawerIndex = {
- -- [itemDisplayName]=[slot],
- -- ...
- }
- local modemPort = 12
- local running = true
- function initialize()
- local self = {}
- function self:loadConfig()
- -- format:
- -- {
- -- [playerName]={
- -- chestAddress=[address],
- -- active=[active],
- -- dumpList={
- -- [itemDisplayName]=true,
- -- ...
- -- },
- -- trashList={
- -- [itemDisplayName]=true,
- -- ...
- -- }
- -- },
- -- ...
- -- }
- print("loading config...")
- if fs.exists(configPath) then
- local status,result = pcall(function()
- local file = fs.open(configPath,"r")
- local contents = file.readAll()
- file.close()
- return textutils.unserialize(contents)
- end)
- if status then
- self:handleConfigData(result)
- else
- term.setTextColor(colors.red)
- print("error loading config - "..result)
- term.setTextColor(colors.white)
- end
- end
- end
- function self:handleConfigData(data)
- local status,result = pcall(function()
- if type(data) ~= "table" then error("data is not a table") end
- for playerName,clientData in ipairs(data) do
- --validate client data
- local status2,result2 = pcall(function()
- if type(clientData) ~= "table" then error("client data is not a table") end
- if clientData.chestAddress ~= nil and
- type(clientData.chestAddress) == "string" and
- clientData.active ~= nil and
- type(clientData.active) == "boolean" then
- return true
- else error("invalid client data") end
- end)
- if status2 then
- --client data is valid
- clients[playerName] = clientData
- else
- term.setTextColor(colors.red)
- print("error loading config - "..result2)
- end
- end
- end)
- if not status then
- term.setTextColor(colors.red)
- print("error loading config - "..result)
- end
- end
- function self:setupPerips()
- print("setting up peripherals...")
- for _,address in ipairs(peripheral.getNames()) do
- local t = peripheral.getType(address)
- if t == "storagedrawers:controller" then
- controller = peripheral.wrap(address)
- elseif t == "xu2:tiletrashcan" then
- trashCan = peripheral.wrap(address)
- elseif t == "modem" and peripheral.call(address,"isWireless") then
- modem = peripheral.wrap(address)
- if not modem.isOpen(modemPort) then modem.open(modemPort) end
- end
- end
- for playerName,playerData in pairs(clients) do
- if peripheral.isPresent(playerData.chestAddress) then
- clients[playerName].chest = peripheral.wrap(playerData.chestAddress)
- else
- term.setTextColor(colors.red)
- print("chest not found for "..playerName)
- clients[playerName] = nil
- end
- end
- if controller == nil then error("Drawer controller not found") end
- if modem == nil then error("Wireless modem not found") end
- if trashCan == nil then error("Trash can not found") end
- end
- function self:loadLists()
- print("loading user lists...")
- local lists = {"dumpList","trashList"}
- for playerName,playerData in pairs(clients) do
- print("loading lists for "..playerName)
- --try to read in lists stored for each player
- local playerFolder = listsFolder.."/"..playerName
- if not fs.exists(playerFolder) then
- fs.makeDir(playerFolder)
- else
- for _,list in ipairs(lists) do
- local listFile = playerFolder.."/"..list..".list"
- if fs.exists(listFile) then
- local status,result = pcall(function()
- local file = fs.open(listFile,"r")
- local contents = file.readAll()
- file.close()
- return textutils.unserialize(contents)
- end)
- if status then
- clients[playerName][list] = result
- end
- end
- end
- end
- --populate tables for any lists that weren't read in
- for _,list in ipairs(lists) do
- if clients[playerName][list] == nil then
- clients[playerName][list] = {}
- end
- end
- end
- end
- term.clear()
- term.setCursorPos(1,1)
- print("initializing...")
- self:loadConfig()
- self:setupPerips()
- self:loadLists()
- drawerIndex = createDrawerIndex()
- end
- function createDrawerIndex()
- print("indexing drawers...")
- local index = {}
- for i=1,controller.size() do
- local meta = controller.getItemMeta(i)
- if meta ~= nil then index[meta.displayName] = i end
- end
- return index
- end
- function main()
- while true do
- for playerName,playerData in pairs(clients) do
- pcall(function()
- local chest = playerData.chest
- for i=1,i<chest.size() do
- local meta = chest.getItemMeta(i)
- if meta ~= nil then
- if playerData.dumpList[meta.displayName] ~= nil and drawerIndex[meta.displayName] ~= nil then
- controller.pullItems(playerData.chestAddress,i,meta.count,drawerIndex[meta.displayName])
- end
- end
- end
- end)
- end
- sleep(2.5)
- end
- end
- local MessageFunctions = {
- ping=function(message)
- return {success=true}
- end,
- pause=function(message)
- clients[message.playerName].active = false
- return {active=false}
- end,
- resume=function(message)
- clients[message.playerName].active = true
- return {active=true}
- end,
- getActive=function(message)
- return {active=clients[message.playerName].active}
- end,
- addDump=function(message)
- if message.displayName ~= nil then
- if clients[message.playerName].dumpList[message.displayName] == nil then
- clients[message.playerName].dumpList[message.displayName] = 1
- saveConfig(
- listsFolder.."/"..message.playerName.."/dumpList.list",
- clients[message.playerName].dumpList
- )
- end
- return {success=true}
- end
- return {success=false}
- end,
- removeDump=function(message)
- if message.displayName ~= nil then
- if clients[message.playerName].dumpList[message.displayName] ~= nil then
- clients[message.playerName].dumpList[message.displayName] = nil
- saveConfig(
- listsFolder.."/"..message.playerName.."/dumpList.list",
- clients[message.playerName].dumpList
- )
- end
- return {success=true}
- end
- return {success=false}
- end,
- getDumpList=function(message)
- return clients[message.playerName].dumpList
- end,
- addTrash=function(message)
- if message.displayName ~= nil then
- if clients[message.playerName].trashList[message.displayName] == nil then
- clients[message.playerName].trashList[message.displayName] = 1
- saveConfig(
- listsFolder.."/"..message.playerName.."/trashList.list",
- clients[message.playerName].trashList
- )
- end
- return {success=true}
- end
- return {success=false}
- end,
- removeTrash=function(message)
- if message.displayName ~= nil then
- if clients[message.playerName].trashList[message.displayName] ~= nil then
- clients[message.playerName].trashList[message.displayName] = nil
- saveConfig(
- listsFolder.."/"..message.playerName.."/trashList.list",
- clients[message.playerName].trashList
- )
- end
- return {success=true}
- end
- return {success=false}
- end,
- getTrashList=function(message)
- return clients[message.playerName].trashList
- end
- }
- function messageListener()
- while true do
- local event,side,freq,replyFreq,message,dist = os.pullEvent("modem_message")
- if type(message) == "table" then
- if message.playerName ~= nil and clients[message.playerName] ~= nil and
- message.operation ~= nil and MessageFunctions[message.operation] ~= nil then
- local response = MessageFunctions[message.operation](message)
- if response ~= nil then
- modem.transmit(replyFreq,modemPort,response)
- end
- end
- end
- end
- end
- local TermFunctions = {
- { text="List Players",
- func=function()
- for playerName,playerData in pairs(clients) do
- print(playerName)
- end
- term.setTextColor(colors.yellow)
- print("Press any key to continue")
- os.pullEvent("key")
- term.setTextColor(colors.white)
- end
- },
- { text="Add Player",
- func=function()
- term.setTextColor(colors.yellow)
- print("Add who?")
- term.setTextColor(colors.white)
- local input = read()
- if clients[input] == nil then
- term.setTextColor(colors.yellow)
- print("Please connect an Extra Utilities 2 Player Chest")
- print("Press any key to cancel")
- local chestAddress = nil
- term.setTextColor(colors.red)
- parallel.waitForAny(function()
- --wait for player chest to be added
- while true do
- local event,address = os.pullEvent("peripheral")
- local t = peripheral.getType(address)
- if t ~= "xu2:tileplayerchest" then
- print("Invalid peripheral attached")
- term.setCursorPos(1,6)
- else
- chestAddress = address
- return
- end
- end
- end,function()
- --cancel function
- os.pullEvent("key")
- end)
- term.clearLine(6)
- if chestAddress == nil then
- print("Add Player operation aborted")
- else
- clients[input] = {
- active=false,
- chestAddress=chestAddress,
- chest=peripheral.wrap(chestAddress)
- }
- if not fs.exists(listsFolder.."/"..input) then fs.makeDir(listsFolder.."/"..input) end
- term.setTextColor(colors.lime)
- --try to read in any existing lists for the player
- local dumpList = loadConfig(listsFolder.."/"..input.."/dumpList.list")
- if dumpList == nil then dumpList = {} end
- local trashList = loadConfig(listsFolder.."/"..input.."/trashList.list")
- if trashList == nil then trashList = {} end
- clients[input].dumpList = dumpList
- clients[input].trashList = trashList
- print("Success")
- end
- else
- term.setTextColor(colors.red)
- print("Player already added")
- end
- term.setTextColor(colors.white)
- sleep(.5)
- end
- },
- { text="Remove Player",
- func=function()
- term.setTextColor(colors.yellow)
- print("Remove who?")
- term.setTextColor(colors.white)
- local input = read()
- if clients[input] ~= nil then
- clients[input] = nil
- term.setTextColor(colors.lime)
- print("Success")
- else
- term.setTextColor(colors.red)
- print("Player was not added")
- end
- term.setTextColor(colors.white)
- sleep(.5)
- end
- },
- { text="Re-index Drawers",
- func=function()
- drawerIndex = createDrawerIndex()
- end
- },
- { text="Terminate",
- func=function()
- running = false
- end
- }
- }
- function termInteractions()
- term.clear()
- term.setCursorPos(1,1)
- for i,funcData in ipairs(TermFunctions) do
- print(i..") "..funcData.text)
- end
- term.setTextColor(colors.yellow)
- print("Enter number from 1 to "..(#TermFunctions))
- term.setTextColor(colors.white)
- local termWidth,termHeight = term.getSize()
- local inputWindow = window.create(term.current(),1,(#TermFunctions)+1,termWidth,termHeight-(#TermFunctions)-1,true)
- term.redirect(inputWindow)
- while running do
- term.clear()
- term.setCursorPos(1,1)
- local input = tonumber(read())
- if input ~= nil and input >= 1 and input <= #TermFunctions then
- TermFunctions[input].func()
- end
- end
- term.redirect(term.native())
- end
- function writeAllConfigs()
- print("saving config...")
- local configData = {}
- for playerName,playerData in pairs(clients) do
- configData[playerName] = {
- chestAddress=playerData.chestAddress,
- active=playerData.active
- }
- end
- saveConfig(configPath,configData)
- print("saving user lists...")
- local lists = {"dumpList","trashList"}
- for playerName,playerData in pairs(clients) do
- for _,list in ipairs(lists) do
- if #playerData[list] ~= 0 then
- saveConfig(listsFolder.."/"..playerName.."/"..list..".list",playerData[list])
- end
- end
- end
- end
- function saveConfig(configPath,configData)
- local file = fs.open(configPath,"w")
- file.write(textutils.serialize(configData))
- file.close()
- end
- function loadConfig(configPath)
- if not fs.exists(configPath) then return nil end
- local file = fs.open(configPath,"r")
- local contents = file.readAll()
- file.close()
- return textutils.unserialize(contents)
- end
- function run()
- initialize()
- parallel.waitForAny(
- termInteractions,
- messageListener,
- main
- )
- writeAllConfigs()
- end
- run()
- sleep(2.5)
- term.clear()
- term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement