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

[SOLVED][<program>:17: Attempt to call string] Fs.readLine() trouble for a whitelist

Started by plazter, 30 August 2016 - 11:50 AM
plazter #1
Posted 30 August 2016 - 01:50 PM
Hello again pros.. :P/>

- Im currently working on an extra security sensor, but cant get the code to read my whitelist File as the title says, i get an attempt to call string in my attempt to insert the names into the whitelist.

-snip-
  for line in datafile.readLine() do
	 table.insert(whitelist, line)
  end
-snip-

And i really cant figure out why…

Heres the code:
Spoiler

s = peripheral.wrap("right")
signal = "left"
whitelist = {}
state = false

function list()
  if fs.exists("whitelist") == false then
	shell.run("edit whitelist")
	else
	print("whitelist allready exist!")
  end
end

function getList()
  local datafile = fs.open("whitelist", "r")
	for line in datafile.readLine() do
	  table.insert(whitelist, line)
	end
  datafile.close()
  print(whitelist[1])
end

function Authorised()
  for k, playerName in ipairs(s.getPlayers()) do
	for p, o in ipairs(playerName) do
	  for _, name in ipairs(whitelist) do
		if playerName:lower() == name:lower() then
		  state = true
		end
	   end
	end
  end

  state = false
end

function sig()
  if state then
	rs.setOutput(side, state)
  else
	rs.setOutput(side, state)
  end
end

list()
getList()

while true do
  sig()
  sleep(1)
end

Pastebin: http://pastebin.com/QVUhkELh

//Plazter

EDIT: New problem, how can i avoid it printing the UUID, and just the player names? :/

function Authorised()
  for k, v in pairs(s.getPlayers()) do
	for p, playerName in pairs(v) do
	   for i = 1,#whitelist[i] do
		  if playerName:lower() == whitelist[i] then
		   --Do something here
		 end -- if
	   end --for
	 end --for
  end --for
end  --function
Edited on 31 August 2016 - 04:03 PM
houseofkraft #2
Posted 30 August 2016 - 02:01 PM
You can try using a variable to store your whitelist

Code:

local whitelist = nil
file = fs.open("whitelist", "r")
whitelist = file.readLine()
file.close()

Sorry if this is not what you wanted. Im not the best at CC
plazter #3
Posted 30 August 2016 - 02:06 PM
You can try using a variable to store your whitelist

Code:

local whitelist = nil
file = fs.open("whitelist", "r")
whitelist = file.readLine()
file.close()

Sorry if this is not what you wanted. Im not the best at CC

Ill give it a go :)/>, ill tell ya if it works or not :P/>

Well it works, but not what im looking for :)/>, thanks for the answer tho houseofkraft :)/>
Tiin57 #4
Posted 30 August 2016 - 02:35 PM

function getList()
  local datafile = fs.open("whitelist", "r")
    for line in datafile.readLine() do
      table.insert(whitelist, line)
    end
  datafile.close()
  print(whitelist[1])
end

The problem appears to be line 2 of getList(). You're iterating over a string, which isn't what you want to do. `handle.readLine()` returns a string, not an array. This code should work:

--# After declaration of `datafile`
local line = datafile.readLine()
while line do
    table.insert(whitelist, line)
    line = datafile.readLine()
end
--# whatever else

Because now you're reading line after line until there are no more lines - generally how you'd want to do it. It looks like you had the right idea, just a bit of confusion with .readLine().
plazter #5
Posted 30 August 2016 - 02:46 PM
-snip-

--# After declaration of `datafile`
local line = datafile.readLine()
while line do
	table.insert(whitelist, line)
	line = datafile.readLine()
end
--# whatever else

Because now you're reading line after line until there are no more lines - generally how you'd want to do it. It looks like you had the right idea, just a bit of confusion with .readLine().

wont local line do fine once? :P/>

And it works man! Cheeeers!

EDIT: that second line is nessesary for it to notice theres not more.. :P/>
Edited on 30 August 2016 - 12:56 PM
plazter #6
Posted 30 August 2016 - 05:09 PM

function Authorised()
  for k, v in pairs(s.getPlayers()) do
	    for p, playerName in pairs(v) do
		   for i = 1,#whitelist[i] do
				  if playerName:lower() == whitelist[i] then
				    print("Allowed: ".. playerName)
				 end -- if
		   end --for
		 end --for
  end --for
end  --function

