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

Detect nil

Started by CaptainStandard, 14 May 2015 - 06:28 AM
CaptainStandard #1
Posted 14 May 2015 - 08:28 AM
Hi,
I am making a program that sends a table over rednet and then extracts data from it to open a file, that part works. But if a nil value is sent over rednet, it crashes. I tried making a code that would detect and reset nil values but it doesnt really work. I will post the code in about 1 hour. But maybe there are some example codes?
SquidDev #2
Posted 14 May 2015 - 09:03 AM
3 topics below this one there was this. Does it help at all? It covers pretty much every possible way of checking for nil. Or you can always do:


if value == nil then
  -- It is nil
end
CaptainStandard #3
Posted 14 May 2015 - 12:48 PM
Thanks. I tried a similar code that you added here but it doesn't work. I will try the other ones.
CaptainStandard #4
Posted 14 May 2015 - 01:20 PM
I tried those on the link you have sent, but it still doesn't work.

This is what my nil detector and remover looks like:

function NilKiller()
if a == nil then
a = "NOa"
print(a)
end
if b == nil then
b = "NOb"
print(B)/>
end
if c == nil then
c = "NOc"
print(c)
end
if d == nil then
d = "NOd"
print(d)
end
CommandDeterminer()
end
It doesn't work for some reason
There are no errors but nil isn't removed.
Any help is very apreciated
Edited on 14 May 2015 - 11:22 AM
valithor #5
Posted 14 May 2015 - 01:59 PM
At this point we are left to guess as to what is wrong with your code. It would be much easier if you post the full code.
CaptainStandard #6
Posted 14 May 2015 - 03:01 PM
This is the whole code:
COPYRIGHT (just to be on the safe side)
The code is not complete yet.
Error is at line 96 (put these two numbers the other way, if you know what I mean)

This is the server

--Variables
encrypt = 9999
screen = 0

--Modemside
function modem()
local modemside = nil
for q, side in ipairs(rs.getSides()) do
if peripheral.getType(side) == "modem" then
modemside = side
end
end
return modemside
end

--Display Top
function DisplayTop()
term.clear()
term.setCursorPos(1,1)
print("BANK SERVER ACTIVE ------------ ", "Modem on ", modemside, " side")
print("---------------------------------------------------")
end

--Command Receiver
function CommandReceiver()
rednet.open(modemside)
id, data = rednet.receive()
if data == nil then
data = {{"NODATA"}}
end
clientid = data["cid"]
command = data["cmd"]
account = data["acc"]
pin = data["pin"]
rednet.close(modemside)
NilKiller()
end

--Nil Killer
function NilKiller()
if clientid == nil then
clientid = "NOID"
print(clientid)
end
if command == nil then
command = "NOCOMMAND"
print(command)
end
if account == nil then
account = "NOACCOUNT"
print(account)
end
if pin == nil then
pin = "NOPIN"
print(pin)
end
CommandDeterminer()
end


--Command Determiner
function CommandDeterminer()
screen = screen + 1
if screen == 5 then
screen = 0
DisplayTop()
end
time = ( textutils.formatTime( os.time(), true ) )
print("COMMAND RECEIVED AT: ", time)
if command == "LOGIN" then
Login()
--elseif command = "BALANCE" then
--Balance()
--elseif command = "TRANSFER" then
--Transfer()
--elseif command = "WITHDRAW" then
--Withdraw()
--elseif command = "DEPOSIT" then
--Deposit()
else
print("INVALID COMMAND")
print("---------------------------------------------------")
CommandReceiver()
end
end

--Login Checker
function LoginChecker()
login = false
user = false
if fs.exists ("accounts/" .. account .. "") == true then
user = true
userfile = fs.open ("accounts/" .. account .. "", "r")
correctpin = userfile.readLine()
Decrypt()
if pin == correctpin then
login = true
end
end
end

function Decrypt()
pinB = tonumber(pin)
if pinB ~= nil then
pin = pin/(encrypt)
pin = tostring(pin)
else end
end

--Login
function Login()
LoginChecker()
if user == true then
if login == true then
print("LOGIN REQUEST BY " .. account .. " ACCEPTED")
response = "true"
else print("LOGIN REQUEST BY " .. account .. " DENIED: BAD LOGIN")
response = "false"
end
else print("LOGIN REQUEST BY " .. account .. " DENIED: NO SUCH ACCOUNT")
response = "false"
end
print(id," ", command, " ", account, " ", pin, " ", login, " ", user)
print("---------------------------------------------------")
Response()
end

