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

Nil problem!

Started by LNETeam, 01 January 2013 - 04:13 AM
LNETeam #1
Posted 01 January 2013 - 05:13 AM
Hello!,

I'm having problems with a logon script. I have the server read an account array (multiple passwords for each computer/user) serialize the table and send it to the client, the client recieves it, unserializes it and creates a new table from that. It then checks the password entered by the user against all values in the table to check if any match. Unfourtunately it seems that the program is not recieving the table correctly please help!! Server and Client code included. P.S I use this with CC-Get. The error is
 LNEX:78: attempt to get length of nil


Server (host):
Spoilerhttp://pastebin.com/0PzY7Up4

Client (LNEX) Code:
Spoilerhttp://pastebin.com/2TTpzZAW
ChunLing #2
Posted 01 January 2013 - 06:45 AM
Did you get the print saying "Profile Load Error"?
LNETeam #3
Posted 01 January 2013 - 09:05 AM
Yeah, on the client. Then the password will be asked for, then the error
ChunLing #4
Posted 01 January 2013 - 10:25 AM
Well then, kim is nil. You should probably make it so that prevents you from trying to use it's length.
LNETeam #5
Posted 01 January 2013 - 11:23 AM
So I should add an error handling?
ChunLing #6
Posted 01 January 2013 - 01:06 PM
You sorta have what looks like one, where that "Profile Load Error" print happens. If you put a return right after that print, then the program would exit without attempting to process kim if it didn't exist. Or you could use os.reboot() like you have elsewhere.

Looking at the getExist() function, it could use some improvement. Particularly, it doesn't filter messages it's getting to make sure they're from cs. To make sure, you can replace this:
event , p1 , p2 = os.pullEvent("rednet_message")
with something more like this
repeat
  p1 , p2 = rednet.receive(2) --or whatever timeout you like
until p1 and p1 == cs
The reason that you would use os.pullEvent would be if you wanted to handle other events, not just rednet messages. And using rednet.receive lets you specify a timeout, so that if the proper computer never replies, you don't just keep waiting forever (unless there's enough rednet spam that you never timeout, in which case you should probably just use a shorter timeout).

This code will ensure that you only process a response from cs, and will get that response if it occurs within the timeout no matter how much other traffic there is, eventually returning nil if cs never replies. The other usage would allow an errant rednet message cause getExist() to return nil, and since that is the ultimate cause of your error, it might be worth addressing.
LNETeam #7
Posted 01 January 2013 - 07:06 PM
So the p2 should be the containing serialized table that I should then use to unserialize? Should I also use a type() identifier? Such as:

if type(p2) ~= "table" then
      assert(type(p2) == "table" , "Received message not account table!")
      return false
end
ChunLing #8
Posted 02 January 2013 - 02:22 AM
I suppose that's a good idea. But you only need one of those, the if with a return false or the assert (which doesn't need to be in an if).
LNETeam #9
Posted 02 January 2013 - 07:11 AM
So is that the reason it's not getting a value for the table? Should I also check to see if the server is actually sending a serialized table?
LNETeam #10
Posted 02 January 2013 - 08:34 AM
I've edited the program to your discretion, but still the same problem, also I threw a tidbit of debug testing on the server on line 91

Here's the new server code:
Spoilerhttp://pastebin.com/0PzY7Up4

Here's the new client code:
Spoilerhttp://pastebin.com/2TTpzZAW
ChunLing #11
Posted 02 January 2013 - 02:49 PM
This client code still doesn't do anything about kim being nil (other than printing "Profile Load Error"), so you'll still have a problem if the server doesn't respond or there's rednet spam (you only check one of your rednet messages to make sure it comes from the server).

If you're in a clean environment and you're positive that there's no rednet spam, then you should add some prints to the server when it's supposed to be sending messages, so that you can easily check and see that the relevant code chunks are getting executed.
LNETeam #12
Posted 03 January 2013 - 01:27 AM
I had an earilier version of this code that was not for multi-user support, only single, now that I added this in, is it just possible there is a read error or just a coding error?
ChunLing #13
Posted 03 January 2013 - 02:37 AM
Um, what is happening with the current code?
LNETeam #14
Posted 03 January 2013 - 10:59 AM
This is currently, attempting, to enable multiuser support for server and client
ChunLing #15
Posted 04 January 2013 - 04:46 AM
Yes, but what actually happens when you run the code? Is getExist() still returning nil, or is it rebooting your client each time, or is it working? Sometimes one thing, sometimes another?
LNETeam #16
Posted 08 January 2013 - 01:56 PM
I run the code, and when the server should be reading or sending id's or passwords, it doesn't print. I go through again and check the logic, the correct function names are called, correct call phrases from the client are called and they are returning, still no printing. The updated code is on the same pastebin as before
ChunLing #17
Posted 08 January 2013 - 08:30 PM
Okay, you need prints right at the beginning of each function that isn't working, so you know exactly when it really got called, and then you need at least one print for each and every execution branch, so you know which branches are happening. You just don't have near enough prints in there to tell you what's going on.