SetElementData: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
No edit summary
(clientChangesPolicy)
 
(59 intermediate revisions by 30 users not shown)
Line 1: Line 1:
{{Server client function}}
{{Server client function}}
__NOTOC__  
__NOTOC__  
This function stores data attached to an element. This data can be any primitive LUA type or MTA element (but not a text item or display).
This function stores [[element data]] under a certain key, attached to an element. Element data set using this is then synced with all clients and the server. The data can contain server-created elements, but you should avoid passing data that is not able to be synced such as xmlnodes, acls, aclgroups etc.


Element data is a useful way to store data attached to players.
As element data is synced to all clients, it can generate a lot of network traffic and be heavy on performance. Events are much more efficient for sending data from a client to the server only, or from the server to a specific client. <br/>
Usage of element data should be discouraged where your goal can be achieved with events like above, and [[table|tables]] for storing and retrieving data.
{{Tip|A simple and efficient way to make a variable known to the server and clients is to use setElementData on the [[root]] element.}}
{{Note|See [[Script security]] for tips on preventing cheaters when using events and element data}}
{{Note|For performance reasons, never use setElementData in events that fire often (like [[onClientRender]]) without further optimization or conditions. In fact, using element data in general, can take such a toll on performance that not using it unless strictly necessary (e.g use alternatives such as storing data in tables) is recommended.}}


{{New items|5.0157|1.5.7-9.20477|A subscription mode has been introduced for [[setElementData]] serverside. When setting data in subscription mode, only clients that are added through [[addElementDataSubscriber]] will receive the data, which is good for performance.
Note this mode only works when setting element data serverside. Setting data clientside still sends the update to all clients if 'synchronize' is set to true.
}}
==Syntax==
<syntaxhighlight lang="lua">
bool setElementData ( element theElement, string key, var value [, bool synchronize = true ] )
</syntaxhighlight>
{{OOP||[[element]]:setData||getElementData}}
===Required Arguments===
*'''theElement:''' The [[element]] you wish to attach the data to.
*'''key:''' The key you wish to store the data under. (Maximum 128 characters.)
*'''value:''' The value you wish to store. See [[element data]] for a list of acceptable datatypes.
===Optional Arguments===
*'''synchronize:''' Determines whether or not the data will be synchronized with the clients(server-side variation) or server(client-side variation)
===Returns===
Returns ''true'' if the data was set successfully, ''false'' otherwise.
{{New items|5.0157|1.5.7-9.20477|
==Syntax==  
==Syntax==  
<section name="Server" class="server" show="true">
<syntaxhighlight lang="lua">
bool setElementData ( element theElement, string key, var value [, string syncMode="broadcast", string clientChangesPolicy="default" ] )
</syntaxhighlight>
{{OOP||[[element]]:setData||getElementData}}
===Required Arguments===
*'''theElement:''' The [[element]] you wish to attach the data to.
*'''key:''' The key you wish to store the data under. (Maximum 31 characters.)
*'''value:''' The value you wish to store. See [[element data]] for a list of acceptable datatypes.
===Optional Arguments===
*'''syncMode:''' Synchronisation mode.
**''"broadcast"'' - Synchronise to all clients (default behavior). You can also parse ''true'' for this option.
**''"local"'' - Don't synchronise. You can also parse ''false'' for this option.
**''"subscribe"'' - Only synchronise to specific clients. See [[addElementDataSubscriber]] and [[removeElementDataSubscriber]].
{{New items|6.0160|1.6.0-22790|
*'''clientChangesPolicy:''' Client changes policy.
**''"default"'' - Use '''elementdata_whitelisted''' setting from [[Server_mtaserver.conf|'''mtaserver.conf''']]
**''"allow"'' - Trust changes from clients.
**''"deny"'' - Deny client changes. The server will trigger the [[onPlayerChangesProtectedData]] event when the client attempts to change the value.
}}
</section>
<section name="Client" class="client" show="true">
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
bool setElementData ( element theElement, string key, var value )  
bool setElementData ( element theElement, string key, var value [, bool synchronize = true ] )
</syntaxhighlight>  
</syntaxhighlight>  
{{OOP||[[element]]:setData||getElementData}}


===Required Arguments===  
===Required Arguments===  
*'''theElement:''' The element you wish to attach the data to
*'''theElement:''' The [[element]] you wish to attach the data to.
*'''key:''' The key you wish to store the data under
*'''key:''' The key you wish to store the data under. (Maximum 31 characters.)
*'''value:''' The value you wish to store
*'''value:''' The value you wish to store. See [[element data]] for a list of acceptable datatypes.
 
===Optional Arguments===
*'''synchronize:''' Determines whether or not the data will be synchronized with the server.
</section>


===Returns===
===Returns===
Returns ''true'' if the data was set succesfully, ''false'' otherwise.
Returns ''true'' if the data was set successfully, ''false'' otherwise.
}}


