This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
zanenewberry's profile picture

Need help with door lock

Started by zanenewberry, 23 June 2013 - 01:27 PM
zanenewberry #1
Posted 23 June 2013 - 03:27 PM
http://pastebin.com/wJHyX8f9
Could I have a pro review this please? My goal is to create a password lock door that has 3 attempts before you get locked out for 60 seconds. When I run this program I get no errors but the program doesn't do the actions I wish it would. The first problem is that the program won't display the attempts when the code says "print(lock)", Second problem is that it skips over the part where it locks you out and just returns to "main()". Third problem, when a person gets the password correct I don't want the program to continue the loop, but it does as if you go the password wrong. Can I have a pro to help me and tell me what I'm doing wrong?
Lyqyd #2
Posted 23 June 2013 - 08:57 PM
Split into new topic.
Spongy141 #3
Posted 23 June 2013 - 10:55 PM
I remember a post exactly like this one, here. Skip what I said on there, it's not fully correct. But still, hope this helps.
Bomb Bloke #4
Posted 24 June 2013 - 03:09 AM
When you create a "for" loop, the variable you use as your counter is "local" to that loop - meaning it can't be accessed anywhere other then inside that loop. This means that when you branch out into your "open()" function it becomes impossible to print the value of "lock".

In regards to your second issue, line 21 has quotes around the "0". This causes the code to treat it as a string rather then a number, so the condition will never be true.

Once the program has opened the door, I'm not sure what you want it to do next. If I'm interpreting things correctly the door only stays open a few seconds then closes - so wouldn't you want the loop to continue, so someone can open it again later…?

Edit: Oh, I see. The system will wait out the rest of their attempts rather then returning to the main menu.

You could have the open() function return something, then the failsafe1() function could react based on that result.

Say you put this between lines 49 and 50:

return true

Then you'd change line 28 to:

if open() then break end

Or you could just combine the two functions together so you don't need to worry about passing data between them.
zanenewberry #5
Posted 24 June 2013 - 09:02 AM
When you create a "for" loop, the variable you use as your counter is "local" to that loop - meaning it can't be accessed anywhere other then inside that loop. This means that when you branch out into your "open()" function it becomes impossible to print the value of "lock".

In regards to your second issue, line 21 has quotes around the "0". This causes the code to treat it as a string rather then a number, so the condition will never be true.

Once the program has opened the door, I'm not sure what you want it to do next. If I'm interpreting things correctly the door only stays open a few seconds then closes - so wouldn't you want the loop to continue, so someone can open it again later…?

Edit: Oh, I see. The system will wait out the rest of their attempts rather then returning to the main menu.

You could have the open() function return something, then the failsafe1() function could react based on that result.

Say you put this between lines 49 and 50:

return true

Then you'd change line 28 to:

if open() then break end

Or you could just combine the two functions together so you don't need to worry about passing data between them.
Thanks! That worked exactly like I wanted. But I have one more question/request. Ok the program, as I said, is the way I want it, but I would like to improve it even more. By this I mean, notice I disabled Ctrl + T for people can't terminate it, but when you get locked out of computer and you have to wait the 60 seconds, people could just Ctrl + S or Ctrl + R the computer to restart the program. I know we cannot disable those two shortcuts. So what I'm thinking we have to do is create a "save" so to speak for when they restart the program, the program knows where it left off and can continue the countdown. The problem is that I never worked with saves and do not know where to even start. Is it possible someone could make some code or point me somewhere that could help me do this. If you post the code, please tell me what I must do to get it working and explain it please. I'm guessing the program or I would have to make a separate program which holds data and the main door lock program could access it and save/load data, almost like multiple classes and the object function in the Java language. Thanks.
Bomb Bloke #6
Posted 24 June 2013 - 09:14 AM
Well, you could do something like that, but would it not be sufficient to simply have the script start out by printing "Booting…" then sleep for a minute? As in, every time it launches?

Obviously such behaviour is to be avoided under most circumstances, as it's annoying, but that's precisely your goal here - to annoy those who seek to circumvent your code.
zanenewberry #7
Posted 24 June 2013 - 11:33 AM
Well, you could do something like that, but would it not be sufficient to simply have the script start out by printing "Booting…" then sleep for a minute? As in, every time it launches?

Obviously such behaviour is to be avoided under most circumstances, as it's annoying, but that's precisely your goal here - to annoy those who seek to circumvent your code.
If I understand you correctly, I don't want to annoy those who know the code, I just want to annoy the person trying to crack the code. If the person restarts the program in the middle of the out of attempts timeout then whats the point of having a wait timer. I would like if when they try to restart the computer during the 60 second countdown, the program will finish the timer when it is started because the person tried to restart the computer to avoid the timer. When I find out how to do this, I'm going to raise the timer to 30 minutes. So is there anyway to do this?
Lyqyd #8
Posted 24 June 2013 - 01:23 PM
You cannot intercept or interrupt the hardcoded shutdown and reboot key sequences (Ctrl-S and Ctrl-R, respectively).
Bomb Bloke #9
Posted 24 June 2013 - 08:14 PM
For a thirty minute timer, yes, saving the current state is rather more worthwhile.

The idea is to make a function to handle the lockout. This gets called if the password attempt threshold is crossed, or, if the program detects the timer was in progress when it launched.

Something like this:

Spoiler
os.pullEvent = os.pullEventRaw

local function lockOut(lockTime)
  for i=1,lockTime do
    filehandle = fs.open("locked","w")           -- Ready a file called "locked" to write to. Contents will be replaced.
    filehandle.write(tostring(lockTime - i + 1)) -- Writes the current lockout time to disk.
    filehandle.close()                           -- Indicates we're done with the file for now.

    term.clear()
    term.setCursorPos(1,1)
    print("Out of Attempts! Please wait "..(lockTime - i + 1).." minutes!")
    sleep(60)
  end

  fs.delete("locked")  -- Lockout complete, so we can delete the file.
end

local function open()  -- Local functions don't stay in RAM when the program ends,
.                      -- but they must be declared before they're called.
. 
.
end

local function failsafe1()
  -- Really this whole function should be merged with the open() function...

  for  lock = 3, 1, -1 do
    if open() then return end
  end

  lockOut(30)
end

local function debug()
.
.
.
end

local function main()
.
.
.
end

do  -- So the local "tempLockTime" variable won't stick around longer then it needs to.
  if fs.exists("locked") then                            -- If a file called "locked" exists, then...
    filehandle = fs.open("locked","r")                   -- ... ready it for reading from...
    local tempLockTime = tonumber(filehandle.readLine()) -- ... read a line from it, convert that to number...
    filehandle.close()                                   -- ... then close the file to indicate we're done with it for now.

    lockOut(tempLockTime)
  end
end

main()

There are still a few problems for you to work out. One is that if the computer is rebooted after only one or two attempts, it'll never go into lock-out mode at all. You may want to adapt it to record attempts to a different file.

Another is that someone could just pickaxe the computer and plonk a redstone torch in its place. A way around this is to rig up two computers talking over rednet - one that can open the door, and one people outside can interact with.
zanenewberry #10
Posted 25 June 2013 - 10:20 AM
Thanks, that's what I am looking for.