Aadvert

Passlock v0 - Fresh from ScITE, may not run.; does nothing

Feb 10th, 2012
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Passlock v0
  2. -- (C) 2012 User 'Advert' at http://www.computercraft.info/forums2/
  3. -- X11/mit licence (use/modify at your will, but please, leave credit where due)
  4.  
  5. -- Settings.
  6. local dConfig = {} -- Marking defaults, so we can revert to them easily.
  7.  
  8. do -- Because I like do statements.
  9.     dConfig["sUserPassword"]    = "open"
  10.     dConfig["sRootPassword"]    = "2good4u"
  11.     dConfig["nOpenTime"]        = 3 -- Number of seconds to keep the door open.
  12.     dConfig["nUserPassFailLock"]= 3 -- Number of user password fails before lock. (0 = disable, 1 = 1 fail, 2 = 2 fails, etc.) Reset at success (root can still login)
  13.     dConfig["nUserPassFailLockDuration"] = 15 -- Number of seconds to lock after nUserPassFailLock password fails
  14.     dConfig["bRootForceOpen"] = false -- Door is forced open by Root user.
  15.     dConfig["bLockAtStartup"] = true -- This will lock the computer for nUserPassFailLockDuration seconds at startup, to prevent bypassing of nUserLockPassFailLock.
  16.     dConfig["sRedstoneSide"] = "back" -- The side the redstone is at.
  17.     -- Stuff not stored here: door state, etc.
  18. end
  19. -- small helper function ;_;
  20. local function copyTable(o)
  21.     -- Will simply copy a table, non-recursively.
  22.     local t = {}
  23.     for k, v in pairs(o) do t[k] = v end
  24.     return t
  25. end
  26.  
  27. local config = copyTable(dConfig)
  28. local bRootExit = false
  29. local bDoorState = true -- true = locked.
  30. local nUserAttempts = 0
  31. local nUserLastAttempt = 0
  32. -- Misc functions
  33.  
  34. local function mergeTable(t1, t2)
  35.     -- This function puts everyting in t2 into t1.
  36.     for k, v in pairs(t2) do
  37.         t1[k] = v
  38.     end
  39.     return t1 -- We return t1 because that's the table you'll want afterwards (even though it doesn't make a new table)
  40. end
  41.  
  42. -- Major functions
  43. -- Making functions local (I don't like messing up _G)
  44. local renderDisplay, checkEvents, loadFromFile, saveToFile
  45. local checkDoorTimer, checkUserLockTimer
  46. -- Core loop components
  47. function renderDisplay()
  48.     -- Frame timer
  49.     os.startTimer(0.2) -- 5 fps is good enough, can even do less, but meh.
  50.     -- Clean the terminal
  51.     term.clear()
  52.     term.setCursorPos(1,1)
  53.  
  54.  
  55.     --TODO
  56. end
  57.  
  58. --
  59. function checkEvents(event, p1, p2)
  60.     -- Used in our loop to check for new OS events.
  61.     if event == "char" then
  62.         if p1 == "x" then
  63.             error("User pressed 'x'. 'x' is a bad key to press.")
  64.         elseif p1 == "s" then
  65.             saveToFile()
  66.             loadFromFile()
  67.         end
  68.     end
  69.  
  70. end
  71.  
  72. function checkDoorTimer()
  73.     --TODO
  74. end
  75.  
  76. function checkUserLockTimer()
  77.     --TODO
  78. end
  79.  
  80. -- Door toggler.
  81. function toggleDoor(bState)
  82.     -- This will toggle the door, or set it's state to bState
  83.     if bState ~= nil then
  84.         bDoorState = bState
  85.     else
  86.         bDoorState = not bDoorState -- not negates the state in boolean: true, any data not nil -> false; false, nil -> true
  87.     end
  88.     return bDoorState -- Good practice to return result, in this case the door's state.
  89. end
  90.  
  91.  
  92.  
  93. -- Saving/loading
  94. do -- This just to make the code neater, really. (And so I can easily collapse the code in ScITE)
  95.  
  96.     function loadFromFile()
  97.         if not fs.exists("passlock-data") then return end -- We can't load nothing.
  98.         local err, res = pcall(function() return loadfile("passlock-data")() end) -- Yes, I'm doing this the easy and hard way.
  99.         if not err then
  100.             print("Error loading configuration: \n", res)
  101.             print("Enter to continue...")
  102.             read()
  103.         end
  104.         mergeTable(config, res) -- This will ensure the defaults are there if a field is missing.
  105.     end
  106.  
  107.     -- Saving helper format strings
  108.     local saveHelper = {}
  109.     saveHelper.boolean = [[config[%q] = %s]]
  110.     saveHelper.string = [[config[%q] = %q]]
  111.     saveHelper.number = [[config[%q] = %d]]
  112.  
  113.     -- Saving function
  114.     function saveToFile()
  115.         -- This is the 'harder' part of the two :(
  116.  
  117.         local sData = [[local config = {} -- This file, generated by Passlock. Edit at your own risk.]] .. "\n"
  118.  
  119.         for k, v in pairs(config) do
  120.             local sDataType = type(v)
  121.             local sSaveHelper = saveHelper[sDataType]
  122.             if not sSaveHelper then
  123.                 -- We have problem, let's just print it, and continue without saving it.
  124.                 print("Warning: (saveToFile) unknown data type, in key: " .. k)
  125.             else
  126.                 -- No errors, save it.
  127.                 sData = sData .. string.format(sSaveHelper, k, tostring(v)) .. "\n"
  128.             end
  129.         end
  130.  
  131.         sData = sData .. [[return config]] -- We need to return the config in order to retrieve it.
  132.         -- Delete and save.
  133.         if fs.exists("passlock-data") then
  134.             fs.delete("passlock-data")
  135.         end
  136.         local hHandle = io.open("passlock-data", "w")
  137.         if not hHandle then
  138.             -- We're pissed, let's error.
  139.             error("Unable to open file handle; call to saveToFile", 2)
  140.         end
  141.         hHandle:write(sData)
  142.         hHandle:close()
  143.     end
  144. end
  145.  
  146.  
  147. -- Looping function
  148. function doImportantStuff()
  149.     while true do
  150.         if bRootExit then -- Quit if user logged in as Root wishes to.
  151.             break
  152.         end
  153.         local event, p1, p2 = os.pullEvent()
  154.         print("Event: ", event, "\n p1 & p2: ", p1, ",", p2)
  155.         if event == "timer" then
  156.             checkDoorTimer() -- Lock the door if it has been open long enough
  157.             checkUserLockTimer() -- Allow user to login again, if enough time has passed.
  158.             renderDisplay() -- Moved inside checkEvents, to provide a static #FPS (i.e typing will cause an overload of timers)
  159.         end
  160.         checkEvents(event, p1, p2) -- Get our user input, or yet another timer event for updating the screen.
  161.         -- Doesn't seem like much, does it? D:
  162.     end
  163. end
  164.  
  165.  
  166. -- Startup function, one-time.
  167. function startup()
  168.     loadFromFile() -- Loads config if it exists.
  169. end
  170.  
  171. -- Loop
  172. while true do
  173.     local err, res = pcall(doImportantStuff)
  174.     if bRootExit then -- Quit if user logged in as Root wishes to.
  175.         break
  176.     end
  177.     if not err then
  178.         if res ~= "Terminated" then
  179.             print("error: ", string.format("%q", res))
  180.             print("enter to continue... (ctrl-t is SUPER EFFECTIVE right now!)")
  181.             read()
  182.         end
  183.     end
  184. end
Advertisement
Add Comment
Please, Sign In to add comment