==Example==  
==Example==
<section name="Server" class="server" show="false">
Example 1
This example allows for a player to add a custom tag onto their nickname, and also revert it back to normal if they wish
<section name="Server" class="server" show="true">
This example allows a player to add a custom tag onto their nickname, and also reverts it back to normal if they wish.
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function addPlayerCustomTag ( player, command, newTag )
function addPlayerCustomTag ( thePlayer, command, newTag )
--Lets check that the newTag param has been entered...
--Let's make sure the newTag param has been entered...
if ( newTag ) then
if ( newTag ) then
--Grab their current playername for saving.
--Grab their current playername for saving.
local sPlayerNickname = getClientName(player)
local sPlayerNickname = getPlayerName ( thePlayer )
--Create their new nickname with their tag
--Create their new nickname with their tag
local sNewPlayerNickname = newTag .. " " .. sPlayerNickname
local sNewPlayerNickname = newTag .. " " .. sPlayerNickname
--Lets first load the element data, see if its there allready
--Let's first load the element data, see if it's there already
--The reason for this is that if a player were to do /addtag twice
--The reason for this is that if a player were to do /addtag twice,
--it would have saved their last tag as their orignal nickname
--the tag would be prepended a second time
--without this check
local sOldNick = getElementData( thePlayer, "tempdata.originalnick" )
local sOldNick = getElementData( player, "tempdata.orignalnick" )
if ( sOldNick == false ) then
if ( sOldNick == false ) then
--Save their orignal nickname in their element data
--Save their orignal nickname in their element data
setElementData ( player, "tempdata.orignalnick", sPlayerNickname )
setElementData ( thePlayer, "tempdata.originalnick", sPlayerNickname )
end
end
--Set their new nickname globally
--Set their new nickname globally
setClientName ( player, sNewPlayerNickname )
setPlayerName ( thePlayer, sNewPlayerNickname )
--Tell them its done
--Tell them it's done
outputChatBox ( "Your new nickname has been set, to put it back to its orignal state you can use /deltag", player )
outputChatBox ( "Your new nickname has been set, to put it back to its original state you can use /deltag", thePlayer )
else
else
--The newTag param was not entered, give a error message
--The newTag param was not entered, give an error message
outputChatBox ( "/addtag - Incorrect syntax, Correct: /addtag <newtag>", player )
outputChatBox ( "/addtag - Incorrect syntax, Correct: /addtag <newtag>", thePlayer )
end
end
end
end
addCommandHandler ( "addtag", addPlayerCustomTag )
addCommandHandler ( "addtag", addPlayerCustomTag )


function removePlayerCustomTag ( player, command )
function removePlayerCustomTag ( thePlayer, command )
--We first need to check that they have allready used /addtag, lets do that now
--We first need to check that they have already used /addtag, let's do that now
local sOldNick = getElementData( player, "tempdata.orignalnick" )
local sOldNick = getElementData( thePlayer, "tempdata.originalnick" )
if ( sOldNick ) then
if ( sOldNick ) then
--Great, they have a tag added, lets reset them
--Great, they have a tag added, let's reset them
--First we will want to reset the element data back to its default (that being false)
--First we will want to reset the element data back to its default (that being false)
setElementData ( player, "tempdata.orignalnick", false )
setElementData ( thePlayer, "tempdata.originalnick", false )
--Now set the client name back
--Now set the client name back
setClientName ( player, sOldNick )
setPlayerName( thePlayer, sOldNick )
--Notify them
--Notify them
outputChatBox ( "Your old nickname has been set", player )
outputChatBox ( "Your old nickname has been set", thePlayer )
end
end
end
end
Line 71: Line 129:
</syntaxhighlight>
</syntaxhighlight>
</section>
</section>
[[tr:setElementData]]


==See Also==
==See Also==
[[pt-br:SetElementData]]
{{Element_functions}}
{{Element_functions}}

Latest revision as of 13:12, 6 December 2024

This function stores element data under a certain key, attached to an element. Element data set using this is then synced with all clients and the server. The data can contain server-created elements, but you should avoid passing data that is not able to be synced such as xmlnodes, acls, aclgroups etc.

As element data is synced to all clients, it can generate a lot of network traffic and be heavy on performance. Events are much more efficient for sending data from a client to the server only, or from the server to a specific client.
Usage of element data should be discouraged where your goal can be achieved with events like above, and tables for storing and retrieving data.

[[{{{image}}}|link=|]] Tip: A simple and efficient way to make a variable known to the server and clients is to use setElementData on the root element.
[[{{{image}}}|link=|]] Note: See Script security for tips on preventing cheaters when using events and element data
[[{{{image}}}|link=|]] Note: For performance reasons, never use setElementData in events that fire often (like onClientRender) without further optimization or conditions. In fact, using element data in general, can take such a toll on performance that not using it unless strictly necessary (e.g use alternatives such as storing data in tables) is recommended.
ADDED/UPDATED IN VERSION 1.5.7-9.20477 :
A subscription mode has been introduced for setElementData serverside. When setting data in subscription mode, only clients that are added through addElementDataSubscriber will receive the data, which is good for performance.

