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

[Lua][Error] rednet.receive() returnign odd things

Started by RadorBlack, 20 January 2013 - 12:07 PM
RadorBlack #1
Posted 20 January 2013 - 01:07 PM
I have run into a strange problem whit this code:
Spoiler
MasterId = 2
Modemside = "bottom"
Pass = "Pass"
AnnounceTime = 10

os.pullEvent_Real = os.pullEvent
os.pullEvent = os.pullEventRaw

function ListenRednet()

  rednet.open(Modemside)

  while true do

	local id, msg = rednet.receive()
	print(msg)
	if id == MasterId then
	  msg = textutils.unserialize(msg)
	  
	  if msg.getState then
		local status = {}
		status = redstone.getSides()
		msg = {}
		
		for k,v in pairs(status) do
		  msg[v] = {}
		  msg[v] = redstone.getOutput(v)
		end
		
		msg = textutils.serialize(msg)

		rednet.send(id, msg)

	  else
		if msg.state then
		  for k,v in pairs(msg.state) do
			redstone.setOutput(k,v)
		  end
		end
	  end
	end
  end
end

function Clear()
  term.clear()
  term.setCursorPos(1,1)
end

function PassTerminate()

  while true do
	Clear()
	term.write("Enter password:")
	input = read("*")
	
	if input == Pass then
	  Clear()
	  term.write("Do you want to exit? (y/n) ")
	  input = read()
	  
	  if input == "y" then
		Clear()
		os.pullEvent = os.pullEvent_Real
		break
	  end
	end
  end
end

function Announce()

	while true do
		rednet.announce()
		os.sleep(AnnounceTime)
	end
end

parallel.waitForAny(ListenRednet,PassTerminate,Announce)
Sender code:
Spoiler

function slaveStatus(id)
  if not slaves[id] then return "Invalid Id" end
local temp = {getState = true}
local msg = textutils.serialize(temp)
  print(msg)
local a = rednet.send(id,msg)

if not a then return "No responce" end

msg = rednet.receive(5)

if not msg then return "No responce" end

slaves[id].state = textutils.unserialize(msg)
end

The problem lies at line 20
if msg.getState then
It throws an error as soon as it recieves the message from the sender whit a strange console output
Spoiler
The lone number "1" you see below "Enter Password" is the Id of the computer it is run on. It seems to vary depending on the Id of the computer i run the code on.
I just can't find a reason for it to be there at all and it seems to be messing with my code. Is there anyone that knows why this is happening?
remiX #2
Posted 20 January 2013 - 01:49 PM
What's the output of print(type(msg.getState)), put it before the if.

And in the senders code, u have local msg = rednet.receive(), make it local id, msg = rednet.receive()?
ChunLing #3
Posted 20 January 2013 - 05:35 PM
I usually like to assign a new variable if I'm going to radically change the type, like from string to table.

In this case, the error is pretty simple. You're entering a password into the PassTerminate() function. This doesn't do anything before the parallel tries advancing the ListenRednet() function, which has received a rednet message from MasterID and is able to continue. When unserialized, that message (which has nothing to do with the password you entered) ended up as a number somehow rather than as a table (this is probably because the string was just digits, rather than a serialized Lua table code).

So when you try to index it, you get an error.
RadorBlack #4
Posted 21 January 2013 - 01:24 AM
What's the output of print(type(msg.getState)), put it before the if.

And in the senders code, u have local msg = rednet.receive(), make it local id, msg = rednet.receive()?

By adding the line "print(type(msg.getState))" somehow fixed the problem… But the output of that was:

bolean
nil

And now when i comment out that very line that i added it works without any problem.

And i fixed the bits of code i forgot to add in the sender.

I usually like to assign a new variable if I'm going to radically change the type, like from string to table.

In this case, the error is pretty simple. You're entering a password into the PassTerminate() function. This doesn't do anything before the parallel tries advancing the ListenRednet() function, which has received a rednet message from MasterID and is able to continue. When unserialized, that message (which has nothing to do with the password you entered) ended up as a number somehow rather than as a table (this is probably because the string was just digits, rather than a serialized Lua table code).

So when you try to index it, you get an error.

The problem was still the same when running only the "LlistenRednet()" function without the parallel function.

The current code of the "ListenRednet" function
Spoiler
function ListenRednet()

  rednet.open(Modemside)

  while true do

	local id, msg = rednet.receive()
	print(msg)
	if id == MasterId then
	  msg = textutils.unserialize(msg)
	  -- print(type(msg.getState))
	  if msg.getState then
		local status = {}
		status = redstone.getSides()
		msg = {}
		
		for k,v in pairs(status) do
		  msg[v] = {}
		  msg[v] = redstone.getOutput(v)
		end
		
		msg = textutils.serialize(msg)

		rednet.send(id, msg)

	  else
		if msg.state then
		  for k,v in pairs(msg.state) do
			redstone.setOutput(k,v)
		  end
		end
	  end
	end
  end
end
The only difference from before is the line "– print(type(msg.getState))"
If i remove that it still works.
Could it have been some kind of bug in the FTB modpack that i'm using? I noticed that it updated today when i started it.
remiX #5
Posted 21 January 2013 - 09:11 AM
Print everything in the msg table after unserializing it


for i, v in pairs(msg) do
    print(tostring(i) .. " - " .. tostring(v))
end
print(type(msg.getState))
print(tostring(msg.getState))
sleep(5) -- so you can read
.....
.
.
ChunLing #6
Posted 21 January 2013 - 01:36 PM
Just for laughs, you have checked that the ID of the computer you've got as the sender is 2, right? And that it actually calls slaveStatus() using the ID of the computer you're running ListenRednet() on?

It might be useful to have the full code of both machines, and the IDs of both. Because if you're still getting the same error, then that rednet message doesn't contain an Lua table, it contains a number.
RadorBlack #7
Posted 22 January 2013 - 12:21 AM
Just for laughs, you have checked that the ID of the computer you've got as the sender is 2, right?  And that it actually calls slaveStatus()  using the ID of the computer you're running ListenRednet() on?

It might be useful to have the full code of both machines, and the IDs of both.  Because if you're still getting the same error, then that rednet message doesn't contain an Lua table, it contains a number.
Like I said in my previous post the error disappeared after I added one line of code without changing anything else in sender or receiver.
3ydney #8
Posted 22 January 2013 - 02:02 AM
YOur problem may be that you have a global status and a local status. The local status is a table, the other status is redstone.getSides().
ChunLing #9
Posted 22 January 2013 - 08:11 AM
The altered line is commented out, it shouldn't be able to affect the code. Or did you not have it commented out before?

If it wasn't commented out, what was the output?