attempt to index a nil value items(help!) - lua

so im gettin this error so i know theres something i probably gotta fix here but i have no idea how .thanks
SCRIPT ERROR: #gcphone/server/server.lua:205: attempt to index a nil value (local 'items')
CODE FROM LINE 205
ESX.RegisterServerCallback('crew-phone:phone-check', function(source, cb)
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return; end
for k, v in pairs(Config.Phones) do
local items = xPlayer.getInventoryItem(v)
if items.count > 0 then
cb(v)
return
end
end
cb(nil)
end)
ESX.RegisterServerCallback('crew-phone:item-check', function(source, cb, data)
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return; end
local items = xPlayer.getInventoryItem(data)
cb(items.count)
end)

This error tells you that items is a nil value and Lua complains about it because you try to index it as in items.count. That doesn't make sense if items is nil
It's like referring to a book page of a non-existant book.
local items is nil because xPlayer.getInventoryItem(data) returned nil
Check wether the local script provides a string for data when triggering the server event and if xPlayer actually has an item like that.
Also check your RegisterServerCallback. The function you define there is the callback. Why is there another callback in that function argument? I think you're confusing things and probably should refer to the manual again.
https://esx-framework.github.io/es_extended/server/functions/registerservercallback/

Related

Roblox studio error "Attempt to concatenate string with Instance"