Note this mode only works when setting element data serverside. Setting data clientside still sends the update to all clients if 'synchronize' is set to true.

Syntax

bool setElementData ( element theElement, string key, var value [, bool synchronize = true ] )

OOP Syntax Help! I don't understand this!

Method: element:setData(...)
Counterpart: getElementData


Required Arguments

  • theElement: The element you wish to attach the data to.
  • key: The key you wish to store the data under. (Maximum 128 characters.)
  • value: The value you wish to store. See element data for a list of acceptable datatypes.

Optional Arguments

  • synchronize: Determines whether or not the data will be synchronized with the clients(server-side variation) or server(client-side variation)

Returns

Returns true if the data was set successfully, false otherwise.

ADDED/UPDATED IN VERSION 1.5.7-9.20477 :

Syntax

Click to collapse [-]
Server
bool setElementData ( element theElement, string key, var value [, string syncMode="broadcast", string clientChangesPolicy="default" ] )

OOP Syntax Help! I don't understand this!

Method: element:setData(...)
Counterpart: getElementData


Required Arguments

  • theElement: The element you wish to attach the data to.
  • key: The key you wish to store the data under. (Maximum 31 characters.)
  • value: The value you wish to store. See element data for a list of acceptable datatypes.

Optional Arguments

  • syncMode: Synchronisation mode.
    • "broadcast" - Synchronise to all clients (default behavior). You can also parse true for this option.
    • "local" - Don't synchronise. You can also parse false for this option.
    • "subscribe" - Only synchronise to specific clients. See addElementDataSubscriber and removeElementDataSubscriber.
ADDED/UPDATED IN VERSION 1.6.0-22790 :
  • clientChangesPolicy: Client changes policy.
    • "default" - Use elementdata_whitelisted setting from mtaserver.conf
    • "allow" - Trust changes from clients.
    • "deny" - Deny client changes. The server will trigger the onPlayerChangesProtectedData event when the client attempts to change the value.
Click to collapse [-]
Client
bool setElementData ( element theElement, string key, var value [, bool synchronize = true ] )

OOP Syntax Help! I don't understand this!

Method: element:setData(...)
Counterpart: getElementData


Required Arguments

  • theElement: The element you wish to attach the data to.
  • key: The key you wish to store the data under. (Maximum 31 characters.)
  • value: The value you wish to store. See element data for a list of acceptable datatypes.

Optional Arguments

  • synchronize: Determines whether or not the data will be synchronized with the server.

Returns

Returns true if the data was set successfully, false otherwise.

Example

Example 1

Click to collapse [-]
Server

This example allows a player to add a custom tag onto their nickname, and also reverts it back to normal if they wish.

function addPlayerCustomTag ( thePlayer, command, newTag )
	--Let's make sure the newTag param has been entered...
	if ( newTag ) then
		--Grab their current playername for saving.
		local sPlayerNickname = getPlayerName ( thePlayer )
		--Create their new nickname with their tag
		local sNewPlayerNickname = newTag .. " " .. sPlayerNickname
		
		--Let's first load the element data, see if it's there already
		--The reason for this is that if a player were to do /addtag twice,
		--the tag would be prepended a second time
		local sOldNick = getElementData( thePlayer, "tempdata.originalnick" )
		if ( sOldNick == false ) then
			--Save their orignal nickname in their element data
			setElementData ( thePlayer, "tempdata.originalnick", sPlayerNickname )
		end
		
		--Set their new nickname globally
		setPlayerName ( thePlayer, sNewPlayerNickname )
		
		--Tell them it's done
		outputChatBox ( "Your new nickname has been set, to put it back to its original state you can use /deltag", thePlayer )
	else
		--The newTag param was not entered, give an error message
		outputChatBox ( "/addtag - Incorrect syntax, Correct: /addtag <newtag>", thePlayer )
	end
end
addCommandHandler ( "addtag", addPlayerCustomTag )

function removePlayerCustomTag ( thePlayer, command )
	--We first need to check that they have already used /addtag, let's do that now
	local sOldNick = getElementData( thePlayer, "tempdata.originalnick" )
	if ( sOldNick ) then
		--Great, they have a tag added, let's reset them
		
		--First we will want to reset the element data back to its default (that being false)
		setElementData ( thePlayer, "tempdata.originalnick", false )
		
		--Now set the client name back
		setPlayerName( thePlayer, sOldNick )
		
		--Notify them
		outputChatBox ( "Your old nickname has been set", thePlayer )
	end
end
addCommandHandler ( "deltag", removePlayerCustomTag )

See Also