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

[Help] Player Detector security door

Started by Feronzed, 02 July 2013 - 04:34 PM
Feronzed #1
Posted 02 July 2013 - 06:34 PM
I've been making program which is supposed to wait for Player Detector event and let only certain players from the list in,
it has additional piece of code which reads how many users are listed on list (user per line), and here comes my problem.
Program seems to count lines correctly, but when I try to read lines again and apply them to custom variable array, I get nil variable when reading lines again.

So here is the code:

function openDoors()
redstone.setOutput("back",true)
sleep(3)
redstone.setOutput("back",false)
end

if not fs.exists("whitelist") then
error("File 'whitelist' not found!")
end

wl = io.open("whitelist", "r")
lc = 0
for line in wl:lines() do
lc = lc + 1
end

un={}
for i=1,lc do
un[i]=wl:readLine()
end

while true do
e, name = os.pullEvent("player")
for i=1,lc do
  if name == un[i] then
   print("Opening doors to player "..name)
   openDoors()
   name = nil
  else
   print("Player "..name.." tried to open the doors!")
  end
end
end
and error code:

startup:19: attempt to call nil
Which indicates that there's an error at this piece of code:

un={}
for i=1,lc do
un[i]=wl:readLine() --ERROR
end
and I know, I tried using wl.readLine() instead of wl:readLine() but it works the same cause I use wl:lines() above in code and it isn't a problem.

Is the reason maybe that I'm passing trought file when counting lines and when I'm trying to apply names, I am at the end of list and there's nothing to apply?
VADemon #2
Posted 02 July 2013 - 09:11 PM
No idea, why it didn't work (blame on me)
However, there's (your fixed and) working code:
function openDoors()
redstone.setOutput("back",true)
sleep(3)
redstone.setOutput("back",false)
end

if not fs.exists("whitelist") then
error("File 'whitelist' not found!")
end

wl = io.open("whitelist", "r")
playerList = {}
for line in wl:lines() do
playerList[line] = true
--example: playerList[ "Notch" ] = true
end

while true do
local event, name = os.pullEvent("player") --no need to clear name, it will be rewritten
  if playerList[name] then
   print("Opening doors to player "..name)
   openDoors()
  else
   print("Player "..name.." tried to open the doors!")
  end
end
It now uses only one iteration to read all lines (nicknames) and add them to table playerList with value true. So everytime a player tries to open the door, it will check whether that player has a positive value set in this table.
PS: You should deny the Ctrl+T (terminate) event if the computer isn't protected from accessing
HurricaneCoder #3
Posted 03 July 2013 - 03:34 PM
Here is your problem the io.open() does not have a readLine() command.
So if you want to read each line you have to first close your file that is currently open.
Then do this:

wl = fs.open(your file,"r")
wl.readLine()
wl.close()
fs does have a read line function in it so use fs.

Hope this help :)/>
Feronzed #4
Posted 03 July 2013 - 03:48 PM
Thank you both for replies, have to try those out and if I have further problems, I'll contact you.
Feronzed #5
Posted 03 July 2013 - 07:41 PM
Everything works nice now, I edited program a bit, replaced name = nil with break so it runs much faster…
Program now looks like this:

function openDoors()
redstone.setOutput("back",true)
sleep(3)
redstone.setOutput("back",false)
end

if not fs.exists("whitelist") then
error("File 'whitelist' not found!")
end

wl = io.open("whitelist", "r")
lc = 0
for line in wl:lines() do
lc = lc + 1
end
wl:close()

wl2 = fs.open("whitelist", "r")
un={}
for i=1,lc do
un[i]=wl2.readLine()
end
wl2.close()

while true do
e, name = os.pullEvent("player")
for i=1,lc do
  if name == un[i] then
   print("Opening doors to player "..name..".")
   openDoors()
   break
  else
   print("Player "..name.." tried to open the doors!")
  end
end
end

This topic can be locked.