Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Function as argument #2942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
MobinYengejehi wants to merge 32 commits into multitheftauto:master
base: master
Choose a base branch
Loading
from MobinYengejehi:function_as_argument

Conversation

@MobinYengejehi
Copy link

@MobinYengejehi MobinYengejehi commented Apr 3, 2023
edited
Loading

hi guys
i could made a method that help lua to pass a function as argument and send it to other resources
and you can use it in both server and client sides
you can pass function as argument in triggerEvent or exports.resource:func_name or setElementData(if you set 4th argument to false) and send it to another resource and call it
and also you can send functions in table (but you can't share metamethods)
for example:

-- resource : A
local player = nil;
local library = {};
function library.SetPlayer(element)
 if isElement(element) then
 player = element;
 end
end
function library.GetPlayer()
 return player;
end
addEvent("getlibrary", false);
addEventHandler("getlibrary", localPlayer, function(send)
 iprint("function is:", send, type(send)); -- type(send) = table
 send(library);
 print("library sent to ", getResourceName(send.resource));
 send:free(); -- cleanup function reference at resource B (this cleans up the memory. if you don't call this method it stays in memory untill program destroy lua stack like stopping resource)
end);
-- resource : B
local library;
triggerEvent("getlibrary", getLocalPlayer(), function(resourceALibrary)
 library = resourceALibrary;
 print("resource B got the library!");
end);
if library then
 print("player is : ", library.GetPlayer()); -- nil
 library.SetPlayer(getLocalPlayer());
 print("player is : ", library.GetPlayer()); -- local player
end

when you pass a function as an argument it will look like a table
and has these values:
-- function reference:
.resource : the resource that owns function
.reference : the reference id
.free : this method deletes the reference. if you call it, means that you won't be able to use that function anymore

note 1 : you can store a function reference in other resource if you want to let it be active otherwise if you call that function in render event or sth like that and you don't use :free method, after seconds your game or server console crashs because it occupies your memory
note 2 : remember when you want to cleanup your function call it as method, like function:free (not like function.free) because free needs a callable value as first argument

fresholia, CrosRoad95, samr46, Git-RubyCommunity, ImAaronFR, MobinYengejehi, flashmta, and Wannacry-ops reacted with thumbs up emoji
add function type to read and write method
define static `CallFunction` method and `CleanupFunction` method
@lopezloo lopezloo added the enhancement New feature or request label Apr 4, 2023
Copy link

couldn't you just implicit convert functions to refs using ref and deref

Copy link
Author

couldn't you just implicit convert functions to refs using ref and deref

i think i couldn't understand well what you mean
but if you mean why those are table
its because it doesn't cause confusion when passing a function as an argument in triggerEvent and other functions and you can check in other resources that where does this function come from

Copy link

No news about this PR? I can't imagine a cases for what need store functions in elementData, but for exports it very useful. 🤔

Copy link
Contributor

This reminds me of #3551

{
lua_newtable(luaVM); // create callable

lua_pushresource(luaVM, m_pResource); // push function inside callable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a referenced resource become stopped this pointer will turn into the dangling one. From what I was able to see there is no an invalidation mechanism for functions.

Copy link
Author

@MobinYengejehi MobinYengejehi Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree

Copy link
Author

@MobinYengejehi MobinYengejehi Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have some cleaner and better version in my mind for this
i will work on it and update its PR to use that instead

Copy link
Member

tederis commented May 31, 2025

I consider this feature as excessive and the implementation as dangerous.

Copy link
Author

i need time to refactor this PR

Copy link
Member

I'm opposed to this. There's no good reason for this to exist, it can be dangerous AND it can cause easy memory leaks.

ArranTuna reacted with thumbs up emoji

Copy link
Member

FileEX commented Aug 13, 2025
edited
Loading

I think that’s a good idea.
With more complex resources, it would often be useful to send something like a callback instead of having to trigger, for example.

(削除) Is it safe? (削除ここまで)
(削除) Yes and no — it depends on how it’s used. We can’t halt project development because of fear or poor script management by the community. We should, however, provide them with tools to manage such a feature, like sending functions.
It is indeed dangerous in the sense that if a potential cheater finds a trigger that accepts a function as an argument and, worse, executes it without checking, they could run arbitrary code on the server. But does that immediately disqualify this PR? Absolutely not. (削除ここまで)

(削除) It’s ultimately the scripters’ responsibility to secure their server. We can help them, but we can’t do it for them. (削除ここまで)

(削除) Imo, the ability to send functions via a trigger or export should have a toggle in mtaserver.conf - but only for the client-to-server direction.
Meaning: the server can always send functions to the client, but the reverse is only possible if the option is enabled in mtaserver.conf. If disabled, the server ignores the function and shows an appropriate warning as it does now. (削除ここまで)

As for element data, I’m not sure if it has any real use here, but if the server ignores a value that’s a function during synchronization (since a cheater could force this even with the 4th sync argument set to true), then that’s fine.

Copy link

Rilot06 commented Aug 13, 2025

It is indeed dangerous in the sense that if a potential cheater finds a trigger that accepts a function as an argument and, worse, executes it without checking, they could run arbitrary code on the server.

but only for the client-to-server direction.
Meaning: the server can always send functions to the client, but the reverse is only possible if the option is enabled in mtaserver.conf. If disabled, the server ignores the function and shows an appropriate warning as it does now.

I think you really misunderstand this PR. How would a client send a function's reference to the server or vice versa? That's not how it works. This is to send functions between resources on the same script side with either local events or exports.

Copy link
Member

FileEX commented Aug 13, 2025

It is indeed dangerous in the sense that if a potential cheater finds a trigger that accepts a function as an argument and, worse, executes it without checking, they could run arbitrary code on the server.
but only for the client-to-server direction.
Meaning: the server can always send functions to the client, but the reverse is only possible if the option is enabled in mtaserver.conf. If disabled, the server ignores the function and shows an appropriate warning as it does now.

I think you really misunderstand this PR. How would a client send a function's reference to the server or vice versa? That's not how it works. This is to send functions between resources on the same script side with either local events or exports.

I don’t know why I kept thinking it was about sending a function between sides, something like a string and reading it through loadstring, lol. Maybe it’s just after work and the effect of being sleep-deprived.

But still... I think a properly refined solution is acceptable. Currently, cheaters can execute any code on the client side, so I don’t think sending a function from resource X to resource Y would create any huge threat here. On the client side, nothing is and never will be truly secure. A cheater can do whatever they want, so sending their own function to some resource doesn’t really give them any additional capability to cause harm.

Copy link

Rilot06 commented Aug 13, 2025

But still... I think a properly refined solution is acceptable. Currently, cheaters can execute any code on the client side, so I don’t think sending a function from resource X to resource Y would create any huge threat here. On the client side, nothing is and never will be truly secure. A cheater can do whatever they want, so sending their own function to some resource doesn’t really give them any additional capability to cause harm.

I don't think megadreams meant the "dangerous" part as in cheaters. More like easy memory leaks, segfaults, etc. But I think if you are careful enough, it can be implemented in a safe way

FileEX reacted with thumbs up emoji

@FileEX FileEX marked this pull request as draft August 24, 2025 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@tederis tederis tederis left review comments

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Labels

enhancement New feature or request

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /