I am working on my own library. When new members are added to the table, it does some sorting of its own in the __newindex function. What I am trying to know, is how to differentiate:
function object:Create()
end
from
function object.Create()
end
You should read Programming in Lua : 16. The linked page talks about this syntax, but the whole chapter is gold.
__namecall
is a Roblox specific metamethod that’s used exclusively on Instances. You can only use it by adding it to a userdata (with newproxy(true)
), and, it doesn’t give you any information about the actual call, that information is only accessible from C code.
The :
function notation is completely identical to the following cases:
function object:Abc(a, b, c)
end
function object.Abc(self, a, b, c)
end
object:Abc(a, b, c)
object.Abc(object, a, b, c) -- Actually a little slower in luau due to optimizations with the above
There isn’t actually a way to differentiate between these, and, in fact, you can use functions on instances like this:
local Destroy = game.Destroy
Destroy(script) -- This works because game.Destroy, script.Destroy, etc are all the same function, they actually use the instance you pass to them as the target on what to destroy. If you print out the functions you can see they are the same function.
The way that Roblox outputs the error message when you don’t use :
is by checking if the first argument is an instance. Really the only way to differentiate is by checking the first argument, there isn’t another way to do this.
That’s not name calling, that’s just a clear call
This is a namecall: workspace("FindFirstChild", "Model")
We can no longer do this, and shouldn’t
Yeah, I am aware that’s not a namecall, sorry if that seemed misleading. My first paragraph at the top is not related to the last part of my message, I was mostly responding to the discussion of the metamethod above, and, I didn’t make it clear my reply was not about the metamethod or namecalling.
If I remember correctly that specific quirk was a bug, I don’t recall all of the details, but, it was removed with one of the initial luau releases and I vaguely remember zeuxg mentioning it.
When you use the :
notation on an instance the __namecall
metamethod is invoked to make function calls faster for instances. This metamethod used to pass the name of the method being called but in luau this was changed, and now only the self
variable and function arguments are passed to the metamethod. The name of the method is no longer passed for performance reasons, it can only be accessed in C code.
This is a namecall:
workspace("FindFirstChild", "Model")
__namecall
is a metamethod which fires when you call a function of an object via :
, it’s just an internal optimization. What you showed doesn’t invoke the metamethod.
The metamethod is only accessible to proxies as Hexcede stated, but for exploiters its not limited.
Additional Info
Exploiters can easily bypass metatable locks simply doing debug.getmetatable
or, getrawmetatable
. which is available to them via custom script executors like Synpase. game
has a metatable, but its locked. Exploiters bypass this and then simply hook up the __namecall
, and can use it to their own advantages. They might even use it for remote methods like FireServer
returning something else than expected!
Here’s an example:
local game_meta = getrawmetatable(game)
local game_namecall = game_meta.__namecall
function game_meta.__namecall(self, ...)
local args = {...}
local method = args[args]
if method == "FireServer" or method == "InvokeServer" then
return "hehe get rekt"
end
-- idk what should i return
end
__newindex
is a metamethod which fires when you append a new key to a table or you update a certain key which already exists.
The difference of these 2 functions down below is that, the one declared with :
, will allow you to access self
, which refers to the object you call the function from. The function declared with .
is just a normal function of the object, nothing fancy.
function object:Create()
end
from
function object.Create()
end
I believe you can do it with __call now…
Luaquack used it in his Ascensionist script inside one of the ModuleScripts that are required for Ascensionist
local m=setmetatable({}, {
__call=function(self, method, ...)
if method~=nil then
if string.lower(tostring(method))=="getservice" then
warn("NOOO YOU CALLED A TABLE NOOOOOOOOOOOOO:"..[[
]]..(...))
return game:GetService(...)
else
return error("You can't call a table, broo its a table not a function bruhh your so bad at scripting if you think tables can be like functions (this is a joke) ", 0)
end
end
end,
})
m("getSErviCE", "Workspace").Name="Wow I JUST CALLED A TABLE LOLZ"
heres the Ascensionist script just incase you wanna check it out.