Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- door_access.lua
- -- Secure door access system with server-verified login
- -- Place computer with modem on RIGHT, door connected via redstone BEHIND
- -- ============================================
- -- CONFIGURATION
- -- ============================================
- local ADMIN_ACCOUNT = "admin"
- local ACCESS_DIR = ".door_access"
- local ACCESS_FILE = ACCESS_DIR .. "/allowed_users.txt"
- local DOOR_OPEN_TIME = 5
- -- ============================================
- -- PERIPHERAL SETUP
- -- ============================================
- local modem = peripheral.wrap("right")
- if not modem then
- error("No modem on right side. Please attach a wireless modem.")
- end
- modem.open(1)
- -- ============================================
- -- ACCESS LIST MANAGEMENT (LOCAL)
- -- ============================================
- local function ensureAccessDir()
- if not fs.exists(ACCESS_DIR) then
- fs.makeDir(ACCESS_DIR)
- end
- end
- local function loadAccessList()
- ensureAccessDir()
- if not fs.exists(ACCESS_FILE) then return {} end
- local file = fs.open(ACCESS_FILE, "r")
- local data = file.readAll()
- file.close()
- return textutils.unserialize(data) or {}
- end
- local function saveAccessList(list)
- ensureAccessDir()
- local file = fs.open(ACCESS_FILE, "w")
- file.write(textutils.serialize(list))
- file.close()
- end
- local function hasAccess(studentId)
- if studentId == ADMIN_ACCOUNT then return true end
- local list = loadAccessList()
- for _, id in ipairs(list) do
- if id == studentId then return true end
- end
- return false
- end
- local function grantAccess(studentId)
- if studentId == ADMIN_ACCOUNT then return true end
- local list = loadAccessList()
- for _, id in ipairs(list) do
- if id == studentId then return true end
- end
- table.insert(list, studentId)
- saveAccessList(list)
- return true
- end
- local function revokeAccess(studentId)
- if studentId == ADMIN_ACCOUNT then return false end
- local list = loadAccessList()
- local newList = {}
- local found = false
- for _, id in ipairs(list) do
- if id ~= studentId then
- table.insert(newList, id)
- else
- found = true
- end
- end
- if found then
- saveAccessList(newList)
- end
- return found
- end
- -- ============================================
- -- SERVER COMMUNICATION
- -- ============================================
- local function sendServerRequest(request, expectedType)
- modem.transmit(1, 1, request)
- local timer = os.startTimer(5)
- while true do
- local event, param1, _, _, message = os.pullEvent()
- if event == "modem_message" and type(message) == "table" then
- if message.type == expectedType then return message end
- if message.type == "error" then return nil end
- elseif event == "timer" and param1 == timer then
- return nil
- end
- end
- end
- local function verifyLogin(studentId, password)
- local response = sendServerRequest({
- type = "login",
- studentId = studentId,
- password = password
- }, "login_response")
- if response and response.success then
- return true
- end
- return false
- end
- -- ============================================
- -- UI HELPERS
- -- ============================================
- local function clear()
- term.clear()
- term.setCursorPos(1, 1)
- end
- local function centerText(text, y)
- local w, _ = term.getSize()
- term.setCursorPos(math.floor((w - #text) / 2) + 1, y)
- term.write(text)
- end
- local function drawHeader(title)
- clear()
- local w, _ = term.getSize()
- term.setTextColor(colors.white)
- if title and #title > 0 then
- print(title)
- print("")
- end
- end
- local function prompt(msg)
- term.setTextColor(colors.gray)
- write(msg or "> ")
- term.setTextColor(colors.white)
- return read()
- end
- local function promptPassword(msg)
- term.setTextColor(colors.gray)
- write(msg or "> ")
- term.setTextColor(colors.white)
- return read("*")
- end
- local function pause()
- term.setTextColor(colors.gray)
- print("")
- print("Press any key...")
- os.pullEvent("key")
- end
- -- ============================================
- -- DOOR CONTROL
- -- ============================================
- local function openDoor()
- term.setTextColor(colors.lime)
- print("")
- print("ACCESS GRANTED")
- print("Door opening for " .. DOOR_OPEN_TIME .. " seconds...")
- term.setTextColor(colors.white)
- redstone.setOutput("back", false) -- Signal OFF to open
- sleep(DOOR_OPEN_TIME)
- redstone.setOutput("back", true) -- Signal ON to close
- end
- -- ============================================
- -- ADMIN MENU
- -- ============================================
- local function adminMenu()
- while true do
- drawHeader("Admin Menu")
- print("1. Open Door")
- print("2. List Allowed Users")
- print("3. Grant Access")
- print("4. Revoke Access")
- print("5. Logout")
- print("")
- local choice = prompt("Select option: ")
- if choice == "1" then
- openDoor()
- return -- Return to login after opening door
- elseif choice == "2" then
- drawHeader("Allowed Users")
- local list = loadAccessList()
- term.setTextColor(colors.yellow)
- print(ADMIN_ACCOUNT .. " (master)")
- term.setTextColor(colors.white)
- if #list == 0 then
- print("(no additional users)")
- else
- for _, id in ipairs(list) do
- print(id)
- end
- end
- pause()
- elseif choice == "3" then
- drawHeader("Grant Access")
- local userId = prompt("Enter username to grant access: ")
- if userId and #userId > 0 then
- if userId == ADMIN_ACCOUNT then
- term.setTextColor(colors.orange)
- print("Admin already has access.")
- elseif hasAccess(userId) then
- term.setTextColor(colors.orange)
- print("User already has access.")
- else
- grantAccess(userId)
- term.setTextColor(colors.lime)
- print("Access granted to: " .. userId)
- end
- term.setTextColor(colors.white)
- pause()
- end
- elseif choice == "4" then
- drawHeader("Revoke Access")
- local list = loadAccessList()
- if #list == 0 then
- print("No users to revoke.")
- pause()
- else
- print("Current users:")
- for i, id in ipairs(list) do
- print(i .. ". " .. id)
- end
- print("")
- local userId = prompt("Enter username to revoke: ")
- if userId and #userId > 0 then
- if revokeAccess(userId) then
- term.setTextColor(colors.lime)
- print("Access revoked from: " .. userId)
- else
- term.setTextColor(colors.red)
- print("User not found in access list.")
- end
- term.setTextColor(colors.white)
- pause()
- end
- end
- elseif choice == "5" then
- return
- end
- end
- end
- -- ============================================
- -- LOGIN SCREEN
- -- ============================================
- local function loginScreen()
- while true do
- drawHeader("")
- term.setTextColor(colors.white)
- local username = prompt("Username: ")
- local password = promptPassword("Password: ")
- print("")
- term.setTextColor(colors.gray)
- print("Verifying...")
- -- Verify with server
- local valid = verifyLogin(username, password)
- if not valid then
- term.setTextColor(colors.red)
- print("")
- print("Invalid credentials.")
- pause()
- else
- -- Check if admin
- if username == ADMIN_ACCOUNT then
- adminMenu()
- else
- -- Check local access list
- if hasAccess(username) then
- openDoor()
- else
- term.setTextColor(colors.red)
- print("")
- print("ACCESS DENIED")
- print("You are not authorized for this door.")
- pause()
- end
- end
- end
- end
- end
- -- ============================================
- -- MAIN
- -- ============================================
- redstone.setOutput("back", true) -- Start with door locked (signal ON)
- loginScreen()
Advertisement
Add Comment
Please, Sign In to add comment