The title is self explanatory. I have a function inside of a table, and I’m sending that table to the client via RemoteFunction:InvokeClient
.
You can’t send function
types across remotes afaik
What even is the point of doing so? Why not just have the function be right there in a modulescript placed in ReplicatedStorage, and then call the function on demand?
Because for what I’m doing, that won’t work.
Are you using loadstrings? Otherwise, all functions declared at runtime are static and explicit and there would be no need to move them around between server & client
No, I am not.
What I want achieved:
Say I have a table,
{
foo = "bar",
cool = function()
print('cool!')
end
}
I want to send that to the client. When I send it, this is what is returned:
{
foo = "bar"
}
The function called “cool” is removed.
That’s what I’ve been telling you. You can’t send functions across remotes, and it’s pointless to do so anyway.
It’s not “pointless”, and that’s the reason why I made this topic. I’m looking for a workaround.
I do not believe there is a workaround. Roblox would prohibit the exchange of executable code for security reasons.
Please read:
And tell me what exactly are you trying to achieve from sending functions
I’m creating a modular admin system. The system take server-sided packages (user made commands using the command template) and client-sided commands. The server sided packages are easy to implement because the module is server-sided, but it’s another story with client-sided commands. All of the data for the client-sided packages (name, aliases, minimum rank required to execute, etc.) are all in the table when it’s passed to the client, except the function, which is why I created this topic.
And what exactly would the passed functions be used for in this case?
Executing the command.
characters
Don’t you think commands should be executed on the server and not on the client for things like replication?
That’s a good point, but it’s always a good idea to have the freedom to do whatever.
I’ll repeat myself; you can use a ModuleScript to store all of the client-sided commands inside ReplicatedStorage. And then, when the server wants the admin to do something client-sided, it just sends over the key for the designated function, then the player indexes the module for the key, and executes whatever function is there. Unless I’m missing something, this does not require the exchange of entire functions across remotes.
I one up @Prototrode. This is pointless (except for very, and I mean VERY, niche cases.)
And, to top off the uselessness, it’s also a security vulnerability if functions can be sent between servers and clients. Because people can modify (exploit) their client and manipulate what happens.
So you’re best off making two designated lists of commands.
A server list, and a client list.
Unless you want to just make everything happen on the client, but you’d want to implement a .Joined system to send old commands to people who just joined.
I understand, but is there a workaround for what I’m trying to accomplish?
w h a t
send function as a string and use loadstring module on server to call that function
Client
RemoteFunction:InvokeServer({
foo = "bar",
cool = " print('cool!') "
})
On the server
local Loadstring = require(path)
RemoteFunction.Invoked = function(table)
local func = Loadstring(table.cool)
return func(table.foo)
end
There should never be any reason to have a ‘unknown’ function, that would need to be sent. Every function in your game should be known and have a purpose.
If you want ‘user created’ admin commands, you have the user create them with your custom ‘language’ then only send that to the client or the server, and have it ‘compiled’ to be executed on that end.
only send data, and let the functions be there waiting for it.
You can define the functions in a modulescript in ReplicatedStorage, and then something along the lines of:
local YourRemoteHere = ...
... -- blah
... -- blah
-- you get a request to do a command.
-- so send the data to clients.
YourRemoteHere:FireAllClients(WhoDidTheCmd, TheCommandName, Arguments)
-- Arguments in your case may also just be a tuple (...)
-- actually yeah I used a tuple below so tuple it is. cooler anyways.
and then the client receives the event, and calls the function something like this maybe:
local YourCommandModule = require(...)
-- assuming you have a format of commands like this:
-- {Name, Description, Rank, UsageTable, Func}
YourRemoteHere.OnClientEvent:Connect(function(WhoDidTheCmd, CommandName, ...)
-- and further assuming you have a function that looks up by name
local Command = YourCommandModule:Find(CommandName)
if Command then
pcall(Command.Func, WhoDidTheCmd, ...)
end
end)
I hope that sums it up?
idk, toodles