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

Name comparator on Infinity Evolved

Started by duykhang2, 24 December 2017 - 08:07 PM
duykhang2 #1
Posted 24 December 2017 - 09:07 PM
Dear community,

I've been into programming recently and I have problems setting up a security system. Since FTB modpack Infinity Evolved has no opensensors I'm forced to use Openperipherals its sensor.

I have looked up on similair threads and recreate them for hours but can't seem to let them work. This is as close as I can get:


x = peripheral.wrap("left")
playername = x.getPlayers()
print(playername)

Entering this code in Lua gives me an UUID and a name. However, using this code outside Lua gives me a table which constantly changes. I am programming with "edit test4", I have removed all my functions and began with a clean slate to get a better understanding on how this works :


sensor = peripheral.wrap("left")
playername = sensor.getPlayers()
print(playername)

How can I retrieve only the name so I can make an authorisation list? Do I have to convert table to string? Is that even effective, since it constantly changes when applying a loop command(while true do) or keep running test4?

Thank you in advance!
Edited on 25 December 2017 - 08:49 AM
Bomb Bloke #2
Posted 25 December 2017 - 12:14 AM
You get a table whether you use the Lua (not LUA) prompt or not, but assuming you enter just "x.getPlayers()" directly into that prompt, it'll indeed likely show you the table's content rather than just the table's pointer. Specifically using "print" should always show you the pointer, but it's important to note that you're working with a table either way.

To manually show table content in the form of a single string, you can use textutils.serialise():

print( textutils.serialise( playername ) )

Other than revealing the structure of the table, though, that's not very useful. If my memory's any good, the structure of the table you're working with will consist of a list of numbered strings, one for every player in the sensor's range. So you could alternatively print out the contents individually, like this:

for i = 1, #playername do   -- A loop that repeats once for each entry in the table.
  print( playername[i] )    -- Prints the i'th entry.
end

… though if the structure is different you'll need to index into it differently (show the structure here if you get stuck). This guide is pretty good for learning about tables in general.
H4X0RZ #3
Posted 25 December 2017 - 01:01 AM
Sorry for being offtopic but looks like you got a Lua Uppercase Accident (LUA) :P/>
duykhang2 #4
Posted 25 December 2017 - 10:22 AM
Current code when applying your advice @Bomb Bloke

local owner = "Headdetect1234"
sensor = peripheral.wrap("left")
while true do
x = sensor.getPlayers()
intruder = false
for i = 1, x do
if x[i].players ~= owner then
intruder = true
elseif x[i].players == owner and truder == false
rs.setOutput("bottom", true)
sleep(3)
rs.setOutput("bottom", false)
intruder = false
end
end
sleep(.5)
end

Whenever I run the code it doesn't detect me and I have to hold ctrl + t to terminate the program. Could you tell me where it goes wrong?

PS: I have indeed a Lua Uppercase Accident and corrected it. Hey, am working hours without sleep.
Bomb Bloke #5
Posted 25 December 2017 - 11:09 AM
There are a number of typos in that code which would prevent it from running at all, but the most important one is where you're checking the undefined "truder" variable for a value of "false" (it's nil).

The logic should also be completing the "for" loop before deciding whether to open the door. It seems you only want it to grant access if the owner is there and no one else is present, but the current behaviour will hinge on the order in which players are detected. You'll want it more like this:

open = false

for i = 1, #x do
	if x[i].players == owner then
		open = true
	else
		open = false
		break  --# Exit the for loop early.
	end
end

if open then
	rs.setOutput("bottom", true)
	sleep(3)
	rs.setOutput("bottom", false)
end

If you're still stuck, please provide an example of what your serialised table looks like. Also note that you can use "pastebin put <scriptName>" at the command line to copy the exact script contents to pastebin.com.
duykhang2 #6
Posted 25 December 2017 - 12:03 PM

owner = "Headdetect1234"
sensor = peripheral.wrap("left")
x = sensor.getPlayers()
open = false

