-- starting script
bootUp()
logged = false
if userExists == false then
smartAPI.userCreate(2)
end
--login script
local attempt = 1
logged = false
while logged == false do
local user, pass = login()
local tUsers = smartAPI.loadUsers()
for i = 1, #tUsers do
if tUsers[i].username == user and tUsers[i].password == pass then
logged = true
end
end
if attempt >= 5 then
smartAPI.errorHandle("LOCK")
elseif logged == true then
break
elseif logged == false then
smartAPI.errorHandle("Username or password is incorrect")
attempt = attempt + 1
end
end
This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Break not working like I need
Started by Cranium, 12 November 2012 - 03:23 PMPosted 12 November 2012 - 04:23 PM
I've got a block of code in my script here that is supposed to log in to my system. However, it is not leaving the loop I created. It does successfully log in when I enter the credentials, but then it restarts the loop. It's supposed to leave the loop as soon as it's logged in. What did I do wrong?
Posted 12 November 2012 - 04:44 PM
Your break is breaking out of your if/then comparison, not out of the loop, I think. Make it a function and use return?
Posted 12 November 2012 - 05:04 PM
It should work just fine.
Posted 12 November 2012 - 05:04 PM
Your break is breaking out of your if/then comparison, not out of the loop, I think. Make it a function and use return?
This is incorrect.
Break has some weird rules. It can only be the last statement of a block. Try this instead:
-- starting script
bootUp()
logged = false
if userExists == false then
smartAPI.userCreate(2)
end
--login script
local attempt = 1
local logged = false
while not logged do
local user, pass = login()
local tUsers = smartAPI.loadUsers()
for i = 1, #tUsers do
if tUsers[i].username == user and tUsers[i].password == pass then
logged = true
end
end
if attempt >= 5 then
smartAPI.errorHandle("LOCK")
elseif logged == false then
smartAPI.errorHandle("Username or password is incorrect")
attempt = attempt + 1
elseif logged == true then
break
end
end
Posted 12 November 2012 - 05:25 PM
I've tried that, and a few other variations of the same thing. It doesn't work though, and I don't know why…Your break is breaking out of your if/then comparison, not out of the loop, I think. Make it a function and use return?
This is incorrect.
Break has some weird rules. It can only be the last statement of a block. Try this instead:-- starting script bootUp() logged = false if userExists == false then smartAPI.userCreate(2) end --login script local attempt = 1 local logged = false while not logged do local user, pass = login() local tUsers = smartAPI.loadUsers() for i = 1, #tUsers do if tUsers[i].username == user and tUsers[i].password == pass then logged = true end end if attempt >= 5 then smartAPI.errorHandle("LOCK") elseif logged == false then smartAPI.errorHandle("Username or password is incorrect") attempt = attempt + 1 elseif logged == true then break end end
Posted 12 November 2012 - 05:50 PM
Then you'll need to post the whole code.
Posted 12 November 2012 - 06:03 PM
eh…..how fun. I'll give you the startup link, the rest should run automatically.
http://pastebin.com/GWUUfNeh
http://pastebin.com/GWUUfNeh
Posted 12 November 2012 - 06:59 PM
try this. this is how i use loops for logins. at the top define a varible. like this
then when you login to break the loop just do this.
locked = true
while locked do
-- code
then when you login to break the loop just do this.
locked = false
its a basic method and works for me really well. try i. its kinda what you have done just a little less typing and it may work.Posted 12 November 2012 - 09:47 PM
Use repeat … until logged, not while not logged do … end. That eliminates the need for break.
Posted 13 November 2012 - 12:58 AM
Just want to chip in with some general info about break vs. return:
If you use break, then you will break out of the first loop (while, for, etc.) is in, but the program will then just continue to run any code that comes after the loop.
If you want the program to end instead, then you could us return, as that will either return from the function is was executed in, or return from your program (thus ending it) if it was executed outside of any function.
But as mentioned above, ending your program with return won't work if you're returning from a function.
Then it might be better to return a boolean value and make the check outside of the function:
If you use break, then you will break out of the first loop (while, for, etc.) is in, but the program will then just continue to run any code that comes after the loop.
If you want the program to end instead, then you could us return, as that will either return from the function is was executed in, or return from your program (thus ending it) if it was executed outside of any function.
while true do
print("In the infinite loop that actually won't loop.^^")
break
end
print("This WILL be printed after the break.")
while true do
print("In the infinite loop that actually won't loop.^^")
return
end
print("This will NOT be printed after the return.")
But as mentioned above, ending your program with return won't work if you're returning from a function.
Then it might be better to return a boolean value and make the check outside of the function:
function foo()
while true do
print("In the infinite loop that actually won't loop.^^")
return false
end
print("This will NOT be printed after the break.")
return true -- pro forma, but not really of use in this example; if unclear, don´t hesitate to ask :P/>/>
end
if not foo() then
return
end
print("This will NOT be printed after foo() returns.")
Posted 13 November 2012 - 03:53 AM
Forgive me if I'm wrong but I experienced a similar problem of not being able to break out of a loop however I got arround that by using break end:
i=1
while i=1 do
…my code…
if nOption == 4 then
term.clear()
term.setCursorPos(1, 1)
break end
That broke my loop, not sure if it'll apply to you :P/>/>
i=1
while i=1 do
…my code…
if nOption == 4 then
term.clear()
term.setCursorPos(1, 1)
break end
That broke my loop, not sure if it'll apply to you :P/>/>
Posted 13 November 2012 - 04:44 AM
I updated the code to work with repeat until logged == true, but it does not work. It will break out of the loop if I enter the user/pass correctly twice, but I shouldn't have to do that….
Posted 13 November 2012 - 06:35 AM
Now, tell me. What does it need to do?
Stop after first one correct?
By the way add this script in the beginning:
Source (CC wiki)
Stop after first one correct?
By the way add this script in the beginning:
local pullEvent = os.pullEvent
os.pullEvent = os.pullEventRaw
and at the end of the code (when the password is correct)
os.pullEvent = pullEvent
It will prevent people from terminating the programSource (CC wiki)
Posted 13 November 2012 - 07:58 AM
Now, tell me. What does it need to do?
Stop after first one correct?
By the way add this script in the beginning:and at the end of the code (when the password is correct)local pullEvent = os.pullEvent os.pullEvent = os.pullEventRaw
It will prevent people from terminating the programos.pullEvent = pullEvent
Source (CC wiki)
I'd think he left it out for now so he can terminate if the program bugs and doesn't want to return to console
Posted 13 November 2012 - 08:18 AM
Now, tell me. What does it need to do?
Stop after first one correct?
By the way add this script in the beginning:and at the end of the code (when the password is correct)local pullEvent = os.pullEvent os.pullEvent = os.pullEventRaw
It will prevent people from terminating the programos.pullEvent = pullEvent
Source (CC wiki)
I'd think he left it out for now so he can terminate if the program bugs and doesn't want to return to console
It was supposed to for later, as you stated.
Posted 13 November 2012 - 12:39 PM
I already do use ctrl t prevention on it. But that's not hte issue I'm having. I need to know why it wants to loop repeatedly even after logging in successfully.
Posted 13 November 2012 - 07:37 PM
i know this is NOT the answer you want. but no one can really find an answer. maybe you should just make a more simple lock. i know this is not the right way of dealing with program problems but if "lua pro's" cant even get it working then i dont think you will find a problem.
Posted 13 November 2012 - 07:45 PM
i know this is NOT the answer you want. but no one can really find an answer. maybe you should just make a more simple lock. i know this is not the right way of dealing with program problems but if "lua pro's" cant even get it working then i dont think you will find a problem.
I'm not sure the fix I suggested was actually even tried. I'm also not going to go through the effort of trying to download and run the installer script onto a fresh computer in minecraft just to look at the rest of the code, when it could easily have all been posted in the first place.
Posted 13 November 2012 - 08:46 PM
thats fair enough. i just think that what is the point of having an error in your program thats really hard to solve and you can just write a easier script that does the same thing and does work. i just think its a slight waste of time thats all.i know this is NOT the answer you want. but no one can really find an answer. maybe you should just make a more simple lock. i know this is not the right way of dealing with program problems but if "lua pro's" cant even get it working then i dont think you will find a problem.
I'm not sure the fix I suggested was actually even tried. I'm also not going to go through the effort of trying to download and run the installer script onto a fresh computer in minecraft just to look at the rest of the code, when it could easily have all been posted in the first place.
Posted 13 November 2012 - 10:46 PM
@Cranium:
That means that any custom keys in your tUsers table won't be counted by it.
Now if you don't have any indexed-only entries in your tUsers table, then the for loop will never be run and thus logged will always remain false.
Possible solutions are either to not use custom keys for the username and password in order for # to work, or to iterate through the table with pairs().
But that depends on how your tUsers table looks, so could you perhaps post an example of a "userList" file?
P.S.: I'm aware that it looks like you have indexed entries, since you're trying to access them via tUsers, but as I mentioned, as long as we don't know exactly what tUsers looks like, that can only be speculation on our part.^^Ok, scratch everything I just said. I've downloaded your program in the meantime and played around with it. It's not your tables, they seem to be fine.
In fact, there is absolutely no problem if I run this startup program manually (after making sure the automatic update doesn't overwrite it again of course).
What happens is that as soon as you enter a correct user and password, the startup program seems to run again.
That is, it does indeed exit the loop, but for some reason the whole program is being run again.
I then tried to run your startup-code from the startup-file via shell.run(), instead of having the code itself in there.
That somehow didn't work though, which really puzzles me. When I tried os.run() instead, then it works without a hitch, but then it still has the same problem as before, i.e. it runs two times in a row.
I did get it working with shell.run() only if I removed everything but the login procedure.
So I suspect there's something fishy going on within your APIs, where you have some proram logic that somehow causes the whole script to run at least one more time after it has ended.
I haven't really looked through the rest of your code, as it is quite a lot of files and code, so I have no idea where this might be happening.
But rest assured that is has nothing to do with break.
It works fine… just two times in a row. :P/>/>
Spoiler
I'm suspecting your problem has to do with #tUsers never returning anything else than 0 in this part:for i = 1, #tUsers do
if tUsers[i].username == user and tUsers[i].password == pass then
logged = true
end
end
The #-symbol only counts indexed table entries.That means that any custom keys in your tUsers table won't be counted by it.
Now if you don't have any indexed-only entries in your tUsers table, then the for loop will never be run and thus logged will always remain false.
Possible solutions are either to not use custom keys for the username and password in order for # to work, or to iterate through the table with pairs().
But that depends on how your tUsers table looks, so could you perhaps post an example of a "userList" file?
P.S.: I'm aware that it looks like you have indexed entries, since you're trying to access them via tUsers, but as I mentioned, as long as we don't know exactly what tUsers looks like, that can only be speculation on our part.^^
In fact, there is absolutely no problem if I run this startup program manually (after making sure the automatic update doesn't overwrite it again of course).
What happens is that as soon as you enter a correct user and password, the startup program seems to run again.
That is, it does indeed exit the loop, but for some reason the whole program is being run again.
I then tried to run your startup-code from the startup-file via shell.run(), instead of having the code itself in there.
That somehow didn't work though, which really puzzles me. When I tried os.run() instead, then it works without a hitch, but then it still has the same problem as before, i.e. it runs two times in a row.
I did get it working with shell.run() only if I removed everything but the login procedure.
So I suspect there's something fishy going on within your APIs, where you have some proram logic that somehow causes the whole script to run at least one more time after it has ended.
I haven't really looked through the rest of your code, as it is quite a lot of files and code, so I have no idea where this might be happening.
But rest assured that is has nothing to do with break.
It works fine… just two times in a row. :P/>/>
Edited on 13 November 2012 - 11:46 PM
Posted 14 November 2012 - 05:47 AM
…….I feel like an idiot. This has absolutely nothing to do with the files or anything else with the loop. This is because I loaded the startup file AS AN API at the top of the code…..So of course it would run twice….
All I had to do was change part of my install block install everything, but only load the actual APIs as an API, skipping the startup.
My new code for the startup is as follows:
All I had to do was change part of my install block install everything, but only load the actual APIs as an API, skipping the startup.
My new code for the startup is as follows:
local function getVersion()
return 1.038
end
os.pullEvent = os.pullEventRaw
local defaultUser = "Admin"
local defaultPass = "Password"
local updateTable = {}
updateTable[1] = {code = "GWUUfNeh", filename = "startup"}
updateTable[2] = {code = "vphtijAh", filename = ".smartOS/smartAPI"}
updateTable[3] = {code = "dXamY7Jc", filename = ".smartOS/smartWrite"}
updateTable[4] = {code = "PFZXduDm", filename = ".smartOS/smartGUI"}
updateTable[5] = {code = "iMZH1L6p", filename = ".smartOS/smartFile"}
--file integrity check
if not fs.exists(".smartOS") then
fs.makeDir(".smartOS")
elseif not fs.exists(".smartOS/userList") then
local tUsers = {}
tUsers[1] = {}
tUsers[1].username = defaultUser
tUsers[1].password = defaultPass
tUsers[1].tZ = "utc"
tUsers[1].level = 1
local userFile = fs.open(".smartOS/userList","w")
userFile.write(textutils.serialize(tUsers))
userFile.close()
userExists = false
end
for i = 1, #updateTable do --this is the block I had to change
if not fs.exists(updateTable[i].filename) then
local updateSite = http.get("http://pastebin.com/raw.php?i="..updateTable[i].code)
local siteFile = updateSite.readAll()
local writeFile = fs.open(updateTable[i].filename,"w")
writeFile.write(siteFile)
writeFile.close()
if not updateTable[i] == "startup" then
os.unloadAPI(updateTable[i].filename)
os.loadAPI(updateTable[i].filename)
end
else
if not updateTable[i] == "startup" then
os.unloadAPI(updateTable[i].filename)
os.loadAPI(updateTable[i].filename)
end
end
end
-- boot screen
local function bootUp()
smartGUI.splash()
term.setCursorPos(4,15)
write("Checking HTTP connection...")
if http then
httpStatus = true
write("Connected")
else
httpStatus = false
write("No connection")
end
term.setCursorPos(4,16)
write("Checking for peripherals...")
smartAPI.pDetect()
write("Complete")
term.setCursorPos(4,17)
write("Checking for updates...")
local updateNum = 0
for i = 1, #updateTable do
local _update = smartAPI.update(updateTable[i].code, updateTable[i].filename)
if _update == true then
updateNum = updateNum + 1
elseif _update == "Error" then
term.setCursorPos(26,17)
write(_update)
end
term.setCursorPos(26,17)
write("Updates found: "..updateNum)
end
if updateNum > 0 then
local query = smartAPI.errorHandle("Would you like to restart now?", "Yes", "No")
if query == 1 then os.reboot() end
end
end
--login
local function login()
term.clear()
term.setCursorPos(1,1)
for i = 1, #smartGUI.loginTab do
print(smartGUI.loginTab[i])
end
term.setCursorPos(20,9)
local inputUser = smartWrite.limitRead(17)
term.setCursorPos(20,10)
local inputPass = smartWrite.limitRead(17, "*")
return inputUser, inputPass
end
-- starting script
bootUp()
logged = false
if userExists == false then
smartAPI.userCreate(2)
end
--login script
local attempt = 1
local logged = false
repeat
local user, pass = login()
local tUsers = smartAPI.loadUsers()
for i = 1, #tUsers do
if tUsers[i].username == user and tUsers[i].password == pass then
logged = true
break
end
end
if attempt >= 5 then
smartAPI.errorHandle("LOCK")
elseif logged == false then
smartAPI.errorHandle("Username or password is incorrect")
attempt = attempt + 1
end
until logged == true
Edited on 14 November 2012 - 04:48 AM
Posted 14 November 2012 - 05:49 AM
It wasn't that they can't get it working, it was that I was being an idiot in the first place trying to simplify some of my code earlier on.i know this is NOT the answer you want. but no one can really find an answer. maybe you should just make a more simple lock. i know this is not the right way of dealing with program problems but if "lua pro's" cant even get it working then i dont think you will find a problem.