This will type the uuid too :(/>
Edited on 30 August 2016 - 03:10 PM
Anavrins #7
Posted 30 August 2016 - 05:27 PM

-snip-
  for line in datafile.readLine() do
	 table.insert(whitelist, line)
  end
-snip-
You were on the right path with this, remove the () after "readLine", and this code will put each individual line of the file in "whitelist"
plazter #8
Posted 30 August 2016 - 05:33 PM

-snip-
  for line in datafile.readLine() do
	 table.insert(whitelist, line)
  end
-snip-
You were on the right path with this, remove the () after "readLine", and this code will put each individual line of the file in "whitelist"
Oh really?, time to test it again :D/>

The entire purpose is to make it detect the whitelisted players then let it turn on but if not keep stuff hidden away / turned off

- You were right man! Cheers!!
Edited on 30 August 2016 - 03:44 PM
TheRockettek #9
Posted 30 August 2016 - 05:52 PM
Or if you make your file formats the list of users as a serialized table (what i do) instead of a plain list and just do

DaTable = textutils.unserialize(Afile.readAll())

But it will error if its not properly serialized :D/>


Afile.write(textutils.serialize(ImATable))
plazter #10
Posted 30 August 2016 - 06:08 PM

-snip-
for t,result in ipairs(s.getPlayers()) do
  local name = result.name:lower()
    for i = 1,#whitelist do
      if name == whitelist[i] then
        rs.setOutput("left", true)
     end
    end
  end
rs.setOutput("left", false)
end


it prints the UUID, and the Name .. and dont turn back off when i leave :P/>, it works fine without the whitelist part :P/>
not sure how to fix it rly :)/>, been trying diffrent stuff :P/> cant seem to figure it out :P/>'


EDIT: Figured it out at last.
- How ever i have a light i use to test it with, and it seems to work the edit's i've done so far, but, the light is not turning back on when i leave it (inverted white lamp)
(Code has been updated in the post here)
Edited on 30 August 2016 - 06:24 PM
TheRockettek #11
Posted 30 August 2016 - 09:00 PM
function tableContains(table,string)
for i,k in pairs(table) do
if string == k then
return true,i
end
end
return false,nil
end
Anavrins #12
Posted 31 August 2016 - 02:21 AM
Load your whitelist into your table as {"plazter" = true, "Anavrins" = true}

local whitelist = {}
for name in file.readLine do
  whitelist[name] = true
end
When checking for a user in the whitelist, instead of using a loop like in Rockets example, you can simply index the name from the whitelist

if whitelist[name] then
  -- Is in whitelist
else
  -- Not in whitelist
end
Edited on 31 August 2016 - 12:21 AM
plazter #13
Posted 31 August 2016 - 05:19 PM
Load your whitelist into your table as {"plazter" = true, "Anavrins" = true}
 local whitelist = {} for name in file.readLine do whitelist[name] = true end 
When checking for a user in the whitelist, instead of using a loop like in Rockets example, you can simply index the name from the whitelist
 if whitelist[name] then -- Is in whitelist else -- Not in whitelist end 

Ok so i changed it, still dont work xD, i might not be understanding you correctly..

function import()
local datafile = fs.open("whitelist", "r")
for name in datafile.readLine do
  table.insert(whitelist, name:lower())
  whitelist[name] = true
end
end
and then where i look

function auth()
  for k,result in pairs(s.getPlayers()) do
   local name = result.name:lower()
   if whitelist[name] then
	 print("ok")
	 else
	 print("nope")
   end
  end
end

keeps saying nope :P/>

EDIT: forgot to add lower() to the whitelist[name]xD
Edited on 31 August 2016 - 03:23 PM
Anavrins #14
Posted 31 August 2016 - 06:36 PM

function import()
local datafile = fs.open("whitelist", "r")
for name in datafile.readLine do
  table.insert(whitelist, name:lower())
  whitelist[name] = true
end
end
You won't be needing that table.insert line, since you're now referencing the whitelist as a string key and not by a numerical index.
plazter #15
Posted 31 August 2016 - 06:41 PM

function import()
local datafile = fs.open("whitelist", "r")
for name in datafile.readLine do
  table.insert(whitelist, name:lower())
  whitelist[name] = true
end
end
You won't be needing that table.insert line, since you're now referencing the whitelist as a string key and not by a numerical index.

oh ok :)/> well thanks a bunch!