--Rednet Response
function Response()
rednet.open(modemside)
tableresponse = {}
tableresponse["cid"] = clientid
tableresponse["cmd"] = command
tableresponse["res"] = response
rednet.broadcast(tableresponse)
rednet.close(modemside)
end

modemside = modem()
DisplayTop()

--Looper
while true do
CommandReceiver()
end

And this is the cllient

--Connection Variables
local serverid = 17
local modemside = "left"
encrypt = 9999
clientid = 1
--Login
function login()

print("Account:")
acc = read ()

print("Password:")
pass = read()
--SimpleNilKiller -- IGNORE THIS
--ALength = acc:len()
--if ALength < 1 then acc = 0
--end
--PLength = pass:len()
--if PLength < 1 then pass = 0
--end -- IGNORE THIS
print(acc, " ### ",pass)
passB = tonumber(pass)
if passB ~= nil then
pass = pass*(encrypt)
print(pass)
sleep(1)
send()
else
send()
end
end
function send()
rednet.open(modemside)
data = {}
data["cid"] = clientid
data["cmd"] = "LOGIN"
data["acc"] = acc
data["pin"] = pass
rednet.broadcast (data)
rednet.close(modemside)
end

while true do
login()
end
Edited on 14 May 2015 - 01:27 PM
Bomb Bloke #7
Posted 14 May 2015 - 03:22 PM
if pin == correctpin then --It errors here: attempt to index ? (a nil value) but if there is no such account then would it not just skip this?

You're not indexing into anything on that line. You've got the line numbers mixed up somehow.

The nearest line on which you are attempting to index is here:

correctpin = userfile.readLine()

You're attempting to index "readLine" out of "userfile". "userfile" might be nil if the fs.open() call on the line above failed; that might happen because the file is locked - possibly by a previous attempt to run your script, because you never called userfile.close()! Make sure you don't have it open in any external editors, reboot the computer, rig the script to close the file handle after reading from it and give it another go.

If you're still having similar errors after that, double check the line number against the script you're actually running.
CaptainStandard #8
Posted 14 May 2015 - 10:19 PM
I have added userfile.close(), unfortunately it still doesn't work.
HPWebcamAble #9
Posted 15 May 2015 - 01:21 AM
I have added userfile.close(), unfortunately it still doesn't work.

Same error? Is it still on line 96?
CaptainStandard #10
Posted 15 May 2015 - 08:48 AM
Unfortunately, yes.
Maybe if I would add a forced variable, instead of detecting nil.
I will try it now.
CaptainStandard #11
Posted 16 May 2015 - 09:23 PM
I can't get it to work. The NilKiller actually detects something and lets it pass but the login checker sees it as nil.
Please help!
flaghacker #12
Posted 16 May 2015 - 09:33 PM
Please post your full code.

Are you sure the file you're trying to open exist? What happens when you try to open it from the lua terminal?
Edited on 16 May 2015 - 07:42 PM
CaptainStandard #13
Posted 16 May 2015 - 10:49 PM
Well the file doesn't exist, ah of course. When the NilKiller sets the account to NOACCOUNT the login checker tries to open it. Thanks a lot!!!
Stupid me
Edited on 16 May 2015 - 08:50 PM
CaptainStandard #14
Posted 16 May 2015 - 11:29 PM
Nope, it still doesn't work. For some reason it sees nil as a value that isn't nil. I tested changing the clientid in the nilkiller to set it to NOID when there was something by doing ~= nil. When I sent it a nil it said NOID.
This makes no sense
HPWebcamAble #15
Posted 17 May 2015 - 01:29 AM
From the 'send' function (Client)

function send()
  rednet.open(modemside)
  data = {}
  data["cid"] = clientid
  data["cmd"] = "LOGIN"
  data["acc"] = acc
  data["pin"] = pass
  rednet.broadcast (data)
  rednet.close(modemside)
end

From the 'CommandReceiver' function (Server)

id, data = rednet.receive()

if data == nil then
  data = {{"NODATA"}}
end

Tables can't be nil. Even if they are empty, they're still tables.
CaptainStandard #16
Posted 17 May 2015 - 08:29 AM
Thanks, I didn't know that. A few lines of code less