Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local passFile = 'etc/pwd'
- local logFile = 'etc/log'
- local roomFile = '/etc/rooms'
- local sha1API = 'sha1'
- local doorSide = 'front'
- local passTable = {}
- local roomTable = {}
- local codes = {succes=1, wrong_user=2, wrong_pass=3, unprivileged=4}
- local codeNames = {"logged in succesfully", "wrong username", "wrong password", "unprivileged user"}
- local privs = { admin=1, mod=2, habitant=3, tempHabitant=4, guest=5}
- local privNames = { "Administrator", "Moderator", "Habitant", "Temporary Habitant", "Guest" }
- local function readLoginsToTable()
- local h = fs.open(passFile, 'r')
- while true do
- local l = h.readLine()
- if not l then
- break
- end
- local iter = string.gmatch(l, "(%w+):(%w+):(%w+):(%w+)")
- local id, user, hash, priv = iter()
- if user and hash then
- passTable[#passTable+1] = {}
- passTable[#passTable].id = id
- passTable[#passTable].user = user
- passTable[#passTable].hash = hash
- passTable[#passTable].privilege = priv
- end
- end
- h.close()
- end
- local function saveLoginsToFile()
- h = fs.open(passFile, 'w')
- for i,v in ipairs(passTable) do
- h.writeLine(v.id .. ':' .. v.user .. ':' .. v.hash .. ':' .. v.privilege)
- end
- h.close()
- end
- local function readRoomsToTable()
- local h = fs.open(roomFile, 'r')
- while true do
- local l = h.readLine()
- if not l then
- break
- end
- local iter = string.gmatch(l, "(%w+):(%w+):(%w+)")
- local id, rnID, userID = iter()
- if id and rnID and userID then
- roomTable[#roomTable+1] = {}
- roomTable[#roomTable].id = id
- roomTable[#roomTable].rnID = rnID
- roomTable[#roomTable].userID = userID
- end
- end
- h.close()
- end
- local function saveRoomsToFile()
- local h = fs.open(roomFile, 'w')
- for i,v in ipairs(roomTable) do
- h.writeLine(v.id .. ':' .. v.rnID .. ':' .. v.userID)
- end
- h.close()
- end
- local function writeLog(user, code)
- if not (user and code) then
- return
- end
- h = fs.open(logFile, 'a')
- h.writeLine("User '" .. user .. "' tried logging in with status: " .. codeNames[code] .. ".")
- h.close()
- end
- local function addUser(user, pass, privilege)
- if user and pass then
- local hash = sha1.sha1(pass)
- passTable[#passTable+1] = {}
- local id
- if (#passTable == 1) then
- id = 1
- else
- id = passTable[#passTable-1].id + 1
- end
- passTable[#passTable].id = id
- passTable[#passTable].user = user
- passTable[#passTable].hash = hash
- -- change this:
- passTable[#passTable].privilege = privilege
- saveLoginsToFile()
- return true
- else
- return false
- end
- end
- local function delUser(username)
- if not username then
- return false
- end
- for i,v in ipairs(passTable) do
- if (v.user == username) then
- table.remove(passTable, i)
- end
- end
- saveLoginsToFile()
- return true
- end
- local function userExists(username)
- if not username then
- return nil
- end
- for i,v in ipairs(passTable) do
- if (v.user == username) then
- return true
- end
- end
- return false
- end
- local function getUserByID(userID)
- if not userID then
- return nil
- end
- for i,v in ipairs(passTable) do
- if (v.id == tostring(userID)) then
- return v
- end
- end
- return nil
- end
- local function closeDoor()
- rs.setOutput(doorSide, true)
- end
- local function openDoor()
- rs.setOutput(doorSide, false)
- sleep(5)
- rs.setOutput(doorSide, true)
- end
- local function openTrap()
- rs.setOutput('left', true)
- end
- local function closeTrap()
- rs.setOutput('left', false)
- end
- local function isRoomDoor(senderID)
- for i,v in ipairs(roomTable) do
- if (tonumber(v.rnID) == tonumber(senderID)) then
- return true
- end
- end
- return false
- end
- local function getRoomUser(senderID)
- for i,v in ipairs(roomTable) do
- if (tonumber(v.rnID) == tonumber(senderID)) then
- return tonumber(v.userID)
- end
- end
- return 0
- end
- local function evaluatePass(user,pass,senderID)
- local hash = sha1.sha1(pass)
- for i,v in ipairs(passTable) do
- if v.user == user then
- if v.hash == hash then
- if( isRoomDoor(senderID) == true) then
- if( tonumber(v.privilege) <= 2 ) or (getRoomUser(senderID) == tonumber(v.id) ) then
- return codes.succes
- else
- return codes.unprivileged
- end
- else
- return codes.succes
- end
- else
- return codes.wrong_pass
- end
- end
- end
- return codes.wrong_user
- end
- local function startModem()
- local sides = {"left", "right", "front", "back", "top", "bottom"}
- for i=1,table.getn(sides) do
- rednet.open(sides[i])
- end
- end
- local function main()
- local failedAttempts = 0
- local time = os.time()
- os.loadAPI(sha1API)
- startModem()
- readLoginsToTable()
- readRoomsToTable()
- closeDoor()
- while true do
- repeat
- local e,id,msg = os.pullEvent('rednet_message')
- if not (msg) or (#msg < 3) then
- break
- end
- local iter = string.gmatch(msg, "(%w+):(%w+)")
- local user, pass = iter()
- if not (user and pass) then
- break
- end
- local code = evaluatePass(user, pass, id)
- rednet.send(id, tostring(code))
- writeLog(user, code)
- if (code == codes.succes) and (isRoomDoor(id) == false) then
- openDoor()
- else
- if ( isRoomDoor(id) == false ) then
- failedAttempts = failedAttempts + 1
- if (failedAttempts >= 3 and (os.time() - time) < 60) then
- openTrap()
- sleep(3)
- closeTrap()
- failedAttempts = 0
- time = os.time()
- end
- end
- end
- until true
- end
- os.unloadAPI(sha1API)
- end
- local function buttonHandler()
- while true do
- os.pullEvent('redstone')
- if rs.getInput('right') == true then
- openDoor()
- end
- end
- end
- function displayMenu(first, second, lst) -- Put the menu text in. User chooses one. The function returns the selection he choose.
- --You now need to type in the number the menu starts, and the number it ends. Made by libraryaddict
- local MenuStuff = lst
- local Scrolled = 1
- local DownDown = 0
- local Mouse = first
- local function rewrite()
- local i = 0
- for n=first, second do
- i = i+1
- if MenuStuff[i+DownDown] then
- term.setCursorPos(4, n)
- term.write(string.rep(" ", string.len(MenuStuff[i+DownDown])))
- end
- end
- end
- local function Draw()
- local i = 0
- for n=first,second do
- i = i+1
- term.setCursorPos(4, n)
- term.write(MenuStuff[i+DownDown])
- end
- term.setCursorPos(1, Mouse)
- term.write(">>")
- end
- Draw()
- while true do
- event,param1 = os.pullEvent()
- if event == "key" then
- term.setCursorPos(1, Mouse)
- term.write(" ")
- rewrite()
- if param1 == 200 then -- Up
- if Scrolled > 1 then
- if Mouse == first and MenuStuff[Scrolled-1] then
- DownDown = DownDown-1
- else
- Mouse = Mouse-1
- end
- Scrolled = Scrolled-1
- end
- elseif param1 == 208 then -- Down
- if Scrolled < #MenuStuff then
- if Mouse == second then
- DownDown = DownDown+1
- else
- Mouse = Mouse+1
- end
- Scrolled = Scrolled+1
- end
- elseif param1 == 28 then -- Enter
- rewrite()
- -- return MenuStuff[Scrolled]
- return Scrolled
- -- break
- end
- Draw()
- end
- end
- end
- local function menu()
- while true do
- term.setCursorPos(1,1)
- term.clear()
- local choice = displayMenu(1,5, {'open trap', 'close trap', 'add user', 'delete user', 'room management'})
- if (choice == 3) then
- term.clear()
- term.setCursorPos(1,1)
- print('Enter the username for the new user:')
- local username = read()
- print('Enter password:')
- local password = read()
- local privilege = 5
- print ("Choose user's privilege:")
- local choosenPriv = displayMenu(6,18, privNames)
- if choosenPriv then
- privilege = choosenPriv
- end
- local exists = userExists(username)
- if (exists) and (exists == true) then
- print('User exists allready.')
- else
- if addUser(username, password, privilege) then
- print("User '" .. username .. "' was added!")
- else
- print('Username or password wasn\'t legit...')
- end
- end
- elseif (choice == 4) then
- term.clear()
- term.setCursorPos(1,1)
- print('Pick the user to delete:')
- local userNames = {}
- local userTexts = {}
- table.insert(userNames, 'CANCEL')
- table.insert(userTexts, 'CANCEL')
- for i,v in ipairs(passTable) do
- table.insert(userNames, v.user)
- table.insert(userTexts, v.id .. ': ' .. v.user .. ' (' .. privNames[tonumber(v.privilege)] .. ')')
- end
- local selected_user = displayMenu(2,18, userTexts)
- if (selected_user) and not (selected_user == 1) then
- term.clear()
- term.setCursorPos(1,1)
- print("Are you sure you want to delete user '" .. userNames[selected_user] .. "'?")
- local yesNo = displayMenu(2,4, {'yes', 'no'})
- if( yesNo == 1) then
- if delUser(userNames[selected_user]) then
- print("User '" .. userNames[selected_user] .. "' has succesfully been deleted.")
- else
- print("Couldn't delete user '" .. userNames[selected_user] .. "'.")
- end
- else
- print("User '" .. userNames[selected_user] .. "' was not deleted.")
- end
- end
- elseif (choice == 5) then
- local rooms = {}
- local roomTexts = {}
- table.insert(roomTexts, 'BACK')
- for i,v in ipairs(roomTable) do
- table.insert(rooms, v)
- if(v.userID == '0') then
- table.insert(roomTexts, 'room ' .. v.id .. ': free')
- else
- local user = getUserByID(v.userID)
- if user then
- table.insert(roomTexts, 'room ' .. v.id .. ": occupied by '" .. user.user .. "'")
- else
- table.insert(roomTexts, 'room ' .. v.id .. ": occupied by a nonexistent user")
- end
- end
- end
- local selected_room = displayMenu(1,18, roomTexts)
- if not (selected_room == 1) then
- local room = rooms[selected_room-1]
- term.clear()
- term.setCursorPos(1,1)
- local freeCheck = displayMenu(2,4, {'free room', 'check user in for this room'})
- if freeCheck == 1 then
- for i,v in ipairs(roomTable) do
- if (v.id == room.id) then
- v.userID = '0'
- term.clear()
- term.setCursorPos(1,1)
- print('Room ' .. room.id .. ' has been freed.')
- saveRoomsToFile()
- break
- end
- end
- else
- term.clear()
- term.setCursorPos(1,1)
- print('Choose the user to assign to this room:')
- local userIDs = {}
- local userTexts = {}
- table.insert(userIDs, 'CANCEL')
- table.insert(userTexts, 'CANCEL')
- for i,v in ipairs(passTable) do
- table.insert(userIDs, v.id)
- table.insert(userTexts, v.id .. ': ' .. v.user .. ' (' .. privNames[tonumber(v.privilege)] .. ')')
- end
- local selected_user = displayMenu(2,18, userTexts)
- if (selected_user > 1) then
- for i,v in ipairs(roomTable) do
- if (v.id == room.id) then
- v.userID = userIDs[selected_user]
- local user = getUserByID(room.userID)
- term.clear()
- term.setCursorPos(1,1)
- print('Room ' .. room.id .. " has been assigned to user '" .. user.user .. "'.")
- saveRoomsToFile()
- break
- end
- end
- end
- end
- end
- elseif (choice == 1) then
- openTrap()
- term.clear()
- term.setCursorPos(1,1)
- print('Opened trap.')
- elseif (choice == 2) then
- closeTrap()
- term.clear()
- term.setCursorPos(1,1)
- print('Closed trap.')
- end
- sleep(1)
- end
- end
- local function serverSideStuff()
- parallel.waitForAny(menu, buttonHandler)
- end
- parallel.waitForAny(main, serverSideStuff)
Add Comment
Please, Sign In to add comment