for i = 1,#x do

if x[i].players == owner then
open = true
else
open = false
break
end
end

if open then
rs.setOutput("bottom", true)
sleep(3)
rs.setOutput("bottom", false)
end

No attempt to run the program now. It just gives me a next line to enter something else. Been trying on singleplayer but doesn't seems to work either.

The results of print(textutils.serialise(names)) gives the table's content indeed, but can't seem to apply it for the name comparator.
Bomb Bloke #7
Posted 25 December 2017 - 10:23 PM
Seems you pulled out the "while" loop, too, so the script will make one attempt at spotting you before ending.

When I say "please provide an example of what your serialised table looks like", I mean post the output of textutils.serialise() here where I can see it.
duykhang2 #8
Posted 25 December 2017 - 10:38 PM
I made an attempt to include a screenshot but failed since I wasn't allowed to. I'll provide tomorrow asap. Have a nice christmas!
duykhang2 #9
Posted 26 December 2017 - 11:24 AM
I have included the image via attached files, since I'll receive this error when include in post: "You are not allowed to use that image extension on this community."

Here is the link with the results:
https://imgur.com/a/XgxLf
Edited on 26 December 2017 - 10:25 AM
Bomb Bloke #10
Posted 27 December 2017 - 06:40 AM
Ok, so you've been trying to refer to a "players" key which isn't in your table: the key you're after is called "name".

if x[i].name == owner then

It might also help you to read the notes I made in this older thread.
Edited on 27 December 2017 - 05:43 AM
duykhang2 #11
Posted 01 January 2018 - 04:17 PM
Ok, so you've been trying to refer to a "players" key which isn't in your table: the key you're after is called "name".

if x[i].name == owner then

It might also help you to read the notes I made in this older thread.

I've taken a look but still couldn't get more wiser on this. My current code now is:


sensor = peripheral.wrap("left")
while true do
local door = false
for _, name in pairs(sensor.getPlayerByName("Headdetect1234")) do
if name == "Headdetect1234" then
door = true
else
print("Not working")
end
if door then
rs.setOutput("bottom", true)
else
redstone.setOutput("bottom", false)
end
sleep(1)
end
end

This however, will keep outputting the result "not working". Appyling:


sensor = peripheral.wrap("left")
while true do
local door = false
for _, name in pairs(sensor.getPlayerByName("Headdetect1234")) do
if sensor[x].name == "Headdetect1234" then
door = true
else
print("Not working")
end
if door then
rs.setOutput("bottom", true)
else
redstone.setOutput("bottom", false)
end
sleep(1)
end
end

Will get me "attempt to index nill ?"
Bomb Bloke #12
Posted 02 January 2018 - 12:25 PM
My current code now is:

for _, name in pairs(sensor.getPlayerByName("Headdetect1234")) do
if name == "Headdetect1234" then

Even assuming sensor.getPlayerByName("Headdetect1234") returns a table with a your name in it, this loop will still print "not working" so long as it contains any other keys - you're checking every bit of data the sensor returns and getting your code to complain about all the bits which don't match.

How about showing me the content of the table sensor.getPlayerByName("Headdetect1234") returns? But just making an assumption that there's a "name" key in there, you may be able to do:

local sensorData = sensor.getPlayerByName("Headdetect1234") -- Note that the peripheral function may return nil if no such player is in range.

if sensorData and sensorData.name == "Headdetect1234" then  -- If sensorData isn't nil/false, and can be indexed into to find a "name" key equal to your name, then...
  rs.setOutput("bottom", true)
else
  rs.setOutput("bottom", false)
end

Appyling:

if sensor[x].name == "Headdetect1234" then

Will get me "attempt to index nill ?"

What's "sensor[x]" supposed to be? You never define "x", and "sensor" is the table of functions for interacting with your wrapped peripheral - it doesn't contain any results from calling sensor.getPlayerByName()!