So I got this error and I cant seem to fix it.
Can anyone tell me how to fix it?
The error was : Attempt to concatenate string with Instance.
Image of the full error
The function:
function chatfunc(msg) -- < error line 523
coroutine.wrap(function()
local amountsofchats = 0
for i,v in pairs(workspace:GetChildren()) do
if v.Name == "amogus"..plr then
amountsofchats += 1
end
end
if amountsofchats >= 5 then
return
end
for i,v in pairs(workspace:GetChildren()) do
if v.Name == "amogus"..plr then
v.StudsOffset += Vector3.new(0,2,0)
end
end
...
The second error thing:
game:GetService("Players")[Username].Chatted:Connect(function(msg)
local msg,Message_ = msg,msg
if string.sub(msg,1,3) == "/e " then
msg = string.sub(msg,4)
end
chatfunc(msg) -- < error line 717
end)
You are getting this error because are you trying to concat a string with an instance for example "string" .. Instance.new("Part").
Now since you didnt give any lines numbers with your code, I am assuming "amogus"..plr is what causes the error, since plr is here an instance you probably ment to do "amogus"..plr.Name which is concatting two strings
Also
i do not recommend doing this at all game:GetService("Players")[Username] if the user has name which is a property of Players service u will get the property instead of the player. for example if you have the username MaxPlayers that will return a number and not the player with that name thus your code will error. So I recommend doing game:GetService("Players"):FindFirstChild(Username)

lua - check if userdata is nil [duplicate]

I have a lua script with code block as below:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
redis.call('HSET', KEYS[2], property, value)
end
end
populate_data(call_data)
populate_data(other_data)
When I try to run the script with the following command KEYS and ARGV as:-
redis-cli --eval dialed.lua "inflight_stats:18" "calls:AC443d7a8111a96ba8074f54a71f0521ce:CA1ec49703eee1959471c71506f43bb42e:dialed" , "{\"from\":\"+18035224181\",\"to\":\"+919943413333\",\"sid\":\"CA1ec49703eee1959471c71506f43bb42e\",\"status\":\"queued\",\"direction\":\"outbound-api\",\"date_created\":null,\"account_sid\":\"AC443d8a8111a96ba8074f54a71f0521ce\"}" "{\"phone\":\"919943413333\",\"campaign_id\":18,\"caller_session_sid\":\"CA828b163153bf5cc301ef5285e38925f9\"}" 0
Error :-
(error) ERR Error running script (call to f_08dcc69ee8baa0200e0cf552948ab4bc338c9978): #user_script:11: #user_script: 11: Lua redis() command arguments must be strings or integers
TL;DR for values returned by cjson.decode(), use cjson.null to compare to JSON's null value.
Explanation: Lua uses nil in tables to mark deleted entries. If JSONinc nulls were converted to Lunatic nils, the decoded objects would be corrupt. Therefore, the cjson lib uses a lightweight userdata type to represent null/nil.
Your 'call_data' has a 'date_created' field that is null - that causes the error.
The funny thing is that Redis, like Lua, will not store a nil/null value, so you'll have to either ignore null values or use a special value in Redis to flag them.
Assuming you'll be ignoring them, here's one way around it:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local null = cjson.null
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
if value ~= null then
redis.call('HSET', KEYS[2], property, value)
end
end
end
populate_data(call_data)
populate_data(other_data)
Also, a small optimization would be to batch the updates, like so:
local payload = {}
for property,value in pairs(source) do
if value ~= null then
table.insert(payload, property)
table.insert(payload, value)
end
end
redis.call('HSET', KEYS[2], unpack(payload))
P.S. if you want, look at ReJSON that I wrote - it is designed to help with what it appears that you're trying to do.

Problem with script in lua, Error nil value (local 'xPlayer')

so when i try to buy something in shop it's just drop me this error.How to fix this?
Code:
RegisterServerEvent('esx_shops:buyItem')
AddEventHandler('esx_shops:buyItem', function(itemName, amount, zone)
local _source = source
local xPlayer = ESX.GetPlayerFromId(_source)
local sourceItem = xPlayer.getInventoryItem(itemName)
amount = ESX.Round(amount)
-- is the player trying to exploit?
if amount < 0 then
print('esx_shops: ' .. xPlayer.identifier .. ' attempted to exploit the shop!')
return
end
Error:
SCRIPT ERROR: #esx_supermarket/server/main.lua:68: attempt to index a nil value (local 'xPlayer')
xPlayer is a nil value. nil values may not be indexed. Doing so causes an error.
So anything like xPlayer[something], xPlayer.something or xPlayer:something() is not allowed.
In your first example
local xPlayer = ESX.GetPlayerFromId(_source)
local sourceItem = xPlayer.getInventoryItem(itemName)
xPlayer is nil because ESX.GetPlayerFromId(_source) did not return a player. Most likely because _source is nil. At least there is nothing in your code that would indicate that source is not nil.
Befor you try to index possible nil values, check wether they are nil.
Please read the Lua manual and do a beginners tutorial.

is there a fix for Nil value for local user

This is for a phone script ive been working on and im trying to update some code but I have been getting a single error.
Error #phone/server.lua:37: attempt to index a nil value (local 'user')
ref (#phone/server.lua:37)
handler (#framework/server/main.lua:242)
getNumberPhone (#phone/server.lua:36)
handler (#phone/server.lua:268)
I tried the one way I was shown here before with no luck.
line 37
function getNumberPhone(source, n)
local n = 0
TriggerEvent('f:getPlayer', source, function(user)
n = user.getPhoneNumber()
end)
return n
end
line 242
AddEventHandler("f:getPlayer", function(user, cb)
if not cb then return end
if(Users)then
if(Users[user])then
cb(Users[user])
else
cb(nil)
end
else
cb(nil)
end
end)
line 36
function getNumberPhone(source, n)
local n = 0
TriggerEvent('f:getPlayer', source, function(user)
n = user.getPhoneNumber()
end)
return n
end
line 286
RegisterServerEvent('gcPhone:allUpdate')
AddEventHandler('gcPhone:allUpdate', function()
local source = source
local identifier = GetPlayerIdentifiers(source)[1]
TriggerClientEvent("gcPhone:myPhoneNumber", source, getNumberPhone(source))
TriggerClientEvent("gcPhone:allMessage", source, getMessages(identifier,source))
TriggerClientEvent("gcPhone:contactList", source, getContacts(identifier))
end)
Explaining the Error
In Lua, this is one of the most common errors you will run into, so it is very important for you to know how to solve it.
The error: attempt to index a nil value
To understand what this error means, you only need to understand these concepts.
In Lua, only tables can be indexed (i.e. myTable[myIndex])
In Lua, if a variable evaluates to nil, then attempting to index it as if it were a table throws an error
So it should be a little easier to understand the error you received. A more explicit way to describe this error would be something like "the Lua interpreter attempted to index your variable user on line 37 but user evaluated to nil."
Your Specific Case
On line 242 you are calling a callback and passing nil
cb(nil)
This callback sends this nil value to line 37 as the user parameter
TriggerEvent('f:getPlayer', source, function(user)
n = user.getPhoneNumber()
end)
So when you try to run user.getPhoneNumber() you are actually running nil.getPhoneNumber(), which throws the error you saw.
Ways to fix this type of error
1) Whenever you are working with a variable that could be nil, create an if statement checking to see if it is nil before proceeding.
2) Make sure you never set that variable to nil.
Ways to fix your specific error
1) On line 36, create this if statement
TriggerEvent('f:getPlayer', source, function(user)
if user ~= nil then
n = user.getPhoneNumber()
end
end)
Or do a similar nil check like this
TriggerEvent('f:getPlayer', source, function(user)
if user then
n = user.getPhoneNumber()
end
end)
2) Always pass a user in your callback. For example, on line 242 and elsewhere, pass an actual user object.
cb(Users[someUser])

Get name of argument of function in lua

When call a lua function like
PrintMe(MyVariableName)
I would like to be able to actually print "MyVariableName" and not it's value(well, for demo purposes).
Obviously I could just pass the string but that requires extra quotes and I also would like to print it's value.
e.g.,
MyVariable = 4
PrintVariable(MyVariable)
Would print "MyVariable is 4" or whatever
I do not want to have to duplicate the name and variable like
PrintVariable(MyVariable, "MyVariable")
as this is unnecessary duplication.
Can lua handle it?
What I'm doing now is passing the variable name in quotes and using loadstring to get the value but I would like to just pass the variable directly without the extra unnecessary quotes(which I thought debug.getlocal did but it ends up returning the value instead of the name).
Here is mock example
function printme1(var, val)
print(var.." = "..val)
end
function printme2(v)
local r
loadstring("r = "..v)() -- equivalent to r = a but must be used since v is a string representing a and not the object a
print(v.." = "..tostring(r))
end
function printme3(v)
-- unknown
end
a = 3
printme1("a", a)
printme2("a")
printme3(a)
In this case all 3 should print the same thing. printme3 obviously is the most convenient.
You can't say PrintVariable(MyVariable), because Lua gives you no way of determining which variable (if any; a constant could have been used) was used to pass an argument to your function. However, you can say PrintVariable('MyVariable') then used the debug API to look for a local variable in the caller's scope which has that name:
function PrintVariable(name)
-- default to showing the global with that name, if any
local value = _G[name]
-- see if we can find a local in the caller's scope with that name
for i=1,math.huge do
local localname, localvalue = debug.getlocal(2,i,1)
if not localname then
break -- no more locals to check
elseif localname == name then
value = localvalue
end
end
if value then
print(string.format("%s = %s", name, tostring(value)))
else
print(string.format("No variable named '%s' found.", name))
end
end
Now you can say:
PrintVariable('MyVariable')
While in this case will print "MyVariable = 4".
Not, if you really want to do this without the quotes, you could check the caller's locals for variables that have a supplied value, but that's occasionally going to give you the wrong variable name if there is more than one variable in the caller's scope with a given value. With that said, here's how you'd do that:
function PrintVariable(value)
local name
-- see if we can find a local in the caller's scope with the given value
for i=1,math.huge do
local localname, localvalue = debug.getlocal(2,i,1)
if not localname then
break
elseif localvalue == value then
name = localname
end
end
-- if we couldn't find a local, check globals
if not name then
for globalname, globalvalue in pairs(_G) do
if globalvalue == value then
name = globalname
end
end
end
if name then
print(string.format("%s = %s", name, tostring(value)))
else
print(string.format("No variable found for the value '%s'.", tostring(value)))
end
end
Now you can say PrintVariable(MyVariable), but if there happened to be another variable in the caller's scope with the value 4, and it occurred before MyVariable, it's that variable name that will be printed.
you can do stuff like this with the debug library... something like this does what you seem to be looking for:
function a_func(arg1, asdf)
-- if this function doesn't use an argument... it shows up as (*temporary) in
-- calls to debug.getlocal() because they aren't used...
if arg1 == "10" then end
if asdf == 99 then end
-- does stuff with arg1 and asdf?
end
-- just a function to dump variables in a user-readable format
function myUnpack(tbl)
if type(tbl) ~= "table" then
return ""
end
local ret = ""
for k,v in pairs(tbl) do
if tostring(v) ~= "" then
ret = ret.. tostring(k).. "=".. tostring(v).. ", "
end
end
return string.gsub(ret, ", $", "")
end
function hook()
-- passing 2 to to debug.getinfo means 'give me info on the function that spawned
-- this call to this function'. level 1 is the C function that called the hook.
local info = debug.getinfo(2)
if info ~= nil and info.what == "Lua" then
local i, variables = 1, {""}
-- now run through all the local variables at this level of the lua stack
while true do
local name, value = debug.getlocal(2, i)
if name == nil then
break
end
-- this just skips unused variables
if name ~= "(*temporary)" then
variables[tostring(name)] = value
end
i = i + 1
end
-- this is what dumps info about a function thats been called
print((info.name or "unknown").. "(".. myUnpack(variables).. ")")
end
end
-- tell the debug library to call lua function 'hook 'every time a function call
-- is made...
debug.sethook(hook, "c")
-- call a function to try it out...
a_func("some string", 2012)
this results in the output:
a_func(asdf=2012, arg1=some string)
you can do fancier stuff to pretty this up, but this basically covers how to do what you're asking.
I have bad news, my friend. You can access function parameter names as they appear at the top of the function, but the data to access exactly what they were named in the calling function does not exist. See the following:
function PrintVariable(VariableToPrint)
--we can use debug.getinfo() to determine the name 'VariableToPrint'
--we cannot determine the name 'MyVariable' without some really convoluted stuff (see comment by VBRonPaulFan on his own answer)
print(VariableToPrint);
end
MyVariable = 4
PrintVariable(MyVariable)
To illustrate this, imagine if we had done:
x = 4
MyVariable = x
MyOtherVariable = x
x = nil
PrintVariable(MyVariable)
Now if you were Lua, what name would you attach in the metadata to the variable that ends up getting passed to the function? Yes, you could walk up the stack with debug.getint() looking for the variable that was passed in, but you may find several references.
Also consider:
PrintVariable("StringLiteral")
What would you call that variable? It has a value but no name.
You could just use this form:
local parms = { "MyVariable" }
local function PrintVariable(vars)
print(parms[1]..": "..vars[1])
end
local MyVariable = "bar"
PrintVariable{MyVariable}
Which gives:
MyVariable: bar
It isn't generic, but it is simple. You avoid the debug library and loadstring by doing it this way. If your editor is any good, you could write a macro to do it.
Another possible solution is add this facility your self.
The Lua C API and source is pretty simple and extendable.
I/we don't know the context of your project/work but if you ARE making/embedding your own Lua build you could extend the debug library with something to do this.
Lua passes it's values by reference, but unknown offhand if these contain a string name in them and if so if easily accessible.
In your example the value declaration is the same as:
_G["MyVariable"] = 4
Since it's global. If it were declared local then like others stated here you can enumerate those via debug.getlocal(). But again in the C context of the actual reference context it might not matter.
Implement a debug.getargumentinfo(...) that extends the argument table with name key, value pairs.
This is quite an old topic and I apologize for bringing it back to life.
In my experience with lua, the closest I know to what the OP asked for is something like this:
PrintVariable = {}
setmetatable(PrintVariable, {__index = function (self, k, v) return string.format('%s = %s', k, _G[k]) end})
VAR = 0
VAR2 = "Hello World"
print(PrintVariable.VAR, PrintVariable.VAR2)
-- Result: VAR = 0 VAR2 = Hello World
I do not give more explanation, because the code is quite readable, however:
What happens here is simple, you only set a metatable to the PrintVariable variable and add the __index metamethod that is called when the table is forced to search for a value in its index, thanks to this functionality you can achieve what you see in the example.
Reference: https://www.lua.org/manual/5.1/manual.html
I hope that future and new visitors will find this helpful.

Resources