Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local version = 1.03
- -- SPECIAL ROOF TRAP EDITION --
- local CabinConfig = {}
- local CabinScreen = {}
- local cabinSettingsFile = "Cabin.Settings"
- local floorDescs = { }
- local floorLines = { }
- local floorPass = { }
- local KeepWaiting = true
- local Unlocked = true
- local relockAlarm = nil
- -- ######################################################
- -- ## Load the API ##
- -- ######################################################
- if fs.exists("ECAPI") then --Check to make sure that the entered API exists
- os.loadAPI("ECAPI")
- print("ECAPI loaded.")
- else
- print("That API does not exist. Retrieving from PasteBin")
- -- we get it automagically
- shell.run("pastebin","get", "1mcEVzzP", "ECAPI")
- os.loadAPI("ECAPI")
- print("ECAPI loaded.")
- end
- -- ######################################################
- -- ## Setup Configuration ##
- -- ######################################################
- local DefaultConfig = {}
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Version",version,"Please do not change this.")
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Network","","Elevator network name:")
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Modem","","Which side is the modem?",'side')
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Intro","Please enter a # or X to exit.","User Message:")
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Floor","Floor","Term for floor?")
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Description","Description","Term for floor descriptions?")
- DefaultCongig = ECAPI.addConfigOption(DefaultConfig,"PWTag","SECURE","Tag for secure floors?")
- DefaultCongig = ECAPI.addConfigOption(DefaultConfig,"PWShow","","Show secure floors [true/false]?")
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"AccessPW","","Access Password:",'pass')
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"ConfigPW","","Config. Password:",'pass') -- note, this is per machine
- DefaultConfig = ECAPI.addConfigOption(DefaultConfig,"Invalid","","Side to activate on invalid password",'side')
- local function networkName()
- return ECAPI.getConfigOption(CabinConfig,"Network")
- end
- local function modemSide()
- return ECAPI.getConfigOption(CabinConfig,"Modem")
- end
- local function floorDesc()
- return ECAPI.getConfigOption(CabinConfig,"Floor")
- end
- -- ######################################################
- -- ## Terminal Functions ##
- -- ######################################################
- local function termClear()
- ECAPI.printCabinTemplate(CabinConfig)
- CabinScreen = ECAPI.setupScreen(CabinScreen)
- term.setCursorPos(3,18)
- local prompt = ""
- if Unlocked then
- prompt = "Command:"
- else
- prompt = ECAPI.getConfigPrompt(CabinConfig,"AccessPW")
- end
- write(prompt)
- term.setCursorPos(3+string.len(prompt)+1,18)
- end
- local function justPrintLine(newLine)
- if Unlocked then
- CabinScreen = ECAPI.justPrintLine(CabinScreen,newLine)
- end
- end
- local function printFloors(floorDescTable)
- if (floorDescTable ~= nil) then
- local rawTable = textutils.unserialize(floorDescTable)
- for flID, flSettings in pairs(rawTable) do
- floorDescs[flID] = flSettings["Description"]
- if (flSettings['Password'] ~= "") then
- floorPass[flID] = flSettings['Password']
- end
- end
- end
- termClear()
- term.setCursorPos(1,6)
- if (ECAPI.table_count(floorDescs)) > 0 then
- --print("if check")
- local preX, preY = 0, 0
- for fl,desc in ECAPI.ripairs(floorDescs) do
- preX, preY = term.getCursorPos()
- floorLines[fl] = preY
- local tag = ""
- if (floorPass[fl] ~= nil) and (floorPass[fl] ~= "") then
- -- There IS a floor password. Tag setting
- tag = "["..ECAPI.getConfigOption(CabinConfig,"PWTag").."] "
- --Should we or should we not print it?
- if (string.lower(ECAPI.getConfigOption(CabinConfig,"PWShow")) ~= "true") then
- -- assume DON'T
- else
- if Unlocked then ECAPI.printLine("| "..ECAPI.padRight(fl,4,' ').." | "..ECAPI.padLeft(tag..desc,40,' ').."|") end
- end
- else
- if Unlocked then ECAPI.printLine("| "..ECAPI.padRight(fl,4,' ').." | "..ECAPI.padLeft(desc,40,' ').."|") end
- end
- end
- if (preY < 15) then
- --ElevatorControlAPI.printLine(divider)
- for i = preY,15 do
- if Unlocked then ECAPI.printLine("| "..ECAPI.padRight("",4,' ').." | "..ECAPI.padLeft("",40,' ').."|") end
- end
- end
- else
- if Unlocked then ECAPI.printLine("* No Floor computers registered. *") end
- end
- if Unlocked then ECAPI.printLine("") end
- term.setCursorPos(12,18)
- -- Any time we redraw the floors, we'll need to 'relocate' the cabin
- ECAPI.broadcast(networkName(),'locate')
- end
- function changeUpdate(output)
- local oldX, oldY = term.getCursorPos()
- term.setCursorPos(10,16)
- if Unlocked then write(ECAPI.padLeft(output,40," ")) end
- os.sleep(.25)
- term.setCursorPos(10,16)
- if Unlocked then write(ECAPI.padLeft(" ",40," ")) end
- term.setCursorPos(oldX,oldY)
- end
- local function updateFloor(floorID,indicator)
- local oldX, oldY = term.getCursorPos()
- for i = 6,15 do
- term.setCursorPos(2,i)
- if Unlocked then write(" ") end
- end
- if (floorLines ~= nil) and (ECAPI.table_count(floorLines) > 0) and (floorID ~= nil) then
- term.setCursorPos(2,floorLines[tonumber(floorID)])
- if Unlocked then write(indicator) end
- end
- term.setCursorPos(oldX, oldY)
- end
- local function openDoor()
- ECAPI.broadcast(networkName(),'openfloor')
- end
- local function selectFloor(whichFloor)
- ECAPI.broadcast(networkName(),'opendoor|invalid|') -- forces all doors closed
- ECAPI.broadcast(networkName(),'request|'..whichFloor)
- end
- local function reconfig(args)
- if (ECAPI.checkPassword(CabinScreen,CabinConfig,"ConfigPW")) then
- local what = args[1]
- if (what == nil) or (what == "") then
- CabinConfig = DefaultConfig
- createNewSettings()
- else
- what = ECAPI.caseCheck(CabinConfig,what)
- if (args[2] == nil) then
- CabinScreen, CabinConfig = ECAPI.getConfigFromUser(CabinScreen,CabinConfig,what)
- else
- CabinConfig = ECAPI.setConfigOption(CabinConfig,what,table.concat(args," ",2))
- end
- -- Make sure to SAVE changes
- ECAPI.table_save(CabinConfig,cabinSettingsFile)
- ECAPI.openModem(modemSide())
- end
- else
- local badSide = ECAPI.getConfigOption(CabinConfig,"Invalid")
- if (badSide == "") then
- changeUpdate("Invalid password.")
- else
- changeUpdate("Wrong password. Goodbye.")
- os.sleep(0.2)
- redstone.setOutput(badSide,false)
- os.sleep(60)
- redstone.setOutput(badSide,true)
- end
- end
- end
- -- ######################################################
- -- ## Settings Functions ##
- -- ######################################################
- local function createNewSettings()
- CabinConfig = DefaultConfig
- termClear()
- -- Confirm settings with the user, then save to file
- CabinScreen = ECAPI.addPrintLine(CabinScreen,"No settings file found. Confirming settings.")
- -- To ensure this code plays nice with multiple elevators, Unique network names are required (as best as can)
- CabinScreen, CabinConfig = ECAPI.getConfigFromUser(CabinScreen,CabinConfig,"Network")
- CabinScreen = ECAPI.printConfig(CabinConfig,CabinScreen,"Network")
- -- Confirm modem side
- CabinScreen, CabinConfig = ECAPI.getConfigFromUser(CabinScreen,CabinConfig,"Modem")
- CabinScreen = ECAPI.printConfig(CabinConfig,CabinScreen,"Modem")
- -- Confirm Welcome message
- CabinScreen, CabinConfig = ECAPI.getConfigFromUser(CabinScreen,CabinConfig,"Intro")
- CabinScreen = ECAPI.printConfig(CabinConfig,CabinScreen,"Intro")
- -- Confirm First column heading
- CabinScreen, CabinConfig = ECAPI.getConfigFromUser(CabinScreen,CabinConfig,"Floor")
- CabinScreen = ECAPI.printConfig(CabinConfig,CabinScreen,"Floor")
- -- Confirm Second column heading
- CabinScreen, CabinConfig = ECAPI.getConfigFromUser(CabinScreen,CabinConfig,"Description")
- CabinScreen = ECAPI.printConfig(CabinConfig,CabinScreen,"Description")
- -- Write to file
- ECAPI.table_save(CabinConfig,cabinSettingsFile)
- termClear()
- end
- local function startupConfirmation()
- -- Check if there's a settings file
- if fs.exists(cabinSettingsFile) then
- termClear()
- CabinConfig = ECAPI.table_load(cabinSettingsFile)
- ECAPI.verifyConfig(DefaultConfig,CabinConfig)
- termClear()
- CabinScreen = ECAPI.justPrintLine(CabinScreen,"Settings loaded.")
- os.sleep(0.5)
- else
- createNewSettings()
- end
- ECAPI.openModem(modemSide())
- if (ECAPI.getConfigOption(CabinConfig,"AccessPW") ~= "") then
- Unlocked = false
- end
- local badSide = ECAPI.getConfigOption(CabinConfig,"Invalid")
- if (badSide ~= "") then
- redstone.setOutput(badSide,true)
- end
- end
- -- ######################################################
- -- ## Input Actions ##
- -- ######################################################
- -- MAX Topic details: 45 characters per table entry
- -- |---------------------------------------------|
- local helpTopics = {
- ["reboot"] = { "Restart this terminal." ,},
- ["clear"] = { "Refresh the terminal screen." ,},
- ["config"] = { "Prints the current settings. Will not print",
- "any set passwords." ,},
- ["reconfig"] = { "With no parameters, re-run the whole setup.",
- "RECONFIG [option] to change a single setting",
- "Note: Reconfig can be password protected via",
- "the ConfigPW setting. If this password is",
- "lost, you will need server admin help or be",
- "forced to recreate the terminal." ,},
- ["broadcast"] = { "Manually broadcast <message>",},
- ["send"] = { "Manually send <id> <message>",},
- ["floors"] = { "Print the usual cabin display"},
- }
- local function printHelp(topic)
- justPrintLine("Help on '"..string.upper(topic).."':")
- local t = helpTopics[topic]
- for _, text in ipairs(t) do
- justPrintLine(" "..text)
- end
- end
- local commands = {
- ["help"] = function (x)
- if (x[1] ~= nil) then
- printHelp(x[1])
- else
- justPrintLine("Please use HELP [COMMAND]. ? for Command List")
- end
- end,
- ["reboot"] = function (x) os.reboot() end,
- ["clear"] = function (x) termClear() end,
- ["broadcast"] = function (x)
- CabinScreen = justPrintInfo(CabinScreen,"REDNET",nil,nil,"Broadcast: "..table.concat(x," ",2))
- ECAPI.broadcast(networkName(),table.concat(x," "))
- end,
- ["send"] = function (x)
- CabinScreen = justPrintInfo(CabinScreen,"REDNET",nil,nil,"Send("..tonumber(x[1]).."): "..table.concat(x," ",2))
- ECAPI.send(networkName(),tonumber(x[1]),table.concat(x," ",2))
- end,
- ["config"] = function (x)
- justPrintLine("Current Configuration:")
- justPrintLine("-------------------------------")
- ECAPI.printConfig(CabinConfig,CabinScreen)
- end,
- ["reconfig"] = function (x) reconfig(x) end,
- ["floors"] = function (x) printFloors() end,
- }
- local function printCommands()
- local col = 1
- local row = {}
- for named, _ in pairs(commands) do
- if (col < 5) then row[col] = string.upper(named) end
- col = col + 1
- if (col == 5) then
- justPrintLine(ECAPI.padLeft(row[1],12," ")..ECAPI.padLeft(row[2],12," ")..ECAPI.padLeft(row[3],12," ")..ECAPI.padLeft(row[4],11," "))
- row = {}
- col = 1
- end
- end
- if (col > 1) then
- -- handles 'remainders'
- justPrintLine(ECAPI.padLeft(row[1],12," ")..ECAPI.padLeft(row[2],12," ")..ECAPI.padLeft(row[3],12," ")..ECAPI.padLeft(row[4],11," "))
- end
- end
- local function processCommands(input)
- local arg = ECAPI.explode(" ",input)
- local command = arg[1]
- table.remove(arg,1)
- if Unlocked then
- if ECAPI.tableContainsKey(commands, command) then
- commands[command](arg)
- else
- --validate the floor is in the list
- if ECAPI.tableContainsKey(floorDescs,tonumber(command)) then
- if ECAPI.tableContainsKey(floorPass,tonumber(command)) then
- -- that floor is secure(ish)
- -- ask for the password
- local pwinput = ECAPI.getPasswordInput("Password:")
- -- check if it's right
- if (pwinput == ECAPI.decrypt(floorPass[tonumber(command)], networkName())) then
- changeUpdate(""..command.." selected.")
- selectFloor(command)
- else
- local badSide = ECAPI.getConfigOption(CabinConfig,"Invalid")
- if (badSide == "") then
- changeUpdate("Wrong Password!")
- else
- changeUpdate("Wrong password. Goodbye.")
- os.sleep(0.2)
- redstone.setOutput(badSide,false)
- os.sleep(60)
- redstone.setOutput(badSide,true)
- end
- end
- else
- changeUpdate(""..command.." selected.")
- selectFloor(command)
- end
- else
- changeUpdate("Invalid selection.")
- end
- end
- else
- if ECAPI.checkPassword(CabinScreen,CabinConfig,"AccessPW") then
- Unlocked = true
- printFloors()
- end
- end
- end
- -- ######################################################
- -- ## Handler Functions ##
- -- ######################################################
- -- User input listener
- local function userConsole()
- while KeepWaiting do
- if Unlocked then
- processCommands(ECAPI.getInput("Command:"))
- else
- if ECAPI.checkPassword(CabinScreen,CabinConfig,"AccessPW") then
- Unlocked = true
- relockAlarm = os.setAlarm(os.time()+2)
- printFloors()
- else
- local badSide = ECAPI.getConfigOption(CabinConfig,"Invalid")
- if (badSide == "") then
- changeUpdate("Invalid password.")
- else
- changeUpdate("Wrong password. Goodbye.")
- os.sleep(0.2)
- redstone.setOutput(badSide,false)
- os.sleep(60)
- redstone.setOutput(badSide,true)
- end
- end
- end
- end
- end
- -- Rednet listener
- local function rednetListener()
- while KeepWaiting do
- local sendID, rawmessage, distance = rednet.receive()
- local packet = ECAPI.explode("|",rawmessage)
- --print("MSG ["..sendID.."]: "..table.concat(packet,"|",2))
- --os.sleep(3)
- if packet[1] == networkName() then
- if string.lower(packet[2]) == 'floordata' then
- printFloors(packet[3])
- elseif string.lower(packet[2]) == 'reboot' then
- os.reboot()
- elseif string.lower(packet[2]) == 'displayfloor' then
- justPrintLine('displayfloor: '..packet[3])
- updateFloor(tonumber(packet[3]),">>")
- --print("arrival")
- --os.sleep(1)
- elseif string.lower(packet[2]) == 'arrival' then
- updateFloor(tonumber(packet[3]),">>")
- elseif string.lower(packet[2]) == 'displayup' then
- --justPrintLine('displayup: '..packet[4])
- updateFloor(tonumber(packet[4]),packet[3])
- elseif string.lower(packet[2]) == 'displaydown' then
- --justPrintLine('displaydown: '..packet[4])
- updateFloor(tonumber(packet[4]),packet[3])
- end
- end
- end
- end
- local function relocker()
- while KeepWaiting do
- local evt,p1 = os.pullEvent("alarm")
- if (relockAlarm ~= nil) and (p1 == relockAlarm) then
- Unlocked = false
- relockAlarm = nil
- end
- end
- end
- -- ######################################################
- -- ## Actual Run Program ##
- -- ######################################################
- startupConfirmation()
- justPrintLine('Gathering floor information.')
- --os.sleep(4) -- startup delay to the network boot up
- -- get floors from network
- ECAPI.broadcast(networkName(),'getfloors')
- parallel.waitForAll(userConsole,rednetListener,relocker)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement