Moderators Popular Post IIYAMA Posted August 18, 2019 Moderators Popular Post Share Posted August 18, 2019 (edited) MTA-Communication-Enhancement This is an enhancement that allows you to communicate between clientside and serverside a bit easier. If you know how to work with events, then you probably do not need this, but it has some nice features which allows you to sit back and write less code + achieve some nice results. Note: It is important to keep in mind that this is an enhancement. Which means it is just an layer on top of the basic functionalities of MTA. And most enhancements come with a cost, in this case that is bit of performance. I will keep the information of topic to the minimal, as I have written most of the information already on the repository. You can find the repository here. Examples Syntax Installation What can you do with it? Calling from clientside to serverside Client callServer("hello") Server function hello () outputChatBox("Hello client!") end Calling from serverside to clientside Server addCommandHandler("callclient", function (player) -- An addCommandHandler is needed, because the client hasn't loaded it's scripts yet. callClient(player, "hello") end, false, false) Client function hello () outputChatBox("Hello server!") end Ok, ok, that was boring. The next one this is a bit nicer! Hello are you there? Just Call-me-back... I miss(ed) you too Callback Client callServer( "callbackMe", "argument", function (argument) -- < This is the callback function outputChatBox(argument) end ) Server function callbackMe (argument) return argument .. " < I looked at it :)" end Callback + internal arguments Sometimes you have arguments that you simply can't send over. > functions Or arguments that shouldn't be send over. > LARGE quantities of database data Internal arguments can be used to pass information to a callback without exposing it to the other side(client/server). Client callServer( "callbackMe", -------------------------------- -- arguments that are send over "argument", -- -------------------------------- function (internalArgument, argument) -- < This is the callback function. outputChatBox(internalArgument) outputChatBox(argument) end, -------------------------------- -- arguments that are not send over "internalArgument" -- < internal argument -- -------------------------------- ) Server function callbackMe (argument) return argument .. " < I looked at it :D" end Ha! Serverside what is that? No need for complicated things! Communicate between clients without writing a single line of serverside. Magic! Note: There is serverside used behind the scenes, you just don't have to write it. Client function smile (player) outputChatBox((isElement(player) and getPlayerName(player) or "[unknown]") .. " has send you a: :)") local x, y, z = getElementPosition(localPlayer) setElementPosition(localPlayer, x, y, z + 100) end addRemoteClientAccessPoint(smile) -- < This function allows other clients to call this function. --------------------------------------- -- -- function getPlayerFromPartialName(name) local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower() if name_:find(name, 1, true) then return player end end end end -- Author: TAPL -- https://wiki.multitheftauto.com/wiki/GetPlayerFromPartialName -- -- --------------------------------------- addCommandHandler("smile", function (cmd, playerName) local player = getPlayerFromPartialName(playerName) if player then outputChatBox("Sending smile!") callRemoteClient(player, "smile", player) else outputChatBox("Can't find player!") end end) Turtle, I will wait for you to catch up. So don't worry, you are still cute. Await functions When a player has joined the server, he or she doesn't have download + loaded his scripts yet. This means that you can't deliver your love letter yet and all your work will be for nothing. But what if you don't have to worry about that? You can just wait now! Server addEventHandler("onPlayerJoin", root, function () callClientAwait(source, "testCallClientAwait") end) Client function testCallClientAwait () outputChatBox("Yes this works!") end Security Worried about security issues? Remote calls for C++/MTA functions have been blocked. There is a whitelist feature included, if enabled your code can only remote-call whitelisted functions. (this is disabled by default) Read the docs for that. Here and here Edited December 2, 2020 by IIYAMA 10 Link to comment
enesbayrktar Posted February 6, 2021 Share Posted February 6, 2021 İts amazingly usefull! I use this on my script but i have one question about multiple argument sending to server-side. Can you give a example for this? callServer('isAccountRegistered', username, function(state) if state then guiSetText(usernameEdt, '') return notifications:error(string.format('%s zaten kullanımda. Lütfen farklı bir ad seç.', username)) end end ) -- i wanna use multiple args when sending, for example. callServer('isAccountRegistered', username, password, caseVariable, function(state) -- TO DO end ) 1 Link to comment
Moderators IIYAMA Posted February 9, 2021 Author Moderators Share Posted February 9, 2021 (edited) On 06/02/2021 at 01:29, enesbayrktar said: İts amazingly usefull! thx! Sorry for my late reply, I didn't notice the notification. The syntax for that function: bool callServer (callFunctionName string [, argument1, argument2, ... ] [, callbackFunction function [, argument1 (internal), argument2 (internal), ...]] ) https://gitlab.com/IIYAMA12/mta-communication-enchantment/tree/master/documentation/syntax#syntax-1 Multiple values can be send over by just adding them between the functionName and the callBackFunction. functionName: 'isAccountRegistered' callBackFunction: function(state) end callServer('isAccountRegistered', username, function(state) end) -- 1 callServer('isAccountRegistered', username, password, function(state) end) -- 2 callServer('isAccountRegistered', username, password, caseVariable, function(state) end) -- 3 It goes through all arguments and detects if there is a function, then that one will be the callBack function. See here where that happens in the source code: https://gitlab.com/IIYAMA12/mta-communication-enchantment/-/blob/master/sync/sync_c.lua#L77 https://gitlab.com/IIYAMA12/mta-communication-enchantment/-/blob/master/sync/sync_shared.lua#L250 So you want to do that, what you already can do and doing it already? Edited February 9, 2021 by IIYAMA 1 Link to comment
enesbayrktar Posted February 9, 2021 Share Posted February 9, 2021 26 minutes ago, IIYAMA said: thx! Sorry for my late reply, I didn't notice the notification. The syntax for that function: bool callServer (callFunctionName string [, argument1, argument2, ... ] [, callbackFunction function [, argument1 (internal), argument2 (internal), ...]] ) https://gitlab.com/IIYAMA12/mta-communication-enchantment/tree/master/documentation/syntax#syntax-1 Multiple values can be send over by just adding them between the functionName and the callBackFunction. functionName: 'isAccountRegistered' callBackFunction: function(state) end callServer('isAccountRegistered', username, function(state) end) -- 1 callServer('isAccountRegistered', username, password, function(state) end) -- 2 callServer('isAccountRegistered', username, password, caseVariable, function(state) end) -- 3 It goes through all arguments and detects if there is a function, then that one will be the callBack function. See here where that happens in the source code: https://gitlab.com/IIYAMA12/mta-communication-enchantment/-/blob/master/sync/sync_c.lua#L77 https://gitlab.com/IIYAMA12/mta-communication-enchantment/-/blob/master/sync/sync_shared.lua#L250 So you want to do that, what you already can do and doing it already? İ tested and its worked, but i dont know its true usage or not of multiple args for this reason i wanna a example code from you. Thanks @IIYAMA 1 Link to comment
Moderators IIYAMA Posted February 9, 2021 Author Moderators Share Posted February 9, 2021 (edited) 21 minutes ago, enesbayrktar said: İ tested and its worked, but i dont know its true usage or not of multiple args for this reason i wanna a example code from you. Thanks @IIYAMA There is only 1 thing you need to know about internal arguments. Those ones that are after the callBack function. If you mix internal arguments with arguments(from serverside), you have to make sure that the last internal argument is not a nil value. Because when all arguments are converted to parameters, both lists will be merged and the first list(internal arguments) will collapse on nil values at the end of the table. Problem: internal2 = nil callServer('isAccountRegistered', username, password, caseVariable, function(internal1, internal2, state) end, "internal1", internal2) Is OK: internal2 = false callServer('isAccountRegistered', username, password, caseVariable, function(internal1, internal2, state) end, "internal1", internal2) As you can see here: list1 = {1, 2, nil, 4, nil} -- internal arguments list2 = {6, 7, 8, 9, 10} for i=1, #list2 do list1[#list1 + 1] = list2 [i] end print(unpack(list1)) -- 1, 2, nil, 4, 6, 7, 8, 9, 10, -- The nil value at index 5 is missing. Edited February 9, 2021 by IIYAMA Link to comment
Recommended Posts