<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Srslyyyy</id>
	<title>Multi Theft Auto: Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Srslyyyy"/>
	<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/wiki/Special:Contributions/Srslyyyy"/>
	<updated>2026-04-24T09:41:32Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=HasObjectPermissionTo&amp;diff=82417</id>
		<title>HasObjectPermissionTo</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=HasObjectPermissionTo&amp;diff=82417"/>
		<updated>2025-08-25T11:54:19Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Server function}}&lt;br /&gt;
This function returns whether or not the given object has access to perform the given action. &lt;br /&gt;
{{Note|Only certain action names work. This function seems to return ''nil'' and output a bad argument error when checking if an object has rights for an action which doesn't start with ''function.'', ''command.'' or ''resource.'' keywords.}}&lt;br /&gt;
&lt;br /&gt;
Scripts frequently wish to limit access to features to particular users. The naive way to do this would be to check if the player who is attempting to perform an action is in a particular group (usually the Admin group). The main issue with doing this is that the Admin group is not guaranteed to exist. It also doesn't give the server admin any flexibility. He might want to allow his 'moderators' access to the function you're limiting access to, or he may want it disabled entirely. &lt;br /&gt;
&lt;br /&gt;
This is where using the ACL properly comes in, and luckily this is very easy. It all comes down to using this function. This, somewhat confusingly named function lets you check if an ACL object (a player or a resource) has a particular ACL right. In this case, we just care about players.&lt;br /&gt;
&lt;br /&gt;
So, first of all, think of a name for your 'right'. Let's say we want a private area only certain people can go in, we'll call our right accessPrivateArea. Then, all you need to do is add one 'if' statement to your code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;if hasObjectPermissionTo ( player, &amp;quot;resource.YourResourceName.accessPrivateArea&amp;quot;, false ) then&lt;br /&gt;
-- Whatever you want to happen if they're allowed in&lt;br /&gt;
else&lt;br /&gt;
-- Whatever you want to happen if they aren't&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that we've named the ''right'' using ''resource.YourResourceName.accessPrivateArea'' - this is just for neatness, so that the admin knows what resource the right belongs to. It's strongly advised you follow this convention. The ''false'' argument specifies the 'defaultPermission', false indicating that if the user hasn't had the right allowed or dissallowed (i.e. the admin hasn't added it to the config), that it should default to being not allowed.&lt;br /&gt;
&lt;br /&gt;
The only downside of using this method is that the admin has to modify his config. The upsides are that the admin has much more control and your script will work for any server, however the admin has configured it.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
{{New feature/item|3.0162|1.7.0|25445|&lt;br /&gt;
'''defaultPermission''' argument now defaults to '''false'''. If third argument is '''nil'''/'''false''' (or not specified), then action (unless explicitly allowed in '''ACL''') won't be processed due to missing rights. May affect the normal operation of existing scripts.&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool hasObjectPermissionTo ( string / element theObject, string theAction [, bool defaultPermission = true/false ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;!-- Yes! This is actually correct this time ^^ notice theObject can be a string! --&amp;gt;&lt;br /&gt;
{{OOP|This function is also a static function underneath the ACL class.|[[ACL]].hasObjectPermissionTo||}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''theObject:''' The object to test if has permission to. This can be a client element (ie. a player), a resource or a string in the form &amp;quot;user.&amp;lt;name&amp;gt;&amp;quot; or &amp;quot;resource.&amp;lt;name&amp;gt;&amp;quot;.&lt;br /&gt;
*'''theAction:''' The action to test if the given object has access to. Ie. &amp;quot;function.kickPlayer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
{{OptionalArg}} &lt;br /&gt;
*'''defaultPermission:''' The default permission if none is specified in either of the groups the given object is a member of. If this is left to true, the given object will have permissions to perform the action unless the opposite is explicitly specified in the [[ACL]]. If false, the action will be denied by default unless explicitly approved by the [[Access Control List]].&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the given object has permission to perform the given action, ''false'' otherwise. Returns ''nil'' if the function failed because of bad arguments.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example kicks a player if the user using it has access to the kickPlayer function.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- Kick command&lt;br /&gt;
function onKickCommandHandler ( playerSource, commandName, playerToKick, stringReason )&lt;br /&gt;
    -- Does the calling user have permission to kick the player? Default&lt;br /&gt;
    -- to false for safety reasons. We do this so any user can't use us to&lt;br /&gt;
    -- kick players.&lt;br /&gt;
    if ( hasObjectPermissionTo ( playerSource, &amp;quot;function.kickPlayer&amp;quot;, false ) ) then&lt;br /&gt;
&lt;br /&gt;
        -- Do we have permission to kick the player? We do this so we can fail&lt;br /&gt;
        -- nicely if this resource doesn't have access to call that function.&lt;br /&gt;
        if ( hasObjectPermissionTo ( resource, &amp;quot;function.kickPlayer&amp;quot;, true ) ) then&lt;br /&gt;
            -- Kick him&lt;br /&gt;
            kickPlayer ( playerToKick, playerSource, stringReason )&lt;br /&gt;
        else&lt;br /&gt;
            -- Resource doesn't have any permissions, sorry&lt;br /&gt;
            outputChatBox ( &amp;quot;kick: The admin resource is not able to kick players. Please give this resource access to 'function.kickPlayer' in the ACL to use this function.&amp;quot;, playerSource )&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        -- User doesn't have any permissions&lt;br /&gt;
        outputChatBox ( &amp;quot;kick: You don't have permissions to use this command.&amp;quot;, playerSource )&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler ( &amp;quot;kick&amp;quot;, onKickCommandHandler )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&amp;lt;!-- Change FunctionArea to the area that this function is in on the main function list page, e.g. Server, Player, Vehicle etc --&amp;gt;&lt;br /&gt;
{{ACL_functions}}&lt;br /&gt;
[[zh-cn:hasObjectPermissionTo]]&lt;br /&gt;
[[pt-br:hasObjectPermissionTo]]&lt;br /&gt;
[[ru:hasObjectPermissionTo]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Ped_move_states&amp;diff=82362</id>
		<title>Template:Ped move states</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Ped_move_states&amp;diff=82362"/>
		<updated>2025-08-10T01:55:47Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Adjust to PR #4350 (https://github.com/multitheftauto/mtasa-blue/pull/4350) by FileEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border:3px solid red;margin-bottom:3px;padding-left:5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;float:right;padding-right:5px;font-weight:bold;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
* '''stand''': The ped is standing still.&lt;br /&gt;
* '''walk''': The ped is walking.&lt;br /&gt;
* '''powerwalk''': The ped is walking quickly.&lt;br /&gt;
* '''jog''': The ped is jogging.&lt;br /&gt;
* '''sprint''': The ped is sprinting.&lt;br /&gt;
* '''crouch''': The ped is crouching still.&lt;br /&gt;
* '''crawl''': The ped is crawling (moving and ducked).&lt;br /&gt;
* '''jump''': The ped is jumping into the air.&lt;br /&gt;
* '''fall''': The ped is falling to the ground.&lt;br /&gt;
* '''climb''': The ped is climbing onto an object.&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''swim:''' The ped is swimming.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''walk_to_point:''' The ped is walking to a vehicle door.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''ascent_jetpack:''' The ped is ascending with jetpack.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''descent_jetpack:''' The ped is descending with jetpack.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''jetpack_flying:''' The ped is flying with jetpack.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''roll:''' The ped is rolling.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25371|'''hanging:''' The ped is hanging onto a wall.}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Ped_move_states&amp;diff=82361</id>
		<title>Template:Ped move states</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Ped_move_states&amp;diff=82361"/>
		<updated>2025-08-10T01:51:59Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Adjust to PR #4316 (https://github.com/multitheftauto/mtasa-blue/pull/4316) by FileEX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border:3px solid red;margin-bottom:3px;padding-left:5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;float:right;padding-right:5px;font-weight:bold;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
* '''stand''': The ped is standing still.&lt;br /&gt;
* '''walk''': The ped is walking.&lt;br /&gt;
* '''powerwalk''': The ped is walking quickly.&lt;br /&gt;
* '''jog''': The ped is jogging.&lt;br /&gt;
* '''sprint''': The ped is sprinting.&lt;br /&gt;
* '''crouch''': The ped is crouching still.&lt;br /&gt;
* '''crawl''': The ped is crawling (moving and ducked).&lt;br /&gt;
* '''jump''': The ped is jumping into the air.&lt;br /&gt;
* '''fall''': The ped is falling to the ground.&lt;br /&gt;
* '''climb''': The ped is climbing onto an object.&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''swim:''' The ped is swimming.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''walk_to_point:''' The ped is walking to a vehicle door.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''ascent_jetpack:''' The ped is ascending with jetpack.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''descent_jetpack:''' The ped is descending with jetpack.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''jetpack_flying:''' The ped is flying with jetpack.}}&lt;br /&gt;
{{New feature/item|3.0171|1.7.0|25351|'''roll:''' The ped is rolling.}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82295</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82295"/>
		<updated>2025-07-25T18:27:59Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|This function omits (but doesn't override) the user game option in '''''Settings -&amp;gt; Video -&amp;gt; FOV'''''}}&lt;br /&gt;
{{Note|It doesn't affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView [, bool instant = false ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to set the field of view of:&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
&lt;br /&gt;
===Optional arguments===&lt;br /&gt;
{{OptionalArg}}&lt;br /&gt;
{{New feature/item|3.0161|1.6.0|23300|&lt;br /&gt;
*'''instant''': If set to ''true'', the value is applied immediately, without delay (does not work with &amp;quot;vehicle_max&amp;quot;).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' camera is set to 20, once resource fully starts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function changeCameraFovOnClientResourceStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;, 20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, changeCameraFovOnClientResourceStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=CreateEffect&amp;diff=82252</id>
		<title>CreateEffect</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=CreateEffect&amp;diff=82252"/>
		<updated>2025-07-21T19:58:52Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
{{New items|3.0140|1.4|&lt;br /&gt;
Creates an [[Element/Effect|effect]] on specified position.&lt;br /&gt;
}}&lt;br /&gt;
{{Note|Not all effects support rotation (e.g. the &amp;quot;fire&amp;quot; - effect doesn't).}}&lt;br /&gt;
{{Note|All effects have their own duration.}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;effect createEffect ( string name, float x, float y, float z [, float rX, float rY, float rZ, float drawDistance = 0, bool soundEnable = false ] )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[Effect]]}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''name:''' A string contains [[Element/Effect#Effects_list|effect name]].&lt;br /&gt;
*'''x:''' A floating point number representing the X coordinate on the map.&lt;br /&gt;
*'''y:''' A floating point number representing the Y coordinate on the map.&lt;br /&gt;
*'''z:''' A floating point number representing the Z coordinate on the map.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
{{OptionalArg}} &lt;br /&gt;
*'''rX:''' A floating point number representing the rotation about the X axis in degrees.&lt;br /&gt;
*'''rY:''' A floating point number representing the rotation about the Y axis in degrees.&lt;br /&gt;
*'''rZ:''' A floating point number representing the rotation about the Z axis in degrees.&lt;br /&gt;
*'''drawDistance:''' A floating point number between 1 and 8191 which represents the draw distance of the effect, or 0 to use the default draw distance.&lt;br /&gt;
{{New feature/item|3.0155|1.5.5||&lt;br /&gt;
*'''soundEnable:''' to enable the sound of the effect.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Returns ===&lt;br /&gt;
Returns the [[Element/Effect|effect]] element if creation was successful, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example allows you to create effect by using 'B' key (use mouse scroll up/down to switch effect).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local effectSwitchUpKey = &amp;quot;mouse_wheel_up&amp;quot;&lt;br /&gt;
local effectSwitchDownKey = &amp;quot;mouse_wheel_down&amp;quot;&lt;br /&gt;
local effectCreateKey = &amp;quot;b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local effectNames = {&lt;br /&gt;
	&amp;quot;blood_heli&amp;quot;, &amp;quot;boat_prop&amp;quot;, &amp;quot;camflash&amp;quot;, &amp;quot;carwashspray&amp;quot;, &amp;quot;cement&amp;quot;, &amp;quot;cloudfast&amp;quot;, &amp;quot;coke_puff&amp;quot;, &amp;quot;coke_trail&amp;quot;, &amp;quot;cigarette_smoke&amp;quot;,&lt;br /&gt;
	&amp;quot;explosion_barrel&amp;quot;, &amp;quot;explosion_crate&amp;quot;, &amp;quot;explosion_door&amp;quot;, &amp;quot;exhale&amp;quot;, &amp;quot;explosion_fuel_car&amp;quot;, &amp;quot;explosion_large&amp;quot;, &amp;quot;explosion_medium&amp;quot;,&lt;br /&gt;
	&amp;quot;explosion_molotov&amp;quot;, &amp;quot;explosion_small&amp;quot;, &amp;quot;explosion_tiny&amp;quot;, &amp;quot;extinguisher&amp;quot;, &amp;quot;flame&amp;quot;, &amp;quot;fire&amp;quot;, &amp;quot;fire_med&amp;quot;, &amp;quot;fire_large&amp;quot;, &amp;quot;flamethrower&amp;quot;,&lt;br /&gt;
	&amp;quot;fire_bike&amp;quot;, &amp;quot;fire_car&amp;quot;, &amp;quot;gunflash&amp;quot;, &amp;quot;gunsmoke&amp;quot;, &amp;quot;insects&amp;quot;, &amp;quot;heli_dust&amp;quot;, &amp;quot;jetpack&amp;quot;, &amp;quot;jetthrust&amp;quot;, &amp;quot;nitro&amp;quot;, &amp;quot;molotov_flame&amp;quot;,&lt;br /&gt;
	&amp;quot;overheat_car&amp;quot;, &amp;quot;overheat_car_electric&amp;quot;, &amp;quot;prt_blood&amp;quot;, &amp;quot;prt_boatsplash&amp;quot;, &amp;quot;prt_bubble&amp;quot;, &amp;quot;prt_cardebris&amp;quot;, &amp;quot;prt_collisionsmoke&amp;quot;,&lt;br /&gt;
	&amp;quot;prt_glass&amp;quot;, &amp;quot;prt_gunshell&amp;quot;, &amp;quot;prt_sand&amp;quot;, &amp;quot;prt_sand2&amp;quot;, &amp;quot;prt_smokeII_3_expand&amp;quot;, &amp;quot;prt_smoke_huge&amp;quot;, &amp;quot;prt_spark&amp;quot;, &amp;quot;prt_spark_2&amp;quot;,&lt;br /&gt;
	&amp;quot;prt_splash&amp;quot;, &amp;quot;prt_wake&amp;quot;, &amp;quot;prt_watersplash&amp;quot;, &amp;quot;prt_wheeldirt&amp;quot;, &amp;quot;petrolcan&amp;quot;, &amp;quot;puke&amp;quot;, &amp;quot;riot_smoke&amp;quot;, &amp;quot;spraycan&amp;quot;, &amp;quot;smoke30lit&amp;quot;, &amp;quot;smoke30m&amp;quot;,&lt;br /&gt;
	&amp;quot;smoke50lit&amp;quot;, &amp;quot;shootlight&amp;quot;, &amp;quot;smoke_flare&amp;quot;, &amp;quot;tank_fire&amp;quot;, &amp;quot;teargas&amp;quot;, &amp;quot;teargasAD&amp;quot;, &amp;quot;tree_hit_fir&amp;quot;, &amp;quot;tree_hit_palm&amp;quot;, &amp;quot;vent&amp;quot;, &amp;quot;vent2&amp;quot;,&lt;br /&gt;
	&amp;quot;water_hydrant&amp;quot;, &amp;quot;water_ripples&amp;quot;, &amp;quot;water_speed&amp;quot;, &amp;quot;water_splash&amp;quot;, &amp;quot;water_splash_big&amp;quot;, &amp;quot;water_splsh_sml&amp;quot;, &amp;quot;water_swim&amp;quot;, &amp;quot;waterfall_end&amp;quot;,&lt;br /&gt;
	&amp;quot;water_fnt_tme&amp;quot;, &amp;quot;water_fountain&amp;quot;, &amp;quot;wallbust&amp;quot;, &amp;quot;WS_factorysmoke&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local effectID = 1&lt;br /&gt;
local effectName = effectNames[effectID]&lt;br /&gt;
local effectCount = (#effectNames) -- there are 82 effects&lt;br /&gt;
&lt;br /&gt;
outputChatBox(&amp;quot;Effect set to: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
&lt;br /&gt;
local function createEffectManually()&lt;br /&gt;
	local playerX, playerY, playerZ = getElementPosition(localPlayer)&lt;br /&gt;
	local effectX, effectY, effectZ = playerX, playerY, (playerZ + 2)&lt;br /&gt;
	local effectRX, effectRY, effectRZ = 0, 0, 0&lt;br /&gt;
	local effectDrawDistance = 300&lt;br /&gt;
	local effectSoundEnable = false&lt;br /&gt;
&lt;br /&gt;
	outputChatBox(&amp;quot;Created effect: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
	createEffect(effectName, effectX, effectY, effectZ, effectRX, effectRY, effectRZ, effectDrawDistance, effectSoundEnable)&lt;br /&gt;
end&lt;br /&gt;
bindKey(effectCreateKey, &amp;quot;down&amp;quot;, createEffectManually)&lt;br /&gt;
&lt;br /&gt;
local function switchEffect(keyName)&lt;br /&gt;
	local effectSwitchUp = (keyName == effectSwitchUpKey)&lt;br /&gt;
	local effectSwitchFactor = (effectSwitchUp and 1 or -1)&lt;br /&gt;
	local effectSwitchTempID = (effectID + effectSwitchFactor)&lt;br /&gt;
	local effectSwitchID = (effectSwitchTempID &amp;gt; effectCount and 1 or effectSwitchTempID &amp;lt; 1 and effectCount or effectSwitchTempID)&lt;br /&gt;
&lt;br /&gt;
	effectID = effectSwitchID&lt;br /&gt;
	effectName = effectNames[effectID]&lt;br /&gt;
&lt;br /&gt;
	outputChatBox(&amp;quot;Effect set to: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
end&lt;br /&gt;
bindKey(effectSwitchDownKey, &amp;quot;down&amp;quot;, switchEffect)&lt;br /&gt;
bindKey(effectSwitchUpKey, &amp;quot;down&amp;quot;, switchEffect)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
{{ChangelogHeader}}&lt;br /&gt;
{{ChangelogItem|1.4.0-9.06892|Added drawDistance argument}}&lt;br /&gt;
{{ChangelogItem|1.5.4-9.11631|Added soundEnable argument}}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
{{Client_Effects_functions}}&lt;br /&gt;
[[ru:createEffect]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=CreateEffect&amp;diff=82251</id>
		<title>CreateEffect</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=CreateEffect&amp;diff=82251"/>
		<updated>2025-07-21T19:57:43Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
{{New items|3.0140|1.4|&lt;br /&gt;
Creates an [[Element/Effect|effect]] on specified position.&lt;br /&gt;
}}&lt;br /&gt;
{{Note|Not all effects support rotation (e.g. the &amp;quot;fire&amp;quot; - effect doesn't).}}&lt;br /&gt;
{{Note|All effects have their own duration.}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;effect createEffect ( string name, float x, float y, float z [, float rX, float rY, float rZ, float drawDistance = 0, bool soundEnable = false ] )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[Effect]]}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''name:''' A string contains [[Element/Effect#Effects_list|effect name]].&lt;br /&gt;
*'''x:''' A floating point number representing the X coordinate on the map.&lt;br /&gt;
*'''y:''' A floating point number representing the Y coordinate on the map.&lt;br /&gt;
*'''z:''' A floating point number representing the Z coordinate on the map.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
{{OptionalArg}} &lt;br /&gt;
*'''rX:''' A floating point number representing the rotation about the X axis in degrees.&lt;br /&gt;
*'''rY:''' A floating point number representing the rotation about the Y axis in degrees.&lt;br /&gt;
*'''rZ:''' A floating point number representing the rotation about the Z axis in degrees.&lt;br /&gt;
*'''drawDistance:''' A floating point number between 1 and 8191 which represents the draw distance of the effect, or 0 to use the default draw distance.&lt;br /&gt;
{{New feature/item|3.0155|1.5.5||&lt;br /&gt;
*'''soundEnable:''' to enable the sound of the effect.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Returns ===&lt;br /&gt;
Returns the [[Element/Effect|effect]] element if creation was successful, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example allows you to create effect by 'B' key (use mouse scroll up/down to switch effect).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local effectSwitchUpKey = &amp;quot;mouse_wheel_up&amp;quot;&lt;br /&gt;
local effectSwitchDownKey = &amp;quot;mouse_wheel_down&amp;quot;&lt;br /&gt;
local effectCreateKey = &amp;quot;b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local effectNames = {&lt;br /&gt;
	&amp;quot;blood_heli&amp;quot;, &amp;quot;boat_prop&amp;quot;, &amp;quot;camflash&amp;quot;, &amp;quot;carwashspray&amp;quot;, &amp;quot;cement&amp;quot;, &amp;quot;cloudfast&amp;quot;, &amp;quot;coke_puff&amp;quot;, &amp;quot;coke_trail&amp;quot;, &amp;quot;cigarette_smoke&amp;quot;,&lt;br /&gt;
	&amp;quot;explosion_barrel&amp;quot;, &amp;quot;explosion_crate&amp;quot;, &amp;quot;explosion_door&amp;quot;, &amp;quot;exhale&amp;quot;, &amp;quot;explosion_fuel_car&amp;quot;, &amp;quot;explosion_large&amp;quot;, &amp;quot;explosion_medium&amp;quot;,&lt;br /&gt;
	&amp;quot;explosion_molotov&amp;quot;, &amp;quot;explosion_small&amp;quot;, &amp;quot;explosion_tiny&amp;quot;, &amp;quot;extinguisher&amp;quot;, &amp;quot;flame&amp;quot;, &amp;quot;fire&amp;quot;, &amp;quot;fire_med&amp;quot;, &amp;quot;fire_large&amp;quot;, &amp;quot;flamethrower&amp;quot;,&lt;br /&gt;
	&amp;quot;fire_bike&amp;quot;, &amp;quot;fire_car&amp;quot;, &amp;quot;gunflash&amp;quot;, &amp;quot;gunsmoke&amp;quot;, &amp;quot;insects&amp;quot;, &amp;quot;heli_dust&amp;quot;, &amp;quot;jetpack&amp;quot;, &amp;quot;jetthrust&amp;quot;, &amp;quot;nitro&amp;quot;, &amp;quot;molotov_flame&amp;quot;,&lt;br /&gt;
	&amp;quot;overheat_car&amp;quot;, &amp;quot;overheat_car_electric&amp;quot;, &amp;quot;prt_blood&amp;quot;, &amp;quot;prt_boatsplash&amp;quot;, &amp;quot;prt_bubble&amp;quot;, &amp;quot;prt_cardebris&amp;quot;, &amp;quot;prt_collisionsmoke&amp;quot;,&lt;br /&gt;
	&amp;quot;prt_glass&amp;quot;, &amp;quot;prt_gunshell&amp;quot;, &amp;quot;prt_sand&amp;quot;, &amp;quot;prt_sand2&amp;quot;, &amp;quot;prt_smokeII_3_expand&amp;quot;, &amp;quot;prt_smoke_huge&amp;quot;, &amp;quot;prt_spark&amp;quot;, &amp;quot;prt_spark_2&amp;quot;,&lt;br /&gt;
	&amp;quot;prt_splash&amp;quot;, &amp;quot;prt_wake&amp;quot;, &amp;quot;prt_watersplash&amp;quot;, &amp;quot;prt_wheeldirt&amp;quot;, &amp;quot;petrolcan&amp;quot;, &amp;quot;puke&amp;quot;, &amp;quot;riot_smoke&amp;quot;, &amp;quot;spraycan&amp;quot;, &amp;quot;smoke30lit&amp;quot;, &amp;quot;smoke30m&amp;quot;,&lt;br /&gt;
	&amp;quot;smoke50lit&amp;quot;, &amp;quot;shootlight&amp;quot;, &amp;quot;smoke_flare&amp;quot;, &amp;quot;tank_fire&amp;quot;, &amp;quot;teargas&amp;quot;, &amp;quot;teargasAD&amp;quot;, &amp;quot;tree_hit_fir&amp;quot;, &amp;quot;tree_hit_palm&amp;quot;, &amp;quot;vent&amp;quot;, &amp;quot;vent2&amp;quot;,&lt;br /&gt;
	&amp;quot;water_hydrant&amp;quot;, &amp;quot;water_ripples&amp;quot;, &amp;quot;water_speed&amp;quot;, &amp;quot;water_splash&amp;quot;, &amp;quot;water_splash_big&amp;quot;, &amp;quot;water_splsh_sml&amp;quot;, &amp;quot;water_swim&amp;quot;, &amp;quot;waterfall_end&amp;quot;,&lt;br /&gt;
	&amp;quot;water_fnt_tme&amp;quot;, &amp;quot;water_fountain&amp;quot;, &amp;quot;wallbust&amp;quot;, &amp;quot;WS_factorysmoke&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local effectID = 1&lt;br /&gt;
local effectName = effectNames[effectID]&lt;br /&gt;
local effectCount = (#effectNames) -- there are 82 effects&lt;br /&gt;
&lt;br /&gt;
outputChatBox(&amp;quot;Effect set to: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
&lt;br /&gt;
local function createEffectManually()&lt;br /&gt;
	local playerX, playerY, playerZ = getElementPosition(localPlayer)&lt;br /&gt;
	local effectX, effectY, effectZ = playerX, playerY, (playerZ + 2)&lt;br /&gt;
	local effectRX, effectRY, effectRZ = 0, 0, 0&lt;br /&gt;
	local effectDrawDistance = 300&lt;br /&gt;
	local effectSoundEnable = false&lt;br /&gt;
&lt;br /&gt;
	outputChatBox(&amp;quot;Created effect: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
	createEffect(effectName, effectX, effectY, effectZ, effectRX, effectRY, effectRZ, effectDrawDistance, effectSoundEnable)&lt;br /&gt;
end&lt;br /&gt;
bindKey(effectCreateKey, &amp;quot;down&amp;quot;, createEffectManually)&lt;br /&gt;
&lt;br /&gt;
local function switchEffect(keyName)&lt;br /&gt;
	local effectSwitchUp = (keyName == effectSwitchUpKey)&lt;br /&gt;
	local effectSwitchFactor = (effectSwitchUp and 1 or -1)&lt;br /&gt;
	local effectSwitchTempID = (effectID + effectSwitchFactor)&lt;br /&gt;
	local effectSwitchID = (effectSwitchTempID &amp;gt; effectCount and 1 or effectSwitchTempID &amp;lt; 1 and effectCount or effectSwitchTempID)&lt;br /&gt;
&lt;br /&gt;
	effectID = effectSwitchID&lt;br /&gt;
	effectName = effectNames[effectID]&lt;br /&gt;
&lt;br /&gt;
	outputChatBox(&amp;quot;Effect set to: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
end&lt;br /&gt;
bindKey(effectSwitchDownKey, &amp;quot;down&amp;quot;, switchEffect)&lt;br /&gt;
bindKey(effectSwitchUpKey, &amp;quot;down&amp;quot;, switchEffect)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
{{ChangelogHeader}}&lt;br /&gt;
{{ChangelogItem|1.4.0-9.06892|Added drawDistance argument}}&lt;br /&gt;
{{ChangelogItem|1.5.4-9.11631|Added soundEnable argument}}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
{{Client_Effects_functions}}&lt;br /&gt;
[[ru:createEffect]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=CreateEffect&amp;diff=82250</id>
		<title>CreateEffect</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=CreateEffect&amp;diff=82250"/>
		<updated>2025-07-21T19:55:47Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Better example to preview effects&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
{{New items|3.0140|1.4|&lt;br /&gt;
Creates an [[Element/Effect|effect]] on specified position.&lt;br /&gt;
}}&lt;br /&gt;
{{Note|Not all effects support rotation (e.g. the &amp;quot;fire&amp;quot; - effect doesn't).}}&lt;br /&gt;
{{Note|All effects have their own duration.}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;effect createEffect ( string name, float x, float y, float z [, float rX, float rY, float rZ, float drawDistance = 0, bool soundEnable = false ] )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[Effect]]}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''name:''' A string contains [[Element/Effect#Effects_list|effect name]].&lt;br /&gt;
*'''x:''' A floating point number representing the X coordinate on the map.&lt;br /&gt;
*'''y:''' A floating point number representing the Y coordinate on the map.&lt;br /&gt;
*'''z:''' A floating point number representing the Z coordinate on the map.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
{{OptionalArg}} &lt;br /&gt;
*'''rX:''' A floating point number representing the rotation about the X axis in degrees.&lt;br /&gt;
*'''rY:''' A floating point number representing the rotation about the Y axis in degrees.&lt;br /&gt;
*'''rZ:''' A floating point number representing the rotation about the Z axis in degrees.&lt;br /&gt;
*'''drawDistance:''' A floating point number between 1 and 8191 which represents the draw distance of the effect, or 0 to use the default draw distance.&lt;br /&gt;
{{New feature/item|3.0155|1.5.5||&lt;br /&gt;
*'''soundEnable:''' to enable the sound of the effect.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Returns ===&lt;br /&gt;
Returns the [[Element/Effect|effect]] element if creation was successful, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example allows you to create effect by 'B' key (use mouse scroll up/down to switch effect).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local effectSwitchUpKey = &amp;quot;mouse_wheel_up&amp;quot;&lt;br /&gt;
local effectSwitchDownKey = &amp;quot;mouse_wheel_down&amp;quot;&lt;br /&gt;
local effectCreateKey = &amp;quot;b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local effectNames = {&lt;br /&gt;
	&amp;quot;blood_heli&amp;quot;, &amp;quot;boat_prop&amp;quot;, &amp;quot;camflash&amp;quot;, &amp;quot;carwashspray&amp;quot;, &amp;quot;cement&amp;quot;, &amp;quot;cloudfast&amp;quot;, &amp;quot;coke_puff&amp;quot;, &amp;quot;coke_trail&amp;quot;, &amp;quot;cigarette_smoke&amp;quot;,&lt;br /&gt;
	&amp;quot;explosion_barrel&amp;quot;, &amp;quot;explosion_crate&amp;quot;, &amp;quot;explosion_door&amp;quot;, &amp;quot;exhale&amp;quot;, &amp;quot;explosion_fuel_car&amp;quot;, &amp;quot;explosion_large&amp;quot;, &amp;quot;explosion_medium&amp;quot;,&lt;br /&gt;
	&amp;quot;explosion_molotov&amp;quot;, &amp;quot;explosion_small&amp;quot;, &amp;quot;explosion_tiny&amp;quot;, &amp;quot;extinguisher&amp;quot;, &amp;quot;flame&amp;quot;, &amp;quot;fire&amp;quot;, &amp;quot;fire_med&amp;quot;, &amp;quot;fire_large&amp;quot;, &amp;quot;flamethrower&amp;quot;,&lt;br /&gt;
	&amp;quot;fire_bike&amp;quot;, &amp;quot;fire_car&amp;quot;, &amp;quot;gunflash&amp;quot;, &amp;quot;gunsmoke&amp;quot;, &amp;quot;insects&amp;quot;, &amp;quot;heli_dust&amp;quot;, &amp;quot;jetpack&amp;quot;, &amp;quot;jetthrust&amp;quot;, &amp;quot;nitro&amp;quot;, &amp;quot;molotov_flame&amp;quot;,&lt;br /&gt;
	&amp;quot;overheat_car&amp;quot;, &amp;quot;overheat_car_electric&amp;quot;, &amp;quot;prt_blood&amp;quot;, &amp;quot;prt_boatsplash&amp;quot;, &amp;quot;prt_bubble&amp;quot;, &amp;quot;prt_cardebris&amp;quot;, &amp;quot;prt_collisionsmoke&amp;quot;,&lt;br /&gt;
	&amp;quot;prt_glass&amp;quot;, &amp;quot;prt_gunshell&amp;quot;, &amp;quot;prt_sand&amp;quot;, &amp;quot;prt_sand2&amp;quot;, &amp;quot;prt_smokeII_3_expand&amp;quot;, &amp;quot;prt_smoke_huge&amp;quot;, &amp;quot;prt_spark&amp;quot;, &amp;quot;prt_spark_2&amp;quot;,&lt;br /&gt;
	&amp;quot;prt_splash&amp;quot;, &amp;quot;prt_wake&amp;quot;, &amp;quot;prt_watersplash&amp;quot;, &amp;quot;prt_wheeldirt&amp;quot;, &amp;quot;petrolcan&amp;quot;, &amp;quot;puke&amp;quot;, &amp;quot;riot_smoke&amp;quot;, &amp;quot;spraycan&amp;quot;, &amp;quot;smoke30lit&amp;quot;, &amp;quot;smoke30m&amp;quot;,&lt;br /&gt;
	&amp;quot;smoke50lit&amp;quot;, &amp;quot;shootlight&amp;quot;, &amp;quot;smoke_flare&amp;quot;, &amp;quot;tank_fire&amp;quot;, &amp;quot;teargas&amp;quot;, &amp;quot;teargasAD&amp;quot;, &amp;quot;tree_hit_fir&amp;quot;, &amp;quot;tree_hit_palm&amp;quot;, &amp;quot;vent&amp;quot;, &amp;quot;vent2&amp;quot;,&lt;br /&gt;
	&amp;quot;water_hydrant&amp;quot;, &amp;quot;water_ripples&amp;quot;, &amp;quot;water_speed&amp;quot;, &amp;quot;water_splash&amp;quot;, &amp;quot;water_splash_big&amp;quot;, &amp;quot;water_splsh_sml&amp;quot;, &amp;quot;water_swim&amp;quot;, &amp;quot;waterfall_end&amp;quot;,&lt;br /&gt;
	&amp;quot;water_fnt_tme&amp;quot;, &amp;quot;water_fountain&amp;quot;, &amp;quot;wallbust&amp;quot;, &amp;quot;WS_factorysmoke&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local effectID = 1&lt;br /&gt;
local effectName = effectNames[effectID]&lt;br /&gt;
local effectCount = (#effectNames) -- there are 82 effects&lt;br /&gt;
&lt;br /&gt;
outputChatBox(&amp;quot;Effect set to: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
&lt;br /&gt;
local function createEffectManually()&lt;br /&gt;
	local effectX, effectY, effectZ = getElementPosition(localPlayer)&lt;br /&gt;
	local effectRX, effectRY, effectRZ = 0, 0, 0&lt;br /&gt;
	local effectDrawDistance = 300&lt;br /&gt;
	local effectSoundEnable = false&lt;br /&gt;
&lt;br /&gt;
	outputChatBox(&amp;quot;Created effect: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
	createEffect(effectName, effectX, effectY, effectZ, effectRX, effectRY, effectRZ, effectDrawDistance, effectSoundEnable)&lt;br /&gt;
end&lt;br /&gt;
bindKey(effectCreateKey, &amp;quot;down&amp;quot;, createEffectManually)&lt;br /&gt;
&lt;br /&gt;
local function switchEffect(keyName)&lt;br /&gt;
	local effectSwitchUp = (keyName == effectSwitchUpKey)&lt;br /&gt;
	local effectSwitchFactor = (effectSwitchUp and 1 or -1)&lt;br /&gt;
	local effectSwitchTempID = (effectID + effectSwitchFactor)&lt;br /&gt;
	local effectSwitchID = (effectSwitchTempID &amp;gt; effectCount and 1 or effectSwitchTempID &amp;lt; 1 and effectCount or effectSwitchTempID)&lt;br /&gt;
&lt;br /&gt;
	effectID = effectSwitchID&lt;br /&gt;
	effectName = effectNames[effectID]&lt;br /&gt;
&lt;br /&gt;
	outputChatBox(&amp;quot;Effect set to: #ffa500&amp;quot;..effectName..&amp;quot;#ffffff (ID: #ffa500&amp;quot;..effectID..&amp;quot;#ffffff)&amp;quot;, 255, 255, 255, true)&lt;br /&gt;
end&lt;br /&gt;
bindKey(effectSwitchDownKey, &amp;quot;down&amp;quot;, switchEffect)&lt;br /&gt;
bindKey(effectSwitchUpKey, &amp;quot;down&amp;quot;, switchEffect)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
{{ChangelogHeader}}&lt;br /&gt;
{{ChangelogItem|1.4.0-9.06892|Added drawDistance argument}}&lt;br /&gt;
{{ChangelogItem|1.5.4-9.11631|Added soundEnable argument}}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
{{Client_Effects_functions}}&lt;br /&gt;
[[ru:createEffect]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=EngineSetModelLODDistance&amp;diff=82247</id>
		<title>EngineSetModelLODDistance</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=EngineSetModelLODDistance&amp;diff=82247"/>
		<updated>2025-07-20T19:37:51Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Replace to predefined variable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function sets a custom LOD distance for any object / model ID. This is the distance at which objects of that model ID are switched to their LOD model, or (if there is no LOD model) become invisible.&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
The actual draw distance used is modified by the draw distance slider in the settings 'Video' tab of the MTA client.&lt;br /&gt;
&lt;br /&gt;
*When the 'Video' tab draw distance slider is 0%, the engineSetModelLODDistance setting approximately matches the draw distance used.&lt;br /&gt;
:''e.g. engineSetModelLODDistance(1337,100) will mean model 1337 will be visible up to a distance of '''100''' units.''&lt;br /&gt;
&lt;br /&gt;
*When the 'Video' tab draw distance slider is 100%, the engineSetModelLODDistance setting is approximately doubled before use.&lt;br /&gt;
:''e.g. engineSetModelLODDistance(1337,100) will mean model 1337 will be visible up to a distance of '''200''' units.''&lt;br /&gt;
&lt;br /&gt;
However, there is a general draw distance limit of 325 units. So engineSetModelLODDistance(1337,400) will mean model 1337 will be visible up to a distance of 325 units no matter what the 'Video' tab says.&lt;br /&gt;
&lt;br /&gt;
Therefore, unless it's really important, engineSetModelLODDistance should not be set to anything greater than 170.&amp;lt;br&amp;gt;&lt;br /&gt;
170 will still give the maximum draw distance (of 325 units) on clients that have a 'Video' tab draw distance setting of 100%, and it will help reduce lag for players who chose a lower draw distance in their settings.&lt;br /&gt;
&lt;br /&gt;
'''Note for low LOD [[object]]s''':&lt;br /&gt;
*The limit is 325 units, but the actual draw distance used is 5 times the setting value. Also, they ignore the 'Video' tab draw distance slider. So a setting of 200 will mean a low LOD element will always have a draw distance of '''1000''' units.&lt;br /&gt;
&lt;br /&gt;
'''Note for low LOD [[building]]s''':&lt;br /&gt;
*The distance must be set greater than 300 for a low LOD building in order to work correctly. Otherwise, the low LOD will always be visible. The actual draw distance is NOT 5 times the setting value.&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool engineSetModelLODDistance ( int model, float distance [, bool extendedLod = false ] ) &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{OOP||Engine.setModelLODDistance}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''model:''' The model / object ID number you want to change the LOD distance of.&lt;br /&gt;
*'''distance:''' New LOD distance value in San Andreas units.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments===&lt;br /&gt;
{{OptionalArg}}&lt;br /&gt;
{{New feature/item|3.0161|1.6.0|22676|&lt;br /&gt;
*'''extendedLod:''' Allows to set a greater distance than the current 325 units.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the function executed succesfully, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example will set the LOD distance of all objects.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- Client-side&lt;br /&gt;
-- WARNING: Can cause significant lag.&lt;br /&gt;
&lt;br /&gt;
-- Adjusts LOD for all objects.&lt;br /&gt;
function setAllObjectsLOD()&lt;br /&gt;
&lt;br /&gt;
    -- Get all current objects.&lt;br /&gt;
    local objects = getElementsByType(&amp;quot;object&amp;quot;, root, false)&lt;br /&gt;
&lt;br /&gt;
    for _, theObject in ipairs(objects) do&lt;br /&gt;
&lt;br /&gt;
        local modelID = getElementModel(theObject)&lt;br /&gt;
        local lodLevel = 325 -- Distance value&lt;br /&gt;
&lt;br /&gt;
        -- Set LOD for this model ID.&lt;br /&gt;
        -- The 'true' enables extended range.&lt;br /&gt;
        engineSetModelLODDistance(modelID, lodLevel, true)&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Command to run the function.&lt;br /&gt;
addCommandHandler(&amp;quot;setAllObjectsLOD&amp;quot;, setAllObjectsLOD)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example will, besides replacing with custom map objects, also set the LOD distance accordingly, a necessary step (otherwise the object could seem to fail loading and only show up 1 feet away).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function replaceObjects()&lt;br /&gt;
&lt;br /&gt;
	local col1 = engineLoadCOL(&amp;quot;map1.col&amp;quot;)&lt;br /&gt;
	local col2 = engineLoadCOL(&amp;quot;map2.col&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local txd = engineLoadTXD(&amp;quot;map.txd&amp;quot;)&lt;br /&gt;
	engineImportTXD(txd, 2357)&lt;br /&gt;
	engineImportTXD(txd, 2290)&lt;br /&gt;
&lt;br /&gt;
	local dff1 = engineLoadDFF(&amp;quot;map1.dff&amp;quot;)&lt;br /&gt;
	local dff2 = engineLoadDFF(&amp;quot;map2.dff&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	engineReplaceCOL(col1, 2357)&lt;br /&gt;
	engineReplaceCOL(col2, 2290)&lt;br /&gt;
	engineReplaceModel(dff1, 2357)&lt;br /&gt;
	engineReplaceModel(dff2, 2290)&lt;br /&gt;
&lt;br /&gt;
	engineSetModelLODDistance(2357, 325)&lt;br /&gt;
	engineSetModelLODDistance(2290, 325)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows how to use LOD's with buildings.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function createMyPyramid()&lt;br /&gt;
    local pos = Vector3(0, 0, 3)&lt;br /&gt;
    local rot = Vector3(0, 0, 0)&lt;br /&gt;
    &lt;br /&gt;
    local modelHi = 8395  -- This model has a lot of polygons&lt;br /&gt;
    local modelLow = 8701 -- This model is optimized for drawing at a long distance&lt;br /&gt;
&lt;br /&gt;
    -- Always call this function if you don't like default draw distance&lt;br /&gt;
    -- or you allocated the model with using engineRequestModel&lt;br /&gt;
    engineSetModelLODDistance(modelHi, 100, true)&lt;br /&gt;
    engineSetModelLODDistance(modelLow, 500, true)&lt;br /&gt;
&lt;br /&gt;
    local lod = createBuilding(modelLow, pos, rot)&lt;br /&gt;
    local building = createBuilding(modelHi, pos, rot)&lt;br /&gt;
&lt;br /&gt;
    setLowLODElement(building,lod)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
{{ChangelogHeader}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22676|Added extendedLod argument}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* [[getVehiclesLODDistance]]&lt;br /&gt;
* [[resetVehiclesLODDistance]]&lt;br /&gt;
* [[setVehiclesLODDistance]]&lt;br /&gt;
{{Engine_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetPedTask&amp;diff=82244</id>
		<title>GetPedTask</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetPedTask&amp;diff=82244"/>
		<updated>2025-07-19T16:30:09Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function is used to get any simple or complex [[task]] of a certain type for a ped.&lt;br /&gt;
&lt;br /&gt;
It can provide feedback on all tasks relating to a ped. For example, while jumping, [[getPedSimplestTask]] will return TASK_SIMPLE_IN_AIR. If you wanted to know specifically if the player has jumped, you would use this function. If you did you will discover that while jumping Primary task 3 is TASK_COMPLEX_JUMP.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
string, string, string, string getPedTask ( ped thePed, string priority, int taskType )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[ped]]:getTask}}&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''thePed''': The [[ped]] whose task you want to retrieve.&lt;br /&gt;
*'''priority''': A string determining which set of tasks you want to retrieve it from. This must be either &amp;quot;primary&amp;quot; or &amp;quot;secondary&amp;quot;.&lt;br /&gt;
*'''taskType''': An integer value representing the task type (or slot) you want to get the task from. Types can be:&lt;br /&gt;
**'''PRIMARY TASKS'''&lt;br /&gt;
***'''0:''' TASK_PHYSICAL_RESPONSE&lt;br /&gt;
***'''1:''' TASK_EVENT_RESPONSE_TEMP&lt;br /&gt;
***'''2:''' TASK_EVENT_RESPONSE_NONTEMP&lt;br /&gt;
***'''3:''' TASK_PRIMARY&lt;br /&gt;
***'''4:''' TASK_DEFAULT&lt;br /&gt;
**'''SECONDARY TASKS'''&lt;br /&gt;
***'''0:''' TASK_SECONDARY_ATTACK&lt;br /&gt;
***'''1:''' TASK_SECONDARY_DUCK&lt;br /&gt;
***'''2:''' TASK_SECONDARY_SAY&lt;br /&gt;
***'''3:''' TASK_SECONDARY_FACIAL_COMPLEX&lt;br /&gt;
***'''4:''' TASK_SECONDARY_PARTIAL_ANIM&lt;br /&gt;
***'''5:''' TASK_SECONDARY_IK&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns the name of the most complex task. See [[list of player tasks]] for valid strings. Returns ''false'' if invalid arguments are specified or if there is no task of the type specified.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
{{New feature|3.0110|1.1|&lt;br /&gt;
Returns between 1 and 4 strings. The first string contains the name of the most complex task, with simpler sub-tasks being named in the following strings. See [[list of player tasks]] for valid strings. Returns ''false'' if invalid arguments are specified or if there is no task of the type specified.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example draws the active primary and secondary tasks (including task hierarchy in 1.1) as your local player moves around the world.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function renderPlayerTasks()&lt;br /&gt;
	local textX, textY = 100, 200&lt;br /&gt;
&lt;br /&gt;
	for taskType = 0, 4 do&lt;br /&gt;
		local a, b, c, d = getPedTask(localPlayer, &amp;quot;primary&amp;quot;, taskType)&lt;br /&gt;
&lt;br /&gt;
		dxDrawText(&amp;quot;Primary task #&amp;quot;..taskType..&amp;quot; is &amp;quot;..tostring(a)..&amp;quot; -&amp;gt; &amp;quot;..tostring(b)..&amp;quot; -&amp;gt; &amp;quot;..tostring(c)..&amp;quot; -&amp;gt; &amp;quot;..tostring(d)..&amp;quot; -&amp;gt; &amp;quot;, textX, textY)&lt;br /&gt;
&lt;br /&gt;
		textY = (textY + 15)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	textY = (textY + 15)&lt;br /&gt;
&lt;br /&gt;
	for taskType = 0, 5 do&lt;br /&gt;
		local a, b, c, d = getPedTask(localPlayer, &amp;quot;secondary&amp;quot;, taskType)&lt;br /&gt;
&lt;br /&gt;
		dxDrawText(&amp;quot;Secondary task #&amp;quot;..taskType..&amp;quot; is &amp;quot;..tostring(a)..&amp;quot; -&amp;gt; &amp;quot;..tostring(b)..&amp;quot; -&amp;gt; &amp;quot;..tostring(c)..&amp;quot; -&amp;gt; &amp;quot;..tostring(d)..&amp;quot; -&amp;gt; &amp;quot;, textX, textY)&lt;br /&gt;
&lt;br /&gt;
		textY = (textY + 15)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientRender&amp;quot;, root, renderPlayerTasks)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client_ped_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetWorldSpecialPropertyEnabled&amp;diff=82232</id>
		<title>SetWorldSpecialPropertyEnabled</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetWorldSpecialPropertyEnabled&amp;diff=82232"/>
		<updated>2025-07-15T07:30:24Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Shared function}}&lt;br /&gt;
&lt;br /&gt;
{{New feature/item|3.0161|1.6.0|22195|Added also as a server-side function. Previously only available as a client-side function.}}&lt;br /&gt;
&lt;br /&gt;
Enables or disables a special world property.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
It's recommended to use server-side function with appropriate [[mtaserver.conf#minclientversion|minclientversion]] for properties like &amp;quot;'''underworldwarp'''&amp;quot;, &amp;quot;'''burnflippedcars'''&amp;quot;, &amp;quot;'''extendedwatercannons'''&amp;quot;, &amp;quot;'''flyingcomponents'''&amp;quot;, &amp;quot;'''vehicle_engine_autostart'''&amp;quot; to avoid possible data desynchronization.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;bool setWorldSpecialPropertyEnabled ( string propname, bool enable )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||||isWorldSpecialPropertyEnabled}}&lt;br /&gt;
[[File:Randomfoliage.jpeg|frame|right|A photo demonstrating ''randomfoliage'' enabled and disabled.]]&lt;br /&gt;
[[File:Roadsignstext.png|frame|right|A photo demonstrating ''roadsignstext'' enabled and disabled.]]&lt;br /&gt;
[[File:Extendedwatercannons.png|frame|right|A photo demonstrating ''extendedwatercannons'' enabled and disabled.]]&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''propname:''' the name of the property to set. Possible values are:&lt;br /&gt;
**'''hovercars''' - equivalent of the JBGVNB cheat, and allows cars to drive on water. (default: false)&lt;br /&gt;
**'''aircars''' - equivalent of the RIPAZHA cheat, and allows cars to fly. (default: false)&lt;br /&gt;
**'''extrabunny''' - equivalent of the CJPHONEHOME or JHJOECW cheat, and allows you to bunny hop on bicycles much higher. (default: false)&lt;br /&gt;
**'''extrajump''' - equivalent of the KANGAROO cheat, and allows you to jump on foot much higher. (default: false)&lt;br /&gt;
**'''randomfoliage''' - toggle randomly generated foliage on the GTA:SA map (default: true)&lt;br /&gt;
**'''snipermoon''' - toggle the GTA:SA easter egg, which increases the size of the moon every time you shoot it with a sniper rifle (default: false)&lt;br /&gt;
**'''extraairresistance''' - toggle the vehicle speed limit on cross-country roads (default: true)&lt;br /&gt;
**{{New feature/item|3.0156|1.5.5|12286|'''underworldwarp''' - toggle warp of peds and vehicles when fall under map (default: true)}}&lt;br /&gt;
**{{New feature/item|3.0160|1.5.9|21125|'''vehiclesunglare''' - toggle the vehicle sun glare effect (default: false) }}&lt;br /&gt;
**{{New feature/item|3.0160|1.5.9|21313| '''coronaztest''' - disable big sun lensflare effect (default: true) }}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|21919| '''watercreatures''' - toggle randomly generated underwater creatures (default: true) }}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22195| '''burnflippedcars''' - toggle the vehicle to burn when upside down (default: true) }}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22199| '''fireballdestruct''' - toggle the aircraft model destruction on explosion ([[Media:FireballDestruct.jpg|preview]]) (default: true) }}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22430| '''roadsignstext''' - toggle the drawing of text on road signs. (default: true)}}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22485| '''extendedwatercannons''' - Increases the default limit of water cannons used at the same time from 3 to 30. (default: true)}}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22596| '''tunnelweatherblend''' - toggle the weather blending effect when the player is in the tunnel. (default: true)}}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22815| '''ignorefirestate''' - Allows aiming when the player is on fire and entering burning vehicles. (default: false)}}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|22909| '''flyingcomponents''' - This property determines whether the detached components such as doors, bumpers, etc., should respawn after a vehicle is recreated (change model or variant) or streamed in. (default: true)}}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|23223| '''vehicleburnexplosions''' - This property toggles creation of additional explosions ([[Explosion_types|type 2 - rocket]]) when plane or helicopter is burning. (default: true)}}&lt;br /&gt;
**{{New feature/item|3.0161|1.6.0|23237| '''vehicle_engine_autostart''' - This property toggles automatic vehicle engine state behavior. (default: true)&amp;lt;br&amp;gt;If you set it to ''false'' then vehicle engine will not start on driver enter and will not stop on driver exit. To control the engine you need to use [[SetVehicleEngineState|setVehicleEngineState]]. Helicopter rotors will spin only if the engine is on (with or without driver inside).}}&lt;br /&gt;
*'''enable:''' whether or not to enable the property.&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if successful, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
This code allows you to enable/disable certain property using '''true''' or '''false'''.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local worldSpecialProperties = {&lt;br /&gt;
	[&amp;quot;hovercars&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;aircars&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;extrabunny&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;extrajump&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;randomfoliage&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;snipermoon&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;extraairresistance&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;underworldwarp&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;vehiclesunglare&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;coronaztest&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;watercreatures&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;burnflippedcars&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;fireballdestruct&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;roadsignstext&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;extendedwatercannons&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;tunnelweatherblend&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;ignorefirestate&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;flyingcomponents&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;vehicleburnexplosions&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;vehicle_engine_autostart&amp;quot;] = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function toggleWorldSpecialProperties()&lt;br /&gt;
	for propertyName, propertyState in pairs(worldSpecialProperties) do&lt;br /&gt;
		setWorldSpecialPropertyEnabled(propertyName, propertyState)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, toggleWorldSpecialProperties)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Changelog==&lt;br /&gt;
{{ChangelogHeader}}&lt;br /&gt;
{{ChangelogItem|1.5.5-3.12286|Added &amp;quot;underworldwarp&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.5.9-1.21125|Added &amp;quot;vehiclesunglare&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.5.9-9.21313|Added &amp;quot;coronaztest&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.21919|Added &amp;quot;watercreatures&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22195|Added &amp;quot;burnflippedcars&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22199|Added &amp;quot;fireballdestruct&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22430|Added &amp;quot;roadsignstext&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22485|Added &amp;quot;extenedwatercannons&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22596|Added &amp;quot;tunnelweatherblend&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22815|Added &amp;quot;ignorefirestate&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.22909|Added &amp;quot;flyingcomponents&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.23223|Added &amp;quot;vehicleburnexplosions&amp;quot; property}}&lt;br /&gt;
{{ChangelogItem|1.6.0-9.23237|Added &amp;quot;vehicle_engine_autostart&amp;quot; property}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{World functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetGlitchEnabled&amp;diff=82231</id>
		<title>SetGlitchEnabled</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetGlitchEnabled&amp;diff=82231"/>
		<updated>2025-07-15T07:28:02Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server function}}&lt;br /&gt;
This function enables or disables glitches that are found in the original Single Player game that can be used to gain an advantage in multiplayer. &lt;br /&gt;
{{Note|By default all these glitches are disabled - use this function to '''enable''' them.}}&lt;br /&gt;
&lt;br /&gt;
Users of the '''fastmove''' glitch may additionally want to install [https://community.mtasa.com/index.php?p=resources&amp;amp;s=details&amp;amp;id=13368 this resource to disable crouchsliding]. &lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;bool setGlitchEnabled ( string glitchName, bool enable )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''glitchName:''' the name of the property to set. Possible values are:&lt;br /&gt;
{{Glitches}}&lt;br /&gt;
*'''enable:''' whether or not to enable the glitch.&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if successful, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example allows you to toggle specific glitch using '''true''' or '''false'''.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local glitchesData = {&lt;br /&gt;
	[&amp;quot;quickreload&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;fastmove&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;fastfire&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;crouchbug&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;highcloserangedamage&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;hitanim&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;fastsprint&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;baddrivebyhitbox&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;quickstand&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;kickoutofvehicle_onmodelreplace&amp;quot;] = false,&lt;br /&gt;
	[&amp;quot;vehicle_rapid_stop&amp;quot;] = false,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function toggleGlitches()&lt;br /&gt;
	for glitchName, glitchState in pairs(glitchesData) do&lt;br /&gt;
		setGlitchEnabled(glitchName, glitchState)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, resourceRoot, toggleGlitches)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Server functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Glitches&amp;diff=82230</id>
		<title>Template:Glitches</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Glitches&amp;diff=82230"/>
		<updated>2025-07-15T07:22:49Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Adjust to https://github.com/multitheftauto/mtasa-blue/pull/4243&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border:3px solid red;margin-bottom:3px;padding-left:5px;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;float:right;padding-right:5px;font-weight:bold;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
*'''quickreload:''' This is the glitch where switching weapons auto-reloads your weapon, without actually performing the reload animation.&lt;br /&gt;
*'''fastmove:''' This is the glitch that can be achieved by a certain key combinations whilst standing up after crouching, which allows you to move quickly with slow weapons (e.g. deagle). Side effect: also enables the &amp;quot;crouchslide&amp;quot; bug - use [https://community.mtasa.com/index.php?p=resources&amp;amp;s=details&amp;amp;id=13368 the &amp;quot;NoCrouchSlide&amp;quot; resource] to remedy this.&lt;br /&gt;
*'''fastfire:''' This is the glitch that can be achieved by cancelling the full fire animation, allowing you to shoot with slow-fire weapons (e.g. deagle) much faster.&lt;br /&gt;
*'''crouchbug:''' This is the glitch where the post shooting animation can be aborted by using the crouch key.&lt;br /&gt;
*'''highcloserangedamage:''' Enabling this removes the extremely high damage guns inflict when fired at very close range.&lt;br /&gt;
*'''hitanim:''' Enabling this allows 'hit by bullet' animations to interrupt player aiming.&lt;br /&gt;
*'''fastsprint:''' Enabling fastsprint allows players to tap space with a macro to boost their speed beyond normal speeds of GTASA.&lt;br /&gt;
*'''baddrivebyhitbox:''' This glitch leaves players invulnerable to gun fire when performing certain driveby animations.&lt;br /&gt;
*'''quickstand:''' This glitch allows players to quickly stand up by pressing the crouch, sprint or jump controls just after releasing the aim weapon button while using one and being ducked.&lt;br /&gt;
*'''kickoutofvehicle_onmodelreplace:''' This glitch enables the old behavior where players get warped out of a vehicle when the model is replaced.&lt;br /&gt;
*{{New feature/item|3.0161|1.6.0|23281|'''vehicle_rapid_stop:''' This glitch enables the old behavior of vehicles (pre-high FPS fix, see PR: [https://github.com/multitheftauto/mtasa-blue/pull/4243 #4243] &amp;amp; [https://github.com/multitheftauto/mtasa-blue/pull/2784 #2784])}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnPlayerTriggerEventThreshold&amp;diff=82229</id>
		<title>OnPlayerTriggerEventThreshold</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnPlayerTriggerEventThreshold&amp;diff=82229"/>
		<updated>2025-07-15T07:17:06Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server event}}&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22313|This event is triggered when a player exceeds the maximum threshold for events via [[triggerServerEvent]].}}&lt;br /&gt;
&lt;br /&gt;
During each interval (''player_triggered_event_interval''), all usage of [[triggerServerEvent]] will be counted for each player. This includes registered events, non-registered events and non-remote events.&lt;br /&gt;
&lt;br /&gt;
If the count exceeds ''max_player_triggered_events_per_interval'', this event will be fired. The count is reset each interval.&lt;br /&gt;
&lt;br /&gt;
You can set these options via [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
{{New feature/item|3.0161|1.6.0|23281|'''eventName:''' the name of last called event.}}&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the [[player]] who exceeded the threshold.&lt;br /&gt;
&lt;br /&gt;
===Canceling===&lt;br /&gt;
Canceling this event has no effect.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function processPlayerTriggerEventThreshold()&lt;br /&gt;
    kickPlayer(source, &amp;quot;Event spam&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerTriggerEventThreshold&amp;quot;, root, processPlayerTriggerEventThreshold)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{See also/Server event|Player events}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnVehicleExplode&amp;diff=82228</id>
		<title>OnVehicleExplode</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnVehicleExplode&amp;diff=82228"/>
		<updated>2025-07-15T06:55:30Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Adjust to https://github.com/multitheftauto/mtasa-blue/pull/4295&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server event}}&lt;br /&gt;
This event is triggered when a vehicle explodes.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool withExplosion, player player&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''withExplosion:''' Determines whether the vehicle was blown with or without an explosion.&lt;br /&gt;
{{New feature/item|3.0161|1.6.0|22680|&lt;br /&gt;
*'''player:''' The player who sent the explosion packet.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the [[vehicle]] that exploded.&lt;br /&gt;
&lt;br /&gt;
==Cancel effect==&lt;br /&gt;
{{New feature/item|3.0161|1.6.0|23281|If this event is cancelled, the vehicle won't explode.}}&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
'''Example 1''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local vagosVehicle = nil&lt;br /&gt;
&lt;br /&gt;
-- This will get called when the vagos vehicle explodes&lt;br /&gt;
function onVagosVehicleExplode ()&lt;br /&gt;
	outputChatBox ( &amp;quot;VAGOS VEHICLE DESTROYED!&amp;quot; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This is called when THIS resource starts&lt;br /&gt;
function onThisResourceStart ()&lt;br /&gt;
&lt;br /&gt;
	-- Create the vagos vehicle. A van.&lt;br /&gt;
	vagosVehicle = createVehicle ( 522, 0, 0, 5 )&lt;br /&gt;
&lt;br /&gt;
	-- Add its explode handler. When this car explodes, onVagosVehicleExplode is called&lt;br /&gt;
	addEventHandler ( &amp;quot;onVehicleExplode&amp;quot;, vagosVehicle, onVagosVehicleExplode )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Add the resource start event&lt;br /&gt;
addEventHandler ( &amp;quot;onResourceStart&amp;quot;, resourceRoot, onThisResourceStart )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Example 2:''' This will show the name of any vehicle that blew up:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function notifyAboutExplosion()&lt;br /&gt;
    -- source is the element that triggered the event and can be used in other events as well&lt;br /&gt;
    outputChatBox(getVehicleName(source) .. &amp;quot; just blew up&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- by using root, it will work for any vehicle (even if it wasn't created via this resource)&lt;br /&gt;
addEventHandler(&amp;quot;onVehicleExplode&amp;quot;, root, notifyAboutExplosion)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{See also/Server event|Vehicle events}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnPlayerTriggerEventThreshold&amp;diff=82192</id>
		<title>OnPlayerTriggerEventThreshold</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnPlayerTriggerEventThreshold&amp;diff=82192"/>
		<updated>2025-07-06T01:25:33Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Adjust parameters to https://github.com/multitheftauto/mtasa-blue/pull/4271&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server event}}&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22313|This event is triggered when a player exceeds the maximum threshold for events via [[triggerServerEvent]].}}&lt;br /&gt;
&lt;br /&gt;
During each interval (''player_triggered_event_interval''), all usage of [[triggerServerEvent]] will be counted for each player. This includes registered events, non-registered events and non-remote events.&lt;br /&gt;
&lt;br /&gt;
If the count exceeds ''max_player_triggered_events_per_interval'', this event will be fired. The count is reset each interval.&lt;br /&gt;
&lt;br /&gt;
You can set these options via [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|23251|'''eventName:''' the name of last called event.}}&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the [[player]] who exceeded the threshold.&lt;br /&gt;
&lt;br /&gt;
===Canceling===&lt;br /&gt;
Canceling this event has no effect.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function processPlayerTriggerEventThreshold()&lt;br /&gt;
    kickPlayer(source, &amp;quot;Event spam&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerTriggerEventThreshold&amp;quot;, root, processPlayerTriggerEventThreshold)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{See also/Server event|Player events}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetCameraFieldOfView&amp;diff=82189</id>
		<title>GetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetCameraFieldOfView&amp;diff=82189"/>
		<updated>2025-07-01T19:40:37Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function returns the field of view of the ''dynamic camera'' as set by [[setCameraFieldOfView]].}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
float getCameraFieldOfView ( string cameraMode )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.getFieldOfView|fov|setCameraFieldOfView}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''cameraMode:''' the camera mode to get the field of view of:&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns one float - the field of view angle&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view is output to the chat whenever the /getfov command is written&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function getCamFOV()&lt;br /&gt;
    outputChatBox(&amp;quot;The camera field of view for 'player walking/running' is: &amp;quot; .. getCameraFieldOfView(&amp;quot;player&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;getfov&amp;quot;, getCamFOV)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:getCameraFieldOfView]]&lt;br /&gt;
[[RO:getCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82188</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82188"/>
		<updated>2025-07-01T19:40:27Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|This function omits (but doesn't override) the user game option in '''''Settings -&amp;gt; Video -&amp;gt; FOV'''''}}&lt;br /&gt;
{{Note|It doesn't affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to set the field of view of:&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' is set to 20 when the player joins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setCameraFOVOnResStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;,20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, setCameraFOVOnResStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82187</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82187"/>
		<updated>2025-07-01T19:40:13Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|This function omits (but doesn't override) the user game option in '''''Settings -&amp;gt; Video -&amp;gt; FOV'''''}}&lt;br /&gt;
{{Note|It doesn't affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to set the field of view of&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' is set to 20 when the player joins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setCameraFOVOnResStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;,20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, setCameraFOVOnResStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82185</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82185"/>
		<updated>2025-06-30T17:38:34Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|This function omits (but doesn't override) the user game option in '''''Settings -&amp;gt; Video -&amp;gt; FOV'''''}}&lt;br /&gt;
{{Note|It doesn't affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to get the field of view of&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' is set to 20 when the player joins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setCameraFOVOnResStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;,20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, setCameraFOVOnResStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82184</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82184"/>
		<updated>2025-06-30T17:37:52Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|This functions omits (but doesn't override) the user game option in '''''Settings -&amp;gt; Video -&amp;gt; FOV'''''}}&lt;br /&gt;
{{Note|It doesn't affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to get the field of view of&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' is set to 20 when the player joins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setCameraFOVOnResStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;,20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, setCameraFOVOnResStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82183</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82183"/>
		<updated>2025-06-30T17:35:51Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Better phrasing for note&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|[[setCameraFieldOfView]] omits (but doesn't override) the user game option in '''''Settings-&amp;gt;Video-&amp;gt;FOV'''''}}&lt;br /&gt;
{{Note|[[setCameraFieldOfView]] does not affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to get the field of view of&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' is set to 20 when the player joins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setCameraFOVOnResStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;,20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, setCameraFOVOnResStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82182</id>
		<title>SetCameraFieldOfView</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetCameraFieldOfView&amp;diff=82182"/>
		<updated>2025-06-30T17:29:23Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Remove misleading/incorrect information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{client function}}&lt;br /&gt;
{{New feature/item|3.0151|1.5.1|7397|This function sets the field of view of the ''dynamic camera'' - this is the field of view of the ''non-fixed camera'' - yes, the camera that the user can control whilst on foot or in a vehicle. The higher the field of view angle, the more you will be able to see to your sides.}}&lt;br /&gt;
{{Note|[[setCameraFieldOfView]] does not affect the FOV for the following camera modes: 1) Player aiming 2) Vehicle front bumper camera 3) Fixed camera}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setCameraFieldOfView ( string cameraMode, float fieldOfView )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||Camera.setFieldOfView||getCameraFieldOfView}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
'''Note:''' after 100, some unexpected things may happen to the camera, particularly in vehicles, use carefully!&lt;br /&gt;
*'''cameraMode:''' the camera mode to get the field of view of&lt;br /&gt;
** &amp;quot;player&amp;quot;: whilst walking/running&lt;br /&gt;
** &amp;quot;vehicle&amp;quot;: whilst in vehicle&lt;br /&gt;
** &amp;quot;vehicle_max&amp;quot;: the max the field of view can go to when the vehicle is moving at a high speed (must be higher than &amp;quot;vehicle&amp;quot;)&lt;br /&gt;
*'''fieldOfView:''' The field of view angle, 0 to 179.&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the arguments are valid, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In this example, the field of view for 'player walking/running' is set to 20 when the player joins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setCameraFOVOnResStart()&lt;br /&gt;
    setCameraFieldOfView(&amp;quot;player&amp;quot;,20)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, setCameraFOVOnResStart)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client camera functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:setCameraFieldOfView]]&lt;br /&gt;
[[RO:setCameraFieldOfView]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Server_mtaserver.conf&amp;diff=82109</id>
		<title>Server mtaserver.conf</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Server_mtaserver.conf&amp;diff=82109"/>
		<updated>2025-06-05T17:53:14Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the settings that can be set in the settings file. ''Setting from the default '''mtaserver.conf''' settings file is in italics''.&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
&lt;br /&gt;
====servername====&lt;br /&gt;
:''&amp;lt;servername&amp;gt;Default MTA Server&amp;lt;/servername&amp;gt;''&lt;br /&gt;
:This parameter specifies the name the server will be visible as in the ingame server browser and on Game-Monitor. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====rule====&lt;br /&gt;
:''&amp;lt;rule name=&amp;quot;NAME_HERE&amp;quot; value=&amp;quot;VALUE_HERE&amp;quot;/&amp;gt;''&lt;br /&gt;
:The rule parameters are optional. There can be as many as you want in the config file. They contain information for the Server Browser/List. [[Server_Browser_Rules|Read this article for more information]].&lt;br /&gt;
&lt;br /&gt;
====owner_email_address====&lt;br /&gt;
:''&amp;lt;owner_email_address&amp;gt;&amp;lt;/owner_email_address&amp;gt;''&lt;br /&gt;
:This parameter specifies the contact email addresses for the owner(s) of this server. &lt;br /&gt;
:The email addresses will not be publicly available, and only used by MTA administrators to contact the server owner. &lt;br /&gt;
:Note: Missing or incorrect owner_email_address can affect visibility in the master server list. &lt;br /&gt;
:Values: Comma separated list of email addresses&lt;br /&gt;
&lt;br /&gt;
====serverip====&lt;br /&gt;
:''&amp;lt;serverip&amp;gt;auto&amp;lt;/serverip&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - it is generally only needed for complex network topologies and should be left at the default value otherwise.&lt;br /&gt;
: This parameter specifies the public IP address that the server will announce to the MTA servers, for the purposes of registering itself in the master server list and receiving some internal status updates. Usually, setting this parameter is only useful for some specialized scenarios, like servers that can be reached by multiple public addresses, or when a firewall is used for controlling incoming connections. If set to auto, the public IP address the requests originate from will be used as the server IP for communicating with MTA servers, which works fine in most cases.&lt;br /&gt;
:Values: auto or x.x.x.x ; default value: auto&lt;br /&gt;
:SERVERIP SHOULD BE LEFT SET TO auto UNLESS YOU ARE SURE OF WHAT YOU ARE DOING&lt;br /&gt;
:WARNING: SETTING serverip AND THEN ASKING FOR SUPPORT CAN CAUSE DEATH OR INJURY&lt;br /&gt;
&lt;br /&gt;
====serverport====&lt;br /&gt;
:''&amp;lt;serverport&amp;gt;22003&amp;lt;/serverport&amp;gt; &lt;br /&gt;
:This parameter specifies the UDP port on which the server will be accepting incoming player connections;&lt;br /&gt;
:default value: 22003. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====maxplayers====&lt;br /&gt;
:''&amp;lt;maxplayers&amp;gt;32&amp;lt;/maxplayers&amp;gt;&lt;br /&gt;
:This parameter specifies the number of maximum player slots available on the server;&lt;br /&gt;
:default value: 32. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====httpserver====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;httpserver&amp;gt;1&amp;lt;/httpserver&amp;gt;&lt;br /&gt;
:This parameter specifies whether the built-in http server will be used.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1. Optional parameter.&lt;br /&gt;
:More information: [[Server_Manual#Using_the_web_interface|Using the web interface]]&lt;br /&gt;
&lt;br /&gt;
====httpport====&lt;br /&gt;
:''&amp;lt;httpport&amp;gt;22005&amp;lt;/httpport&amp;gt;&lt;br /&gt;
:This parameter specifies the TCP port on which the server will be accepting incoming http connections. It can be set to the same value as &amp;lt;serverport&amp;gt;. It is a required parameter if &amp;lt;httpserver&amp;gt; is set to 1.&lt;br /&gt;
:More information: [[Server_Manual#Using_the_web_interface|Using the web interface]]&lt;br /&gt;
&lt;br /&gt;
====httpdownloadurl====&lt;br /&gt;
:''&amp;lt;httpdownloadurl&amp;gt;&amp;lt;/httpdownloadurl&amp;gt;&lt;br /&gt;
:If set, this parameter specifies the external URL from which clients will be able to download needed resources ingame. Otherwise they will download them directly from the server.&lt;br /&gt;
:More information: [[Server_Manual#Configuring_an_external_web_server|Configuring an external web server]]&lt;br /&gt;
&lt;br /&gt;
====httpmaxconnectionsperclient====&lt;br /&gt;
:''&amp;lt;httpmaxconnectionsperclient&amp;gt;5&amp;lt;/httpmaxconnectionsperclient&amp;gt;&lt;br /&gt;
:This parameter limits the number of http connections each client can make. Depending on the type of http server that is used, a lower figure may reduce download timeouts. Only relevant when using an external http server.&lt;br /&gt;
:Available range: 1 to 8.&lt;br /&gt;
&lt;br /&gt;
====httpthreadcount====&lt;br /&gt;
:''&amp;lt;httpthreadcount&amp;gt;8&amp;lt;/httpthreadcount&amp;gt;&lt;br /&gt;
:Number of HTTP server threads.&lt;br /&gt;
:Available range: 1 to 20. default value: 8&lt;br /&gt;
&lt;br /&gt;
====httpdosthreshold====&lt;br /&gt;
:''&amp;lt;httpdosthreshold&amp;gt;20&amp;lt;/httpdosthreshold&amp;gt;&lt;br /&gt;
:This parameter limits the number http connections that an IP can initiate over a short period of time.&lt;br /&gt;
:Available range: 1 to 100. default value: 20&lt;br /&gt;
&lt;br /&gt;
====http_dos_exclude====&lt;br /&gt;
:''&amp;lt;http_dos_exclude&amp;gt;&amp;lt;/http_dos_exclude&amp;gt;&lt;br /&gt;
:This parameter lists the IP addresses that are to be excluded from http dos threshold limits.&lt;br /&gt;
:e.g. 88.11.22.33,101.2.3.4&lt;br /&gt;
&lt;br /&gt;
====allow_gta3_img_mods====&lt;br /&gt;
:''&amp;lt;allow_gta3_img_mods&amp;gt;none&amp;lt;/allow_gta3_img_mods&amp;gt;&lt;br /&gt;
:By default, the server will block the use of locally customized gta3.img player skins&lt;br /&gt;
:This setting can be used to allow such mods. Not recommended for competitive servers.&lt;br /&gt;
:Values: none, peds ; default value: none&lt;br /&gt;
&lt;br /&gt;
====client_file====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;client_file name=&amp;quot;data/carmods.dat&amp;quot; verify=&amp;quot;0&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:By default, the server will block the use of customized GTA:SA data files.&lt;br /&gt;
:To allow specific client files, add one or more of the above lines.&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cclient_file_name.3D.22data.2Fcarmods.dat.22_verify.3D.220.22.2F.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====disableac====&lt;br /&gt;
:''&amp;lt;disableac&amp;gt;&amp;lt;/disableac&amp;gt;&lt;br /&gt;
:Comma separated list of disabled anti-cheats.&lt;br /&gt;
:e.g. To disable anti-cheat #2 and #3, use: 2,3&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cdisableac.3E.3C.2Fdisableac.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====enablesd====&lt;br /&gt;
:''&amp;lt;enablesd&amp;gt;31,32&amp;lt;/enablesd&amp;gt;&lt;br /&gt;
:Comma separated list of enabled special detections. A special detection is a type of anti-cheat for (usually) harmless game modifications. &lt;br /&gt;
:Competitive servers may wish to enable certain special detections, but most servers should leave this setting on its default.&lt;br /&gt;
:Values: special detection (SD) codes ; default value: 31,32 (e.g. enables special detections #31 and #32)&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cenablesd.3E.3C.2Fenablesd.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====hideac====&lt;br /&gt;
:''&amp;lt;hideac&amp;gt;0&amp;lt;/hideac&amp;gt;&lt;br /&gt;
:When this parameter is enabled client won't get any info about Anticheat settings when connecting to server.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0. Optional parameter.&lt;br /&gt;
&lt;br /&gt;
====minclientversion====&lt;br /&gt;
:''&amp;lt;minclientversion&amp;gt;&amp;lt;/minclientversion&amp;gt;&lt;br /&gt;
:Minimum client version. Clients with a lower version will not be allowed to connect. After disconnection, clients will be given an opportunity to download an update. If left blank, this setting is disabled and there are no restrictions on who can connect. Version numbers are described in [[getPlayerVersion]] and look like this: 1.6.0-9.22953.0&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:'''Note that this setting only determines if the client should be prompted to update. The actual build number they receive will be the [[https://nightly.mtasa.com/ver highest available]].'''&lt;br /&gt;
&lt;br /&gt;
====minclientversion_auto_update====&lt;br /&gt;
:''&amp;lt;minclientversion_auto_update&amp;gt;1&amp;lt;/minclientversion_auto_update&amp;gt;&lt;br /&gt;
:This parameter specifies if/when the &amp;lt;minclientversion&amp;gt; setting is automatically updated.&lt;br /&gt;
:Keeping &amp;lt;minclientversion&amp;gt; updated can help reduce cheating.&lt;br /&gt;
:Note: The instant setting (2) is only recommended for competitive servers.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled (delayed by a few days), 2 - enabled (instant) ; default value: 1.&lt;br /&gt;
&lt;br /&gt;
====recommendedclientversion====&lt;br /&gt;
:''&amp;lt;recommendedclientversion&amp;gt;&amp;lt;/recommendedclientversion&amp;gt;&lt;br /&gt;
:Recommended client version. When connecting, if clients have a lower version, they will be given the option to download an update. If left blank, this setting is disabled.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:'''Note that this setting only determines if the client should be prompted to update. The actual build number they receive will be the [[https://nightly.mtasa.com/ver highest available]].'''&lt;br /&gt;
&lt;br /&gt;
====ase====&lt;br /&gt;
:''&amp;lt;ase&amp;gt;1&amp;lt;/ase&amp;gt;&lt;br /&gt;
:This parameter can be used to make the server report to Game-Monitor master servers, allowing it to be visible in the in-game server browser. An additional UDP port needs to be available for this to work (value from &amp;lt;serverport&amp;gt; + 123 , so on a default &amp;lt;serverport&amp;gt; value 22003 the right port will be 22126 ).&lt;br /&gt;
:Available values: 0 - disabled , 1 - enabled. Optional parameter, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====donotbroadcastlan====&lt;br /&gt;
:''&amp;lt;donotbroadcastlan&amp;gt;0&amp;lt;/donotbroadcastlan&amp;gt;&lt;br /&gt;
:This parameter allows you to disable LAN broadcasting.	&lt;br /&gt;
&lt;br /&gt;
====password====&lt;br /&gt;
:''&amp;lt;password&amp;gt;&amp;lt;/password&amp;gt; &lt;br /&gt;
:If set, players will have to provide a password specified below, before they can connect to the server. If left blank, server doesn't require a password from them.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerPassword]] or [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====net_auto_filter====&lt;br /&gt;
:''&amp;lt;net_auto_filter&amp;gt;1&amp;lt;/net_auto_filter&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Net auto filter.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled. default value: 1&lt;br /&gt;
&lt;br /&gt;
====update_cycle_datagrams_limit====&lt;br /&gt;
:''&amp;lt;update_cycle_datagrams_limit&amp;gt;4&amp;lt;/update_cycle_datagrams_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Send datagrams limit.&lt;br /&gt;
:Available range: 1 to 100. default value: 4&lt;br /&gt;
&lt;br /&gt;
====update_cycle_messages_limit====&lt;br /&gt;
:''&amp;lt;update_cycle_messages_limit&amp;gt;50&amp;lt;/update_cycle_messages_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Send messages limit.&lt;br /&gt;
:Available range: 10 to 1000. default value: 50&lt;br /&gt;
&lt;br /&gt;
====bandwidth_reduction====&lt;br /&gt;
:''&amp;lt;bandwidth_reduction&amp;gt;medium&amp;lt;/bandwidth_reduction&amp;gt; &lt;br /&gt;
:This parameter reduces the server's bandwidth usage by using various optimizations.&lt;br /&gt;
:Values: none, medium or maximum ; default value: medium&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====unoccupied_vehicle_syncer_distance====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;unoccupied_vehicle_syncer_distance&amp;gt;130&amp;lt;/unoccupied_vehicle_syncer_distance&amp;gt;&lt;br /&gt;
:This parameter determines the distance limit for remote synced unoccupied vehicles&lt;br /&gt;
:Available range: 50 - 400; default value: 130&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====ped_syncer_distance====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;ped_syncer_distance&amp;gt;100&amp;lt;/ped_syncer_distance&amp;gt;&lt;br /&gt;
:This parameter determines the distance limit for remote synced peds&lt;br /&gt;
:Available range: 50 - 400; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====player_sync_interval====&lt;br /&gt;
:''&amp;lt;player_sync_interval&amp;gt;100&amp;lt;/player_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between player sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====lightweight_sync_interval====&lt;br /&gt;
:''&amp;lt;lightweight_sync_interval&amp;gt;1500&amp;lt;/lightweight_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between lightweight (player) sync packets.&lt;br /&gt;
:Available range: 200 - 4000; default value: 1500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====camera_sync_interval====&lt;br /&gt;
:''&amp;lt;camera_sync_interval&amp;gt;500&amp;lt;/camera_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between camera sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====ped_sync_interval====&lt;br /&gt;
:''&amp;lt;ped_sync_interval&amp;gt;500&amp;lt;/ped_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between ped sync packets when the ped is near the player.&lt;br /&gt;
:Available range: 50 - 4000; default value: 500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====ped_far_sync_interval====&lt;br /&gt;
:''&amp;lt;ped_far_sync_interval&amp;gt;2000&amp;lt;/ped_far_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between ped sync packets when the ped is far away from the player.&lt;br /&gt;
:Available range: 50 - 4000; default value: 2000&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====unoccupied_vehicle_sync_interval====&lt;br /&gt;
:''&amp;lt;unoccupied_vehicle_sync_interval&amp;gt;400&amp;lt;/unoccupied_vehicle_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between unoccupied vehicle sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 400&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====keysync_mouse_sync_interval====&lt;br /&gt;
:''&amp;lt;keysync_mouse_sync_interval&amp;gt;100&amp;lt;/keysync_mouse_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the minimum time in milliseconds between key sync packets due to mouse movement.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====keysync_analog_sync_interval====&lt;br /&gt;
:''&amp;lt;keysync_analog_sync_interval&amp;gt;100&amp;lt;/keysync_analog_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the minimum time in milliseconds between key sync packets due to joystick movement.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====donkey_work_interval====&lt;br /&gt;
:''&amp;lt;donkey_work_interval&amp;gt;100&amp;lt;/donkey_work_interval&amp;gt;&lt;br /&gt;
:Update near list interval in milliseconds.&lt;br /&gt;
:Available range: 50 to 4000. default value: 100&lt;br /&gt;
&lt;br /&gt;
====bullet_sync====&lt;br /&gt;
:''&amp;lt;bullet_sync&amp;gt;1&amp;lt;/bullet_sync&amp;gt;   &lt;br /&gt;
:This parameter can improve the reliability of shots when using certain weapons. However, it uses more bandwidth.&lt;br /&gt;
:Note that bullet sync will be active regardless of this setting when certain [[setGlitchEnabled|glitches]] are enabled.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22430|&lt;br /&gt;
====vehicle_contact_sync_radius====&lt;br /&gt;
:''&amp;lt;vehicle_contact_sync_radius&amp;gt;30&amp;lt;/vehicle_contact_sync_radius&amp;gt;   &lt;br /&gt;
:This parameter specifies the radius in which any contact with a vehicle will turn the player into its syncer.&lt;br /&gt;
:Changing this setting to 0 will cause vehicles to not pick a new syncer based on which player is touching the vehicle.&lt;br /&gt;
:Available range: 0 to 130.  Default - 30&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====vehext_percent====&lt;br /&gt;
:''&amp;lt;vehext_percent&amp;gt;0&amp;lt;/vehext_percent&amp;gt;&lt;br /&gt;
:This parameter sets the amount of extrapolation that clients will apply to remote vehicles. &lt;br /&gt;
:This can reduce some of the latency induced location disparency by predicting where the remote vehicles will probably be.&lt;br /&gt;
:Depending on the gamemode, an incorrect prediction may have a negative effect. &lt;br /&gt;
:Therefore this setting should be considered experimental.&lt;br /&gt;
:Available range: 0 to 100.  Default - 0&lt;br /&gt;
&lt;br /&gt;
====vehext_ping_limit====&lt;br /&gt;
:''&amp;lt;vehext_ping_limit&amp;gt;150&amp;lt;/vehext_ping_limit&amp;gt;&lt;br /&gt;
:This parameter places a limit on how much time (in milliseconds) the vehicle extrapolation will attempt to compensate for.&lt;br /&gt;
:Only relevant if &amp;lt;vehext_percent&amp;gt; is greater than zero.&lt;br /&gt;
:Available range: 50 to 500.  Default - 150&lt;br /&gt;
&lt;br /&gt;
====latency_reduction====&lt;br /&gt;
:''&amp;lt;latency_reduction&amp;gt;0&amp;lt;/latency_reduction&amp;gt;&lt;br /&gt;
:This parameter can reduce the delay of player actions appearing on remote clients by 2 frames (approx 50ms).&lt;br /&gt;
:Due to the impact this may have on shot lag compensation, it should be considered experimental.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0.&lt;br /&gt;
:Bugs caused by enabling latency_reduction: https://bugs.mtasa.com/view.php?id=8191 + https://bugs.mtasa.com/view.php?id=8226&lt;br /&gt;
&lt;br /&gt;
====threadnet====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;threadnet&amp;gt;1&amp;lt;/threadnet&amp;gt;&lt;br /&gt;
:This parameter specifies whether or not to run the network synchronization on another thread.&lt;br /&gt;
:Enabling will make the sync smoother, but may increase CPU usage slightly.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====idfile====&lt;br /&gt;
:''&amp;lt;idfile&amp;gt;server-id.keys&amp;lt;/idfile&amp;gt; &lt;br /&gt;
:Specifies the location and file name of this servers unique private key. This is used to prevent private files saved on the client from being read by other servers. &lt;br /&gt;
:Keep a backup of this file in a safe place. Default value: server-id.keys&lt;br /&gt;
:More information about client private files: [[Filepath]]&lt;br /&gt;
&lt;br /&gt;
====logfile====&lt;br /&gt;
:''&amp;lt;logfile&amp;gt;logs/server.log&amp;lt;/logfile&amp;gt;&lt;br /&gt;
:Specifies the location and name of the main server log file. If left blank, server won't be saving this file.&lt;br /&gt;
&lt;br /&gt;
====authfile====&lt;br /&gt;
:''&amp;lt;authfile&amp;gt;logs/server_auth.log&amp;lt;/authfile&amp;gt;&lt;br /&gt;
:As well as the main log file, login successes and failures are logged here for easy reviewing of security issues. If left blank, this file is not used&lt;br /&gt;
&lt;br /&gt;
====dbfile====&lt;br /&gt;
:''&amp;lt;dbfile&amp;gt;logs/db.log&amp;lt;/dbfile&amp;gt;&lt;br /&gt;
:Specifies the location and name of the file used to log database queries. The server command [[Server_Commands#debugdb|debugdb]] sets the amount of logging.&lt;br /&gt;
&lt;br /&gt;
====loadstringfile====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;loadstringfile&amp;gt;logs/loadstring.log&amp;lt;/loadstringfile&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the location and name of the file used to log loadstring function calls. If left blank or not set, no logging is done.&lt;br /&gt;
&lt;br /&gt;
====acl====&lt;br /&gt;
:''&amp;lt;acl&amp;gt;acl.xml&amp;lt;/acl&amp;gt; &lt;br /&gt;
:This parameter specifies the location and name of the Access Control List settings file. If left&lt;br /&gt;
:blank, server will use acl.xml file, located in the same folder as this configuration file.&lt;br /&gt;
&lt;br /&gt;
====scriptdebuglogfile====&lt;br /&gt;
:''&amp;lt;scriptdebuglogfile&amp;gt;logs/scripts.log&amp;lt;/scriptdebuglogfile&amp;gt; &lt;br /&gt;
:Specifies the location and name of the debugscript log file. If left blank, server won't be saving this file.&lt;br /&gt;
&lt;br /&gt;
====scriptdebugloglevel====&lt;br /&gt;
:''&amp;lt;scriptdebugloglevel&amp;gt;0&amp;lt;/scriptdebugloglevel&amp;gt;&lt;br /&gt;
:Specifies the level of the debugscript log file. Available values: 0, 1, 2, 3. When not set, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====htmldebuglevel====&lt;br /&gt;
:''&amp;lt;htmldebuglevel&amp;gt;0&amp;lt;/htmldebuglevel&amp;gt;&lt;br /&gt;
:Specifies the level of the html debug. Available values: 0, 1, 2, 3. When not set, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====filter_duplicate_log_lines====&lt;br /&gt;
:''&amp;lt;filter_duplicate_log_lines&amp;gt;1&amp;lt;/filter_duplicate_log_lines&amp;gt;&lt;br /&gt;
:Specifies whether or not duplicate log lines should be filtered. Available values: 0 or 1, defaults to 1.&lt;br /&gt;
&lt;br /&gt;
====fpslimit====&lt;br /&gt;
:''&amp;lt;fpslimit&amp;gt;74&amp;lt;/fpslimit&amp;gt;&lt;br /&gt;
:Specifies the frame rate limit that will be applied to connecting clients.&lt;br /&gt;
:Available range: 25 to 32767. Default: 74. You can also use 0 for uncapped fps.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====voice====&lt;br /&gt;
:''&amp;lt;voice&amp;gt;0&amp;lt;/voice&amp;gt;&lt;br /&gt;
:This parameter specifies whether or not to enable player voice chat in-game&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled&lt;br /&gt;
&lt;br /&gt;
====voice_samplerate====&lt;br /&gt;
:''&amp;lt;voice_samplerate&amp;gt;1&amp;lt;/voice_samplerate&amp;gt;&lt;br /&gt;
:This parameter specifies the sample rate for voice chat.  'voice' parameter must be set to 1 for this to be effective. Higher settings use more bandwidth and increase the sampling quality of voice chat&lt;br /&gt;
:Values: 0 - Narrowband (8kHz), 1 - Wideband (16kHz), 2 - Ultrawideband (32kHz).  Default - 1&lt;br /&gt;
&lt;br /&gt;
====voice_quality====&lt;br /&gt;
:''&amp;lt;voice_quality&amp;gt;4&amp;lt;/voice_quality&amp;gt;&lt;br /&gt;
:This parameter specifies the voice quality for voice chat.  'voice' parameter must be set to 1 for this to be effective. Higher settings use more bandwidth and increase the the overall quality of voice chat&lt;br /&gt;
:Available range: 0 to 10.  Default - 4&lt;br /&gt;
&lt;br /&gt;
====voice_bitrate====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;voice_bitrate&amp;gt;24600&amp;lt;/voice_bitrate&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the voice bitrate, in bps. This optional parameter overrides the previous two settings. If not set, MTA handles this automatically.  Use with care.&lt;br /&gt;
&lt;br /&gt;
====backup_path====&lt;br /&gt;
:''&amp;lt;backup_path&amp;gt;backups&amp;lt;/backup_path&amp;gt;&lt;br /&gt;
:This parameter specifies the path to use for a basic backup of some server files. Note that basic backups are only made during server startup. Default value: backups&lt;br /&gt;
&lt;br /&gt;
====backup_interval====&lt;br /&gt;
:''&amp;lt;backup_interval&amp;gt;3&amp;lt;/backup_interval&amp;gt;&lt;br /&gt;
:This parameter specifies the number of days between each basic backup. Backups are only made during server startup, so the actual interval maybe much longer. Setting backup_interval to 0 will disable backups&lt;br /&gt;
:Available range: 0 to 30.  Default - 3&lt;br /&gt;
&lt;br /&gt;
====backup_copies====&lt;br /&gt;
:''&amp;lt;backup_copies&amp;gt;10&amp;lt;/backup_copies&amp;gt;&lt;br /&gt;
:This parameter specifies the maximum number of backup copies to keep. Setting backup_copies to 0 will disable backups&lt;br /&gt;
:Available range: 0 to 100.  Default - 10&lt;br /&gt;
&lt;br /&gt;
====compact_internal_databases====&lt;br /&gt;
:''&amp;lt;compact_internal_databases&amp;gt;1&amp;lt;/compact_internal_databases&amp;gt;&lt;br /&gt;
:This parameter specifies when the internal sqlite databases should be defragmented.&lt;br /&gt;
:For more info see: https://www.sqlite.org/lang_vacuum.html&lt;br /&gt;
:Values: 0 - Never, 1 - On server start only after basic backup, 2 - On server start always.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====server_logic_fps_limit====&lt;br /&gt;
:''&amp;lt;server_logic_fps_limit&amp;gt;0&amp;lt;/server_logic_fps_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Server logic FPS limit.&lt;br /&gt;
:Available range: 0 to 100. default value: 0&lt;br /&gt;
&lt;br /&gt;
====crash_dump_upload====&lt;br /&gt;
:''&amp;lt;crash_dump_upload&amp;gt;1&amp;lt;/crash_dump_upload&amp;gt;&lt;br /&gt;
:This parameter specifies whether server crash dump files should be sent to MTA HQ.&lt;br /&gt;
:Values: 0 - Off, 1 - On. Default - 1&lt;br /&gt;
&lt;br /&gt;
====fakelag====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;fakelag&amp;gt;0&amp;lt;/fakelag&amp;gt;&lt;br /&gt;
:This parameter specifies whether the [[Command fakelag|fakelag and sfakelag]] commands are enabled&lt;br /&gt;
:Values: 0 - Off, 1 - On. Default - 0&lt;br /&gt;
&lt;br /&gt;
====auth_serial_groups====&lt;br /&gt;
:''&amp;lt;auth_serial_groups&amp;gt;Admin&amp;lt;/auth_serial_groups&amp;gt;&lt;br /&gt;
:This parameter lists the ACL groups that are protected by serial authorization.&lt;br /&gt;
:Login attempts to a protected account from a second serial are blocked until the serial is manually authorized via the authserial command.&lt;br /&gt;
:For more info see: https://mtasa.com/authserial&lt;br /&gt;
:Note: This is security critical feature and disabling auth_serial_groups can affect visibility in the master server list.&lt;br /&gt;
:Values: Comma separated list of ACL groups.  Default - Admin&lt;br /&gt;
:See [[Authorized Serial Account Protection]] for more information.&lt;br /&gt;
&lt;br /&gt;
====auth_serial_http====&lt;br /&gt;
:''&amp;lt;auth_serial_http&amp;gt;1&amp;lt;/auth_serial_http&amp;gt;&lt;br /&gt;
:This parameter specifies if the authorized serial login checks should also apply to the http interface.&lt;br /&gt;
:Protected account login attempts to the http interface will only succeed if the IP address matches one recently used by the account holder in-game.&lt;br /&gt;
:For more info see: https://mtasa.com/authserialhttp&lt;br /&gt;
:Note: This is security critical feature and disabling auth_serial_http can affect visibility in the master server list.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====auth_serial_http_ip_exceptions====&lt;br /&gt;
:''&amp;lt;auth_serial_http_ip_exceptions&amp;gt;127.0.0.1&amp;lt;/auth_serial_http_ip_exceptions&amp;gt;&lt;br /&gt;
:This parameter specifies which IP addresses should always pass auth_serial_http checks.&lt;br /&gt;
:Values: Comma separated list of IP addresses&lt;br /&gt;
&lt;br /&gt;
====database_credentials_protection====&lt;br /&gt;
:''&amp;lt;database_credentials_protection&amp;gt;1&amp;lt;/database_credentials_protection&amp;gt;&lt;br /&gt;
:This parameter specifies if extra security measures are applied to resources which use [[dbConnect]] with MySQL.&lt;br /&gt;
:The extra measures are:&lt;br /&gt;
: - script files cannot be accessed with [[fileOpen]]&lt;br /&gt;
: - [[meta.xml]] is read-only&lt;br /&gt;
:'''NOTE:''' This only protects resources which use [[dbConnect]] with MySQL.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled; default - 1&lt;br /&gt;
&lt;br /&gt;
{{New items|6.0160|1.6.0-22790|&lt;br /&gt;
====elementdata_whitelisted====&lt;br /&gt;
:''&amp;lt;elementdata_whitelisted&amp;gt;0&amp;lt;/elementdata_whitelisted&amp;gt;&lt;br /&gt;
:Enables extra protection for [[SetElementData|element data]].&lt;br /&gt;
:When this option is enabled, the server ignores element data sync packets from the client, except for allowed keys.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled; default - 0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{New items|6.0160|1.6.0-22815|&lt;br /&gt;
====check_duplicate_serials====&lt;br /&gt;
:''&amp;lt;check_duplicate_serials&amp;gt;1&amp;lt;/check_duplicate_serials&amp;gt;&lt;br /&gt;
:This parameter determines whether server will compare player serial on connection to any other serial present on server. &lt;br /&gt;
:When this option is enabled, the server will deny entry for player whose serial is already in use by other player on server. You might want to disable this when using VMs.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled; default - 1&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====player_triggered_event_interval====&lt;br /&gt;
:''&amp;lt;player_triggered_event_interval&amp;gt;1000&amp;lt;/player_triggered_event_interval&amp;gt;&lt;br /&gt;
:Time interval for counting max (see below: max_player_triggered_events_per_interval) triggered events (via triggerServerEvent), exceeding this will call [[onPlayerTriggerEventThreshold]]&lt;br /&gt;
:Values: 50-5000; default: 1000 (in ms)&lt;br /&gt;
&lt;br /&gt;
====max_player_triggered_events_per_interval====&lt;br /&gt;
:''&amp;lt;max_player_triggered_events_per_interval&amp;gt;100&amp;lt;/max_player_triggered_events_per_interval&amp;gt;&lt;br /&gt;
:Max triggered amount of events (via triggerServerEvent) within interval above (player_triggered_event_interval), exceeding this will call [[onPlayerTriggerEventThreshold]]&lt;br /&gt;
:Values: 1-1000; default: 100&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22930|&lt;br /&gt;
====player_teleport_alert====  &lt;br /&gt;
:''&amp;lt;player_teleport_alert&amp;gt;100&amp;lt;/player_teleport_alert&amp;gt;  &lt;br /&gt;
:Defines the maximum allowed unexpected position change (in units). If a player's position changes by more than this value without using [[setElementPosition]], the event [[onPlayerTeleport]] will be triggered.  &lt;br /&gt;
:Values: 5-500; default: 100&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====module====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;module src=&amp;quot;sample_win32.dll&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;module src=&amp;quot;sample_linux.so&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the module(s) which are loaded with the server. To load several modules, add more &amp;lt;module&amp;gt; parameter(s). Optional parameter.&lt;br /&gt;
&lt;br /&gt;
====resource_client_file_checks====&lt;br /&gt;
&amp;lt;!-- added by https://github.com/multitheftauto/mtasa-blue/pull/3822 --&amp;gt;&lt;br /&gt;
:''&amp;lt;resource_client_file_checks&amp;gt;1&amp;lt;/resource_client_file_checks&amp;gt;&lt;br /&gt;
:If enabled, the server will perform checks on files in resources (listed in [[meta.xml]]) with PNG, TXD and DFF extensions, checking if they are corrupted. When the system finds a non-valid file of these types, it outputs a warning to the server console.&lt;br /&gt;
:You may want to disable thse checks when storing different/non-conforming data in files with these extensions (e.g. encrypted data).&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====resource====&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;admin&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;defaultstats&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;helpmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;joinquit&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;mapcycler&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;mapmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;parachute&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;resourcebrowser&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;1&amp;quot; default=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;resourcemanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;scoreboard&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;spawnmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;voice&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;votemanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;webadmin&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;play&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src-&amp;quot;resources&amp;quot; startup&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot;&lt;br /&gt;
:Specifies persistent resources which are loaded when the server starts. Persistent resources are not stopped even if all the other resources that depend on them stop; that is, the only way to stop them is by explicitly using the ''stop'' server command or [[stopResource]] scripting function. To load several resources, add more &amp;lt;resource&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
:In addition, there are several flags which control how the server deals with each resource:&lt;br /&gt;
&lt;br /&gt;
:* '''src''': the resource name. This is the only mandatory flag.&lt;br /&gt;
:* '''startup''': controls whether the resource will be started with the server or not. If &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot;, the resource will be started. If not specified, defaults to not starting the resource.&lt;br /&gt;
:* '''protected''': if &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot;, the resource will not be able to be stopped when started. Otherwise, even if not specified, it will default to the normal behaviour.&lt;br /&gt;
:* '''default''': if given a &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot; value, this resource will be the one who populates the built-in HTTP server main page, which is seen when no resource is given in the web address. It is not possible to have more than one default resource.&lt;br /&gt;
&lt;br /&gt;
====busy_sleep_time====&lt;br /&gt;
:''&amp;lt;busy_sleep_time&amp;gt;-1&amp;lt;/busy_sleep_time&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - This parameter configures the server's sleep duration in milliseconds during busy processing, affecting CPU usage and responsiveness.  &lt;br /&gt;
:Available range: -1 to 50; default value: -1  &lt;br /&gt;
:-1 sets the server to automatically determine the optimal value based on workload.  &lt;br /&gt;
:Setting it to 0 is recommended for achieving the best performance but may result in higher CPU usage.  &lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
====idle_sleep_time====&lt;br /&gt;
:''&amp;lt;idle_sleep_time&amp;gt;-1&amp;lt;/idle_sleep_time&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - This parameter configures the server's sleep duration in milliseconds during idle periods, affecting CPU usage and responsiveness.&lt;br /&gt;
:Available range: -1 to 50; default value: -1&lt;br /&gt;
:-1 sets the server to automatically determine the optimal value based on workload.&lt;br /&gt;
:Setting it to 10 is recommended for achieving the best performance while balancing CPU usage.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
==Deprecated settings==&lt;br /&gt;
&lt;br /&gt;
The following settings have been deprecated in the production version of MTA:SA and no longer work.&lt;br /&gt;
&lt;br /&gt;
====networkencryption====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf - also seems to be deprecated in code --&amp;gt;&lt;br /&gt;
:''&amp;lt;networkencryption&amp;gt;1&amp;lt;/networkencryption&amp;gt;&lt;br /&gt;
:This parameter specifies whether communications between the server and client is encrypted. Encryption can help prevent network data being viewed and modified.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1. Optional parameter.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====autologin====&lt;br /&gt;
&amp;lt;!-- removed from MTA:SA at https://github.com/multitheftauto/mtasa-blue/commit/e392c417da03b295c7f8342a7f6c1467d094db12#diff-b828bcbfff7135920f9a1179be3e3617 --&amp;gt;&lt;br /&gt;
:''&amp;lt;autologin&amp;gt;0&amp;lt;/autologin&amp;gt;&lt;br /&gt;
:Specifies whether or not players should automatically be logged in based on their IP adresses.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0.&lt;br /&gt;
&lt;br /&gt;
====httpautoclientfiles====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf - doesn't exists in code too --&amp;gt;&lt;br /&gt;
:''&amp;lt;httpautoclientfiles&amp;gt;1&amp;lt;/httpautoclientfiles&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Support]]&lt;br /&gt;
[[ru:Server mtaserver.conf]]&lt;br /&gt;
[[pl:mtaserver.conf]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Server_mtaserver.conf&amp;diff=82107</id>
		<title>Server mtaserver.conf</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Server_mtaserver.conf&amp;diff=82107"/>
		<updated>2025-06-05T07:06:28Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the settings that can be set in the settings file. ''Setting from the default '''mtaserver.conf''' settings file is in italics''.&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
&lt;br /&gt;
====servername====&lt;br /&gt;
:''&amp;lt;servername&amp;gt;Default MTA Server&amp;lt;/servername&amp;gt;''&lt;br /&gt;
:This parameter specifies the name the server will be visible as in the ingame server browser and on Game-Monitor. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====rule====&lt;br /&gt;
:''&amp;lt;rule name=&amp;quot;NAME_HERE&amp;quot; value=&amp;quot;VALUE_HERE&amp;quot;/&amp;gt;''&lt;br /&gt;
:The rule parameters are optional. There can be as many as you want in the config file. They contain information for the Server Browser/List. [[Server_Browser_Rules|Read this article for more information]].&lt;br /&gt;
&lt;br /&gt;
====owner_email_address====&lt;br /&gt;
:''&amp;lt;owner_email_address&amp;gt;&amp;lt;/owner_email_address&amp;gt;''&lt;br /&gt;
:This parameter specifies the contact email addresses for the owner(s) of this server. &lt;br /&gt;
:The email addresses will not be publicly available, and only used by MTA administrators to contact the server owner. &lt;br /&gt;
:Note: Missing or incorrect owner_email_address can affect visibility in the master server list. &lt;br /&gt;
:Values: Comma separated list of email addresses&lt;br /&gt;
&lt;br /&gt;
====serverip====&lt;br /&gt;
:''&amp;lt;serverip&amp;gt;auto&amp;lt;/serverip&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - it is generally only needed for complex network topologies and should be left at the default value otherwise.&lt;br /&gt;
: This parameter specifies the public IP address that the server will announce to the MTA servers, for the purposes of registering itself in the master server list and receiving some internal status updates. Usually, setting this parameter is only useful for some specialized scenarios, like servers that can be reached by multiple public addresses, or when a firewall is used for controlling incoming connections. If set to auto, the public IP address the requests originate from will be used as the server IP for communicating with MTA servers, which works fine in most cases.&lt;br /&gt;
:Values: auto or x.x.x.x ; default value: auto&lt;br /&gt;
:SERVERIP SHOULD BE LEFT SET TO auto UNLESS YOU ARE SURE OF WHAT YOU ARE DOING&lt;br /&gt;
:WARNING: SETTING serverip AND THEN ASKING FOR SUPPORT CAN CAUSE DEATH OR INJURY&lt;br /&gt;
&lt;br /&gt;
====serverport====&lt;br /&gt;
:''&amp;lt;serverport&amp;gt;22003&amp;lt;/serverport&amp;gt; &lt;br /&gt;
:This parameter specifies the UDP port on which the server will be accepting incoming player connections;&lt;br /&gt;
:default value: 22003. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====maxplayers====&lt;br /&gt;
:''&amp;lt;maxplayers&amp;gt;32&amp;lt;/maxplayers&amp;gt;&lt;br /&gt;
:This parameter specifies the number of maximum player slots available on the server;&lt;br /&gt;
:default value: 32. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====httpserver====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;httpserver&amp;gt;1&amp;lt;/httpserver&amp;gt;&lt;br /&gt;
:This parameter specifies whether the built-in http server will be used.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1. Optional parameter.&lt;br /&gt;
:More information: [[Server_Manual#Using_the_web_interface|Using the web interface]]&lt;br /&gt;
&lt;br /&gt;
====httpport====&lt;br /&gt;
:''&amp;lt;httpport&amp;gt;22005&amp;lt;/httpport&amp;gt;&lt;br /&gt;
:This parameter specifies the TCP port on which the server will be accepting incoming http connections. It can be set to the same value as &amp;lt;serverport&amp;gt;. It is a required parameter if &amp;lt;httpserver&amp;gt; is set to 1.&lt;br /&gt;
:More information: [[Server_Manual#Using_the_web_interface|Using the web interface]]&lt;br /&gt;
&lt;br /&gt;
====httpdownloadurl====&lt;br /&gt;
:''&amp;lt;httpdownloadurl&amp;gt;&amp;lt;/httpdownloadurl&amp;gt;&lt;br /&gt;
:If set, this parameter specifies the external URL from which clients will be able to download needed resources ingame. Otherwise they will download them directly from the server.&lt;br /&gt;
:More information: [[Server_Manual#Configuring_an_external_web_server|Configuring an external web server]]&lt;br /&gt;
&lt;br /&gt;
====httpmaxconnectionsperclient====&lt;br /&gt;
:''&amp;lt;httpmaxconnectionsperclient&amp;gt;5&amp;lt;/httpmaxconnectionsperclient&amp;gt;&lt;br /&gt;
:This parameter limits the number of http connections each client can make. Depending on the type of http server that is used, a lower figure may reduce download timeouts. Only relevant when using an external http server.&lt;br /&gt;
:Available range: 1 to 8.&lt;br /&gt;
&lt;br /&gt;
====httpthreadcount====&lt;br /&gt;
:''&amp;lt;httpthreadcount&amp;gt;8&amp;lt;/httpthreadcount&amp;gt;&lt;br /&gt;
:Number of HTTP server threads.&lt;br /&gt;
:Available range: 1 to 20. default value: 8&lt;br /&gt;
&lt;br /&gt;
====httpdosthreshold====&lt;br /&gt;
:''&amp;lt;httpdosthreshold&amp;gt;20&amp;lt;/httpdosthreshold&amp;gt;&lt;br /&gt;
:This parameter limits the number http connections that an IP can initiate over a short period of time.&lt;br /&gt;
:Available range: 1 to 100. default value: 20&lt;br /&gt;
&lt;br /&gt;
====http_dos_exclude====&lt;br /&gt;
:''&amp;lt;http_dos_exclude&amp;gt;&amp;lt;/http_dos_exclude&amp;gt;&lt;br /&gt;
:This parameter lists the IP addresses that are to be excluded from http dos threshold limits.&lt;br /&gt;
:e.g. 88.11.22.33,101.2.3.4&lt;br /&gt;
&lt;br /&gt;
====allow_gta3_img_mods====&lt;br /&gt;
:''&amp;lt;allow_gta3_img_mods&amp;gt;none&amp;lt;/allow_gta3_img_mods&amp;gt;&lt;br /&gt;
:By default, the server will block the use of locally customized gta3.img player skins&lt;br /&gt;
:This setting can be used to allow such mods. Not recommended for competitive servers.&lt;br /&gt;
:Values: none, peds ; default value: none&lt;br /&gt;
&lt;br /&gt;
====client_file====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;client_file name=&amp;quot;data/carmods.dat&amp;quot; verify=&amp;quot;0&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:By default, the server will block the use of customized GTA:SA data files.&lt;br /&gt;
:To allow specific client files, add one or more of the above lines.&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cclient_file_name.3D.22data.2Fcarmods.dat.22_verify.3D.220.22.2F.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====disableac====&lt;br /&gt;
:''&amp;lt;disableac&amp;gt;&amp;lt;/disableac&amp;gt;&lt;br /&gt;
:Comma separated list of disabled anti-cheats.&lt;br /&gt;
:e.g. To disable anti-cheat #2 and #3, use: 2,3&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cdisableac.3E.3C.2Fdisableac.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====enablesd====&lt;br /&gt;
:''&amp;lt;enablesd&amp;gt;31,32&amp;lt;/enablesd&amp;gt;&lt;br /&gt;
:Comma separated list of enabled special detections. A special detection is a type of anti-cheat for (usually) harmless game modifications. &lt;br /&gt;
:Competitive servers may wish to enable certain special detections, but most servers should leave this setting on its default.&lt;br /&gt;
:Values: special detection (SD) codes ; default value: 31,32 (e.g. enables special detections #31 and #32)&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cenablesd.3E.3C.2Fenablesd.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====hideac====&lt;br /&gt;
:''&amp;lt;hideac&amp;gt;0&amp;lt;/hideac&amp;gt;&lt;br /&gt;
:When this parameter is enabled client won't get any info about Anticheat settings when connecting to server.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0. Optional parameter.&lt;br /&gt;
&lt;br /&gt;
====minclientversion====&lt;br /&gt;
:''&amp;lt;minclientversion&amp;gt;&amp;lt;/minclientversion&amp;gt;&lt;br /&gt;
:Minimum client version. Clients with a lower version will not be allowed to connect. After disconnection, clients will be given an opportunity to download an update. If left blank, this setting is disabled and there are no restrictions on who can connect. Version numbers are described in [[getPlayerVersion]] and look like this: 1.6.0-9.22953.0&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:'''Note that this setting only determines if the client should be prompted to update. The actual build number they receive will be the [[https://nightly.mtasa.com/ver highest available]].'''&lt;br /&gt;
&lt;br /&gt;
====minclientversion_auto_update====&lt;br /&gt;
:''&amp;lt;minclientversion_auto_update&amp;gt;1&amp;lt;/minclientversion_auto_update&amp;gt;&lt;br /&gt;
:This parameter specifies if/when the &amp;lt;minclientversion&amp;gt; setting is automatically updated.&lt;br /&gt;
:Keeping &amp;lt;minclientversion&amp;gt; updated can help reduce cheating.&lt;br /&gt;
:Note: The instant setting (2) is only recommended for competitive servers.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled (delayed by a few days), 2 - enabled (instant) ; default value: 1.&lt;br /&gt;
&lt;br /&gt;
====recommendedclientversion====&lt;br /&gt;
:''&amp;lt;recommendedclientversion&amp;gt;&amp;lt;/recommendedclientversion&amp;gt;&lt;br /&gt;
:Recommended client version. When connecting, if clients have a lower version, they will be given the option to download an update. If left blank, this setting is disabled.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:'''Note that this setting only determines if the client should be prompted to update. The actual build number they receive will be the [[https://nightly.mtasa.com/ver highest available]].'''&lt;br /&gt;
&lt;br /&gt;
====ase====&lt;br /&gt;
:''&amp;lt;ase&amp;gt;1&amp;lt;/ase&amp;gt;&lt;br /&gt;
:This parameter can be used to make the server report to Game-Monitor master servers, allowing it to be visible in the in-game server browser. An additional UDP port needs to be available for this to work (value from &amp;lt;serverport&amp;gt; + 123 , so on a default &amp;lt;serverport&amp;gt; value 22003 the right port will be 22126 ).&lt;br /&gt;
:Available values: 0 - disabled , 1 - enabled. Optional parameter, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====donotbroadcastlan====&lt;br /&gt;
:''&amp;lt;donotbroadcastlan&amp;gt;0&amp;lt;/donotbroadcastlan&amp;gt;&lt;br /&gt;
:This parameter allows you to disable LAN broadcasting.	&lt;br /&gt;
&lt;br /&gt;
====password====&lt;br /&gt;
:''&amp;lt;password&amp;gt;&amp;lt;/password&amp;gt; &lt;br /&gt;
:If set, players will have to provide a password specified below, before they can connect to the server. If left blank, server doesn't require a password from them.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerPassword]] or [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====net_auto_filter====&lt;br /&gt;
:''&amp;lt;net_auto_filter&amp;gt;1&amp;lt;/net_auto_filter&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Net auto filter.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled. default value: 1&lt;br /&gt;
&lt;br /&gt;
====update_cycle_datagrams_limit====&lt;br /&gt;
:''&amp;lt;update_cycle_datagrams_limit&amp;gt;4&amp;lt;/update_cycle_datagrams_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Send datagrams limit.&lt;br /&gt;
:Available range: 1 to 100. default value: 4&lt;br /&gt;
&lt;br /&gt;
====update_cycle_messages_limit====&lt;br /&gt;
:''&amp;lt;update_cycle_messages_limit&amp;gt;50&amp;lt;/update_cycle_messages_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Send messages limit.&lt;br /&gt;
:Available range: 10 to 1000. default value: 50&lt;br /&gt;
&lt;br /&gt;
====bandwidth_reduction====&lt;br /&gt;
:''&amp;lt;bandwidth_reduction&amp;gt;medium&amp;lt;/bandwidth_reduction&amp;gt; &lt;br /&gt;
:This parameter reduces the server's bandwidth usage by using various optimizations.&lt;br /&gt;
:Values: none, medium or maximum ; default value: medium&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====unoccupied_vehicle_syncer_distance====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;unoccupied_vehicle_syncer_distance&amp;gt;130&amp;lt;/unoccupied_vehicle_syncer_distance&amp;gt;&lt;br /&gt;
:This parameter determines the distance limit for remote synced unoccupied vehicles&lt;br /&gt;
:Available range: 50 - 400; default value: 130&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====ped_syncer_distance====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;ped_syncer_distance&amp;gt;100&amp;lt;/ped_syncer_distance&amp;gt;&lt;br /&gt;
:This parameter determines the distance limit for remote synced peds&lt;br /&gt;
:Available range: 50 - 400; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====player_sync_interval====&lt;br /&gt;
:''&amp;lt;player_sync_interval&amp;gt;100&amp;lt;/player_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between player sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====lightweight_sync_interval====&lt;br /&gt;
:''&amp;lt;lightweight_sync_interval&amp;gt;1500&amp;lt;/lightweight_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between lightweight (player) sync packets.&lt;br /&gt;
:Available range: 200 - 4000; default value: 1500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====camera_sync_interval====&lt;br /&gt;
:''&amp;lt;camera_sync_interval&amp;gt;500&amp;lt;/camera_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between camera sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====ped_sync_interval====&lt;br /&gt;
:''&amp;lt;ped_sync_interval&amp;gt;500&amp;lt;/ped_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between ped sync packets when the ped is near the player.&lt;br /&gt;
:Available range: 50 - 4000; default value: 500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====ped_far_sync_interval====&lt;br /&gt;
:''&amp;lt;ped_far_sync_interval&amp;gt;2000&amp;lt;/ped_far_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between ped sync packets when the ped is far away from the player.&lt;br /&gt;
:Available range: 50 - 4000; default value: 2000&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====unoccupied_vehicle_sync_interval====&lt;br /&gt;
:''&amp;lt;unoccupied_vehicle_sync_interval&amp;gt;400&amp;lt;/unoccupied_vehicle_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between unoccupied vehicle sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 400&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====keysync_mouse_sync_interval====&lt;br /&gt;
:''&amp;lt;keysync_mouse_sync_interval&amp;gt;100&amp;lt;/keysync_mouse_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the minimum time in milliseconds between key sync packets due to mouse movement.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====keysync_analog_sync_interval====&lt;br /&gt;
:''&amp;lt;keysync_analog_sync_interval&amp;gt;100&amp;lt;/keysync_analog_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the minimum time in milliseconds between key sync packets due to joystick movement.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====donkey_work_interval====&lt;br /&gt;
:''&amp;lt;donkey_work_interval&amp;gt;100&amp;lt;/donkey_work_interval&amp;gt;&lt;br /&gt;
:Update near list interval in milliseconds.&lt;br /&gt;
:Available range: 50 to 4000. default value: 100&lt;br /&gt;
&lt;br /&gt;
====bullet_sync====&lt;br /&gt;
:''&amp;lt;bullet_sync&amp;gt;1&amp;lt;/bullet_sync&amp;gt;   &lt;br /&gt;
:This parameter can improve the reliability of shots when using certain weapons. However, it uses more bandwidth.&lt;br /&gt;
:Note that bullet sync will be active regardless of this setting when certain [[setGlitchEnabled|glitches]] are enabled.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22430|&lt;br /&gt;
====vehicle_contact_sync_radius====&lt;br /&gt;
:''&amp;lt;vehicle_contact_sync_radius&amp;gt;30&amp;lt;/vehicle_contact_sync_radius&amp;gt;   &lt;br /&gt;
:This parameter specifies the radius in which any contact with a vehicle will turn the player into its syncer.&lt;br /&gt;
:Changing this setting to 0 will cause vehicles to not pick a new syncer based on which player is touching the vehicle.&lt;br /&gt;
:Available range: 0 to 130.  Default - 30&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====vehext_percent====&lt;br /&gt;
:''&amp;lt;vehext_percent&amp;gt;0&amp;lt;/vehext_percent&amp;gt;&lt;br /&gt;
:This parameter sets the amount of extrapolation that clients will apply to remote vehicles. &lt;br /&gt;
:This can reduce some of the latency induced location disparency by predicting where the remote vehicles will probably be.&lt;br /&gt;
:Depending on the gamemode, an incorrect prediction may have a negative effect. &lt;br /&gt;
:Therefore this setting should be considered experimental.&lt;br /&gt;
:Available range: 0 to 100.  Default - 0&lt;br /&gt;
&lt;br /&gt;
====vehext_ping_limit====&lt;br /&gt;
:''&amp;lt;vehext_ping_limit&amp;gt;150&amp;lt;/vehext_ping_limit&amp;gt;&lt;br /&gt;
:This parameter places a limit on how much time (in milliseconds) the vehicle extrapolation will attempt to compensate for.&lt;br /&gt;
:Only relevant if &amp;lt;vehext_percent&amp;gt; is greater than zero.&lt;br /&gt;
:Available range: 50 to 500.  Default - 150&lt;br /&gt;
&lt;br /&gt;
====latency_reduction====&lt;br /&gt;
:''&amp;lt;latency_reduction&amp;gt;0&amp;lt;/latency_reduction&amp;gt;&lt;br /&gt;
:This parameter can reduce the delay of player actions appearing on remote clients by 2 frames (approx 50ms).&lt;br /&gt;
:Due to the impact this may have on shot lag compensation, it should be considered experimental.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0.&lt;br /&gt;
:Bugs caused by enabling latency_reduction: https://bugs.mtasa.com/view.php?id=8191 + https://bugs.mtasa.com/view.php?id=8226&lt;br /&gt;
&lt;br /&gt;
====threadnet====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;threadnet&amp;gt;1&amp;lt;/threadnet&amp;gt;&lt;br /&gt;
:This parameter specifies whether or not to run the network synchronization on another thread.&lt;br /&gt;
:Enabling will make the sync smoother, but may increase CPU usage slightly.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====idfile====&lt;br /&gt;
:''&amp;lt;idfile&amp;gt;server-id.keys&amp;lt;/idfile&amp;gt; &lt;br /&gt;
:Specifies the location and file name of this servers unique private key. This is used to prevent private files saved on the client from being read by other servers. &lt;br /&gt;
:Keep a backup of this file in a safe place. Default value: server-id.keys&lt;br /&gt;
:More information about client private files: [[Filepath]]&lt;br /&gt;
&lt;br /&gt;
====logfile====&lt;br /&gt;
:''&amp;lt;logfile&amp;gt;logs/server.log&amp;lt;/logfile&amp;gt;&lt;br /&gt;
:Specifies the location and name of the main server log file. If left blank, server won't be saving this file.&lt;br /&gt;
&lt;br /&gt;
====authfile====&lt;br /&gt;
:''&amp;lt;authfile&amp;gt;logs/server_auth.log&amp;lt;/authfile&amp;gt;&lt;br /&gt;
:As well as the main log file, login successes and failures are logged here for easy reviewing of security issues. If left blank, this file is not used&lt;br /&gt;
&lt;br /&gt;
====dbfile====&lt;br /&gt;
:''&amp;lt;dbfile&amp;gt;logs/db.log&amp;lt;/dbfile&amp;gt;&lt;br /&gt;
:Specifies the location and name of the file used to log database queries. The server command [[Server_Commands#debugdb|debugdb]] sets the amount of logging.&lt;br /&gt;
&lt;br /&gt;
====loadstringfile====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;loadstringfile&amp;gt;logs/loadstring.log&amp;lt;/loadstringfile&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the location and name of the file used to log loadstring function calls. If left blank or not set, no logging is done.&lt;br /&gt;
&lt;br /&gt;
====acl====&lt;br /&gt;
:''&amp;lt;acl&amp;gt;acl.xml&amp;lt;/acl&amp;gt; &lt;br /&gt;
:This parameter specifies the location and name of the Access Control List settings file. If left&lt;br /&gt;
:blank, server will use acl.xml file, located in the same folder as this configuration file.&lt;br /&gt;
&lt;br /&gt;
====scriptdebuglogfile====&lt;br /&gt;
:''&amp;lt;scriptdebuglogfile&amp;gt;logs/scripts.log&amp;lt;/scriptdebuglogfile&amp;gt; &lt;br /&gt;
:Specifies the location and name of the debugscript log file. If left blank, server won't be saving this file.&lt;br /&gt;
&lt;br /&gt;
====scriptdebugloglevel====&lt;br /&gt;
:''&amp;lt;scriptdebugloglevel&amp;gt;0&amp;lt;/scriptdebugloglevel&amp;gt;&lt;br /&gt;
:Specifies the level of the debugscript log file. Available values: 0, 1, 2, 3. When not set, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====htmldebuglevel====&lt;br /&gt;
:''&amp;lt;htmldebuglevel&amp;gt;0&amp;lt;/htmldebuglevel&amp;gt;&lt;br /&gt;
:Specifies the level of the html debug. Available values: 0, 1, 2, 3. When not set, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====filter_duplicate_log_lines====&lt;br /&gt;
:''&amp;lt;filter_duplicate_log_lines&amp;gt;1&amp;lt;/filter_duplicate_log_lines&amp;gt;&lt;br /&gt;
:Specifies whether or not duplicate log lines should be filtered. Available values: 0 or 1, defaults to 1.&lt;br /&gt;
&lt;br /&gt;
====fpslimit====&lt;br /&gt;
:''&amp;lt;fpslimit&amp;gt;74&amp;lt;/fpslimit&amp;gt;&lt;br /&gt;
:Specifies the frame rate limit that will be applied to connecting clients.&lt;br /&gt;
:Available range: 25 to 32767. Default: 74. You can also use 0 for uncapped fps.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====voice====&lt;br /&gt;
:''&amp;lt;voice&amp;gt;0&amp;lt;/voice&amp;gt;&lt;br /&gt;
:This parameter specifies whether or not to enable player voice chat in-game&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled&lt;br /&gt;
&lt;br /&gt;
====voice_samplerate====&lt;br /&gt;
:''&amp;lt;voice_samplerate&amp;gt;1&amp;lt;/voice_samplerate&amp;gt;&lt;br /&gt;
:This parameter specifies the sample rate for voice chat.  'voice' parameter must be set to 1 for this to be effective. Higher settings use more bandwidth and increase the sampling quality of voice chat&lt;br /&gt;
:Values: 0 - Narrowband (8kHz), 1 - Wideband (16kHz), 2 - Ultrawideband (32kHz).  Default - 1&lt;br /&gt;
&lt;br /&gt;
====voice_quality====&lt;br /&gt;
:''&amp;lt;voice_quality&amp;gt;4&amp;lt;/voice_quality&amp;gt;&lt;br /&gt;
:This parameter specifies the voice quality for voice chat.  'voice' parameter must be set to 1 for this to be effective. Higher settings use more bandwidth and increase the the overall quality of voice chat&lt;br /&gt;
:Available range: 0 to 10.  Default - 4&lt;br /&gt;
&lt;br /&gt;
====voice_bitrate====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;voice_bitrate&amp;gt;24600&amp;lt;/voice_bitrate&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the voice bitrate, in bps. This optional parameter overrides the previous two settings. If not set, MTA handles this automatically.  Use with care.&lt;br /&gt;
&lt;br /&gt;
====backup_path====&lt;br /&gt;
:''&amp;lt;backup_path&amp;gt;backups&amp;lt;/backup_path&amp;gt;&lt;br /&gt;
:This parameter specifies the path to use for a basic backup of some server files. Note that basic backups are only made during server startup. Default value: backups&lt;br /&gt;
&lt;br /&gt;
====backup_interval====&lt;br /&gt;
:''&amp;lt;backup_interval&amp;gt;3&amp;lt;/backup_interval&amp;gt;&lt;br /&gt;
:This parameter specifies the number of days between each basic backup. Backups are only made during server startup, so the actual interval maybe much longer. Setting backup_interval to 0 will disable backups&lt;br /&gt;
:Available range: 0 to 30.  Default - 3&lt;br /&gt;
&lt;br /&gt;
====backup_copies====&lt;br /&gt;
:''&amp;lt;backup_copies&amp;gt;10&amp;lt;/backup_copies&amp;gt;&lt;br /&gt;
:This parameter specifies the maximum number of backup copies to keep. Setting backup_copies to 0 will disable backups&lt;br /&gt;
:Available range: 0 to 100.  Default - 10&lt;br /&gt;
&lt;br /&gt;
====compact_internal_databases====&lt;br /&gt;
:''&amp;lt;compact_internal_databases&amp;gt;1&amp;lt;/compact_internal_databases&amp;gt;&lt;br /&gt;
:This parameter specifies when the internal sqlite databases should be defragmented.&lt;br /&gt;
:For more info see: https://www.sqlite.org/lang_vacuum.html&lt;br /&gt;
:Values: 0 - Never, 1 - On server start only after basic backup, 2 - On server start always.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====server_logic_fps_limit====&lt;br /&gt;
:''&amp;lt;server_logic_fps_limit&amp;gt;0&amp;lt;/server_logic_fps_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Server logic FPS limit.&lt;br /&gt;
:Available range: 0 to 100. default value: 0&lt;br /&gt;
&lt;br /&gt;
====crash_dump_upload====&lt;br /&gt;
:''&amp;lt;crash_dump_upload&amp;gt;1&amp;lt;/crash_dump_upload&amp;gt;&lt;br /&gt;
:This parameter specifies whether server crash dump files should be sent to MTA HQ.&lt;br /&gt;
:Values: 0 - Off, 1 - On. Default - 1&lt;br /&gt;
&lt;br /&gt;
====fakelag====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;fakelag&amp;gt;0&amp;lt;/fakelag&amp;gt;&lt;br /&gt;
:This parameter specifies whether the [[Command fakelag|fakelag and sfakelag]] commands are enabled&lt;br /&gt;
:Values: 0 - Off, 1 - On. Default - 0&lt;br /&gt;
&lt;br /&gt;
====auth_serial_groups====&lt;br /&gt;
:''&amp;lt;auth_serial_groups&amp;gt;Admin&amp;lt;/auth_serial_groups&amp;gt;&lt;br /&gt;
:This parameter lists the ACL groups that are protected by serial authorization.&lt;br /&gt;
:Login attempts to a protected account from a second serial are blocked until the serial is manually authorized via the authserial command.&lt;br /&gt;
:For more info see: https://mtasa.com/authserial&lt;br /&gt;
:Note: This is security critical feature and disabling auth_serial_groups can affect visibility in the master server list.&lt;br /&gt;
:Values: Comma separated list of ACL groups.  Default - Admin&lt;br /&gt;
:See [[Authorized Serial Account Protection]] for more information.&lt;br /&gt;
&lt;br /&gt;
====auth_serial_http====&lt;br /&gt;
:''&amp;lt;auth_serial_http&amp;gt;1&amp;lt;/auth_serial_http&amp;gt;&lt;br /&gt;
:This parameter specifies if the authorized serial login checks should also apply to the http interface.&lt;br /&gt;
:Protected account login attempts to the http interface will only succeed if the IP address matches one recently used by the account holder in-game.&lt;br /&gt;
:For more info see: https://mtasa.com/authserialhttp&lt;br /&gt;
:Note: This is security critical feature and disabling auth_serial_http can affect visibility in the master server list.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====auth_serial_http_ip_exceptions====&lt;br /&gt;
:''&amp;lt;auth_serial_http_ip_exceptions&amp;gt;127.0.0.1&amp;lt;/auth_serial_http_ip_exceptions&amp;gt;&lt;br /&gt;
:This parameter specifies which IP addresses should always pass auth_serial_http checks.&lt;br /&gt;
:Values: Comma separated list of IP addresses&lt;br /&gt;
&lt;br /&gt;
====database_credentials_protection====&lt;br /&gt;
:''&amp;lt;database_credentials_protection&amp;gt;1&amp;lt;/database_credentials_protection&amp;gt;&lt;br /&gt;
:This parameter specifies if extra security measures are applied to resources which use [[dbConnect]] with MySQL.&lt;br /&gt;
:The extra measures are:&lt;br /&gt;
: - script files cannot be accessed with [[fileOpen]]&lt;br /&gt;
: - [[meta.xml]] is read-only&lt;br /&gt;
:'''NOTE:''' This only protects resources which use [[dbConnect]] with MySQL.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
{{New items|6.0160|1.6.0-22790|&lt;br /&gt;
====elementdata_whitelisted====&lt;br /&gt;
:''&amp;lt;elementdata_whitelisted&amp;gt;0&amp;lt;/elementdata_whitelisted&amp;gt;&lt;br /&gt;
:Enables extra protection for [[SetElementData|element data]].&lt;br /&gt;
:When this option is enabled, the server ignores element data sync packets from the client, except for allowed keys.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{New items|6.0160|1.6.0-22815|&lt;br /&gt;
====check_duplicate_serials====&lt;br /&gt;
:''&amp;lt;check_duplicate_serials&amp;gt;1&amp;lt;/check_duplicate_serials&amp;gt;&lt;br /&gt;
:This parameter determines whether server will compare player serial on connection to any other serial present on server. &lt;br /&gt;
:When this option is enabled, the server will deny entry for player whose serial is already in use by other player on server. You might want to disable this when using VMs.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====player_triggered_event_interval====&lt;br /&gt;
:''&amp;lt;player_triggered_event_interval&amp;gt;1000&amp;lt;/player_triggered_event_interval&amp;gt;&lt;br /&gt;
:Time interval for counting max (see below: max_player_triggered_events_per_interval) triggered events (via triggerServerEvent), exceeding this will call [[onPlayerTriggerEventThreshold]]&lt;br /&gt;
:Values: 50-5000; default: 1000 (in ms)&lt;br /&gt;
&lt;br /&gt;
====max_player_triggered_events_per_interval====&lt;br /&gt;
:''&amp;lt;max_player_triggered_events_per_interval&amp;gt;100&amp;lt;/max_player_triggered_events_per_interval&amp;gt;&lt;br /&gt;
:Max triggered amount of events (via triggerServerEvent) within interval above (player_triggered_event_interval), exceeding this will call [[onPlayerTriggerEventThreshold]]&lt;br /&gt;
:Values: 1-1000; default: 100&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22930|&lt;br /&gt;
====player_teleport_alert====  &lt;br /&gt;
:''&amp;lt;player_teleport_alert&amp;gt;100&amp;lt;/player_teleport_alert&amp;gt;  &lt;br /&gt;
:Defines the maximum allowed unexpected position change (in units). If a player's position changes by more than this value without using [[setElementPosition]], the event [[onPlayerTeleport]] will be triggered.  &lt;br /&gt;
:Values: 5-500; default: 100&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====module====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;module src=&amp;quot;sample_win32.dll&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;module src=&amp;quot;sample_linux.so&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the module(s) which are loaded with the server. To load several modules, add more &amp;lt;module&amp;gt; parameter(s). Optional parameter.&lt;br /&gt;
&lt;br /&gt;
====resource_client_file_checks====&lt;br /&gt;
&amp;lt;!-- added by https://github.com/multitheftauto/mtasa-blue/pull/3822 --&amp;gt;&lt;br /&gt;
:''&amp;lt;resource_client_file_checks&amp;gt;1&amp;lt;/resource_client_file_checks&amp;gt;&lt;br /&gt;
:If enabled, the server will perform checks on files in resources (listed in [[meta.xml]]) with PNG, TXD and DFF extensions, checking if they are corrupted. When the system finds a non-valid file of these types, it outputs a warning to the server console.&lt;br /&gt;
:You may want to disable thse checks when storing different/non-conforming data in files with these extensions (e.g. encrypted data).&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====resource====&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;admin&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;defaultstats&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;helpmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;joinquit&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;mapcycler&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;mapmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;parachute&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;resourcebrowser&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;1&amp;quot; default=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;resourcemanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;scoreboard&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;spawnmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;voice&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;votemanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;webadmin&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;play&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src-&amp;quot;resources&amp;quot; startup&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot;&lt;br /&gt;
:Specifies persistent resources which are loaded when the server starts. Persistent resources are not stopped even if all the other resources that depend on them stop; that is, the only way to stop them is by explicitly using the ''stop'' server command or [[stopResource]] scripting function. To load several resources, add more &amp;lt;resource&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
:In addition, there are several flags which control how the server deals with each resource:&lt;br /&gt;
&lt;br /&gt;
:* '''src''': the resource name. This is the only mandatory flag.&lt;br /&gt;
:* '''startup''': controls whether the resource will be started with the server or not. If &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot;, the resource will be started. If not specified, defaults to not starting the resource.&lt;br /&gt;
:* '''protected''': if &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot;, the resource will not be able to be stopped when started. Otherwise, even if not specified, it will default to the normal behaviour.&lt;br /&gt;
:* '''default''': if given a &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot; value, this resource will be the one who populates the built-in HTTP server main page, which is seen when no resource is given in the web address. It is not possible to have more than one default resource.&lt;br /&gt;
&lt;br /&gt;
====busy_sleep_time====&lt;br /&gt;
:''&amp;lt;busy_sleep_time&amp;gt;-1&amp;lt;/busy_sleep_time&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - This parameter configures the server's sleep duration in milliseconds during busy processing, affecting CPU usage and responsiveness.  &lt;br /&gt;
:Available range: -1 to 50; default value: -1  &lt;br /&gt;
:-1 sets the server to automatically determine the optimal value based on workload.  &lt;br /&gt;
:Setting it to 0 is recommended for achieving the best performance but may result in higher CPU usage.  &lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
====idle_sleep_time====&lt;br /&gt;
:''&amp;lt;idle_sleep_time&amp;gt;-1&amp;lt;/idle_sleep_time&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - This parameter configures the server's sleep duration in milliseconds during idle periods, affecting CPU usage and responsiveness.&lt;br /&gt;
:Available range: -1 to 50; default value: -1&lt;br /&gt;
:-1 sets the server to automatically determine the optimal value based on workload.&lt;br /&gt;
:Setting it to 10 is recommended for achieving the best performance while balancing CPU usage.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
==Deprecated settings==&lt;br /&gt;
&lt;br /&gt;
The following settings have been deprecated in the production version of MTA:SA and no longer work.&lt;br /&gt;
&lt;br /&gt;
====networkencryption====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf - also seems to be deprecated in code --&amp;gt;&lt;br /&gt;
:''&amp;lt;networkencryption&amp;gt;1&amp;lt;/networkencryption&amp;gt;&lt;br /&gt;
:This parameter specifies whether communications between the server and client is encrypted. Encryption can help prevent network data being viewed and modified.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1. Optional parameter.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====autologin====&lt;br /&gt;
&amp;lt;!-- removed from MTA:SA at https://github.com/multitheftauto/mtasa-blue/commit/e392c417da03b295c7f8342a7f6c1467d094db12#diff-b828bcbfff7135920f9a1179be3e3617 --&amp;gt;&lt;br /&gt;
:''&amp;lt;autologin&amp;gt;0&amp;lt;/autologin&amp;gt;&lt;br /&gt;
:Specifies whether or not players should automatically be logged in based on their IP adresses.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0.&lt;br /&gt;
&lt;br /&gt;
====httpautoclientfiles====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf - doesn't exists in code too --&amp;gt;&lt;br /&gt;
:''&amp;lt;httpautoclientfiles&amp;gt;1&amp;lt;/httpautoclientfiles&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Support]]&lt;br /&gt;
[[ru:Server mtaserver.conf]]&lt;br /&gt;
[[pl:mtaserver.conf]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Server_mtaserver.conf&amp;diff=82106</id>
		<title>Server mtaserver.conf</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Server_mtaserver.conf&amp;diff=82106"/>
		<updated>2025-06-05T07:05:32Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Add check_duplicate_serials by Nico (https://github.com/multitheftauto/mtasa-blue/pull/3854)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists the settings that can be set in the settings file. ''Setting from the default '''mtaserver.conf''' settings file is in italics''.&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
&lt;br /&gt;
====servername====&lt;br /&gt;
:''&amp;lt;servername&amp;gt;Default MTA Server&amp;lt;/servername&amp;gt;''&lt;br /&gt;
:This parameter specifies the name the server will be visible as in the ingame server browser and on Game-Monitor. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====rule====&lt;br /&gt;
:''&amp;lt;rule name=&amp;quot;NAME_HERE&amp;quot; value=&amp;quot;VALUE_HERE&amp;quot;/&amp;gt;''&lt;br /&gt;
:The rule parameters are optional. There can be as many as you want in the config file. They contain information for the Server Browser/List. [[Server_Browser_Rules|Read this article for more information]].&lt;br /&gt;
&lt;br /&gt;
====owner_email_address====&lt;br /&gt;
:''&amp;lt;owner_email_address&amp;gt;&amp;lt;/owner_email_address&amp;gt;''&lt;br /&gt;
:This parameter specifies the contact email addresses for the owner(s) of this server. &lt;br /&gt;
:The email addresses will not be publicly available, and only used by MTA administrators to contact the server owner. &lt;br /&gt;
:Note: Missing or incorrect owner_email_address can affect visibility in the master server list. &lt;br /&gt;
:Values: Comma separated list of email addresses&lt;br /&gt;
&lt;br /&gt;
====serverip====&lt;br /&gt;
:''&amp;lt;serverip&amp;gt;auto&amp;lt;/serverip&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - it is generally only needed for complex network topologies and should be left at the default value otherwise.&lt;br /&gt;
: This parameter specifies the public IP address that the server will announce to the MTA servers, for the purposes of registering itself in the master server list and receiving some internal status updates. Usually, setting this parameter is only useful for some specialized scenarios, like servers that can be reached by multiple public addresses, or when a firewall is used for controlling incoming connections. If set to auto, the public IP address the requests originate from will be used as the server IP for communicating with MTA servers, which works fine in most cases.&lt;br /&gt;
:Values: auto or x.x.x.x ; default value: auto&lt;br /&gt;
:SERVERIP SHOULD BE LEFT SET TO auto UNLESS YOU ARE SURE OF WHAT YOU ARE DOING&lt;br /&gt;
:WARNING: SETTING serverip AND THEN ASKING FOR SUPPORT CAN CAUSE DEATH OR INJURY&lt;br /&gt;
&lt;br /&gt;
====serverport====&lt;br /&gt;
:''&amp;lt;serverport&amp;gt;22003&amp;lt;/serverport&amp;gt; &lt;br /&gt;
:This parameter specifies the UDP port on which the server will be accepting incoming player connections;&lt;br /&gt;
:default value: 22003. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====maxplayers====&lt;br /&gt;
:''&amp;lt;maxplayers&amp;gt;32&amp;lt;/maxplayers&amp;gt;&lt;br /&gt;
:This parameter specifies the number of maximum player slots available on the server;&lt;br /&gt;
:default value: 32. It is a required parameter.&lt;br /&gt;
&lt;br /&gt;
====httpserver====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;httpserver&amp;gt;1&amp;lt;/httpserver&amp;gt;&lt;br /&gt;
:This parameter specifies whether the built-in http server will be used.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1. Optional parameter.&lt;br /&gt;
:More information: [[Server_Manual#Using_the_web_interface|Using the web interface]]&lt;br /&gt;
&lt;br /&gt;
====httpport====&lt;br /&gt;
:''&amp;lt;httpport&amp;gt;22005&amp;lt;/httpport&amp;gt;&lt;br /&gt;
:This parameter specifies the TCP port on which the server will be accepting incoming http connections. It can be set to the same value as &amp;lt;serverport&amp;gt;. It is a required parameter if &amp;lt;httpserver&amp;gt; is set to 1.&lt;br /&gt;
:More information: [[Server_Manual#Using_the_web_interface|Using the web interface]]&lt;br /&gt;
&lt;br /&gt;
====httpdownloadurl====&lt;br /&gt;
:''&amp;lt;httpdownloadurl&amp;gt;&amp;lt;/httpdownloadurl&amp;gt;&lt;br /&gt;
:If set, this parameter specifies the external URL from which clients will be able to download needed resources ingame. Otherwise they will download them directly from the server.&lt;br /&gt;
:More information: [[Server_Manual#Configuring_an_external_web_server|Configuring an external web server]]&lt;br /&gt;
&lt;br /&gt;
====httpmaxconnectionsperclient====&lt;br /&gt;
:''&amp;lt;httpmaxconnectionsperclient&amp;gt;5&amp;lt;/httpmaxconnectionsperclient&amp;gt;&lt;br /&gt;
:This parameter limits the number of http connections each client can make. Depending on the type of http server that is used, a lower figure may reduce download timeouts. Only relevant when using an external http server.&lt;br /&gt;
:Available range: 1 to 8.&lt;br /&gt;
&lt;br /&gt;
====httpthreadcount====&lt;br /&gt;
:''&amp;lt;httpthreadcount&amp;gt;8&amp;lt;/httpthreadcount&amp;gt;&lt;br /&gt;
:Number of HTTP server threads.&lt;br /&gt;
:Available range: 1 to 20. default value: 8&lt;br /&gt;
&lt;br /&gt;
====httpdosthreshold====&lt;br /&gt;
:''&amp;lt;httpdosthreshold&amp;gt;20&amp;lt;/httpdosthreshold&amp;gt;&lt;br /&gt;
:This parameter limits the number http connections that an IP can initiate over a short period of time.&lt;br /&gt;
:Available range: 1 to 100. default value: 20&lt;br /&gt;
&lt;br /&gt;
====http_dos_exclude====&lt;br /&gt;
:''&amp;lt;http_dos_exclude&amp;gt;&amp;lt;/http_dos_exclude&amp;gt;&lt;br /&gt;
:This parameter lists the IP addresses that are to be excluded from http dos threshold limits.&lt;br /&gt;
:e.g. 88.11.22.33,101.2.3.4&lt;br /&gt;
&lt;br /&gt;
====allow_gta3_img_mods====&lt;br /&gt;
:''&amp;lt;allow_gta3_img_mods&amp;gt;none&amp;lt;/allow_gta3_img_mods&amp;gt;&lt;br /&gt;
:By default, the server will block the use of locally customized gta3.img player skins&lt;br /&gt;
:This setting can be used to allow such mods. Not recommended for competitive servers.&lt;br /&gt;
:Values: none, peds ; default value: none&lt;br /&gt;
&lt;br /&gt;
====client_file====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;client_file name=&amp;quot;data/carmods.dat&amp;quot; verify=&amp;quot;0&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:By default, the server will block the use of customized GTA:SA data files.&lt;br /&gt;
:To allow specific client files, add one or more of the above lines.&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cclient_file_name.3D.22data.2Fcarmods.dat.22_verify.3D.220.22.2F.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====disableac====&lt;br /&gt;
:''&amp;lt;disableac&amp;gt;&amp;lt;/disableac&amp;gt;&lt;br /&gt;
:Comma separated list of disabled anti-cheats.&lt;br /&gt;
:e.g. To disable anti-cheat #2 and #3, use: 2,3&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cdisableac.3E.3C.2Fdisableac.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====enablesd====&lt;br /&gt;
:''&amp;lt;enablesd&amp;gt;31,32&amp;lt;/enablesd&amp;gt;&lt;br /&gt;
:Comma separated list of enabled special detections. A special detection is a type of anti-cheat for (usually) harmless game modifications. &lt;br /&gt;
:Competitive servers may wish to enable certain special detections, but most servers should leave this setting on its default.&lt;br /&gt;
:Values: special detection (SD) codes ; default value: 31,32 (e.g. enables special detections #31 and #32)&lt;br /&gt;
:More information: [[Anti-cheat_guide#.3Cenablesd.3E.3C.2Fenablesd.3E|Anti-cheat guide]]&lt;br /&gt;
&lt;br /&gt;
====hideac====&lt;br /&gt;
:''&amp;lt;hideac&amp;gt;0&amp;lt;/hideac&amp;gt;&lt;br /&gt;
:When this parameter is enabled client won't get any info about Anticheat settings when connecting to server.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0. Optional parameter.&lt;br /&gt;
&lt;br /&gt;
====minclientversion====&lt;br /&gt;
:''&amp;lt;minclientversion&amp;gt;&amp;lt;/minclientversion&amp;gt;&lt;br /&gt;
:Minimum client version. Clients with a lower version will not be allowed to connect. After disconnection, clients will be given an opportunity to download an update. If left blank, this setting is disabled and there are no restrictions on who can connect. Version numbers are described in [[getPlayerVersion]] and look like this: 1.6.0-9.22953.0&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:'''Note that this setting only determines if the client should be prompted to update. The actual build number they receive will be the [[https://nightly.mtasa.com/ver highest available]].'''&lt;br /&gt;
&lt;br /&gt;
====minclientversion_auto_update====&lt;br /&gt;
:''&amp;lt;minclientversion_auto_update&amp;gt;1&amp;lt;/minclientversion_auto_update&amp;gt;&lt;br /&gt;
:This parameter specifies if/when the &amp;lt;minclientversion&amp;gt; setting is automatically updated.&lt;br /&gt;
:Keeping &amp;lt;minclientversion&amp;gt; updated can help reduce cheating.&lt;br /&gt;
:Note: The instant setting (2) is only recommended for competitive servers.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled (delayed by a few days), 2 - enabled (instant) ; default value: 1.&lt;br /&gt;
&lt;br /&gt;
====recommendedclientversion====&lt;br /&gt;
:''&amp;lt;recommendedclientversion&amp;gt;&amp;lt;/recommendedclientversion&amp;gt;&lt;br /&gt;
:Recommended client version. When connecting, if clients have a lower version, they will be given the option to download an update. If left blank, this setting is disabled.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:'''Note that this setting only determines if the client should be prompted to update. The actual build number they receive will be the [[https://nightly.mtasa.com/ver highest available]].'''&lt;br /&gt;
&lt;br /&gt;
====ase====&lt;br /&gt;
:''&amp;lt;ase&amp;gt;1&amp;lt;/ase&amp;gt;&lt;br /&gt;
:This parameter can be used to make the server report to Game-Monitor master servers, allowing it to be visible in the in-game server browser. An additional UDP port needs to be available for this to work (value from &amp;lt;serverport&amp;gt; + 123 , so on a default &amp;lt;serverport&amp;gt; value 22003 the right port will be 22126 ).&lt;br /&gt;
:Available values: 0 - disabled , 1 - enabled. Optional parameter, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====donotbroadcastlan====&lt;br /&gt;
:''&amp;lt;donotbroadcastlan&amp;gt;0&amp;lt;/donotbroadcastlan&amp;gt;&lt;br /&gt;
:This parameter allows you to disable LAN broadcasting.	&lt;br /&gt;
&lt;br /&gt;
====password====&lt;br /&gt;
:''&amp;lt;password&amp;gt;&amp;lt;/password&amp;gt; &lt;br /&gt;
:If set, players will have to provide a password specified below, before they can connect to the server. If left blank, server doesn't require a password from them.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerPassword]] or [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====net_auto_filter====&lt;br /&gt;
:''&amp;lt;net_auto_filter&amp;gt;1&amp;lt;/net_auto_filter&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Net auto filter.&lt;br /&gt;
:Values: 0 - disabled, 1 - enabled. default value: 1&lt;br /&gt;
&lt;br /&gt;
====update_cycle_datagrams_limit====&lt;br /&gt;
:''&amp;lt;update_cycle_datagrams_limit&amp;gt;4&amp;lt;/update_cycle_datagrams_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Send datagrams limit.&lt;br /&gt;
:Available range: 1 to 100. default value: 4&lt;br /&gt;
&lt;br /&gt;
====update_cycle_messages_limit====&lt;br /&gt;
:''&amp;lt;update_cycle_messages_limit&amp;gt;50&amp;lt;/update_cycle_messages_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Send messages limit.&lt;br /&gt;
:Available range: 10 to 1000. default value: 50&lt;br /&gt;
&lt;br /&gt;
====bandwidth_reduction====&lt;br /&gt;
:''&amp;lt;bandwidth_reduction&amp;gt;medium&amp;lt;/bandwidth_reduction&amp;gt; &lt;br /&gt;
:This parameter reduces the server's bandwidth usage by using various optimizations.&lt;br /&gt;
:Values: none, medium or maximum ; default value: medium&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====unoccupied_vehicle_syncer_distance====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;unoccupied_vehicle_syncer_distance&amp;gt;130&amp;lt;/unoccupied_vehicle_syncer_distance&amp;gt;&lt;br /&gt;
:This parameter determines the distance limit for remote synced unoccupied vehicles&lt;br /&gt;
:Available range: 50 - 400; default value: 130&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====ped_syncer_distance====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;ped_syncer_distance&amp;gt;100&amp;lt;/ped_syncer_distance&amp;gt;&lt;br /&gt;
:This parameter determines the distance limit for remote synced peds&lt;br /&gt;
:Available range: 50 - 400; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====player_sync_interval====&lt;br /&gt;
:''&amp;lt;player_sync_interval&amp;gt;100&amp;lt;/player_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between player sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====lightweight_sync_interval====&lt;br /&gt;
:''&amp;lt;lightweight_sync_interval&amp;gt;1500&amp;lt;/lightweight_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between lightweight (player) sync packets.&lt;br /&gt;
:Available range: 200 - 4000; default value: 1500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====camera_sync_interval====&lt;br /&gt;
:''&amp;lt;camera_sync_interval&amp;gt;500&amp;lt;/camera_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between camera sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====ped_sync_interval====&lt;br /&gt;
:''&amp;lt;ped_sync_interval&amp;gt;500&amp;lt;/ped_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between ped sync packets when the ped is near the player.&lt;br /&gt;
:Available range: 50 - 4000; default value: 500&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====ped_far_sync_interval====&lt;br /&gt;
:''&amp;lt;ped_far_sync_interval&amp;gt;2000&amp;lt;/ped_far_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between ped sync packets when the ped is far away from the player.&lt;br /&gt;
:Available range: 50 - 4000; default value: 2000&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====unoccupied_vehicle_sync_interval====&lt;br /&gt;
:''&amp;lt;unoccupied_vehicle_sync_interval&amp;gt;400&amp;lt;/unoccupied_vehicle_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the time in milliseconds between unoccupied vehicle sync packets.&lt;br /&gt;
:Available range: 50 - 4000; default value: 400&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====keysync_mouse_sync_interval====&lt;br /&gt;
:''&amp;lt;keysync_mouse_sync_interval&amp;gt;100&amp;lt;/keysync_mouse_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the minimum time in milliseconds between key sync packets due to mouse movement.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====keysync_analog_sync_interval====&lt;br /&gt;
:''&amp;lt;keysync_analog_sync_interval&amp;gt;100&amp;lt;/keysync_analog_sync_interval&amp;gt; &lt;br /&gt;
:This parameter determines the minimum time in milliseconds between key sync packets due to joystick movement.&lt;br /&gt;
:Available range: 50 - 4000; default value: 100&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
:Suggested values for this and the other sync_interval settings can be found here: [[Sync_interval_settings|Sync interval settings]]&lt;br /&gt;
&lt;br /&gt;
====donkey_work_interval====&lt;br /&gt;
:''&amp;lt;donkey_work_interval&amp;gt;100&amp;lt;/donkey_work_interval&amp;gt;&lt;br /&gt;
:Update near list interval in milliseconds.&lt;br /&gt;
:Available range: 50 to 4000. default value: 100&lt;br /&gt;
&lt;br /&gt;
====bullet_sync====&lt;br /&gt;
:''&amp;lt;bullet_sync&amp;gt;1&amp;lt;/bullet_sync&amp;gt;   &lt;br /&gt;
:This parameter can improve the reliability of shots when using certain weapons. However, it uses more bandwidth.&lt;br /&gt;
:Note that bullet sync will be active regardless of this setting when certain [[setGlitchEnabled|glitches]] are enabled.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22430|&lt;br /&gt;
====vehicle_contact_sync_radius====&lt;br /&gt;
:''&amp;lt;vehicle_contact_sync_radius&amp;gt;30&amp;lt;/vehicle_contact_sync_radius&amp;gt;   &lt;br /&gt;
:This parameter specifies the radius in which any contact with a vehicle will turn the player into its syncer.&lt;br /&gt;
:Changing this setting to 0 will cause vehicles to not pick a new syncer based on which player is touching the vehicle.&lt;br /&gt;
:Available range: 0 to 130.  Default - 30&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====vehext_percent====&lt;br /&gt;
:''&amp;lt;vehext_percent&amp;gt;0&amp;lt;/vehext_percent&amp;gt;&lt;br /&gt;
:This parameter sets the amount of extrapolation that clients will apply to remote vehicles. &lt;br /&gt;
:This can reduce some of the latency induced location disparency by predicting where the remote vehicles will probably be.&lt;br /&gt;
:Depending on the gamemode, an incorrect prediction may have a negative effect. &lt;br /&gt;
:Therefore this setting should be considered experimental.&lt;br /&gt;
:Available range: 0 to 100.  Default - 0&lt;br /&gt;
&lt;br /&gt;
====vehext_ping_limit====&lt;br /&gt;
:''&amp;lt;vehext_ping_limit&amp;gt;150&amp;lt;/vehext_ping_limit&amp;gt;&lt;br /&gt;
:This parameter places a limit on how much time (in milliseconds) the vehicle extrapolation will attempt to compensate for.&lt;br /&gt;
:Only relevant if &amp;lt;vehext_percent&amp;gt; is greater than zero.&lt;br /&gt;
:Available range: 50 to 500.  Default - 150&lt;br /&gt;
&lt;br /&gt;
====latency_reduction====&lt;br /&gt;
:''&amp;lt;latency_reduction&amp;gt;0&amp;lt;/latency_reduction&amp;gt;&lt;br /&gt;
:This parameter can reduce the delay of player actions appearing on remote clients by 2 frames (approx 50ms).&lt;br /&gt;
:Due to the impact this may have on shot lag compensation, it should be considered experimental.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0.&lt;br /&gt;
:Bugs caused by enabling latency_reduction: https://bugs.mtasa.com/view.php?id=8191 + https://bugs.mtasa.com/view.php?id=8226&lt;br /&gt;
&lt;br /&gt;
====threadnet====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;threadnet&amp;gt;1&amp;lt;/threadnet&amp;gt;&lt;br /&gt;
:This parameter specifies whether or not to run the network synchronization on another thread.&lt;br /&gt;
:Enabling will make the sync smoother, but may increase CPU usage slightly.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====idfile====&lt;br /&gt;
:''&amp;lt;idfile&amp;gt;server-id.keys&amp;lt;/idfile&amp;gt; &lt;br /&gt;
:Specifies the location and file name of this servers unique private key. This is used to prevent private files saved on the client from being read by other servers. &lt;br /&gt;
:Keep a backup of this file in a safe place. Default value: server-id.keys&lt;br /&gt;
:More information about client private files: [[Filepath]]&lt;br /&gt;
&lt;br /&gt;
====logfile====&lt;br /&gt;
:''&amp;lt;logfile&amp;gt;logs/server.log&amp;lt;/logfile&amp;gt;&lt;br /&gt;
:Specifies the location and name of the main server log file. If left blank, server won't be saving this file.&lt;br /&gt;
&lt;br /&gt;
====authfile====&lt;br /&gt;
:''&amp;lt;authfile&amp;gt;logs/server_auth.log&amp;lt;/authfile&amp;gt;&lt;br /&gt;
:As well as the main log file, login successes and failures are logged here for easy reviewing of security issues. If left blank, this file is not used&lt;br /&gt;
&lt;br /&gt;
====dbfile====&lt;br /&gt;
:''&amp;lt;dbfile&amp;gt;logs/db.log&amp;lt;/dbfile&amp;gt;&lt;br /&gt;
:Specifies the location and name of the file used to log database queries. The server command [[Server_Commands#debugdb|debugdb]] sets the amount of logging.&lt;br /&gt;
&lt;br /&gt;
====loadstringfile====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;loadstringfile&amp;gt;logs/loadstring.log&amp;lt;/loadstringfile&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the location and name of the file used to log loadstring function calls. If left blank or not set, no logging is done.&lt;br /&gt;
&lt;br /&gt;
====acl====&lt;br /&gt;
:''&amp;lt;acl&amp;gt;acl.xml&amp;lt;/acl&amp;gt; &lt;br /&gt;
:This parameter specifies the location and name of the Access Control List settings file. If left&lt;br /&gt;
:blank, server will use acl.xml file, located in the same folder as this configuration file.&lt;br /&gt;
&lt;br /&gt;
====scriptdebuglogfile====&lt;br /&gt;
:''&amp;lt;scriptdebuglogfile&amp;gt;logs/scripts.log&amp;lt;/scriptdebuglogfile&amp;gt; &lt;br /&gt;
:Specifies the location and name of the debugscript log file. If left blank, server won't be saving this file.&lt;br /&gt;
&lt;br /&gt;
====scriptdebugloglevel====&lt;br /&gt;
:''&amp;lt;scriptdebugloglevel&amp;gt;0&amp;lt;/scriptdebugloglevel&amp;gt;&lt;br /&gt;
:Specifies the level of the debugscript log file. Available values: 0, 1, 2, 3. When not set, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====htmldebuglevel====&lt;br /&gt;
:''&amp;lt;htmldebuglevel&amp;gt;0&amp;lt;/htmldebuglevel&amp;gt;&lt;br /&gt;
:Specifies the level of the html debug. Available values: 0, 1, 2, 3. When not set, defaults to 0.&lt;br /&gt;
&lt;br /&gt;
====filter_duplicate_log_lines====&lt;br /&gt;
:''&amp;lt;filter_duplicate_log_lines&amp;gt;1&amp;lt;/filter_duplicate_log_lines&amp;gt;&lt;br /&gt;
:Specifies whether or not duplicate log lines should be filtered. Available values: 0 or 1, defaults to 1.&lt;br /&gt;
&lt;br /&gt;
====fpslimit====&lt;br /&gt;
:''&amp;lt;fpslimit&amp;gt;74&amp;lt;/fpslimit&amp;gt;&lt;br /&gt;
:Specifies the frame rate limit that will be applied to connecting clients.&lt;br /&gt;
:Available range: 25 to 32767. Default: 74. You can also use 0 for uncapped fps.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====voice====&lt;br /&gt;
:''&amp;lt;voice&amp;gt;0&amp;lt;/voice&amp;gt;&lt;br /&gt;
:This parameter specifies whether or not to enable player voice chat in-game&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled&lt;br /&gt;
&lt;br /&gt;
====voice_samplerate====&lt;br /&gt;
:''&amp;lt;voice_samplerate&amp;gt;1&amp;lt;/voice_samplerate&amp;gt;&lt;br /&gt;
:This parameter specifies the sample rate for voice chat.  'voice' parameter must be set to 1 for this to be effective. Higher settings use more bandwidth and increase the sampling quality of voice chat&lt;br /&gt;
:Values: 0 - Narrowband (8kHz), 1 - Wideband (16kHz), 2 - Ultrawideband (32kHz).  Default - 1&lt;br /&gt;
&lt;br /&gt;
====voice_quality====&lt;br /&gt;
:''&amp;lt;voice_quality&amp;gt;4&amp;lt;/voice_quality&amp;gt;&lt;br /&gt;
:This parameter specifies the voice quality for voice chat.  'voice' parameter must be set to 1 for this to be effective. Higher settings use more bandwidth and increase the the overall quality of voice chat&lt;br /&gt;
:Available range: 0 to 10.  Default - 4&lt;br /&gt;
&lt;br /&gt;
====voice_bitrate====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;voice_bitrate&amp;gt;24600&amp;lt;/voice_bitrate&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the voice bitrate, in bps. This optional parameter overrides the previous two settings. If not set, MTA handles this automatically.  Use with care.&lt;br /&gt;
&lt;br /&gt;
====backup_path====&lt;br /&gt;
:''&amp;lt;backup_path&amp;gt;backups&amp;lt;/backup_path&amp;gt;&lt;br /&gt;
:This parameter specifies the path to use for a basic backup of some server files. Note that basic backups are only made during server startup. Default value: backups&lt;br /&gt;
&lt;br /&gt;
====backup_interval====&lt;br /&gt;
:''&amp;lt;backup_interval&amp;gt;3&amp;lt;/backup_interval&amp;gt;&lt;br /&gt;
:This parameter specifies the number of days between each basic backup. Backups are only made during server startup, so the actual interval maybe much longer. Setting backup_interval to 0 will disable backups&lt;br /&gt;
:Available range: 0 to 30.  Default - 3&lt;br /&gt;
&lt;br /&gt;
====backup_copies====&lt;br /&gt;
:''&amp;lt;backup_copies&amp;gt;10&amp;lt;/backup_copies&amp;gt;&lt;br /&gt;
:This parameter specifies the maximum number of backup copies to keep. Setting backup_copies to 0 will disable backups&lt;br /&gt;
:Available range: 0 to 100.  Default - 10&lt;br /&gt;
&lt;br /&gt;
====compact_internal_databases====&lt;br /&gt;
:''&amp;lt;compact_internal_databases&amp;gt;1&amp;lt;/compact_internal_databases&amp;gt;&lt;br /&gt;
:This parameter specifies when the internal sqlite databases should be defragmented.&lt;br /&gt;
:For more info see: https://www.sqlite.org/lang_vacuum.html&lt;br /&gt;
:Values: 0 - Never, 1 - On server start only after basic backup, 2 - On server start always.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====server_logic_fps_limit====&lt;br /&gt;
:''&amp;lt;server_logic_fps_limit&amp;gt;0&amp;lt;/server_logic_fps_limit&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING'''&lt;br /&gt;
:Server logic FPS limit.&lt;br /&gt;
:Available range: 0 to 100. default value: 0&lt;br /&gt;
&lt;br /&gt;
====crash_dump_upload====&lt;br /&gt;
:''&amp;lt;crash_dump_upload&amp;gt;1&amp;lt;/crash_dump_upload&amp;gt;&lt;br /&gt;
:This parameter specifies whether server crash dump files should be sent to MTA HQ.&lt;br /&gt;
:Values: 0 - Off, 1 - On. Default - 1&lt;br /&gt;
&lt;br /&gt;
====fakelag====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf --&amp;gt;&lt;br /&gt;
:''&amp;lt;fakelag&amp;gt;0&amp;lt;/fakelag&amp;gt;&lt;br /&gt;
:This parameter specifies whether the [[Command fakelag|fakelag and sfakelag]] commands are enabled&lt;br /&gt;
:Values: 0 - Off, 1 - On. Default - 0&lt;br /&gt;
&lt;br /&gt;
====auth_serial_groups====&lt;br /&gt;
:''&amp;lt;auth_serial_groups&amp;gt;Admin&amp;lt;/auth_serial_groups&amp;gt;&lt;br /&gt;
:This parameter lists the ACL groups that are protected by serial authorization.&lt;br /&gt;
:Login attempts to a protected account from a second serial are blocked until the serial is manually authorized via the authserial command.&lt;br /&gt;
:For more info see: https://mtasa.com/authserial&lt;br /&gt;
:Note: This is security critical feature and disabling auth_serial_groups can affect visibility in the master server list.&lt;br /&gt;
:Values: Comma separated list of ACL groups.  Default - Admin&lt;br /&gt;
:See [[Authorized Serial Account Protection]] for more information.&lt;br /&gt;
&lt;br /&gt;
====auth_serial_http====&lt;br /&gt;
:''&amp;lt;auth_serial_http&amp;gt;1&amp;lt;/auth_serial_http&amp;gt;&lt;br /&gt;
:This parameter specifies if the authorized serial login checks should also apply to the http interface.&lt;br /&gt;
:Protected account login attempts to the http interface will only succeed if the IP address matches one recently used by the account holder in-game.&lt;br /&gt;
:For more info see: https://mtasa.com/authserialhttp&lt;br /&gt;
:Note: This is security critical feature and disabling auth_serial_http can affect visibility in the master server list.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====auth_serial_http_ip_exceptions====&lt;br /&gt;
:''&amp;lt;auth_serial_http_ip_exceptions&amp;gt;127.0.0.1&amp;lt;/auth_serial_http_ip_exceptions&amp;gt;&lt;br /&gt;
:This parameter specifies which IP addresses should always pass auth_serial_http checks.&lt;br /&gt;
:Values: Comma separated list of IP addresses&lt;br /&gt;
&lt;br /&gt;
====database_credentials_protection====&lt;br /&gt;
:''&amp;lt;database_credentials_protection&amp;gt;1&amp;lt;/database_credentials_protection&amp;gt;&lt;br /&gt;
:This parameter specifies if extra security measures are applied to resources which use [[dbConnect]] with MySQL.&lt;br /&gt;
:The extra measures are:&lt;br /&gt;
: - script files cannot be accessed with [[fileOpen]]&lt;br /&gt;
: - [[meta.xml]] is read-only&lt;br /&gt;
:'''NOTE:''' This only protects resources which use [[dbConnect]] with MySQL.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
{{New items|6.0160|1.6.0-22790|&lt;br /&gt;
====elementdata_whitelisted====&lt;br /&gt;
:''&amp;lt;elementdata_whitelisted&amp;gt;0&amp;lt;/elementdata_whitelisted&amp;gt;&lt;br /&gt;
:Enables extra protection for [[SetElementData|element data]].&lt;br /&gt;
:When this option is enabled, the server ignores element data sync packets from the client, except for allowed keys.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{New items|6.0160|1.6.0-22815|&lt;br /&gt;
====check_duplicate_serials====&lt;br /&gt;
:''&amp;lt;check_duplicate_serials&amp;gt;1&amp;lt;/check_duplicate_serials&amp;gt;&lt;br /&gt;
:This parameter determines whether server will compare player serial on player connection to any other serial present on server. &lt;br /&gt;
:When this option is enabled, the server will deny entry for player whose serial is already in use by other player on server. You might want to disable this when using VMs.&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====player_triggered_event_interval====&lt;br /&gt;
:''&amp;lt;player_triggered_event_interval&amp;gt;1000&amp;lt;/player_triggered_event_interval&amp;gt;&lt;br /&gt;
:Time interval for counting max (see below: max_player_triggered_events_per_interval) triggered events (via triggerServerEvent), exceeding this will call [[onPlayerTriggerEventThreshold]]&lt;br /&gt;
:Values: 50-5000; default: 1000 (in ms)&lt;br /&gt;
&lt;br /&gt;
====max_player_triggered_events_per_interval====&lt;br /&gt;
:''&amp;lt;max_player_triggered_events_per_interval&amp;gt;100&amp;lt;/max_player_triggered_events_per_interval&amp;gt;&lt;br /&gt;
:Max triggered amount of events (via triggerServerEvent) within interval above (player_triggered_event_interval), exceeding this will call [[onPlayerTriggerEventThreshold]]&lt;br /&gt;
:Values: 1-1000; default: 100&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|22930|&lt;br /&gt;
====player_teleport_alert====  &lt;br /&gt;
:''&amp;lt;player_teleport_alert&amp;gt;100&amp;lt;/player_teleport_alert&amp;gt;  &lt;br /&gt;
:Defines the maximum allowed unexpected position change (in units). If a player's position changes by more than this value without using [[setElementPosition]], the event [[onPlayerTeleport]] will be triggered.  &lt;br /&gt;
:Values: 5-500; default: 100&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====module====&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;module src=&amp;quot;sample_win32.dll&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:''&amp;lt;nowiki&amp;gt;&amp;lt;!-- &amp;lt;module src=&amp;quot;sample_linux.so&amp;quot; /&amp;gt; --&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
:Specifies the module(s) which are loaded with the server. To load several modules, add more &amp;lt;module&amp;gt; parameter(s). Optional parameter.&lt;br /&gt;
&lt;br /&gt;
====resource_client_file_checks====&lt;br /&gt;
&amp;lt;!-- added by https://github.com/multitheftauto/mtasa-blue/pull/3822 --&amp;gt;&lt;br /&gt;
:''&amp;lt;resource_client_file_checks&amp;gt;1&amp;lt;/resource_client_file_checks&amp;gt;&lt;br /&gt;
:If enabled, the server will perform checks on files in resources (listed in [[meta.xml]]) with PNG, TXD and DFF extensions, checking if they are corrupted. When the system finds a non-valid file of these types, it outputs a warning to the server console.&lt;br /&gt;
:You may want to disable thse checks when storing different/non-conforming data in files with these extensions (e.g. encrypted data).&lt;br /&gt;
:Values: 0 - Off, 1 - Enabled.  Default - 1&lt;br /&gt;
&lt;br /&gt;
====resource====&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;admin&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;defaultstats&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;helpmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;joinquit&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;mapcycler&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;mapmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;parachute&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;resourcebrowser&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;1&amp;quot; default=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;resourcemanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;scoreboard&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;spawnmanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;voice&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;votemanager&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;webadmin&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src=&amp;quot;play&amp;quot; startup=&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
:''&amp;lt;resource src-&amp;quot;resources&amp;quot; startup&amp;quot;1&amp;quot; protected=&amp;quot;0&amp;quot;&lt;br /&gt;
:Specifies persistent resources which are loaded when the server starts. Persistent resources are not stopped even if all the other resources that depend on them stop; that is, the only way to stop them is by explicitly using the ''stop'' server command or [[stopResource]] scripting function. To load several resources, add more &amp;lt;resource&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
:In addition, there are several flags which control how the server deals with each resource:&lt;br /&gt;
&lt;br /&gt;
:* '''src''': the resource name. This is the only mandatory flag.&lt;br /&gt;
:* '''startup''': controls whether the resource will be started with the server or not. If &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot;, the resource will be started. If not specified, defaults to not starting the resource.&lt;br /&gt;
:* '''protected''': if &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot;, the resource will not be able to be stopped when started. Otherwise, even if not specified, it will default to the normal behaviour.&lt;br /&gt;
:* '''default''': if given a &amp;quot;1&amp;quot;, &amp;quot;true&amp;quot; or &amp;quot;yes&amp;quot; value, this resource will be the one who populates the built-in HTTP server main page, which is seen when no resource is given in the web address. It is not possible to have more than one default resource.&lt;br /&gt;
&lt;br /&gt;
====busy_sleep_time====&lt;br /&gt;
:''&amp;lt;busy_sleep_time&amp;gt;-1&amp;lt;/busy_sleep_time&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - This parameter configures the server's sleep duration in milliseconds during busy processing, affecting CPU usage and responsiveness.  &lt;br /&gt;
:Available range: -1 to 50; default value: -1  &lt;br /&gt;
:-1 sets the server to automatically determine the optimal value based on workload.  &lt;br /&gt;
:Setting it to 0 is recommended for achieving the best performance but may result in higher CPU usage.  &lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
====idle_sleep_time====&lt;br /&gt;
:''&amp;lt;idle_sleep_time&amp;gt;-1&amp;lt;/idle_sleep_time&amp;gt;&lt;br /&gt;
:'''ONLY USE THIS PARAMETER IF YOU ARE SURE OF WHAT YOU ARE DOING''' - This parameter configures the server's sleep duration in milliseconds during idle periods, affecting CPU usage and responsiveness.&lt;br /&gt;
:Available range: -1 to 50; default value: -1&lt;br /&gt;
:-1 sets the server to automatically determine the optimal value based on workload.&lt;br /&gt;
:Setting it to 10 is recommended for achieving the best performance while balancing CPU usage.&lt;br /&gt;
:This parameter can be changed and saved while the server is running with [[setServerConfigSetting]].&lt;br /&gt;
&lt;br /&gt;
==Deprecated settings==&lt;br /&gt;
&lt;br /&gt;
The following settings have been deprecated in the production version of MTA:SA and no longer work.&lt;br /&gt;
&lt;br /&gt;
====networkencryption====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf - also seems to be deprecated in code --&amp;gt;&lt;br /&gt;
:''&amp;lt;networkencryption&amp;gt;1&amp;lt;/networkencryption&amp;gt;&lt;br /&gt;
:This parameter specifies whether communications between the server and client is encrypted. Encryption can help prevent network data being viewed and modified.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 1. Optional parameter.&lt;br /&gt;
:This parameter can changed and saved while the server is running with [[setServerConfigSetting]]&lt;br /&gt;
&lt;br /&gt;
====autologin====&lt;br /&gt;
&amp;lt;!-- removed from MTA:SA at https://github.com/multitheftauto/mtasa-blue/commit/e392c417da03b295c7f8342a7f6c1467d094db12#diff-b828bcbfff7135920f9a1179be3e3617 --&amp;gt;&lt;br /&gt;
:''&amp;lt;autologin&amp;gt;0&amp;lt;/autologin&amp;gt;&lt;br /&gt;
:Specifies whether or not players should automatically be logged in based on their IP adresses.&lt;br /&gt;
:Values: 0 - disabled , 1 - enabled ; default value: 0.&lt;br /&gt;
&lt;br /&gt;
====httpautoclientfiles====&lt;br /&gt;
&amp;lt;!-- no longer present in mtaserver.conf - doesn't exists in code too --&amp;gt;&lt;br /&gt;
:''&amp;lt;httpautoclientfiles&amp;gt;1&amp;lt;/httpautoclientfiles&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Support]]&lt;br /&gt;
[[ru:Server mtaserver.conf]]&lt;br /&gt;
[[pl:mtaserver.conf]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnClientPlayerWeaponFire&amp;diff=82105</id>
		<title>OnClientPlayerWeaponFire</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnClientPlayerWeaponFire&amp;diff=82105"/>
		<updated>2025-06-05T05:19:34Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Client event}}&lt;br /&gt;
__NOTOC__ &lt;br /&gt;
This event is called when a player fires a weapon.  This event does not trigger for melee weapons. Projectile weapons or the camera will only trigger the event if fired by the local player.&lt;br /&gt;
{{Note|This event is only triggered for players that are streamed in}}&lt;br /&gt;
{{Note|This does not trigger for any player's melee weapons or for remote player's projectile weapons or cameras}}&lt;br /&gt;
==Parameters==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
int weapon, int ammo, int ammoInClip, float hitX, float hitY, float hitZ, element hitElement, float startX, float startY, float startZ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
*'''weapon''':  an [[int]] representing [[weapons|weapon]] used for firing a shot.&lt;br /&gt;
*'''ammo''': an [[int]] amount of ammo left for this weapon type.&lt;br /&gt;
*'''ammoInClip''': an [[int]] amount of ammo left for this weapon type in clip.&lt;br /&gt;
*'''hitX''': [[float]] world X coordinate representing the hit point.&lt;br /&gt;
*'''hitY''': [[float]] world Y coordinate representing the hit point.&lt;br /&gt;
*'''hitZ''': [[float]] world Z coordinate representing the hit point.&lt;br /&gt;
*'''hitElement''': an [[element]] which was hit by a shot.&lt;br /&gt;
{{New feature/item|3.0131|1.3.1|4311|&lt;br /&gt;
*'''startX''': [[float]] world X coordinate representing the start of the bullet. Note: This is not the gun muzzle.&lt;br /&gt;
*'''startY''': [[float]] world Y coordinate representing the start of the bullet.&lt;br /&gt;
*'''startZ''': [[float]] world Z coordinate representing the start of the bullet.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the streamed in [[player]] who fired the weapon.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example implements custom gunshot sounds.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerWeaponSounds = {&lt;br /&gt;
	[22] = &amp;quot;sounds/weap/colt45.wav&amp;quot;,&lt;br /&gt;
	[23] = &amp;quot;sounds/weap/silenced.wav&amp;quot;,&lt;br /&gt;
	[24] = &amp;quot;sounds/weap/deagle.wav&amp;quot;,&lt;br /&gt;
	[25] = &amp;quot;sounds/weap/shotgun.wav&amp;quot;,&lt;br /&gt;
	[26] = &amp;quot;sounds/weap/sawed-off.wav&amp;quot;,&lt;br /&gt;
	[27] = &amp;quot;sounds/weap/combat shotgun.wav&amp;quot;,&lt;br /&gt;
	[28] = &amp;quot;sounds/weap/uzi.wav&amp;quot;,&lt;br /&gt;
	[30] = &amp;quot;sounds/weap/ak-47.wav&amp;quot;,&lt;br /&gt;
	[31] = &amp;quot;sounds/weap/m4.wav&amp;quot;,&lt;br /&gt;
	[32] = &amp;quot;sounds/weap/tec9.wav&amp;quot;,&lt;br /&gt;
	[34] = &amp;quot;sounds/weap/sniper.wav&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function playCustomWeaponSound(weaponID)&lt;br /&gt;
	local playerWeaponSoundPath = playerWeaponSounds[weaponID]&lt;br /&gt;
&lt;br /&gt;
	if (not playerWeaponSoundPath) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerMuzzleX, playerMuzzleY, playerMuzzleZ = getPedWeaponMuzzlePosition(source)&lt;br /&gt;
	local playerWeaponSound = playSound3D(playerWeaponSoundPath, playerMuzzleX, playerMuzzleY, playerMuzzleZ)&lt;br /&gt;
&lt;br /&gt;
	if (not playerWeaponSound) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	setSoundMaxDistance(playerWeaponSound, 90)&lt;br /&gt;
	setSoundVolume(playerWeaponSound, 0.6)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerWeaponFire&amp;quot;, root, playCustomWeaponSound)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example sends a warning to the local player if they shoot another player with a minigun.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--First, we create a function for the event handler to use.&lt;br /&gt;
function onClientPlayerWeaponFireFunc(weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement )&lt;br /&gt;
    if weapon == 38 and getElementType(hitElement)==&amp;quot;player&amp;quot; then -- If the player shoots with a minigun, and hits another player...&lt;br /&gt;
         outputChatBox ( &amp;quot;Don't kill people with minigun, it's lame!&amp;quot;, 255, 0, 0 ) -- We output a warning to him.&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
-- Add this as a handler so that the function will be triggered every time the local player fires.&lt;br /&gt;
addEventHandler ( &amp;quot;onClientPlayerWeaponFire&amp;quot;, localPlayer, onClientPlayerWeaponFireFunc )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example makes the Shotgun fire explosive rounds.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientPlayerWeaponFireFunc(weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement)&lt;br /&gt;
    if (weapon == 25) then -- If the player shoots with a shotgun&lt;br /&gt;
        createExplosion(hitX, hitY, hitZ, 12, true, 0, true) -- Creates a tiny explosion where the bullet hit.&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
-- Add this as a handler so that the function will be triggered every time a player fires.&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerWeaponFire&amp;quot;, root, onClientPlayerWeaponFireFunc)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
===Client player events===&lt;br /&gt;
{{Client_player_events}}&lt;br /&gt;
===Client event functions===&lt;br /&gt;
{{Client_event_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnClientPlayerWeaponFire&amp;diff=82104</id>
		<title>OnClientPlayerWeaponFire</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnClientPlayerWeaponFire&amp;diff=82104"/>
		<updated>2025-06-05T05:19:05Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Client event}}&lt;br /&gt;
__NOTOC__ &lt;br /&gt;
This event is called when a player fires a weapon.  This event does not trigger for melee weapons. Projectile weapons or the camera will only trigger the event if fired by the local player.&lt;br /&gt;
{{Note|This event is only triggered for players that are streamed in}}&lt;br /&gt;
{{Note|This does not trigger for any player's melee weapons or for remote player's projectile weapons or cameras}}&lt;br /&gt;
==Parameters==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
int weapon, int ammo, int ammoInClip, float hitX, float hitY, float hitZ, element hitElement, float startX, float startY, float startZ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
*'''weapon''':  an [[int]] representing [[weapons|weapon]] used for firing a shot.&lt;br /&gt;
*'''ammo''': an [[int]] amount of ammo left for this weapon type.&lt;br /&gt;
*'''ammoInClip''': an [[int]] amount of ammo left for this weapon type in clip.&lt;br /&gt;
*'''hitX''': [[float]] world X coordinate representing the hit point.&lt;br /&gt;
*'''hitY''': [[float]] world Y coordinate representing the hit point.&lt;br /&gt;
*'''hitZ''': [[float]] world Z coordinate representing the hit point.&lt;br /&gt;
*'''hitElement''': an [[element]] which was hit by a shot.&lt;br /&gt;
{{New feature/item|3.0131|1.3.1|4311|&lt;br /&gt;
*'''startX''': [[float]] world X coordinate representing the start of the bullet. Note: This is not the gun muzzle.&lt;br /&gt;
*'''startY''': [[float]] world Y coordinate representing the start of the bullet.&lt;br /&gt;
*'''startZ''': [[float]] world Z coordinate representing the start of the bullet.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the streamed in [[player]] who fired the weapon.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example implements custom gunshot sounds.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerWeaponSounds = {&lt;br /&gt;
	[22] = &amp;quot;sounds/weap/colt45.wav&amp;quot;,&lt;br /&gt;
	[23] = &amp;quot;sounds/weap/silenced.wav&amp;quot;,&lt;br /&gt;
	[24] = &amp;quot;sounds/weap/deagle.wav&amp;quot;,&lt;br /&gt;
	[25] = &amp;quot;sounds/weap/shotgun.wav&amp;quot;,&lt;br /&gt;
	[26] = &amp;quot;sounds/weap/sawed-off.wav&amp;quot;,&lt;br /&gt;
	[27] = &amp;quot;sounds/weap/combat shotgun.wav&amp;quot;,&lt;br /&gt;
	[28] = &amp;quot;sounds/weap/uzi.wav&amp;quot;,&lt;br /&gt;
	[30] = &amp;quot;sounds/weap/ak-47.wav&amp;quot;,&lt;br /&gt;
	[31] = &amp;quot;sounds/weap/m4.wav&amp;quot;,&lt;br /&gt;
	[32] = &amp;quot;sounds/weap/tec9.wav&amp;quot;,&lt;br /&gt;
	[34] = &amp;quot;sounds/weap/sniper.wav&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function playCustomWeaponSound(weaponID)&lt;br /&gt;
	local playerWeaponSoundPath = playerWeaponSounds[weaponID]&lt;br /&gt;
&lt;br /&gt;
	if (not playerWeaponSoundPath) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerMuzzleX, playerMuzzleY, playerMuzzleZ = getPedWeaponMuzzlePosition(source)&lt;br /&gt;
	local playerWeaponSound = playSound3D(playerWeaponSoundPath, playerMuzzleX, playerMuzzleY, playerMuzzleZ)&lt;br /&gt;
&lt;br /&gt;
	if (not playerWeaponCustomSoundPath) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	setSoundMaxDistance(playerWeaponSound, 90)&lt;br /&gt;
	setSoundVolume(playerWeaponSound, 0.6)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerWeaponFire&amp;quot;, root, playCustomWeaponSound)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example sends a warning to the local player if they shoot another player with a minigun.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--First, we create a function for the event handler to use.&lt;br /&gt;
function onClientPlayerWeaponFireFunc(weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement )&lt;br /&gt;
    if weapon == 38 and getElementType(hitElement)==&amp;quot;player&amp;quot; then -- If the player shoots with a minigun, and hits another player...&lt;br /&gt;
         outputChatBox ( &amp;quot;Don't kill people with minigun, it's lame!&amp;quot;, 255, 0, 0 ) -- We output a warning to him.&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
-- Add this as a handler so that the function will be triggered every time the local player fires.&lt;br /&gt;
addEventHandler ( &amp;quot;onClientPlayerWeaponFire&amp;quot;, localPlayer, onClientPlayerWeaponFireFunc )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example makes the Shotgun fire explosive rounds.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientPlayerWeaponFireFunc(weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement)&lt;br /&gt;
    if (weapon == 25) then -- If the player shoots with a shotgun&lt;br /&gt;
        createExplosion(hitX, hitY, hitZ, 12, true, 0, true) -- Creates a tiny explosion where the bullet hit.&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
-- Add this as a handler so that the function will be triggered every time a player fires.&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerWeaponFire&amp;quot;, root, onClientPlayerWeaponFireFunc)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
===Client player events===&lt;br /&gt;
{{Client_player_events}}&lt;br /&gt;
===Client event functions===&lt;br /&gt;
{{Client_event_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=ShowCursor&amp;diff=82009</id>
		<title>ShowCursor</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=ShowCursor&amp;diff=82009"/>
		<updated>2025-05-22T06:35:31Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
This function is used to show or hide a [[player]]'s cursor.&lt;br /&gt;
{{Note|Regardless of the cursor state you set using this function, the cursor will always be visible while the menu, the chatbox input line or the console are active, or if another resource has called this function.}}&lt;br /&gt;
{{Note| Be aware of that if showCursor enbaled by a resource you can't disabled it from a different ressource showCursor(false) will not works, in order to make it works, disable it from the original resource that enabled it or use export }}&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool showCursor ( player thePlayer, bool show, [ bool toggleControls = true ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePlayer:''' The [[player]] you want to show or hide the cursor of.&lt;br /&gt;
*'''show:''' A boolean value determining whether to show (''true'') or hide (''false'') the cursor.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
{{OptionalArg}} &lt;br /&gt;
*'''toggleControls:''' A boolean value determining whether to disable controls whilst the cursor is showing.  ''true'' implies controls are disabled, ''false'' implies controls remain enabled.&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool showCursor ( bool show, [ bool toggleControls = true ]  )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''show:''' A boolean value determining whether to show (''true'') or hide (''false'') the cursor.&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
{{OptionalArg}} &lt;br /&gt;
*'''toggleControls:''' A boolean value determining whether to disable controls whilst the cursor is showing.  ''true'' implies controls are disabled, ''false'' implies controls remain enabled.&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the player's cursor was shown or hidden successfully, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example shows the cursor for a player named &amp;quot;Dave&amp;quot;, then outputs a message if it was shown successfully.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local thePlayer = getPlayerFromName ( &amp;quot;Dave&amp;quot; )              -- get the player named Dave&lt;br /&gt;
if thePlayer then                                           -- if we got him&lt;br /&gt;
    showCursor ( thePlayer, true )                          -- make his cursor show&lt;br /&gt;
    if isCursorShowing ( thePlayer ) then                   -- did it show?&lt;br /&gt;
        outputChatBox ( &amp;quot;Cursor is now showing for Dave.&amp;quot; ) -- print a message to the chat box&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example shows the cursor all the time&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
showCursor ( true ) -- Shows cursor&lt;br /&gt;
showCursor ( false ) -- Doesnt Show Cursor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Cursor_functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:showCursor]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetPedGender&amp;diff=82007</id>
		<title>GetPedGender</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetPedGender&amp;diff=82007"/>
		<updated>2025-05-19T12:32:29Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Code refactor &amp;amp; add missing skins&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Useful Function}}&lt;br /&gt;
&lt;br /&gt;
Get the gender of peds and players.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
string = getPedGender(element ped)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
* '''ped:''' The ped/player you want the gender of.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns 1 value:&lt;br /&gt;
* '''gender:''' The gender of the ped/player. Possible values: &amp;quot;male&amp;quot;, &amp;quot;female&amp;quot; (or &amp;quot;unknown&amp;quot;). Returns false if no player/ped element is provided.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server- and/or clientside Script&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local pedMaleSkins = {&lt;br /&gt;
	0, 1, 2, 3, 4, 5, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,&lt;br /&gt;
	24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36,&lt;br /&gt;
	37, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 57,&lt;br /&gt;
	58, 59, 60, 61, 62, 65, 66, 67, 68, 70, 71, 72, 73,&lt;br /&gt;
	78, 79, 80, 81, 82, 83, 84, 94, 95, 96, 97, 98,&lt;br /&gt;
	99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,&lt;br /&gt;
	110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,&lt;br /&gt;
	122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135,&lt;br /&gt;
	136, 137, 142, 143, 144, 146, 147, 153, 154, 155, 156,&lt;br /&gt;
	158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,&lt;br /&gt;
	170, 171, 173, 174, 175, 176, 177, 179, 180, 181, 182,&lt;br /&gt;
	183, 184, 185, 186, 187, 188, 189, 200, 202, 203, 204,&lt;br /&gt;
	206, 209, 210, 212, 213, 217, 220, 221, 222, 223, 227,&lt;br /&gt;
	228, 229, 230, 234, 235, 236, 239, 240, 241, 242, 247,&lt;br /&gt;
	248, 249, 250, 252, 253, 254, 255, 258, 259, 260, 261,&lt;br /&gt;
	262, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,&lt;br /&gt;
	275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285,&lt;br /&gt;
	286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297,&lt;br /&gt;
	299, 300, 301, 302, 303, 305, 306, 307, 308, 309, 310,&lt;br /&gt;
	311, 312&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local pedFemaleSkins = {&lt;br /&gt;
	6, 9, 10, 11, 12, 13, 31, 38, 39, 40, 41, 53, 54,&lt;br /&gt;
	55, 56, 63, 64, 69, 75, 76, 77, 85, 86, 87, 88, 89,&lt;br /&gt;
	90, 91, 92, 93, 129, 130, 131, 138, 139, 140, 141,&lt;br /&gt;
	145, 148, 150, 151, 152, 157, 169, 172, 178, 190, 191,&lt;br /&gt;
	192, 193, 194, 195, 196, 197, 198, 199, 201, 205, 207,&lt;br /&gt;
	211, 214, 215, 216, 218, 219, 224, 225, 226, 231, 232,&lt;br /&gt;
	233, 237, 238, 243, 244, 245, 246, 251, 256, 257, 263,&lt;br /&gt;
	298, 304&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local pedElementTypes = {&lt;br /&gt;
	[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
	[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
	local maleSkinsTemp = {}&lt;br /&gt;
	local femaleSkinsTemp = {}&lt;br /&gt;
&lt;br /&gt;
	for skinID = 1, #pedMaleSkins do&lt;br /&gt;
		local pedModelID = pedMaleSkins[skinID]&lt;br /&gt;
&lt;br /&gt;
		maleSkinsTemp[pedModelID] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for skinID = 1, #pedFemaleSkins do&lt;br /&gt;
		local pedModelID = pedFemaleSkins[skinID]&lt;br /&gt;
&lt;br /&gt;
		femaleSkinsTemp[pedModelID] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	pedMaleSkins = maleSkinsTemp&lt;br /&gt;
	pedFemaleSkins = femaleSkinsTemp&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function getSkinGender(pedModel)&lt;br /&gt;
	local skinMale = pedMaleSkins[pedModel] and &amp;quot;male&amp;quot;&lt;br /&gt;
	local skinFemale = pedFemaleSkins[pedModel] and &amp;quot;female&amp;quot;&lt;br /&gt;
	local skinGender = (skinMale or skinFemale or &amp;quot;unknown&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	return skinGender&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function getPedGender(pedElement)&lt;br /&gt;
	local validElement = isElement(pedElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(pedElement)&lt;br /&gt;
	local pedType = pedElementTypes[elementType]&lt;br /&gt;
&lt;br /&gt;
	if (not pedType) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local pedModel = getElementModel(pedElement)&lt;br /&gt;
	local pedGender = getSkinGender(pedModel)&lt;br /&gt;
&lt;br /&gt;
	return pedGender&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
&lt;br /&gt;
The command /gender will display the gender of your player element.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
addCommandHandler(&amp;quot;gender&amp;quot;, &lt;br /&gt;
function () &lt;br /&gt;
	outputChatBox(&amp;quot;My gender: &amp;quot; .. tostring(getPedGender(localPlayer)))&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Author: IIYAMA.&lt;br /&gt;
Dataset by: Lexr128&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81996</id>
		<title>SetFPSLimit</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81996"/>
		<updated>2025-05-19T05:27:23Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Server client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function sets the maximum [http://en.wikipedia.org/wiki/Frame_rate FPS (Frames per second)] that players on the server can run their game at.  &lt;br /&gt;
{{Note|&lt;br /&gt;
* When set client side, the actual limit used is the lowest of both the server and client set values.&lt;br /&gt;
* Starting from version [[https://buildinfo.mtasa.com/?Revision=21313&amp;amp;Branch r21313]] and above '''fpsLimit''' range is '''25-32767'''. In older MTA releases it was '''25-100'''.&lt;br /&gt;
}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setFPSLimit ( int fpsLimit )         &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''fpsLimit:''' An integer value representing the maximum FPS. Refer to the note above for possible values. You can also pass '''0''' or '''false''', in which case the FPS limit will be the one set in the client settings (by default '''100 FPS''' and the client fps limit should also be manually changed via &amp;quot;'''fps_limit=0'''&amp;quot; in console or '''MTA San Andreas\MTA\config\coreconfig.xml''').&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if successful, or ''false'' if it was not possible to set the limit or an invalid value was passed.&lt;br /&gt;
&lt;br /&gt;
==Issues when increasing FPS==&lt;br /&gt;
Note: with &amp;quot;very high&amp;quot; FPS, any FPS limit over 74 is meant.&lt;br /&gt;
It is recommended to set a conservative FPS limit (between 40-60 and 74 highest) because high FPS can break some GTA internal calculations, causing various bugs. The higher the FPS the more of a problem these become:&lt;br /&gt;
&lt;br /&gt;
74 FPS is the breaking point that opens the door to various more severe GTA bugs related to FPS and physics.&lt;br /&gt;
&lt;br /&gt;
* Physics of vehicles is effected, both high and low FPSes may bring their own set of unfair advantages. Speaking about the consequences of high FPS in this context, up to 70 or 74 FPS is considered safe (as any differences in physics, if they do exist to begin with as they theoretically should, are so tiny that they are unmeasurable and thus wouldn't affect racing results in practise). Anything beyond 74 FPS may cause impactful discrepancies.&lt;br /&gt;
&lt;br /&gt;
* Pressing the horn button to turn on and off sirens gets really hard at very high FPS. For instance, at 100 FPS, you are more likely to hit the regular horn 3 times (inconsistent) before eventually triggering the siren, besides taking a similar amount of tries to turn off the siren.&lt;br /&gt;
* At very high FPS, climbing over certain objects will result in instant death. Example at: 2520.108, -1681.407, 19.406, 266 - [https://wiki.multitheftauto.com/wiki/SetFPSLimit#Fix_for_climbing_over_certain_objects you can use this Lua code to fix it.]&lt;br /&gt;
* The higher your FPS, the more of a penalty in satchel throwing distance (up to ~10% at very high FPS) will apply.&lt;br /&gt;
&lt;br /&gt;
For a full list of FPS-related GTA bugs (that are much less likely to impact gameplay in a meaningful way) and MTA developers' progress in tackling them, see the [https://github.com/multitheftauto/mtasa-blue/projects/14 Framerate issues tracker] github project.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example allows players to limit their own FPS using a command.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local minFPS = 25&lt;br /&gt;
local maxFPS = 100&lt;br /&gt;
&lt;br /&gt;
function fpsFunction(commandName, fpsLimit)&lt;br /&gt;
	local newFPS = tonumber(fpsLimit)&lt;br /&gt;
	local displaySyntax = (not newFPS) or (newFPS &amp;lt; minFPS) or (newFPS &amp;gt; maxFPS)&lt;br /&gt;
&lt;br /&gt;
	if (displaySyntax) then&lt;br /&gt;
		outputChatBox(&amp;quot;Syntax: /&amp;quot;..commandName..&amp;quot; [&amp;quot;..minFPS..&amp;quot; ~ &amp;quot;..maxFPS..&amp;quot;] - limit your own FPS.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local currentLimit = getFPSLimit()&lt;br /&gt;
	local setNewFPS = (newFPS ~= currentLimit)&lt;br /&gt;
&lt;br /&gt;
	if (setNewFPS) then&lt;br /&gt;
		outputChatBox(&amp;quot;Your FPS has been limited to: &amp;quot;..newFPS..&amp;quot;.&amp;quot;)&lt;br /&gt;
		setFPSLimit(newFPS)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;limitfps&amp;quot;, fpsFunction)&lt;br /&gt;
addCommandHandler(&amp;quot;fpslimit&amp;quot;, fpsFunction)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fix for climbing over certain objects==&lt;br /&gt;
You can use this small code to fix one of high FPS issues, specifically the one which would instantly kill player climbing over some objects.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientPlayerDamage(attackerElement, damageType, bodyPart)&lt;br /&gt;
	local fallDamage = (damageType == 54)&lt;br /&gt;
&lt;br /&gt;
	if (not fallDamage) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerTask = getPedSimplestTask(localPlayer)&lt;br /&gt;
	local playerClimbing = (playerTask == &amp;quot;TASK_SIMPLE_CLIMB&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	if (playerClimbing) then&lt;br /&gt;
		cancelEvent()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerDamage&amp;quot;, localPlayer, onClientPlayerDamage)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Server functions}}&lt;br /&gt;
&lt;br /&gt;
[[pl:setFPSLimit]]&lt;br /&gt;
[[ru:setFPSLimit]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnClientPedDamage&amp;diff=81992</id>
		<title>OnClientPedDamage</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnClientPedDamage&amp;diff=81992"/>
		<updated>2025-05-11T20:43:21Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Client event}}&lt;br /&gt;
This event is triggered whenever a [[ped]] is damaged.&lt;br /&gt;
{{Note|This event is only triggered for peds that are streamed in}}&lt;br /&gt;
==Parameters==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
element attacker, int weapon, int bodypart [, float loss ]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*'''attacker''': A [[player]] [[element]] representing the attacker or [[vehicle]] [[element]] (when a ped falls of a bike).&lt;br /&gt;
*'''weapon''': An integer representing the [[Weapons|weapon ID]] the attacker used&lt;br /&gt;
*'''bodypart''': An integer representing the bodypart the ped was damaged&lt;br /&gt;
{{BodyParts}}&lt;br /&gt;
*'''loss''': A float representing the percentage of health the ped lost.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the [[ped]] that got damaged&lt;br /&gt;
&lt;br /&gt;
==Cancel effect==&lt;br /&gt;
If this event is [[Event system#Canceling|canceled]], then any damaging effects to the ped will cease.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example cancels any damage done to peds&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function cancelPedDamage()&lt;br /&gt;
	cancelEvent() -- cancel any damage done to peds&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPedDamage&amp;quot;, root, cancelPedDamage)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
===Client ped events===&lt;br /&gt;
{{Client_ped_events}}&lt;br /&gt;
===Client event functions===&lt;br /&gt;
{{Client_event_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Weapons&amp;diff=81991</id>
		<title>Weapons</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Weapons&amp;diff=81991"/>
		<updated>2025-05-11T19:51:12Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Scripting functions that ask for a weapon ID need an integer that refers to the GTASA weapon ID list. They are listed below.&lt;br /&gt;
{{Note|&lt;br /&gt;
*Clip size () denotes clip size when the weapon is dual wielded. Weapons without this specification are not dual wield weapons.&lt;br /&gt;
*GTASA [[Weapon_skill_levels|weapon stats]] will affect movement, accuracy, damage, and dual wield capability. See [[setPedStat]] to change these stats. The default MTA server package comes with a resource called &amp;quot;defaultStats&amp;quot; that sets GTASA weapon stats to 999. See the weapon stats link for more info.&lt;br /&gt;
*For death reasons, especially in event handlers for onPlayerWasted or similar, also have a look at the [[Damage Types]].&lt;br /&gt;
*'''Name''' is compatible with functions [[getWeaponNameFromID]], [[getWeaponIDFromName]].&lt;br /&gt;
*'''Bullet Sync''' refers to whether they are triggered by the [[OnPlayerWeaponFire]] event.&lt;br /&gt;
}}&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;text-align:center; margin: 1em auto 1em auto; border:1px solid black&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Slot || class=&amp;quot;unsortable&amp;quot; | Type || class=&amp;quot;unsortable&amp;quot; | Image || Name || ID || class=&amp;quot;unsortable&amp;quot; | Model ID || class=&amp;quot;unsortable&amp;quot; | Clip || class=&amp;quot;unsortable&amp;quot; | Sharing slot ammo || class=&amp;quot;unsortable&amp;quot; | Bullet Sync&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 0&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Hand&lt;br /&gt;
| [[Image:Fist.png]] || align=&amp;quot;left&amp;quot; | Fist || 0 || - || -&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | -&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Knuckle.png]] || align=&amp;quot;left&amp;quot; | Brassknuckle || 1 || 331 || -&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;8&amp;quot; | 1&lt;br /&gt;
! rowspan=&amp;quot;8&amp;quot; | Melee&lt;br /&gt;
| [[Image:Golfclub.png]] || align=&amp;quot;left&amp;quot; | Golfclub || 2 || 333 || -&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | -&lt;br /&gt;
| rowspan=&amp;quot;8&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Nitestik.png]] || align=&amp;quot;left&amp;quot; | Nightstick || 3 || 334 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Knife.png]] || align=&amp;quot;left&amp;quot; | Knife || 4 || 335 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Bat.png]] || align=&amp;quot;left&amp;quot; | Bat || 5 || 336 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Shovel.png]] || align=&amp;quot;left&amp;quot; | Shovel || 6 || 337 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Poolcue.png]] || align=&amp;quot;left&amp;quot; | Poolstick || 7 || 338 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Katana.png]] || align=&amp;quot;left&amp;quot; | Katana || 8 || 339 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Saw.png]] || align=&amp;quot;left&amp;quot; | Chainsaw || 9 || 341 || -&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | 2&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | Handguns&lt;br /&gt;
| [[Image:Colt45.png]] || align=&amp;quot;left&amp;quot; | Colt 45 || 22 || 346 || 17 (34)&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | '''No'''&amp;lt;br/&amp;gt;''Replacing handgun resets slot 2 ammo''&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Yes&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Silenced.png]] || align=&amp;quot;left&amp;quot; | Silenced || 23 || 347 || 17&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Deagle.png]] || align=&amp;quot;left&amp;quot; | Deagle || 24 || 348 || 7&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | 3&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | Shotguns&lt;br /&gt;
| [[Image:Shotgun.png]] || align=&amp;quot;left&amp;quot; | Shotgun || 25 || 349 || 1&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Yes&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Yes&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Sawnoff.png]] || align=&amp;quot;left&amp;quot; | Sawed-off || 26 || 350 || 2 (4)&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Spas12.png]] || align=&amp;quot;left&amp;quot; | Combat Shotgun || 27 || 351 || 7&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | 4&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | Sub-Machine Guns&lt;br /&gt;
| [[Image:Mac10.png]] || align=&amp;quot;left&amp;quot; | Uzi || 28 || 352 || 50 (100)&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Yes&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Yes&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Mp5.png]] || align=&amp;quot;left&amp;quot; | MP5 || 29 || 353 || 30&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Tec9.png]] || align=&amp;quot;left&amp;quot; | Tec-9 || 32 || 372 || 50 (100)&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Assault Rifles&lt;br /&gt;
| [[Image:Ak47.png]] || align=&amp;quot;left&amp;quot; | AK-47 || 30 || 355 || 30&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Yes&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Yes&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:M4.png]] || align=&amp;quot;left&amp;quot; | M4 || 31 || 356 || 50&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Rifles&lt;br /&gt;
| [[Image:Rifle.png]] || align=&amp;quot;left&amp;quot; | Rifle || 33 || 357 || 1&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | '''No'''&amp;lt;br/&amp;gt;''Replacing rifle resets slot 6 ammo''&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Yes&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Sniper.png]] || align=&amp;quot;left&amp;quot; | Sniper || 34 || 358 || 1&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;4&amp;quot; | 7&lt;br /&gt;
! rowspan=&amp;quot;4&amp;quot; | Heavy Weapons&lt;br /&gt;
| [[Image:Rocketla.png]] || align=&amp;quot;left&amp;quot; | Rocket Launcher || 35 || 359 || 1&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | '''No'''&amp;lt;br/&amp;gt;''Replacing heavy weapon resets slot 7 ammo''&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Heatseek.png]] || align=&amp;quot;left&amp;quot; | Rocket Launcher HS || 36 || 360 || 1&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Flame.png]] || align=&amp;quot;left&amp;quot; | Flamethrower || 37 || 361 || 50&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Minigun.png]] || align=&amp;quot;left&amp;quot; | Minigun || 38 || 362 || 500&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;4&amp;quot; | 8&lt;br /&gt;
! rowspan=&amp;quot;4&amp;quot; | Projectiles&lt;br /&gt;
| [[Image:Grenade.png]] || align=&amp;quot;left&amp;quot; | Grenade || 16 || 342 || 1&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | '''No'''&amp;lt;br/&amp;gt;''Replacing projectile resets slot 8 ammo''&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Teargas.png]] || align=&amp;quot;left&amp;quot; | Teargas || 17 || 343 || 1&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Molotov.png]] || align=&amp;quot;left&amp;quot; | Molotov || 18 || 344 || 1&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Satchel.png]] || align=&amp;quot;left&amp;quot; | Satchel || 39 || 363 || 1&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | 9&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | Special 1&lt;br /&gt;
| [[Image:Spraycan.png]] || align=&amp;quot;left&amp;quot; | Spraycan || 41 || 365 || 500&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | '''No'''&amp;lt;br/&amp;gt;''Replacing slot 9 weapon resets slot 9 ammo''&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fire_ex.png]] || align=&amp;quot;left&amp;quot; | Fire Extinguisher || 42 || 366 || 500&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Camera.png]] || align=&amp;quot;left&amp;quot; | Camera || 43 || 367 || 36&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;5&amp;quot; | 10&lt;br /&gt;
! rowspan=&amp;quot;5&amp;quot; | Gifts&lt;br /&gt;
| [[Image:Dildo1.png]] || align=&amp;quot;left&amp;quot; | Dildo || 10 || 321 || -&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | -&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Dildo2.png]] || align=&amp;quot;left&amp;quot; | Dildo || 11 || 322 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Vibe1.png]] || align=&amp;quot;left&amp;quot; | Vibrator || 12 || 323 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Flowers.png]] || align=&amp;quot;left&amp;quot; | Flower || 14 || 325 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Cane.png]] || align=&amp;quot;left&amp;quot; | Cane || 15 || 326 || -&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | 11&lt;br /&gt;
! rowspan=&amp;quot;3&amp;quot; | Special 2&lt;br /&gt;
| [[Image:Irgoggle.png]] || align=&amp;quot;left&amp;quot; | Nightvision || 44 || 368 || -&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | -&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Irgoggle.png]] || align=&amp;quot;left&amp;quot; | Infrared || 45 || 369 || -&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Paracute.png]] || align=&amp;quot;left&amp;quot; | Parachute || 46 || 371 || -&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;1&amp;quot; | 12&lt;br /&gt;
! rowspan=&amp;quot;1&amp;quot; | Satchel Detonator&lt;br /&gt;
| [[Image:Bomb.png]] || align=&amp;quot;left&amp;quot; | Bomb || 40 || 364 || -&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | -&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; | No&lt;br /&gt;
|}&lt;br /&gt;
Lua tables with weapons:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local weaponsID = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 32, 30, 31, 33, 34, 35, 36, 37, 38, 16, 17, 18, 39, 41, 42, 43, 10, 11, 12, 14, 15, 44, 45, 46, 40}&lt;br /&gt;
local weaponsBySlot = {&lt;br /&gt;
	[0] = {0, 1}, -- hand&lt;br /&gt;
	[1] = {2, 3, 4, 5, 6, 7, 8, 9},	-- melee&lt;br /&gt;
	[2] = {22, 23, 24}, -- handguns&lt;br /&gt;
	[3] = {25, 26, 27}, -- shotguns&lt;br /&gt;
	[4] = {28, 29, 32}, -- sub-machine guns&lt;br /&gt;
	[5] = {30, 31}, -- assault rifles&lt;br /&gt;
	[6] = {33, 34}, -- rifles&lt;br /&gt;
	[7] = {35, 36, 37, 38}, -- heavy weapons&lt;br /&gt;
	[8] = {16, 17, 18, 39}, -- projectiles&lt;br /&gt;
	[9] = {41, 42, 43}, -- special 1&lt;br /&gt;
	[10] = {10, 11, 12, 14, 15}, -- gifts&lt;br /&gt;
	[11] = {44, 45, 46}, -- special 2&lt;br /&gt;
	[12] = {40}, -- satchel detonator&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
{{Weapon functions|server}}== See Also ==&lt;br /&gt;
* [[Id|Ids]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ID Lists]]&lt;br /&gt;
&lt;br /&gt;
[[hu:Weapons]]&lt;br /&gt;
[[it:Armi]]&lt;br /&gt;
[[ru:Weapons]]&lt;br /&gt;
[[de:Waffen]]&lt;br /&gt;
[[pl:Weapons]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=81978</id>
		<title>Script security</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=81978"/>
		<updated>2025-05-03T16:34:46Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Securing setElementData */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Awareness of client memory==&lt;br /&gt;
&lt;br /&gt;
Starting from very basics:&lt;br /&gt;
* You should be aware that everything you store on client-side is at risk, this includes .lua files as well. Any confidential (and/or) important data which is stored, or travels through client-side (player PC) could be accessed by malicious clients.&lt;br /&gt;
* To keep sensitive data (and/or) Lua logic safe - use server-side.&lt;br /&gt;
* Do note that scripts marked as '''shared''' act also as '''client code''', which means that everything above applies to them. For example defining:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;shared&amp;quot;/&amp;gt; &amp;lt;!-- this script will run separately both on client and server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Is same as doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;client&amp;quot;/&amp;gt; &amp;lt;!-- define it separately on client --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;server&amp;quot;/&amp;gt; &amp;lt;!-- do the same, but on server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Additional protection layer==&lt;br /&gt;
&lt;br /&gt;
In order to make things ''slightly harder*'' for those having bad intentions towards your server, you can make use of cache attribute (and/or [https://luac.mtasa.com/ Lua compile (also known as Luac) with extra obfuscation set to level '''3'''] - [https://wiki.multitheftauto.com/wiki/Lua_compilation_API API]) available in [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml], along with configuring MTA's built-in AC by toggling SD (Special detections), see: [https://wiki.multitheftauto.com/wiki/Anti-cheat_guide Anti-cheat guide].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;shared.lua&amp;quot; type=&amp;quot;shared&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;client.lua&amp;quot; type=&amp;quot;client&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Slightly harder'' '''but not impossible''' for some to obtain client code, yet does good job at keeping '''most''' people away from inspecting your .lua files - those looking for possible logic flaws (bugs) or missing/incorrect security based checks.&lt;br /&gt;
* Can be used on both '''client''' and '''shared''' script type (has no effect on server-sided Lua).&lt;br /&gt;
* It doesn't remove Lua files which were previously downloaded.&lt;br /&gt;
&lt;br /&gt;
==Detecting and dealing with backdoors and cheats==&lt;br /&gt;
'''To ensure minimum (or no) damage resulting from Lua scripts:'''&lt;br /&gt;
* Keep your server up-to-date, you can [https://nightly.multitheftauto.com/ download latest server builds from MTA:SA nightly site.] Information on specific builds can be [https://buildinfo.multitheftauto.com/ found here.]&lt;br /&gt;
* Keep your resources up-to-date, you can [https://github.com/multitheftauto/mtasa-resources download latest (default) resources from GitHub repository.] Those often contain latest security fixes, which could mean difference between having your server resist from attack or not.&lt;br /&gt;
* Make sure to properly configure [https://wiki.multitheftauto.com/wiki/Access%20Control%20List ACL (Access Control List)] - which will block resources from using certain, potentially dangerous functions.&lt;br /&gt;
* Zero-trust with giving away admin rights for resources (including maps) coming from unknown sources.&lt;br /&gt;
* Before running any resource you don't trust, analyze:&lt;br /&gt;
** [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml] of it, for possible hidden scripts lurking beneath other file extensions.&lt;br /&gt;
** It's source code, for malicious logic.&lt;br /&gt;
* Do not run/keep using compiled resources (scripts) of which legitimacy you aren't sure.&lt;br /&gt;
&lt;br /&gt;
'''To ensure minimum damage when a cheater connects to your server:'''&lt;br /&gt;
* When making scripts, remember to never trust data coming from a client.&lt;br /&gt;
* While reviewing scripts for possible security holes. Look at any data coming from the client that is being trusted.&lt;br /&gt;
* Any kind of data could be sent, hence server scripts which communicate with client by receiving data sent by players should validate it, before further use in latter parts of code. Mostly, it will be done either by [[setElementData]] or [[triggerServerEvent]].&lt;br /&gt;
* You shouldn't rely only on player [https://wiki.multitheftauto.com/wiki/Serial serial], when it comes to processing crucial operations (auto-login/admin actions). '''Serials aren't guaranted to be unique or non-fakable'''. This is why you should '''put it behind''' account system, as '''important authentication factor''' (e.g: '''login &amp;amp; password''').&lt;br /&gt;
* Server-side logic '''can not be bypassed''' or '''tampered''' with (unless server is breached or when there is a bug in code, but that's whole different scenario) - '''use it to your advantage'''. In majority of cases, you will be able to perform security validations with no participation of client-side.&lt;br /&gt;
* Using concept of '''''“All parameters including source can be faked and should not be trusted. Global variable client can be trusted.”''''' - gives you reliable assurance that player to which you refer (via '''client''') '''is''' in fact, '''the one which really called event'''. This approach will protect you from situations where cheater can call &amp;amp; process for instance: admin events (e.g kick/ban player) by passing the actual admin ('''2nd''' argument in '''[[triggerServerEvent]]'''), or trigger events for other players (as if they were the ones who called them, but in reality it was forcefully done by cheater) - as a consequence of using wrong variable. To make sure you fully understood it, take a look at examples below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	DON'T EVER DO THAT - THAT IS COMPLETELY WRONG AND INSECURE&lt;br /&gt;
	THE ISSUE: BY USING 'source' IN hasObjectPermissionTo YOU ARE LEAVING DOOR STRAIGHT OPEN FOR CHEATERS&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerWrongAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(source, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- the vulnerability lies here...&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerWrongAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerWrongAdminEvent&amp;quot;, root, onServerWrongAdminEvent)&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	onServerCorrectAdminEvent IS PERFECTLY SECURED, AS IT SHOULD BE&lt;br /&gt;
	NO ISSUE HERE: WE'VE USED 'client' IN hasObjectPermissionTo WHICH MAKES IT SAFE FROM FAKING PLAYER WHO CALLED EVENT&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerCorrectAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(client, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- is player allowed to do that?&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerCorrectAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerCorrectAdminEvent&amp;quot;, root, onServerCorrectAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing setElementData==&lt;br /&gt;
&lt;br /&gt;
* You should refrain from using [[element data]] everywhere, it should be only used when really necessary. It is advised to replace it with [[triggerClientEvent]] instead.&lt;br /&gt;
* If you still insist on using it, it is recommended to set '''4th''' argument in [[setElementData]] to '''false''' (disabling sync for this, certain data) and use subscriber mode - [[addElementDataSubscriber]], for both security &amp;amp; performance reasons described in [https://wiki.multitheftauto.com/wiki/Script_security#Securing_triggerServerEvent event section.]&lt;br /&gt;
{{Important Note|Disabling sync however, doesn't fully protect data key. It would be still vulnerable by default, but in this case you are not leaving it in plain sight. Using [[getAllElementData]] or digging in RAM wouldn't expose it, since it won't be synced to client in first place. Therefore, it needs to be added to anti-cheat as well.}} &lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of basic element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = tostring(sourceElement) -- element which received data&lt;br /&gt;
	local logOldValue = tostring(oldValue) -- old value&lt;br /&gt;
	local logNewValue = tostring(newValue) -- new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;=======================================\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;=======================================&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local logVisibleTo = root -- specify who will see this log in console, in this case each player connected to server&lt;br /&gt;
	local hadData = (oldValue ~= nil) -- check if element had such data before&lt;br /&gt;
&lt;br /&gt;
	if (hadData) then -- if element had such data before&lt;br /&gt;
		setElementData(sourceElement, dataKey, oldValue, true) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
	else&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it completely&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	outputConsole(logText, logVisibleTo) -- print it to console&lt;br /&gt;
&lt;br /&gt;
	return true -- all success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeBasicAC(dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not go further&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkSpecialThing = (dataKey == &amp;quot;special_thing&amp;quot;) -- compare whether dataKey matches &amp;quot;special_thing&amp;quot;&lt;br /&gt;
	local checkFlagWaving = (dataKey == &amp;quot;flag_waving&amp;quot;) -- compare whether dataKey matches &amp;quot;flag_waving&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if (checkSpecialThing) then -- if it does, do our security checks&lt;br /&gt;
		local invalidElement = (client ~= source) -- verify whether source element is different from player which changed data&lt;br /&gt;
&lt;br /&gt;
		if (invalidElement) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;special_thing&amp;quot; can only be set for player himself&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkFlagWaving) then -- if it does, do our security checks&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(client) -- get player's current vehicle&lt;br /&gt;
		local invalidVehicle = (playerVehicle ~= source) -- verify whether source element is different from player's vehicle&lt;br /&gt;
&lt;br /&gt;
		if (invalidVehicle) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;flag_waving&amp;quot; can only be set for player's own vehicle&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeBasicAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of advanced element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan, allowOnlyProtectedKeys to true (as per default configuration)&lt;br /&gt;
	If allowOnlyProtectedKeys is enabled, do not forget to add every client-side element data key to protectedKeys table - otherwise you will face false-positives&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (handleDataChange) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	[&amp;quot;keyName&amp;quot;] = { -- name of key which would be protected&lt;br /&gt;
		onlyForPlayerHimself = true, -- enabling this (true) will make sure that this element data key can only be set on player who synced it (ignores onlyForOwnPlayerVeh and allowForElements), use false/nil to disable this&lt;br /&gt;
		onlyForOwnPlayerVeh = false, -- enabling this (true) will make sure that this element data key can only be set on player's current vehicle who synced it (ignores allowForElements), use false/nil to disable this&lt;br /&gt;
		allowForElements = { -- restrict this key for certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
			[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = { -- restrict this key for certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 32}, -- if value is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
		allowedTableLength = {1, 64}, -- if value is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
		allowedNumberRange = {1, 128}, -- if value is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
	}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering element data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local allowOnlyProtectedKeys = true -- disallow (remove by using removeElementData) every element data besides those given in protectedKeys table; in case someone wanted to flood server with garbage keys, which would be kept in memory until server restart or manual remove - setElementData(source, key, nil) won't remove it; it has to be removeElementData&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
local protectedKeys = {&lt;br /&gt;
	[&amp;quot;vehicleNumber&amp;quot;] = { -- we want vehicleNumber to be set only on vehicles, with stricte numbers in range of 1-100&lt;br /&gt;
		allowForElements = {&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedNumberRange = {1, 100},&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;personalVehData&amp;quot;] = { -- we want be able to set personalVehData only on current vehicle, also it should be a string with length between 1-24&lt;br /&gt;
		onlyForOwnPlayerVeh = true,&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 24},&lt;br /&gt;
	},&lt;br /&gt;
	-- perform security checks on keys stored in this table, in a convenient way&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of element which received data&lt;br /&gt;
	local logOldValue = inspect(oldValue) -- in-depth view of old value&lt;br /&gt;
	local logNewValue = inspect(newValue) -- in-depth view of new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Fail reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (forceRemove) then -- we don't want this element data key to exist at all&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it&lt;br /&gt;
&lt;br /&gt;
		return true -- return success and stop here, we don't need further checks&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	setElementData(sourceElement, dataKey, oldValue, true) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
&lt;br /&gt;
	return true -- return success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function handleDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from protectedKeys), false otherwise&lt;br /&gt;
	local protectedKey = protectedKeys[dataKey] -- look up whether key changed is stored in protectedKeys table&lt;br /&gt;
&lt;br /&gt;
	if (not protectedKey) then -- if it's not&lt;br /&gt;
&lt;br /&gt;
		if (allowOnlyProtectedKeys) then -- if we don't want garbage keys&lt;br /&gt;
			local failReason = &amp;quot;Key isn't present in protectedKeys&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = true -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return true -- this key isn't protected, let it through&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local onlyForPlayerHimself = protectedKey.onlyForPlayerHimself -- if key has &amp;quot;self-set&amp;quot; lock&lt;br /&gt;
	local onlyForOwnPlayerVeh = protectedKey.onlyForOwnPlayerVeh -- if key has &amp;quot;self-vehicle&amp;quot; lock&lt;br /&gt;
	local allowForElements = protectedKey.allowForElements -- if key has element type check&lt;br /&gt;
	local allowedDataTypes = protectedKey.allowedDataTypes -- if key has allowed data type check&lt;br /&gt;
&lt;br /&gt;
	if (onlyForPlayerHimself) then -- if &amp;quot;self-set&amp;quot; lock is active&lt;br /&gt;
		local matchingElement = (clientElement == sourceElement) -- verify whether player who set data is equal to element which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElement) then -- if it's not matching&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player himself&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (onlyForOwnPlayerVeh) then -- if &amp;quot;self-vehicle&amp;quot; lock is active&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(clientElement) -- get current vehicle of player which set data&lt;br /&gt;
		local matchingVehicle = (playerVehicle == sourceElement) -- check whether it matches the one which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingVehicle) then -- if it doesn't match&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player's own vehicle&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowForElements) then -- check if it's one of them&lt;br /&gt;
		local elementType = getElementType(sourceElement) -- get type of element whose data changed&lt;br /&gt;
		local matchingElementType = allowForElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElementType) then -- this isn't matching&lt;br /&gt;
			local failReason = &amp;quot;Invalid element type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowedDataTypes) then -- if there's allowed data types&lt;br /&gt;
		local valueType = type(newValue) -- get data type of value&lt;br /&gt;
		local matchingType = allowedDataTypes[valueType] -- check if it's one of allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingType) then -- if it's not then&lt;br /&gt;
			local failReason = &amp;quot;Invalid data type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedStringLength = protectedKey.allowedStringLength -- if key has specified string length check&lt;br /&gt;
		local dataString = (valueType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
		if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
			local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
			local stringLength = utf8.len(newValue) -- get length of data string&lt;br /&gt;
			local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedTableLength = protectedKey.allowedTableLength -- if key has table length check&lt;br /&gt;
		local dataTable = (valueType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
		if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
			local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
			local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
			local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
			local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
			for _, _ in pairs(newValue) do -- loop through whole table&lt;br /&gt;
				tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
				minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
				maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
				if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
					break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
				local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedNumberRange = protectedKey.allowedNumberRange -- if key has allowed number range check&lt;br /&gt;
		local dataNumber = (valueType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
		if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
			local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
			local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
			local matchingRange = (newValue &amp;gt;= minRange) and (newValue &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingRange) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this data key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeAdvancedAC(dataKey, oldValue, newValue) -- this event makes use of handleDataChange, the code was split for better readability&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not continue&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedChange = handleDataChange(client, source, dataKey, oldValue, newValue) -- run our security checks&lt;br /&gt;
&lt;br /&gt;
	if (approvedChange) then -- it's all cool and good&lt;br /&gt;
		return false -- we don't need further action&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(client, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(client, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeAdvancedAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing triggerServerEvent==&lt;br /&gt;
&lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player (client) '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
* Do '''not''' use the same name for your custom event as MTA native server events (which aren't remotely triggerable by default), e.g: '''onPlayerLogin'''; doing so would open door for cheaters manipulations.&lt;br /&gt;
* Be aware to which players event is sent via [[triggerClientEvent]]. For both security &amp;amp; performance reasons, admin like events should be received by admins only (to prevent confidential data being accessed), in the same time you shouldn't send each event to everyone on server (e.g: login success event which hides login panel for certain player). [[triggerClientEvent]] allows you to specify the event receiver as first (optional) argument. It defaults to [[root]], meaning if you don't specify it, it will be sent to everyone connected to server - even those who are still downloading server cache (which results in ''Server triggered clientside event eventName, but event is not added clientside.''). You can either pass player element or table with receivers:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playersToReceiveEvent = {player1, player2, player3} -- each playerX is player element&lt;br /&gt;
&lt;br /&gt;
triggerClientEvent(playersToReceiveEvent, ...) -- do not forget to fill the latter part of arguments&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of anti-cheat function designed for events, used for data validation for both normal, and admin events which are called from client-side.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan to true (as per default configuration)&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (processServerEventData) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	checkACLGroup = { -- check whether player who called event belongs to at least one group below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;Admin&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkPermissions = { -- check whether player who called event has permission to at least one thing below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;function.kickPlayer&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkEventData = {&lt;br /&gt;
		{&lt;br /&gt;
			debugData = &amp;quot;source&amp;quot;, -- optional details for report shown in debug message&lt;br /&gt;
			eventData = source, -- data we want to verify&lt;br /&gt;
			equalTo = client, -- compare whether eventData == equalTo&lt;br /&gt;
			allowedElements = { -- restrict eventData to be certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
				[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedDataTypes = { -- restrict eventData to be certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
				[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedStringLength = {1, 32}, -- if eventData is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
			allowedTableLength = {1, 64}, -- if eventData is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
			allowedNumberRange = {1, 128}, -- if eventData is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering server event data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
function processServerEventData(clientElement, sourceElement, serverEvent, securityChecks) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from securityChecks), false otherwise&lt;br /&gt;
	if (not securityChecks) then -- if we haven't passed any security checks&lt;br /&gt;
		return true -- nothing to check, let code go further&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (not clientElement) then -- if client variable isn't available for some reason (although it should never happen)&lt;br /&gt;
		local failReason = &amp;quot;Client variable not present&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkACLGroup = securityChecks.checkACLGroup -- if there's any ACL groups to check&lt;br /&gt;
	local checkPermissions = securityChecks.checkPermissions -- if there's any permissions to check&lt;br /&gt;
	local checkEventData = securityChecks.checkEventData -- if there's any data checks&lt;br /&gt;
&lt;br /&gt;
	if (checkACLGroup) then -- let's check player ACL groups&lt;br /&gt;
		local playerAccount = getPlayerAccount(clientElement) -- get current account of player&lt;br /&gt;
		local guestAccount = isGuestAccount(playerAccount) -- if account is guest (meaning player is not logged in)&lt;br /&gt;
&lt;br /&gt;
		if (guestAccount) then -- it's the case&lt;br /&gt;
			local failReason = &amp;quot;Can't retrieve player login - guest account&amp;quot; -- reason shown in report&lt;br /&gt;
			local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
			reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local accountName = getAccountName(playerAccount) -- get name of player's current account&lt;br /&gt;
		local aclString = &amp;quot;user.&amp;quot;..accountName -- format it for further use in isObjectInACLGroup function&lt;br /&gt;
&lt;br /&gt;
		for groupID = 1, #checkACLGroup do -- iterate over table of given groups&lt;br /&gt;
			local groupName = checkACLGroup[groupID] -- get each group name&lt;br /&gt;
			local aclGroup = aclGetGroup(groupName) -- check if such group exists&lt;br /&gt;
&lt;br /&gt;
			if (not aclGroup) then -- it doesn't&lt;br /&gt;
				local failReason = &amp;quot;ACL group '&amp;quot;..groupName..&amp;quot;' is missing&amp;quot; -- reason shown in report&lt;br /&gt;
				local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
				reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local playerInACLGroup = isObjectInACLGroup(aclString, aclGroup) -- check if player belong to the group&lt;br /&gt;
&lt;br /&gt;
			if (playerInACLGroup) then -- yep, it's the case&lt;br /&gt;
				return true -- so it's a success&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Player doesn't belong to any given ACL group&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkPermissions) then -- check if player has at least one desired permission&lt;br /&gt;
		local allowedByDefault = false -- does he have access by default&lt;br /&gt;
&lt;br /&gt;
		for permissionID = 1, #checkPermissions do -- iterate over all permissions&lt;br /&gt;
			local permissionName = checkPermissions[permissionID] -- get permission name&lt;br /&gt;
			local hasPermission = hasObjectPermissionTo(clientElement, permissionName, allowedByDefault) -- check whether player is allowed to perform certain action&lt;br /&gt;
&lt;br /&gt;
			if (hasPermission) then -- if player has access&lt;br /&gt;
				return true -- one is available (and enough), server won't bother to check others (as return keywords also breaks loop)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Not enough permissions&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkEventData) then -- if there is some data to verify&lt;br /&gt;
&lt;br /&gt;
		for dataID = 1, #checkEventData do -- iterate over each of data&lt;br /&gt;
			local dataToCheck = checkEventData[dataID] -- get each data set&lt;br /&gt;
			local eventData = dataToCheck.eventData -- this is the one we'll be verifying&lt;br /&gt;
			local equalTo = dataToCheck.equalTo -- we want to compare whether eventData == equalTo&lt;br /&gt;
			local allowedElements = dataToCheck.allowedElements -- check whether is element, and whether belongs to certain element types&lt;br /&gt;
			local allowedDataTypes = dataToCheck.allowedDataTypes -- do we restrict data to be certain type?&lt;br /&gt;
			local debugData = dataToCheck.debugData -- additional helper data&lt;br /&gt;
			local debugText = debugData and &amp;quot; (&amp;quot;..debugData..&amp;quot;)&amp;quot; or &amp;quot;&amp;quot; -- if it's present, format it nicely&lt;br /&gt;
&lt;br /&gt;
			if (equalTo) then -- equal check exists&lt;br /&gt;
				local matchingData = (eventData == equalTo) -- compare whether those two values are equal&lt;br /&gt;
&lt;br /&gt;
				if (not matchingData) then -- they aren't&lt;br /&gt;
					local failReason = &amp;quot;Data isn't equal @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedElements) then -- we do check whether is an element, and belongs to at least one given in the list&lt;br /&gt;
				local validElement = isElement(eventData) -- check if it's actual element&lt;br /&gt;
&lt;br /&gt;
				if (not validElement) then -- it's not&lt;br /&gt;
					local failReason = &amp;quot;Data isn't element @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local elementType = getElementType(eventData) -- it's element, so we want to know it's type&lt;br /&gt;
				local matchingElementType = allowedElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingElementType) then -- it's not allowed&lt;br /&gt;
					local failReason = &amp;quot;Invalid element type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedDataTypes) then -- let's check allowed data types&lt;br /&gt;
				local dataType = type(eventData) -- get data type&lt;br /&gt;
				local matchingType = allowedDataTypes[dataType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingType) then -- it isn't&lt;br /&gt;
					local failReason = &amp;quot;Invalid data type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedStringLength = dataToCheck.allowedStringLength -- if data has string length check&lt;br /&gt;
				local dataString = (dataType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
				if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
					local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
					local stringLength = utf8.len(eventData) -- get length of data string&lt;br /&gt;
					local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedTableLength = dataToCheck.allowedTableLength -- if data has table length check&lt;br /&gt;
				local dataTable = (dataType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
				if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
					local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
					local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
					local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
					local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
					for _, _ in pairs(eventData) do -- loop through whole table&lt;br /&gt;
						tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
						minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
						maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
						if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
							break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
						local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedNumberRange = dataToCheck.allowedNumberRange -- if data has number range check&lt;br /&gt;
				local dataNumber = (dataType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
				if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
					local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
					local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
					local matchingRange = (eventData &amp;gt;= minRange) and (eventData &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingRange) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this event call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- helper function to log and handle accidents&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view player which called event&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of source element&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected event abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Event: &amp;quot;..serverEvent..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect or skipPunishment) then -- we don't want to punish player for some reason&lt;br /&gt;
		return true -- stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(clientElement, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(clientElement, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- all done, report success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onServerEvent(clientData)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local dataToPass = 10&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerEvent&amp;quot;, localPlayer, dataToPass)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = clientData, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;number&amp;quot;] = true, -- we want it to be only number&lt;br /&gt;
					},&lt;br /&gt;
					allowedNumberRange = {1, 100}, -- in range of 1 to 100&lt;br /&gt;
					debugData = &amp;quot;clientData&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerEvent&amp;quot;, root, onServerEvent)&lt;br /&gt;
&lt;br /&gt;
function onServerAdminEvent(playerToBan)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server admin event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local playerToBan = getPlayerFromName(&amp;quot;playerToBan&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerAdminEvent&amp;quot;, localPlayer, playerToBan)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerAdminEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkACLGroup = { -- we need to check whether player who called event belongs to ACL groups&lt;br /&gt;
				&amp;quot;Admin&amp;quot;, -- in this case admin group&lt;br /&gt;
			},&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = playerToBan, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;player&amp;quot;] = true, -- we want it to be player&lt;br /&gt;
					},&lt;br /&gt;
					debugData = &amp;quot;playerToBan&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerAdminEvent&amp;quot;, root, onServerAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing server-only events==&lt;br /&gt;
* It is very important to '''disable remote triggering''' ability in [https://wiki.multitheftauto.com/wiki/AddEvent addEvent], to prevent calling server-side only events from client-side.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example shows how you should make event server-side only.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onServerSideOnlyEvent()&lt;br /&gt;
	-- do some server-side stuff&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerSideOnlyEvent&amp;quot;, false) -- set second argument (allowRemoteTriger) to false, so it can't be called from client&lt;br /&gt;
addEventHandler(&amp;quot;onServerSideOnlyEvent&amp;quot;, root, onServerSideOnlyEvent) -- associate our event with function onServerSideOnlyEvent&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing projectiles &amp;amp; explosions==&lt;br /&gt;
This section (and '''code''' is '''work in progress''') - '''use at your own risk'''.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile ammo tracker:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerProjectileAmmo = {} -- store player-held weapons ammo here&lt;br /&gt;
local playerWeaponsToTrack = { -- keep track of ammo for certain player-held weapon types, basically those which create projectile; [weaponID] = weaponSlot&lt;br /&gt;
	[16] = 8, -- grenade&lt;br /&gt;
	[17] = 8, -- teargas&lt;br /&gt;
	[18] = 8, -- molotov&lt;br /&gt;
	[35] = 7, -- rocket launcher&lt;br /&gt;
	[36] = 7, -- rocket launcher (heat-seeking)&lt;br /&gt;
	[39] = 8, -- satchel charge&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for weaponID, weaponSlot in pairs(playerWeaponsToTrack) do&lt;br /&gt;
		local weaponInSlot = getPedWeapon(playerElement, weaponSlot)&lt;br /&gt;
		local weaponTotalAmmo = getPedTotalAmmo(playerElement, weaponSlot)&lt;br /&gt;
		local weaponHasAmmo = (weaponTotalAmmo &amp;gt; 0)&lt;br /&gt;
		local weaponMatching = (weaponInSlot == weaponID)&lt;br /&gt;
		local updateWeaponAmmo = (weaponMatching and weaponHasAmmo)&lt;br /&gt;
&lt;br /&gt;
		if (updateWeaponAmmo) then&lt;br /&gt;
			local storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			local newWeaponAmmo = (updateWeaponAmmo and weaponTotalAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
			if (not storedProjectileAmmo) then&lt;br /&gt;
				playerProjectileAmmo[playerElement] = {}&lt;br /&gt;
				storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			storedProjectileAmmo[weaponID] = newWeaponAmmo&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function hasPlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
	local projectileAmmo = (projectileData and projectileData[projectileWeapon])&lt;br /&gt;
&lt;br /&gt;
	return projectileAmmo&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectileData) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileWeaponAmmo = playerProjectileData[projectileWeapon]&lt;br /&gt;
	local tempProjectileAmmo = (projectileWeaponAmmo - 1)&lt;br /&gt;
	local newProjectileAmmo = (tempProjectileAmmo &amp;gt; 0 and tempProjectileAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectileData[projectileWeapon] = newProjectileAmmo&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerWeaponSwitchAntiCheat(previousWeaponID, currentWeaponID)&lt;br /&gt;
	setTimer(updateProjectileAmmoForPlayer, 50, 1, source)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWeaponSwitch&amp;quot;, root, onPlayerWeaponSwitchAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onResourceStartAntiCheat()&lt;br /&gt;
	local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	for playerID = 1, #playersTable do&lt;br /&gt;
		local playerElement = playersTable[playerID]&lt;br /&gt;
&lt;br /&gt;
		updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, resourceRoot, onResourceStartAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerWastedQuitAntiCheat()&lt;br /&gt;
	playerProjectileAmmo[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWasted&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerCreatedProjectiles = {} -- store count of legitimately created player projectiles; [playerElement] = {[projectileType] = activeProjectiles}&lt;br /&gt;
local projectileTypes = {&lt;br /&gt;
	[16] = { -- Grenade&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[17] = { -- Teargas&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[17] = true, -- teargas&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[18] = { -- Molotov&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[19] = { -- Rocket&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[425] = true, -- hunter&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[20] = { -- Rocket (heat-seeking)&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[21] = { -- Airbomb&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[39] = { -- Satchel charge&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[39] = true, -- satchel charge&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[58] = { -- Hydra flare&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportProjectileAbnormality(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	local projectileSyncer = inspect(playerElement)&lt;br /&gt;
	local projectilePosition = projectileX..&amp;quot;, &amp;quot;..projectileY..&amp;quot;, &amp;quot;..projectileZ&lt;br /&gt;
	local projectileZoneName = getZoneName(projectileX, projectileY, projectileZ, false)&lt;br /&gt;
	local projectileCityName = getZoneName(projectileX, projectileY, projectileZ, true)&lt;br /&gt;
	local projectileLog =&lt;br /&gt;
		&amp;quot;* Detected projectile abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile syncer: &amp;quot;..projectileSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile type: &amp;quot;..projectileType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile position: &amp;quot;..projectilePosition.. &amp;quot; (&amp;quot;..projectileZoneName..&amp;quot;, &amp;quot;..projectileCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(projectileLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processProjectileChecks(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
	local projectileAllowed = projectileData.projectileAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not projectileAllowed) then&lt;br /&gt;
		return false, &amp;quot;Projectile not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileAllowedWeapons = projectileData.projectileAllowedWeapons&lt;br /&gt;
&lt;br /&gt;
	if (projectileAllowedWeapons) then&lt;br /&gt;
		local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
		local allowedWeapon = projectileAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedWeapon) then&lt;br /&gt;
			return false, &amp;quot;Player is not holding correct weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
		local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
		if (not playerHasAmmo) then&lt;br /&gt;
			return false, &amp;quot;Player doesn't have ammo for weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerVehicle) then&lt;br /&gt;
		local projectileAllowedVehicles = projectileData.projectileAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
		if (projectileAllowedVehicles) then&lt;br /&gt;
			local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
			local allowedVehicle = projectileAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedVehicle) then&lt;br /&gt;
				return false, &amp;quot;Player is not inside allowed vehicles&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
			local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
			if (not playerDriver) then&lt;br /&gt;
				return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Player in vehicle&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxDistanceFromCreator = projectileData.projectileMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToProjectile = getDistanceBetweenPoints3D(playerX, playerY, playerZ, projectileX, projectileY, projectileZ)&lt;br /&gt;
		local matchingProjectileDistance = (distanceToProjectile &amp;lt;= projectileMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileDistance) then&lt;br /&gt;
			return false, &amp;quot;Projectile distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxVelocity = projectileData.projectileMaxVelocity&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxVelocity) then&lt;br /&gt;
		local projectileVelocity = (projectileVX ^ 2 + projectileVY ^ 2 + projectileVZ ^ 2)&lt;br /&gt;
		local projectileSpeed = math.sqrt(projectileVelocity)&lt;br /&gt;
		local matchingProjectileVelocity = (projectileSpeed &amp;lt;= projectileMaxVelocity)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileVelocity) then&lt;br /&gt;
			return false, &amp;quot;Projectile velocity mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function trackPlayerProjectile(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		playerCreatedProjectiles[playerElement] = {}&lt;br /&gt;
		playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID] or 0&lt;br /&gt;
	local newProjectilesCount = (projectilesByType + 1)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
&lt;br /&gt;
	if (not projectileData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileBehaviour = projectileData.projectileOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not projectileBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = projectileBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = projectileBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = projectileBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID]&lt;br /&gt;
&lt;br /&gt;
	if (not projectilesByType) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local tempProjectilesCount = (projectilesByType - 1)&lt;br /&gt;
	local newProjectilesCount = (tempProjectilesCount &amp;gt; 0 and tempProjectilesCount or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerProjectileCreationAntiCheat(projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local approvedProjectile, detectionCode = processProjectileChecks(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedProjectile) then&lt;br /&gt;
		trackPlayerProjectile(source, projectileType)&lt;br /&gt;
&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportProjectileAbnormality(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerProjectileCreation&amp;quot;, root, onPlayerProjectileCreationAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerQuitAntiCheat()&lt;br /&gt;
	playerCreatedProjectiles[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Explosions handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local rocketInstantExplosionDistanceThreshold = 1.55 -- distance below which only explosion will be created (and not rocket projectile, hence not calling onPlayerProjectileCreation); do not change it&lt;br /&gt;
local explosionTypes = { -- more specific info on explosion, and whether it is allowed&lt;br /&gt;
	[0] = { -- Grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[1] = { -- Molotov&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[2] = { -- Rocket&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[3] = { -- Rocket weak&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[4] = { -- Car&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[5] = { -- Car quick&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[6] = { -- Boat&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[7] = { -- Heli&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[8] = { -- Mine&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[9] = { -- Object&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[10] = { -- Tank grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionMaxDistanceFromCreator = 80,&lt;br /&gt;
		explosionAllowedVehicles = {&lt;br /&gt;
			[432] = true,&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	[11] = { -- Small&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[12] = { -- Tiny&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportExplosionAbnormality(playerElement, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	local explosionSyncer = inspect(playerElement)&lt;br /&gt;
	local explosionType = explosionType&lt;br /&gt;
	local explosionPosition = explosionX..&amp;quot;, &amp;quot;..explosionY..&amp;quot;, &amp;quot;..explosionZ&lt;br /&gt;
	local explosionZoneName = getZoneName(explosionX, explosionY, explosionZ, false)&lt;br /&gt;
	local explosionCityName = getZoneName(explosionX, explosionY, explosionZ, true)&lt;br /&gt;
	local explosionLog =&lt;br /&gt;
		&amp;quot;* Detected explosion abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion syncer: &amp;quot;..explosionSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion type: &amp;quot;..explosionType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion position: &amp;quot;..explosionPosition.. &amp;quot; (&amp;quot;..explosionZoneName..&amp;quot;, &amp;quot;..explosionCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(explosionLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processExplosionChecks(playerElement, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
	local explosionAllowed = explosionData.explosionAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not explosionAllowed) then&lt;br /&gt;
		return false, &amp;quot;Explosion type not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local rocketExplosion = (explosionType == 2)&lt;br /&gt;
&lt;br /&gt;
	if (rocketExplosion) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local instantExplosion = (distanceToExplosion &amp;lt; rocketInstantExplosionDistanceThreshold)&lt;br /&gt;
&lt;br /&gt;
		if (instantExplosion) then&lt;br /&gt;
			local explosionAllowedWeapons = explosionData.explosionAllowedWeapons&lt;br /&gt;
			local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
			local allowedWeapon = explosionAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedWeapon) then&lt;br /&gt;
				return false, &amp;quot;Player is not holding rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
			local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
			if (not playerHasAmmo) then&lt;br /&gt;
				return false, &amp;quot;Player doesn't have ammo for rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedProjectiles = explosionData.explosionAllowedProjectiles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedProjectiles) then&lt;br /&gt;
&lt;br /&gt;
		for projectileID, _ in pairs(explosionAllowedProjectiles) do&lt;br /&gt;
			local atleastOneProjectile = decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
&lt;br /&gt;
			if (atleastOneProjectile) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Explosion created without respective projectile&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedVehicles = explosionData.explosionAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedVehicles) then&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
		if (not playerVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is not in vehicle&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
		local allowedVehicle = explosionAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is inside not allowed vehicles&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
		local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
		if (not playerDriver) then&lt;br /&gt;
			return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionMaxDistanceFromCreator = explosionData.explosionMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (explosionMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local matchingExplosionDistance = (distanceToExplosion &amp;lt; explosionMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingExplosionDistance) then&lt;br /&gt;
			return false, &amp;quot;Explosion distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
&lt;br /&gt;
	if (not explosionData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionBehaviour = explosionData.explosionOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not explosionBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = explosionBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = explosionBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = explosionBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onExplosionAntiCheat(explosionX, explosionY, explosionZ, explosionType)&lt;br /&gt;
	local serverSyncExplosion = (source == root)&lt;br /&gt;
&lt;br /&gt;
	if (serverSyncExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedExplosion, detectionCode = processExplosionChecks(source, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportExplosionAbnormality(source, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onExplosion&amp;quot;, root, onExplosionAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handling non-registered events==&lt;br /&gt;
&lt;br /&gt;
See: [[onPlayerTriggerInvalidEvent]]&lt;br /&gt;
&lt;br /&gt;
==Handling events spam==&lt;br /&gt;
See: [[onPlayerTriggerEventThreshold]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnPlayerZoneChange&amp;diff=81977</id>
		<title>OnPlayerZoneChange</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnPlayerZoneChange&amp;diff=81977"/>
		<updated>2025-05-01T15:05:14Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
&amp;lt;lowercasetitle&amp;gt;&amp;lt;/lowercasetitle&amp;gt; __NOTOC__&lt;br /&gt;
This code implements an [[event]] that is triggered when the [[player]] enters a new area on the map.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
string oldZone, string newZone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''oldZone:''' old zone of [[player]].&lt;br /&gt;
*'''newZone:''' new zone of [[player]].&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the player whose zone was changed.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playersZone = {}&lt;br /&gt;
local zoneEventName = (localPlayer and &amp;quot;onClientPlayerZoneChange&amp;quot; or &amp;quot;onPlayerZoneChange&amp;quot;) -- client = &amp;quot;onClientPlayerZoneChange&amp;quot; — server = &amp;quot;onPlayerZoneChange&amp;quot;&lt;br /&gt;
local zoneCitiesOnly = false -- only major cities?&lt;br /&gt;
&lt;br /&gt;
local function checkPlayersZone()&lt;br /&gt;
    local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    for playerID = 1, #playersTable do&lt;br /&gt;
        local playerElement = playersTable[playerID]&lt;br /&gt;
        local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
        local playerZoneNow = getZoneName(playerX, playerY, playerZ, zoneCitiesOnly)&lt;br /&gt;
        local playerZoneSaved = playersZone[playerElement]&lt;br /&gt;
        local playerZoneNeedsUpdate = (playerZoneSaved and playerZoneSaved ~= playerZoneNow)&lt;br /&gt;
&lt;br /&gt;
        if (playerZoneNeedsUpdate) then&lt;br /&gt;
            triggerEvent(zoneEventName, playerElement, playerZoneSaved, playerZoneNow)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        playersZone[playerElement] = playerZoneNow&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addEvent(zoneEventName, false) -- disable remote triggering so players couldn't trigger this event on server (&amp;amp; vice-versa)&lt;br /&gt;
setTimer(checkPlayersZone, 1000, 0)&lt;br /&gt;
&lt;br /&gt;
local function clearPlayersZone()&lt;br /&gt;
    playersZone[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(localPlayer and &amp;quot;onClientPlayerQuit&amp;quot; or &amp;quot;onPlayerQuit&amp;quot;, root, clearPlayersZone)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Authors:''' [[User:IManGaaX|Youssef Maged (iManGaaX)]]&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example will make label with the full zone name of the player, '''onPlayerZoneChange''' is function is change the label text to new zone when the player enter a new zone.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local myCurrentZoneLabel&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, function()&lt;br /&gt;
    local firstZone = getElementZoneName(localPlayer)&lt;br /&gt;
    myCurrentZoneLabel = guiCreateLabel(0, 0, 0.20, 0.02, firstZone, true)&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, function(_, newZone)&lt;br /&gt;
    if (source == localPlayer) then&lt;br /&gt;
        guiSetText(myCurrentZoneLabel, newZone)&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
This example will out put in the chat the new zone full name when the player enter a new zone.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, function(oldZone, newZone)&lt;br /&gt;
    outputChatBox(&amp;quot;Your Zone is Changed from &amp;quot;..(oldZone)..&amp;quot; to &amp;quot;..(newZone)..&amp;quot;.&amp;quot;, source, 255, 255, 0)&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=EngineReplaceModel&amp;diff=81976</id>
		<title>EngineReplaceModel</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=EngineReplaceModel&amp;diff=81976"/>
		<updated>2025-05-01T10:57:01Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
&lt;br /&gt;
This function replaces the given model ID with the model contained in a DFF file loaded by [[engineLoadDFF]]. This function supports [[vehicle|vehicles]], [[object|objects]], [[ped|peds]] and [[player|players]].&lt;br /&gt;
&lt;br /&gt;
Since version [https://buildinfo.multitheftauto.com/?Revision=23124&amp;amp;Branch= r23124] and above replacing CJ clothing became possible - see: [[Clothing Component IDs]]. Body parts replacements aren't supported at the moment.&lt;br /&gt;
&lt;br /&gt;
To replace weapon models you must use their object IDs, not weapon IDs. There is a weapon model list available at [[Weapons]].&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
* Follow loading order ('''COL''' -&amp;gt; '''TXD''' -&amp;gt; '''DFF''') which is used in the example - as other orders can cause collisions, textures or the DFF not to load due to technical limitations.&lt;br /&gt;
* Default GTA map objects behave inconsistently when using this function on them. If you want to replace models in the original GTA map, you need to call [[engineRestreamWorld]] after replacing models as well.&lt;br /&gt;
* A raw data DFF element can only be used once, because the underlying memory for the model is released after replacement.&lt;br /&gt;
* If the replacement model is broken and the original model is not loaded/streamed-in at the time of replacement, this function will succeed and you won't see any error message, neither when the model replacement fails once the original model starts to load/stream-in.}}&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool engineReplaceModel ( dff theModel, int modelID [, bool alphaTransparency = false ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{OOP||[[DFF|dff]]:replace}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''theModel:''' The model to replace the given model ID with&lt;br /&gt;
*'''modelID:''' The model it to replace the model of&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
*'''alphaTransparency:''' Set to true if model uses semi-transparent textures, e.g. windows. This will ensure other objects behind the semi-transparent textures are rendered correctly. (Can slightly impact performance, so only set when required)&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the model was successfully replaced, ''false'' if it failed for some reason, ie. the DFF or the model ID is not valid.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example allows you to replace single or many models (with ability to toggle TXD filtering/DFF alpha transparency) - by using [[table]]. Do not forget to add those file paths to [[meta.xml]]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientResourceStartReplaceModels()&lt;br /&gt;
	local modelsToReplace = {&lt;br /&gt;
		{ -- replace object (all object IDs here: https://dev.prineside.com/en/gtasa_samp_model_id/)&lt;br /&gt;
			colFile = &amp;quot;object.col&amp;quot;,&lt;br /&gt;
			txdFile = &amp;quot;object.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;object.dff&amp;quot;,&lt;br /&gt;
			modelID = 1337,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
		{ -- replace vehicle (all vehicle IDs here: https://wiki.multitheftauto.com/wiki/Vehicle_IDs)&lt;br /&gt;
			colFile = false, -- if file is not present set to false/nil&lt;br /&gt;
			txdFile = &amp;quot;vehicle.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;vehicle.dff&amp;quot;,&lt;br /&gt;
			modelID = 434,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
		{ -- replace skin (all ped IDs here: https://wiki.multitheftauto.com/wiki/Character_Skins)&lt;br /&gt;
			colFile = false, -- if file is not present set to false/nil&lt;br /&gt;
			txdFile = &amp;quot;ped.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;ped.dff&amp;quot;,&lt;br /&gt;
			modelID = 16,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
		{ -- replace weapon (all weapon IDs here: https://wiki.multitheftauto.com/wiki/Weapons)&lt;br /&gt;
			colFile = false, -- if file is not present set to false/nil&lt;br /&gt;
			txdFile = &amp;quot;m4.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;m4.dff&amp;quot;,&lt;br /&gt;
			modelID = 356,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for assetID = 1, #modelsToReplace do&lt;br /&gt;
		local modelData = modelsToReplace[assetID]&lt;br /&gt;
		local modelCol = modelData.colFile&lt;br /&gt;
		local modelTxd = modelData.txdFile&lt;br /&gt;
		local modelDff = modelData.dffFile&lt;br /&gt;
		local modelID = modelData.modelID&lt;br /&gt;
&lt;br /&gt;
		if (modelCol) then&lt;br /&gt;
			local colData = engineLoadCOL(modelCol)&lt;br /&gt;
&lt;br /&gt;
			if (colData) then&lt;br /&gt;
				engineReplaceCOL(colData, modelID)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if (modelTxd) then&lt;br /&gt;
			local filteringEnabled = modelData.filteringEnabled&lt;br /&gt;
			local txdData = engineLoadTXD(modelTxd, filteringEnabled)&lt;br /&gt;
&lt;br /&gt;
			if (txdData) then&lt;br /&gt;
				engineImportTXD(txdData, modelID)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if (modelDff) then&lt;br /&gt;
			local dffData = engineLoadDFF(modelDff)&lt;br /&gt;
&lt;br /&gt;
			if (dffData) then&lt;br /&gt;
				local alphaTransparency = modelData.alphaTransparency&lt;br /&gt;
				&lt;br /&gt;
				engineReplaceModel(dffData, modelID, alphaTransparency)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, onClientResourceStartReplaceModels)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Engine_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=EngineReplaceModel&amp;diff=81975</id>
		<title>EngineReplaceModel</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=EngineReplaceModel&amp;diff=81975"/>
		<updated>2025-05-01T10:55:44Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
&lt;br /&gt;
This function replaces the given model ID with the model contained in a DFF file loaded by [[engineLoadDFF]]. This function supports [[vehicle|vehicles]], [[object|objects]], [[ped|peds]] and [[player|players]].&lt;br /&gt;
Since version [https://buildinfo.multitheftauto.com/?Revision=23124&amp;amp;Branch= r23124] and above replacing CJ clothing became possible - see: [[Clothing Component IDs]]. Body parts replacements aren't supported at the moment.&lt;br /&gt;
{{Deprecated feature|3.0111|1.1.1|This function does not support ped and weapon models.}}&lt;br /&gt;
&lt;br /&gt;
To replace weapon models you must use their object IDs, not weapon IDs. There is a weapon model list available at [[weapons]].&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
* Follow loading order ('''COL''' -&amp;gt; '''TXD''' -&amp;gt; '''DFF''') which is used in the example - as other orders can cause collisions, textures or the DFF not to load due to technical limitations.&lt;br /&gt;
* Default GTA map objects behave inconsistently when using this function on them. If you want to replace models in the original GTA map, you need to call [[engineRestreamWorld]] after replacing models as well.&lt;br /&gt;
* A raw data DFF element can only be used once, because the underlying memory for the model is released after replacement.&lt;br /&gt;
* If the replacement model is broken and the original model is not loaded/streamed-in at the time of replacement, this function will succeed and you won't see any error message, neither when the model replacement fails once the original model starts to load/stream-in.}}&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool engineReplaceModel ( dff theModel, int modelID [, bool alphaTransparency = false ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{OOP||[[DFF|dff]]:replace}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''theModel:''' The model to replace the given model ID with&lt;br /&gt;
*'''modelID:''' The model it to replace the model of&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
*'''alphaTransparency:''' Set to true if model uses semi-transparent textures, e.g. windows. This will ensure other objects behind the semi-transparent textures are rendered correctly. (Can slightly impact performance, so only set when required)&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the model was successfully replaced, ''false'' if it failed for some reason, ie. the DFF or the model ID is not valid.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example allows you to replace single or many models (with ability to toggle TXD filtering/DFF alpha transparency) - by using [[table]]. Do not forget to add those file paths to [[meta.xml]]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientResourceStartReplaceModels()&lt;br /&gt;
	local modelsToReplace = {&lt;br /&gt;
		{ -- replace object (all object IDs here: https://dev.prineside.com/en/gtasa_samp_model_id/)&lt;br /&gt;
			colFile = &amp;quot;object.col&amp;quot;,&lt;br /&gt;
			txdFile = &amp;quot;object.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;object.dff&amp;quot;,&lt;br /&gt;
			modelID = 1337,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
		{ -- replace vehicle (all vehicle IDs here: https://wiki.multitheftauto.com/wiki/Vehicle_IDs)&lt;br /&gt;
			colFile = false, -- if file is not present set to false/nil&lt;br /&gt;
			txdFile = &amp;quot;vehicle.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;vehicle.dff&amp;quot;,&lt;br /&gt;
			modelID = 434,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
		{ -- replace skin (all ped IDs here: https://wiki.multitheftauto.com/wiki/Character_Skins)&lt;br /&gt;
			colFile = false, -- if file is not present set to false/nil&lt;br /&gt;
			txdFile = &amp;quot;ped.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;ped.dff&amp;quot;,&lt;br /&gt;
			modelID = 16,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
		{ -- replace weapon (all weapon IDs here: https://wiki.multitheftauto.com/wiki/Weapons)&lt;br /&gt;
			colFile = false, -- if file is not present set to false/nil&lt;br /&gt;
			txdFile = &amp;quot;m4.txd&amp;quot;,&lt;br /&gt;
			dffFile = &amp;quot;m4.dff&amp;quot;,&lt;br /&gt;
			modelID = 356,&lt;br /&gt;
			alphaTransparency = false,&lt;br /&gt;
			filteringEnabled = true,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for assetID = 1, #modelsToReplace do&lt;br /&gt;
		local modelData = modelsToReplace[assetID]&lt;br /&gt;
		local modelCol = modelData.colFile&lt;br /&gt;
		local modelTxd = modelData.txdFile&lt;br /&gt;
		local modelDff = modelData.dffFile&lt;br /&gt;
		local modelID = modelData.modelID&lt;br /&gt;
&lt;br /&gt;
		if (modelCol) then&lt;br /&gt;
			local colData = engineLoadCOL(modelCol)&lt;br /&gt;
&lt;br /&gt;
			if (colData) then&lt;br /&gt;
				engineReplaceCOL(colData, modelID)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if (modelTxd) then&lt;br /&gt;
			local filteringEnabled = modelData.filteringEnabled&lt;br /&gt;
			local txdData = engineLoadTXD(modelTxd, filteringEnabled)&lt;br /&gt;
&lt;br /&gt;
			if (txdData) then&lt;br /&gt;
				engineImportTXD(txdData, modelID)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if (modelDff) then&lt;br /&gt;
			local dffData = engineLoadDFF(modelDff)&lt;br /&gt;
&lt;br /&gt;
			if (dffData) then&lt;br /&gt;
				local alphaTransparency = modelData.alphaTransparency&lt;br /&gt;
				&lt;br /&gt;
				engineReplaceModel(dffData, modelID, alphaTransparency)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, onClientResourceStartReplaceModels)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Engine_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PathListDir&amp;diff=81965</id>
		<title>PathListDir</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PathListDir&amp;diff=81965"/>
		<updated>2025-04-27T16:20:23Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Shared function}}&lt;br /&gt;
&lt;br /&gt;
{{New feature/item|3.161|1.6.0|22470|&lt;br /&gt;
Reads a specified directory and returns all entries inside of it. These entries can be file or folder names.&lt;br /&gt;
}}&lt;br /&gt;
{{Note|&lt;br /&gt;
* Listing other resource directory can be done by passing '''&amp;quot;:resourceName/.&amp;quot;'''&lt;br /&gt;
* For listing current resource (the one where code is executed), you can pass either '''&amp;quot;&amp;quot;''' or '''&amp;quot;:currentResourceName/.&amp;quot;''' (preferably use first approach, because the latter will require removing this part, once result is ready)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
table pathListDir ( string path )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[path]]:listDir}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''path:''' A [[string]] containing a path you want to get entries from&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns [[table]] with all entries in a specified directory.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example loads all models from a certain directory&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- from https://gist.github.com/kgriffs/124aae3ac80eefe57199451b823c24ec&lt;br /&gt;
local function stringEndsWith(str, ending)&lt;br /&gt;
    return ending == &amp;quot;&amp;quot; or str:sub(-#ending) == ending&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- get all files from a models directory that exists in the resource root folder (resources/ResourceName)&lt;br /&gt;
-- and load them into the game&lt;br /&gt;
addEventHandler('onClientResourceStart', resourceRoot, function()&lt;br /&gt;
    local entries = pathListDir('models') or {}&lt;br /&gt;
    for _, fileOrFolder in ipairs(entries) do&lt;br /&gt;
        if pathIsFile(fileOrFolder) then&lt;br /&gt;
            local file = fileOrFolder&lt;br /&gt;
            local modelName = tonumber(file:sub(1, -5))&lt;br /&gt;
            if modelName then&lt;br /&gt;
                -- the full path to the file&lt;br /&gt;
                local filePath = 'models/'..file&lt;br /&gt;
&lt;br /&gt;
                if stringEndsWith(file, '.col') then&lt;br /&gt;
                    local colData = engineLoadCOL(filePath)&lt;br /&gt;
                    if colData then&lt;br /&gt;
                        engineReplaceCOL(colData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if stringEndsWith(file, '.txd') then&lt;br /&gt;
                    local txdData = engineLoadTXD(filePath)&lt;br /&gt;
                    if txdData then&lt;br /&gt;
                        engineImportTXD(txdData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if stringEndsWith(file, '.dff') then&lt;br /&gt;
                    local dffData = engineLoadDFF(filePath)&lt;br /&gt;
                    if dffData then&lt;br /&gt;
                        engineReplaceModel(dffData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end, false)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Shared_path_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnPlayerZoneChange&amp;diff=81957</id>
		<title>OnPlayerZoneChange</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnPlayerZoneChange&amp;diff=81957"/>
		<updated>2025-04-22T21:33:16Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
&amp;lt;lowercasetitle&amp;gt;&amp;lt;/lowercasetitle&amp;gt; __NOTOC__&lt;br /&gt;
This code implements an [[event]] that is triggered when the [[player]] enters a new area on the map.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
string oldZone, string newZone&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''oldZone:''' old zone of [[player]].&lt;br /&gt;
*'''newZone:''' new zone of [[player]].&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the player whose zone was changed.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playersZone = {}&lt;br /&gt;
local zoneEventName = (localPlayer and &amp;quot;onClientPlayerZoneChange&amp;quot; or &amp;quot;onPlayerZoneChange&amp;quot;) -- client = &amp;quot;onClientPlayerZoneChange&amp;quot; — server = &amp;quot;onPlayerZoneChange&amp;quot;&lt;br /&gt;
local zoneCitiesOnly = false -- only major cities?&lt;br /&gt;
&lt;br /&gt;
local function checkPlayersZone()&lt;br /&gt;
	local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	for playerID = 1, #playersTable do&lt;br /&gt;
		local playerElement = playersTable[playerID]&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local playerZoneNow = getZoneName(playerX, playerY, playerZ, zoneCitiesOnly)&lt;br /&gt;
		local playerZoneSaved = playersZone[playerElement]&lt;br /&gt;
		local playerZoneNeedsUpdate = (playerZoneSaved and playerZoneSaved ~= playerZoneNow)&lt;br /&gt;
&lt;br /&gt;
		if (playerZoneNeedsUpdate) then&lt;br /&gt;
			triggerEvent(zoneEventName, playerElement, playerZoneSaved, playerZoneNow)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		playersZone[playerElement] = playerZoneNow&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEvent(zoneEventName, false) -- disable remote triggering so players couldn't trigger this event on server (&amp;amp; vice-versa)&lt;br /&gt;
setTimer(checkPlayersZone, 1000, 0)&lt;br /&gt;
&lt;br /&gt;
local function clearPlayersZone()&lt;br /&gt;
	playersZone[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(localPlayer and &amp;quot;onClientPlayerQuit&amp;quot; or &amp;quot;onPlayerQuit&amp;quot;, root, clearPlayersZone)&lt;br /&gt;
&lt;br /&gt;
-- example for server:&lt;br /&gt;
&lt;br /&gt;
function onPlayerZoneChange(oldZone, newZone)&lt;br /&gt;
	iprint(source, oldZone, newZone)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, onPlayerZoneChange)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Author:''' [[User:IManGaaX|Youssef Maged (iManGaaX)]]&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example will make label with the full zone name of the player, '''onPlayerZoneChange''' is function is change the label text to new zone when the player enter a new zone.&lt;br /&gt;
{{RequiredFunctions|getElementZoneFullName}}&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local myCurrentZoneLabel&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, function()&lt;br /&gt;
    local text = getElementZoneFullName(localPlayer)&lt;br /&gt;
    myCurrentZoneLabel = guiCreateLabel(0, 0, 0.20, 0.02, text, true)&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, function()&lt;br /&gt;
    if (source == localPlayer) then&lt;br /&gt;
    	local newText = getElementZoneFullName(localPlayer)&lt;br /&gt;
        guiSetText(myCurrentZoneLabel, newText)&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
This example will out put in the chat the new zone full name when the player enter a new zone.&lt;br /&gt;
{{RequiredFunctions|getElementZoneFullName}}&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, function()&lt;br /&gt;
    local newZone = getElementZoneFullName(source)&lt;br /&gt;
    outputChatBox(&amp;quot;Your Zone is Changed to &amp;quot;..(newZone)..&amp;quot;.&amp;quot;, source, 255, 255, 0)&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Scripting_Tips&amp;diff=81956</id>
		<title>Scripting Tips</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Scripting_Tips&amp;diff=81956"/>
		<updated>2025-04-22T21:21:49Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Fix misleading information &amp;amp; add information about RT&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a variety of things that knowing, make life easier for MTA scripters.&lt;br /&gt;
&lt;br /&gt;
== General Lua ==&lt;br /&gt;
* The ''infinite loop / too long execution error'' which aborts execution can be disabled with ''debug.sethook(nil)''&lt;br /&gt;
* Be careful when looping a table where you intend to delete multiple rows, if 2 of them are in a row the 2nd one will get skipped! You must loop the table backwards (reverse ipairs). For example: ''for i = #table, 1, -1 do''&lt;br /&gt;
* Rather than having if checks inside if checks inside if checks, consider using ''return'' for example ''if (not ready) then return false end''&lt;br /&gt;
* A quick way to clamp a number between a lower and upper value: math.min(math.max(x, min), max) and easy to remember, just think: &amp;quot;min max min max&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== MTA Scripting ==&lt;br /&gt;
* Remember that 'false' boolean has a value - If you want to delete a variable or element/account data, use 'nil' instead - this will reduce memory and disk usage (minuscule optimization, only notable on larger servers)&lt;br /&gt;
* Remember that 99% of the time it's a bug in your script, not an MTA bug! Don't report something to GitHub Issues until you're absolutely certain the bug can be reproduced with a small piece of script.&lt;br /&gt;
* As MTA already has so many functions and events virtually everything you want to do is already possible, as long as you're willing to do the work! You'll find better solutions to problems as there are many ways to achieve the same thing as long as you know all the functions and events.&lt;br /&gt;
* If a script is getting too complicated, try putting back-end stuff in another file so the main script calls the functions in the 2nd one. For example rather than having meaningless things like ''vehicleTable[vehicle][7]'' in the main file, put that in a function in the 2nd file and have the main file call a meaningfully named function so rather than seeing a useless ''7'' you'd see something like ''getFuel'' and although this might take longer to set-up you'll save time in the long run as you'll spend less time being confused when you come back to it in a weeks time to debug a problem.&lt;br /&gt;
* Your client side scripts can cause desync if you're not careful, try to keep the psychical world equal with every player. For example if your script creates a client side object make sure your script will create it for everyone nearby, else people will be wondering why a player appears to be constantly floating and falling.&lt;br /&gt;
* Instead of using ''onClientResourceStart'' or ''onResourceStart'' events attached to ''resourceRoot'' like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function warnPeopleThatThisResourceStarted()&lt;br /&gt;
    outputChatBox(&amp;quot;The resource &amp;quot; .. getResourceName(resource) .. &amp;quot; has just started!&amp;quot;, 0, 255, 0)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, warnPeopleThatThisResourceStarted)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You can also use this outside of any function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;outputChatBox(&amp;quot;The resource &amp;quot; .. getResourceName(resource) .. &amp;quot; has just started!&amp;quot;, 0, 255, 0)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
However the result won't be exactly the same, as onClientResourceStart gets called only when all resource scripts are fully loaded, whilst code outside of it will be ran once '''this specific''' script is loaded. This is important, because load order of scripts exists, and you might want to call other script function (which gets loaded into memory afterwards), resulting in '''attempt to call global''' error. By using this specific event you have reliable time-frame to call it.&lt;br /&gt;
* string.dump produces unsigned compiled Lua code which is not allowed for security reasons. The only way to transport code now is by using the source code. e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;exampleFunction = [===[&lt;br /&gt;
    return param&lt;br /&gt;
]===]&lt;br /&gt;
&lt;br /&gt;
local loadedFunction = loadstring(exampleFunction)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MTA Scripting - Element IDs Being Reused ==&lt;br /&gt;
* If your script is covered in [[isTimer]] and [[isElement]] checks to hide debug warnings from deleted elements not being dereferenced (making the variable nil) you will regret it when that element ID or timer pointer has to be re-used by MTA in a weeks time and your script starts acting strangely and you won't have a clue why. Dereference destroyed elements and disconnected players!&lt;br /&gt;
* Why would MTA reuse it in a weeks time? Everything has a userdata value whether it's a function or an element, there is a limited amount of these available meaning that eventually the server will be forced to use the same userdata value twice, as long as whatever that userdata value was for is no longer valid. This could happen within hours, weeks or even never depending on how many elements are being created and destroyed by your scripts.&lt;br /&gt;
* For example if you have a race server that has 100 objects in every map and the map was changing every 5 minutes your server would go through at least 1200 an hour, 28,800 a day, 201,600 a week in userdata values, it can't keep going up and up though eventually it will have to reuse the same userdata values and as long as you're dereferencing in your scripts, it won't be a problem.&lt;br /&gt;
&lt;br /&gt;
The is an example of a script which fails to dereference, because when the player quits their userdata value remains in the table, but what if in a weeks time another player joins and they get assigned the same userdata value?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local admins = {}&lt;br /&gt;
local secretPasswordOnlyAdminsShouldKnow = &amp;quot;12345678&amp;quot;&lt;br /&gt;
&lt;br /&gt;
function adminLogin()&lt;br /&gt;
    if (hasObjectPermissionTo(source, &amp;quot;command.ban&amp;quot;, false)) then&lt;br /&gt;
        admins[source] = true&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerLogin&amp;quot;, root, adminLogin)&lt;br /&gt;
&lt;br /&gt;
function cmdGetSecretPassword(plr)&lt;br /&gt;
    if (not admins[plr]) then&lt;br /&gt;
        return false&lt;br /&gt;
    end&lt;br /&gt;
    outputChatBox(&amp;quot;The secret password is &amp;quot;..secretPasswordOnlyAdminsShouldKnow, plr)&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;getsecretpass&amp;quot;, cmdGetSecretPassword)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some random player who joins in a weeks time gets the same userdata value as an admin, that player can now use &amp;quot;getsecretpass&amp;quot;. Solution? De-reference on destruction!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function onQuit()&lt;br /&gt;
    admins[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onQuit)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server Performance ==&lt;br /&gt;
* Server lagging? Check [[Debugging#Debugging_Performance_Issues|this page of debugging performance issues]]&lt;br /&gt;
* Using '''localPlayer''' (or if not possible: '''resourceRoot''') in '''2nd''' argument of triggerServer(Client)Event for events is much more efficient than using root.&lt;br /&gt;
* Try to be efficient, but if what you're doing is too time consuming or complex, is it really efficient?&lt;br /&gt;
* Unless you have hundreds of players, don't worry about making little optimizations, check ''performancebrowser'' or ''ipb'' (ingame performancebrowser) and make sure no resource is using significantly more than the others.&lt;br /&gt;
&lt;br /&gt;
== Client Performance ==&lt;br /&gt;
* The biggest cause of client script CPU usage is anything done in onClient/Pre/HUD/Render because it is called every frame. For example if you have a script which calls dxDrawLine3D 20 times, 60 times a second, if those lines are only in 1 part of the map, consider adding a [[getDistanceBetweenPoints3D]] check between the local player and the general area that those lines are in and if they're no where near the player, don't draw the lines.&lt;br /&gt;
* '''dxDraw*''' functions can be highly optimised by using [https://wiki.multitheftauto.com/wiki/DxCreateRenderTarget dxCreateRenderTarget], which will merge them into one single '''dxDrawImage''' resulting in much less calls. This can be applied to parts of interface which are static, or updated periodically.&lt;br /&gt;
* Another thing that gets called a lot and could therefore be quite consuming if not careful are events like [[onClientPlayerWeaponFire]] and [[onClientPlayerDamage]] so any scripts that use these should only be bound to the necessary elements (such as localPlayer instead of root) and run the simplest if statements for example if you wanted to handle a certain weapon being fired in a certain dimension it's better to check weapon first as that's a simple weaponID == x rather than getElementDimension(source) == y.&lt;br /&gt;
&lt;br /&gt;
== Speed comparison between local and global variables ==&lt;br /&gt;
&lt;br /&gt;
=== Slower ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
a = 1&lt;br /&gt;
for i=1,10000000 do&lt;br /&gt;
   a = 1&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;global&amp;quot;, stop - start ) -- more than 500ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
local b = 1&lt;br /&gt;
for i=1,10000000 do&lt;br /&gt;
   b = 1&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;local&amp;quot;, stop - start ) -- less than 200ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Speed comparison between structural and OOP scripting ==&lt;br /&gt;
=== Slower ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
a = 1&lt;br /&gt;
for i=1,1000000 do&lt;br /&gt;
   a = localPlayer.position&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;variable&amp;quot;, stop - start ) -- more than 1500ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
b = nil&lt;br /&gt;
for i=1,1000000 do&lt;br /&gt;
   b = getElementPosition(localPlayer)&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;structural&amp;quot;, stop - start ) -- less than 200ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=OnPlayerZoneChange&amp;diff=81955</id>
		<title>OnPlayerZoneChange</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=OnPlayerZoneChange&amp;diff=81955"/>
		<updated>2025-04-22T01:05:24Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Code improvements, including security fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
&amp;lt;lowercasetitle&amp;gt;&amp;lt;/lowercasetitle&amp;gt; __NOTOC__&lt;br /&gt;
This code implements an [[event]] that is triggered when the [[player]] enters a new area on the map.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
No parameters.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The [[event system#Event source|source]] of this event is the player whose zone was changed.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playersZone = {}&lt;br /&gt;
local zoneEventName = (localPlayer and &amp;quot;onClientPlayerZoneChange&amp;quot; or &amp;quot;onPlayerZoneChange&amp;quot;) -- client = &amp;quot;onClientPlayerZoneChange&amp;quot; — server = &amp;quot;onPlayerZoneChange&amp;quot;&lt;br /&gt;
local zoneCitiesOnly = false -- only major cities?&lt;br /&gt;
&lt;br /&gt;
local function checkPlayersZone()&lt;br /&gt;
	local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	for playerID = 1, #playersTable do&lt;br /&gt;
		local playerElement = playersTable[playerID]&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local playerZoneNow = getZoneName(playerX, playerY, playerZ, zoneCitiesOnly)&lt;br /&gt;
		local playerZoneSaved = playersZone[playerElement]&lt;br /&gt;
		local playerZoneNeedsUpdate = (playerZoneSaved and playerZoneSaved ~= playerZoneNow)&lt;br /&gt;
&lt;br /&gt;
		if (playerZoneNeedsUpdate) then&lt;br /&gt;
			triggerEvent(zoneEventName, playerElement, playerZoneSaved, playerZoneNow)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		playersZone[playerElement] = playerZoneNow&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEvent(zoneEventName, false) -- disable remote triggering so players couldn't trigger this event on server (&amp;amp; vice-versa)&lt;br /&gt;
setTimer(checkPlayersZone, 1000, 0)&lt;br /&gt;
&lt;br /&gt;
local function clearPlayersZone()&lt;br /&gt;
	playersZone[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(localPlayer and &amp;quot;onClientPlayerQuit&amp;quot; or &amp;quot;onPlayerQuit&amp;quot;, root, clearPlayersZone)&lt;br /&gt;
&lt;br /&gt;
-- example for server:&lt;br /&gt;
&lt;br /&gt;
function onPlayerZoneChange(oldZone, newZone)&lt;br /&gt;
	iprint(source, oldZone, newZone)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, onPlayerZoneChange)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Author:''' [[User:IManGaaX|Youssef Maged (iManGaaX)]]&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
This example will make label with the full zone name of the player, '''onPlayerZoneChange''' is function is change the label text to new zone when the player enter a new zone.&lt;br /&gt;
{{RequiredFunctions|getElementZoneFullName}}&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local myCurrentZoneLabel&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, function()&lt;br /&gt;
    local text = getElementZoneFullName(localPlayer)&lt;br /&gt;
    myCurrentZoneLabel = guiCreateLabel(0, 0, 0.20, 0.02, text, true)&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, function()&lt;br /&gt;
    if (source == localPlayer) then&lt;br /&gt;
    	local newText = getElementZoneFullName(localPlayer)&lt;br /&gt;
        guiSetText(myCurrentZoneLabel, newText)&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
This example will out put in the chat the new zone full name when the player enter a new zone.&lt;br /&gt;
{{RequiredFunctions|getElementZoneFullName}}&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerZoneChange&amp;quot;, root, function()&lt;br /&gt;
    local newZone = getElementZoneFullName(source)&lt;br /&gt;
    outputChatBox(&amp;quot;Your Zone is Changed to &amp;quot;..(newZone)..&amp;quot;.&amp;quot;, source, 255, 255, 0)&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PathListDir&amp;diff=81951</id>
		<title>PathListDir</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PathListDir&amp;diff=81951"/>
		<updated>2025-04-20T21:49:25Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Shared function}}&lt;br /&gt;
&lt;br /&gt;
{{New feature/item|3.161|1.6.0|22470|&lt;br /&gt;
Reads a specified directory and returns all entries inside of it. These entries can be file or folder names.&lt;br /&gt;
}}&lt;br /&gt;
{{Note|&lt;br /&gt;
* Listing other resource directory can be done by passing '''&amp;quot;:resourceName/.&amp;quot;'''&lt;br /&gt;
* For listing current resource (the one where code is executed), you can pass either '''&amp;quot;&amp;quot;''' or '''&amp;quot;:currentResourceName/.&amp;quot;'''&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
table pathListDir ( string path )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[path]]:listDir}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''path:''' A [[string]] containing a path you want to get entries from&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns [[table]] with all entries in a specified directory.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example loads all models from a certain directory&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- from https://gist.github.com/kgriffs/124aae3ac80eefe57199451b823c24ec&lt;br /&gt;
local function stringEndsWith(str, ending)&lt;br /&gt;
    return ending == &amp;quot;&amp;quot; or str:sub(-#ending) == ending&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- get all files from a models directory that exists in the resource root folder (resources/ResourceName)&lt;br /&gt;
-- and load them into the game&lt;br /&gt;
addEventHandler('onClientResourceStart', resourceRoot, function()&lt;br /&gt;
    local entries = pathListDir('models') or {}&lt;br /&gt;
    for _, fileOrFolder in ipairs(entries) do&lt;br /&gt;
        if pathIsFile(fileOrFolder) then&lt;br /&gt;
            local file = fileOrFolder&lt;br /&gt;
            local modelName = tonumber(file:sub(1, -5))&lt;br /&gt;
            if modelName then&lt;br /&gt;
                -- the full path to the file&lt;br /&gt;
                local filePath = 'models/'..file&lt;br /&gt;
&lt;br /&gt;
                if stringEndsWith(file, '.col') then&lt;br /&gt;
                    local colData = engineLoadCOL(filePath)&lt;br /&gt;
                    if colData then&lt;br /&gt;
                        engineReplaceCOL(colData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if stringEndsWith(file, '.txd') then&lt;br /&gt;
                    local txdData = engineLoadTXD(filePath)&lt;br /&gt;
                    if txdData then&lt;br /&gt;
                        engineImportTXD(txdData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if stringEndsWith(file, '.dff') then&lt;br /&gt;
                    local dffData = engineLoadDFF(filePath)&lt;br /&gt;
                    if dffData then&lt;br /&gt;
                        engineReplaceModel(dffData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end, false)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Shared_path_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PathListDir&amp;diff=81950</id>
		<title>PathListDir</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PathListDir&amp;diff=81950"/>
		<updated>2025-04-20T18:58:07Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: Add note about listing current &amp;amp; other resource directories&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Shared function}}&lt;br /&gt;
&lt;br /&gt;
{{New feature/item|3.161|1.6.0|22470|&lt;br /&gt;
Reads a specified directory and returns all entries inside of it. These entries can be file or folder names.&lt;br /&gt;
}}&lt;br /&gt;
{{Note|&lt;br /&gt;
* Listing other resource directory can be done by passing '''&amp;quot;:resourceName/.&amp;quot;'''&lt;br /&gt;
* For listing current resource (the one where code is executed), you can pass either '''&amp;quot;&amp;quot;''' or '''&amp;quot;:resourceName/.&amp;quot;'''&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
table pathListDir ( string path )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[path]]:listDir}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''path:''' A [[string]] containing a path you want to get entries from&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns [[table]] with all entries in a specified directory.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example loads all models from a certain directory&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- from https://gist.github.com/kgriffs/124aae3ac80eefe57199451b823c24ec&lt;br /&gt;
local function stringEndsWith(str, ending)&lt;br /&gt;
    return ending == &amp;quot;&amp;quot; or str:sub(-#ending) == ending&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- get all files from a models directory that exists in the resource root folder (resources/ResourceName)&lt;br /&gt;
-- and load them into the game&lt;br /&gt;
addEventHandler('onClientResourceStart', resourceRoot, function()&lt;br /&gt;
    local entries = pathListDir('models') or {}&lt;br /&gt;
    for _, fileOrFolder in ipairs(entries) do&lt;br /&gt;
        if pathIsFile(fileOrFolder) then&lt;br /&gt;
            local file = fileOrFolder&lt;br /&gt;
            local modelName = tonumber(file:sub(1, -5))&lt;br /&gt;
            if modelName then&lt;br /&gt;
                -- the full path to the file&lt;br /&gt;
                local filePath = 'models/'..file&lt;br /&gt;
&lt;br /&gt;
                if stringEndsWith(file, '.col') then&lt;br /&gt;
                    local colData = engineLoadCOL(filePath)&lt;br /&gt;
                    if colData then&lt;br /&gt;
                        engineReplaceCOL(colData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if stringEndsWith(file, '.txd') then&lt;br /&gt;
                    local txdData = engineLoadTXD(filePath)&lt;br /&gt;
                    if txdData then&lt;br /&gt;
                        engineImportTXD(txdData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if stringEndsWith(file, '.dff') then&lt;br /&gt;
                    local dffData = engineLoadDFF(filePath)&lt;br /&gt;
                    if dffData then&lt;br /&gt;
                        engineReplaceModel(dffData, modelName)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end, false)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Shared_path_functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetPositionInFrontOfElement&amp;diff=81948</id>
		<title>GetPositionInFrontOfElement</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetPositionInFrontOfElement&amp;diff=81948"/>
		<updated>2025-04-20T01:31:06Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: No need for table here&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
This function returns position in provided distance away from element, including element's rotation&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;float, float, float getPositionInFrontOfElement( element theElement, float distance )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
* '''theElement''': The element you want to get position in front of.&lt;br /&gt;
* '''distance''': Distance from an element you want to get position in.&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns three ''floats'' indicating the position in front of the element, ''x'', ''y'' and ''z'' respectively.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function getPositionInFrontOfElement(theElement, distance)&lt;br /&gt;
	assert((type(theElement) == &amp;quot;element&amp;quot; or type(theElement == &amp;quot;userdata&amp;quot;)), &amp;quot;Bad argument @ 'getPositionInFrontOfElement' [Expected element at argument 1, got &amp;quot;..(type(theElement))..&amp;quot;]&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local x, y, z = getElementPosition(theElement)&lt;br /&gt;
	local _, _, rz = getElementRotation(theElement)&lt;br /&gt;
&lt;br /&gt;
	local rotationRad = math.rad(rz)&lt;br /&gt;
	local objX = x - distance * math.sin(rotationRad)&lt;br /&gt;
	local objY = y + distance * math.cos(rotationRad)&lt;br /&gt;
	local objZ = z&lt;br /&gt;
&lt;br /&gt;
	return objX, objY, objZ&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addCommandHandler(&amp;quot;createtreeonmyface&amp;quot;, function(_, distance)&lt;br /&gt;
    local x, y, z = getPositionInFrontOfElement(localPlayer, tonumber(distance))&lt;br /&gt;
    if (x) then &lt;br /&gt;
        createObject(660, x, y, z)&lt;br /&gt;
    end &lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addCommandHandler(&amp;quot;createtreeonmyface&amp;quot;, function(player, _, distance)&lt;br /&gt;
    local x, y, z = getPositionInFrontOfElement(player, tonumber(distance))&lt;br /&gt;
    if (x) then &lt;br /&gt;
        createObject(660, x, y, z)&lt;br /&gt;
    end &lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Author:''' bover.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81943</id>
		<title>SetFPSLimit</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81943"/>
		<updated>2025-04-18T12:08:19Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Required Arguments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Server client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function sets the maximum [http://en.wikipedia.org/wiki/Frame_rate FPS (Frames per second)] that players on the server can run their game at.  &lt;br /&gt;
{{Note|&lt;br /&gt;
* When set client side, the actual limit used is the lowest of both the server and client set values.&lt;br /&gt;
* Starting from version [[https://buildinfo.mtasa.com/?Revision=21313&amp;amp;Branch r21313]] and above '''fpsLimit''' range is '''25-32767'''. In older MTA releases it was '''25-100'''.&lt;br /&gt;
}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setFPSLimit ( int fpsLimit )         &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''fpsLimit:''' An integer value representing the maximum FPS. Refer to the note above for possible values. You can also pass '''0''' or '''false''', in which case the FPS limit will be the one set in the client settings (by default, '''100 FPS''' and the client fps limit should also be manually changed via &amp;quot;'''fps_limit=0'''&amp;quot; in console or '''MTA San Andreas\MTA\config\coreconfig.xml''').&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if successful, or ''false'' if it was not possible to set the limit or an invalid value was passed.&lt;br /&gt;
&lt;br /&gt;
==Issues when increasing FPS==&lt;br /&gt;
Note: with &amp;quot;very high&amp;quot; FPS, any FPS limit over 74 is meant.&lt;br /&gt;
It is recommended to set a conservative FPS limit (between 40-60 and 74 highest) because high FPS can break some GTA internal calculations, causing various bugs. The higher the FPS the more of a problem these become:&lt;br /&gt;
&lt;br /&gt;
74 FPS is the breaking point that opens the door to various more severe GTA bugs related to FPS and physics.&lt;br /&gt;
&lt;br /&gt;
* Physics of vehicles is effected, both high and low FPSes may bring their own set of unfair advantages. Speaking about the consequences of high FPS in this context, up to 70 or 74 FPS is considered safe (as any differences in physics, if they do exist to begin with as they theoretically should, are so tiny that they are unmeasurable and thus wouldn't affect racing results in practise). Anything beyond 74 FPS may cause impactful discrepancies.&lt;br /&gt;
&lt;br /&gt;
* Pressing the horn button to turn on and off sirens gets really hard at very high FPS. For instance, at 100 FPS, you are more likely to hit the regular horn 3 times (inconsistent) before eventually triggering the siren, besides taking a similar amount of tries to turn off the siren.&lt;br /&gt;
* At very high FPS, climbing over certain objects will result in instant death. Example at: 2520.108, -1681.407, 19.406, 266 - [https://wiki.multitheftauto.com/wiki/SetFPSLimit#Fix_for_climbing_over_certain_objects you can use this Lua code to fix it.]&lt;br /&gt;
* The higher your FPS, the more of a penalty in satchel throwing distance (up to ~10% at very high FPS) will apply.&lt;br /&gt;
&lt;br /&gt;
For a full list of FPS-related GTA bugs (that are much less likely to impact gameplay in a meaningful way) and MTA developers' progress in tackling them, see the [https://github.com/multitheftauto/mtasa-blue/projects/14 Framerate issues tracker] github project.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example allows players to limit their own FPS using a command.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local minFPS = 25&lt;br /&gt;
local maxFPS = 100&lt;br /&gt;
&lt;br /&gt;
function fpsFunction(commandName, fpsLimit)&lt;br /&gt;
	local newFPS = tonumber(fpsLimit)&lt;br /&gt;
	local displaySyntax = (not newFPS) or (newFPS &amp;lt; minFPS) or (newFPS &amp;gt; maxFPS)&lt;br /&gt;
&lt;br /&gt;
	if (displaySyntax) then&lt;br /&gt;
		outputChatBox(&amp;quot;Syntax: /&amp;quot;..commandName..&amp;quot; [&amp;quot;..minFPS..&amp;quot; ~ &amp;quot;..maxFPS..&amp;quot;] - limit your own FPS.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local currentLimit = getFPSLimit()&lt;br /&gt;
	local setNewFPS = (newFPS ~= currentLimit)&lt;br /&gt;
&lt;br /&gt;
	if (setNewFPS) then&lt;br /&gt;
		outputChatBox(&amp;quot;Your FPS has been limited to: &amp;quot;..newFPS..&amp;quot;.&amp;quot;)&lt;br /&gt;
		setFPSLimit(newFPS)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;limitfps&amp;quot;, fpsFunction)&lt;br /&gt;
addCommandHandler(&amp;quot;fpslimit&amp;quot;, fpsFunction)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fix for climbing over certain objects==&lt;br /&gt;
You can use this small code to fix one of high FPS issues, specifically the one which would instantly kill player climbing over some objects.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientPlayerDamage(attackerElement, damageType, bodyPart)&lt;br /&gt;
	local fallDamage = (damageType == 54)&lt;br /&gt;
&lt;br /&gt;
	if (not fallDamage) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerTask = getPedSimplestTask(localPlayer)&lt;br /&gt;
	local playerClimbing = (playerTask == &amp;quot;TASK_SIMPLE_CLIMB&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	if (playerClimbing) then&lt;br /&gt;
		cancelEvent()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerDamage&amp;quot;, localPlayer, onClientPlayerDamage)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Server functions}}&lt;br /&gt;
&lt;br /&gt;
[[pl:setFPSLimit]]&lt;br /&gt;
[[ru:setFPSLimit]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81942</id>
		<title>SetFPSLimit</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81942"/>
		<updated>2025-04-18T12:07:54Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Server client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function sets the maximum [http://en.wikipedia.org/wiki/Frame_rate FPS (Frames per second)] that players on the server can run their game at.  &lt;br /&gt;
{{Note|&lt;br /&gt;
* When set client side, the actual limit used is the lowest of both the server and client set values.&lt;br /&gt;
* Starting from version [[https://buildinfo.mtasa.com/?Revision=21313&amp;amp;Branch r21313]] and above '''fpsLimit''' range is '''25-32767'''. In older MTA releases it was '''25-100'''.&lt;br /&gt;
}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setFPSLimit ( int fpsLimit )         &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''fpsLimit:''' An integer value representing the maximum FPS. Refer to the note above for possible values. You can also pass '''0''' or '''false''', in which case the FPS limit will be the one set in the client settings (by default, '''100 FPS''' and the client fps limit should also be manually changed via &amp;quot;'''fps_limit=0'''&amp;quot; in console or '''MTA San Andreas 1.5\MTA\config\coreconfig.xml''').&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if successful, or ''false'' if it was not possible to set the limit or an invalid value was passed.&lt;br /&gt;
&lt;br /&gt;
==Issues when increasing FPS==&lt;br /&gt;
Note: with &amp;quot;very high&amp;quot; FPS, any FPS limit over 74 is meant.&lt;br /&gt;
It is recommended to set a conservative FPS limit (between 40-60 and 74 highest) because high FPS can break some GTA internal calculations, causing various bugs. The higher the FPS the more of a problem these become:&lt;br /&gt;
&lt;br /&gt;
74 FPS is the breaking point that opens the door to various more severe GTA bugs related to FPS and physics.&lt;br /&gt;
&lt;br /&gt;
* Physics of vehicles is effected, both high and low FPSes may bring their own set of unfair advantages. Speaking about the consequences of high FPS in this context, up to 70 or 74 FPS is considered safe (as any differences in physics, if they do exist to begin with as they theoretically should, are so tiny that they are unmeasurable and thus wouldn't affect racing results in practise). Anything beyond 74 FPS may cause impactful discrepancies.&lt;br /&gt;
&lt;br /&gt;
* Pressing the horn button to turn on and off sirens gets really hard at very high FPS. For instance, at 100 FPS, you are more likely to hit the regular horn 3 times (inconsistent) before eventually triggering the siren, besides taking a similar amount of tries to turn off the siren.&lt;br /&gt;
* At very high FPS, climbing over certain objects will result in instant death. Example at: 2520.108, -1681.407, 19.406, 266 - [https://wiki.multitheftauto.com/wiki/SetFPSLimit#Fix_for_climbing_over_certain_objects you can use this Lua code to fix it.]&lt;br /&gt;
* The higher your FPS, the more of a penalty in satchel throwing distance (up to ~10% at very high FPS) will apply.&lt;br /&gt;
&lt;br /&gt;
For a full list of FPS-related GTA bugs (that are much less likely to impact gameplay in a meaningful way) and MTA developers' progress in tackling them, see the [https://github.com/multitheftauto/mtasa-blue/projects/14 Framerate issues tracker] github project.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example allows players to limit their own FPS using a command.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local minFPS = 25&lt;br /&gt;
local maxFPS = 100&lt;br /&gt;
&lt;br /&gt;
function fpsFunction(commandName, fpsLimit)&lt;br /&gt;
	local newFPS = tonumber(fpsLimit)&lt;br /&gt;
	local displaySyntax = (not newFPS) or (newFPS &amp;lt; minFPS) or (newFPS &amp;gt; maxFPS)&lt;br /&gt;
&lt;br /&gt;
	if (displaySyntax) then&lt;br /&gt;
		outputChatBox(&amp;quot;Syntax: /&amp;quot;..commandName..&amp;quot; [&amp;quot;..minFPS..&amp;quot; ~ &amp;quot;..maxFPS..&amp;quot;] - limit your own FPS.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local currentLimit = getFPSLimit()&lt;br /&gt;
	local setNewFPS = (newFPS ~= currentLimit)&lt;br /&gt;
&lt;br /&gt;
	if (setNewFPS) then&lt;br /&gt;
		outputChatBox(&amp;quot;Your FPS has been limited to: &amp;quot;..newFPS..&amp;quot;.&amp;quot;)&lt;br /&gt;
		setFPSLimit(newFPS)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;limitfps&amp;quot;, fpsFunction)&lt;br /&gt;
addCommandHandler(&amp;quot;fpslimit&amp;quot;, fpsFunction)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fix for climbing over certain objects==&lt;br /&gt;
You can use this small code to fix one of high FPS issues, specifically the one which would instantly kill player climbing over some objects.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientPlayerDamage(attackerElement, damageType, bodyPart)&lt;br /&gt;
	local fallDamage = (damageType == 54)&lt;br /&gt;
&lt;br /&gt;
	if (not fallDamage) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerTask = getPedSimplestTask(localPlayer)&lt;br /&gt;
	local playerClimbing = (playerTask == &amp;quot;TASK_SIMPLE_CLIMB&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	if (playerClimbing) then&lt;br /&gt;
		cancelEvent()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerDamage&amp;quot;, localPlayer, onClientPlayerDamage)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Server functions}}&lt;br /&gt;
&lt;br /&gt;
[[pl:setFPSLimit]]&lt;br /&gt;
[[ru:setFPSLimit]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81902</id>
		<title>SetFPSLimit</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetFPSLimit&amp;diff=81902"/>
		<updated>2025-04-04T06:37:32Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Fix for climbing over certain objects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Server client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function sets the maximum [http://en.wikipedia.org/wiki/Frame_rate FPS (Frames per second)] that players on the server can run their game at.  &lt;br /&gt;
{{Note|&lt;br /&gt;
* When set client side, the actual limit used is the lowest of both the server and client set values.&lt;br /&gt;
* Starting from version [[https://buildinfo.mtasa.com/?Revision=21313&amp;amp;Branch r21313]] and above '''fpsLimit''' range is '''25-32767'''. In older MTA releases it was '''25-100'''.&lt;br /&gt;
}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setFPSLimit ( int fpsLimit )         &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''fpsLimit:''' An integer value representing the maximum FPS. Refer to the note above for possible values. You can also pass '''0''' or '''false''', in which case the FPS limit will be the one set in the client settings (by default, '''100 FPS''' and the client fps limit should also be manually changed via &amp;quot;'''fps_limit=0'''&amp;quot; in console or '''MTA San Andreas 1.5\MTA\config\coreconfig.xml''').&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if successful, or ''false'' if it was not possible to set the limit or an invalid value was passed.&lt;br /&gt;
&lt;br /&gt;
==Issues when increasing FPS==&lt;br /&gt;
Note: with &amp;quot;very high&amp;quot; FPS, any FPS limit over 74 is meant.&lt;br /&gt;
It is recommended to set a conservative FPS limit (between 40-60 and 74 highest) because high FPS can break some GTA internal calculations, causing various bugs. The higher the FPS the more of a problem these become:&lt;br /&gt;
&lt;br /&gt;
74 FPS is the breaking point that opens the door to various more severe GTA bugs related to FPS and physics.&lt;br /&gt;
&lt;br /&gt;
* Physics of vehicles is effected, both high and low FPSes may bring their own set of unfair advantages. Speaking about the consequences of high FPS in this context, up to 70 or 74 FPS is considered safe (as any differences in physics, if they do exist to begin with as they theoretically should, are so tiny that they are unmeasurable and thus wouldn't affect racing results in practise). Anything beyond 74 FPS may cause impactful discrepancies.&lt;br /&gt;
&lt;br /&gt;
* Pressing the horn button to turn on and off sirens gets really hard at very high FPS. For instance, at 100 FPS, you are more likely to hit the regular horn 3 times (inconsistent) before eventually triggering the siren, besides taking a similar amount of tries to turn off the siren.&lt;br /&gt;
* At very high FPS, climbing over certain objects will result in instant death. Example at: 2520.108, -1681.407, 19.406, 266 - [https://wiki.multitheftauto.com/wiki/SetFPSLimit#Fix_for_climbing_over_certain_objects you can use this Lua code to fix it.]&lt;br /&gt;
* The higher your FPS, the more of a penalty in satchel throwing distance (up to ~10% at very high FPS) will apply.&lt;br /&gt;
&lt;br /&gt;
For a full list of FPS-related GTA bugs (that are much less likely to impact gameplay in a meaningful way) and MTA developers' progress in tackling them, see the [https://github.com/multitheftauto/mtasa-blue/projects/14 Framerate issues tracker] github project.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example allows players to limit their own FPS using a command.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local minFPS = 25&lt;br /&gt;
local maxFPS = 100&lt;br /&gt;
&lt;br /&gt;
function fpsFunction(commandName, fpsLimit)&lt;br /&gt;
	local newFPS = tonumber(fpsLimit)&lt;br /&gt;
	local displaySyntax = (not newFPS) or (newFPS &amp;lt; minFPS) or (newFPS &amp;gt; maxFPS)&lt;br /&gt;
&lt;br /&gt;
	if displaySyntax then&lt;br /&gt;
		outputChatBox(&amp;quot;Syntax: /&amp;quot;..commandName..&amp;quot; [&amp;quot;..minFPS..&amp;quot; ~ &amp;quot;..maxFPS..&amp;quot;] - limit your own FPS.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local currentLimit = getFPSLimit()&lt;br /&gt;
	local setNewFPS = (newFPS ~= currentLimit)&lt;br /&gt;
&lt;br /&gt;
	if setNewFPS then&lt;br /&gt;
		outputChatBox(&amp;quot;Your FPS has been limited to: &amp;quot;..newFPS..&amp;quot;.&amp;quot;)&lt;br /&gt;
		setFPSLimit(newFPS)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;limitfps&amp;quot;, fpsFunction)&lt;br /&gt;
addCommandHandler(&amp;quot;fpslimit&amp;quot;, fpsFunction)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fix for climbing over certain objects==&lt;br /&gt;
You can use this small code to fix one of high FPS issues, specifically the one which would instantly kill player climbing over some objects.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onClientPlayerDamage(attackerElement, damageType, bodyPart)&lt;br /&gt;
	local fallDamage = (damageType == 54)&lt;br /&gt;
&lt;br /&gt;
	if (not fallDamage) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerTask = getPedSimplestTask(localPlayer)&lt;br /&gt;
	local playerClimbing = (playerTask == &amp;quot;TASK_SIMPLE_CLIMB&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	if (playerClimbing) then&lt;br /&gt;
		cancelEvent()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientPlayerDamage&amp;quot;, localPlayer, onClientPlayerDamage)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Server functions}}&lt;br /&gt;
&lt;br /&gt;
[[pl:setFPSLimit]]&lt;br /&gt;
[[ru:setFPSLimit]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=81897</id>
		<title>Script security</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=81897"/>
		<updated>2025-04-01T19:30:49Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Securing projectiles &amp;amp; explosions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Awareness of client memory==&lt;br /&gt;
&lt;br /&gt;
Starting from very basics:&lt;br /&gt;
* You should be aware that everything you store on client-side is at risk, this includes .lua files as well. Any confidential (and/or) important data which is stored, or travels through client-side (player PC) could be accessed by malicious clients.&lt;br /&gt;
* To keep sensitive data (and/or) Lua logic safe - use server-side.&lt;br /&gt;
* Do note that scripts marked as '''shared''' act also as '''client code''', which means that everything above applies to them. For example defining:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;shared&amp;quot;/&amp;gt; &amp;lt;!-- this script will run separately both on client and server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Is same as doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;client&amp;quot;/&amp;gt; &amp;lt;!-- define it separately on client --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;server&amp;quot;/&amp;gt; &amp;lt;!-- do the same, but on server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Additional protection layer==&lt;br /&gt;
&lt;br /&gt;
In order to make things ''slightly harder*'' for those having bad intentions towards your server, you can make use of cache attribute (and/or [https://luac.mtasa.com/ Lua compile (also known as Luac) with extra obfuscation set to level '''3'''] - [https://wiki.multitheftauto.com/wiki/Lua_compilation_API API]) available in [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml], along with configuring MTA's built-in AC by toggling SD (Special detections), see: [https://wiki.multitheftauto.com/wiki/Anti-cheat_guide Anti-cheat guide].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;shared.lua&amp;quot; type=&amp;quot;shared&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;client.lua&amp;quot; type=&amp;quot;client&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Slightly harder'' '''but not impossible''' for some to obtain client code, yet does good job at keeping '''most''' people away from inspecting your .lua files - those looking for possible logic flaws (bugs) or missing/incorrect security based checks.&lt;br /&gt;
* Can be used on both '''client''' and '''shared''' script type (has no effect on server-sided Lua).&lt;br /&gt;
* It doesn't remove Lua files which were previously downloaded.&lt;br /&gt;
&lt;br /&gt;
==Detecting and dealing with backdoors and cheats==&lt;br /&gt;
'''To ensure minimum (or no) damage resulting from Lua scripts:'''&lt;br /&gt;
* Keep your server up-to-date, you can [https://nightly.multitheftauto.com/ download latest server builds from MTA:SA nightly site.] Information on specific builds can be [https://buildinfo.multitheftauto.com/ found here.]&lt;br /&gt;
* Keep your resources up-to-date, you can [https://github.com/multitheftauto/mtasa-resources download latest (default) resources from GitHub repository.] Those often contain latest security fixes, which could mean difference between having your server resist from attack or not.&lt;br /&gt;
* Make sure to properly configure [https://wiki.multitheftauto.com/wiki/Access%20Control%20List ACL (Access Control List)] - which will block resources from using certain, potentially dangerous functions.&lt;br /&gt;
* Zero-trust with giving away admin rights for resources (including maps) coming from unknown sources.&lt;br /&gt;
* Before running any resource you don't trust, analyze:&lt;br /&gt;
** [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml] of it, for possible hidden scripts lurking beneath other file extensions.&lt;br /&gt;
** It's source code, for malicious logic.&lt;br /&gt;
* Do not run/keep using compiled resources (scripts) of which legitimacy you aren't sure.&lt;br /&gt;
&lt;br /&gt;
'''To ensure minimum damage when a cheater connects to your server:'''&lt;br /&gt;
* When making scripts, remember to never trust data coming from a client.&lt;br /&gt;
* While reviewing scripts for possible security holes. Look at any data coming from the client that is being trusted.&lt;br /&gt;
* Any kind of data could be sent, hence server scripts which communicate with client by receiving data sent by players should validate it, before further use in latter parts of code. Mostly, it will be done either by [[setElementData]] or [[triggerServerEvent]].&lt;br /&gt;
* You shouldn't rely only on player [https://wiki.multitheftauto.com/wiki/Serial serial], when it comes to processing crucial operations (auto-login/admin actions). '''Serials aren't guaranted to be unique or non-fakable'''. This is why you should '''put it behind''' account system, as '''important authentication factor''' (e.g: '''login &amp;amp; password''').&lt;br /&gt;
* Server-side logic '''can not be bypassed''' or '''tampered''' with (unless server is breached or when there is a bug in code, but that's whole different scenario) - '''use it to your advantage'''. In majority of cases, you will be able to perform security validations with no participation of client-side.&lt;br /&gt;
* Using concept of '''''“All parameters including source can be faked and should not be trusted. Global variable client can be trusted.”''''' - gives you reliable assurance that player to which you refer (via '''client''') '''is''' in fact, '''the one which really called event'''. This approach will protect you from situations where cheater can call &amp;amp; process for instance: admin events (e.g kick/ban player) by passing the actual admin ('''2nd''' argument in '''[[triggerServerEvent]]'''), or trigger events for other players (as if they were the ones who called them, but in reality it was forcefully done by cheater) - as a consequence of using wrong variable. To make sure you fully understood it, take a look at examples below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	DON'T EVER DO THAT - THAT IS COMPLETELY WRONG AND INSECURE&lt;br /&gt;
	THE ISSUE: BY USING 'source' IN hasObjectPermissionTo YOU ARE LEAVING DOOR STRAIGHT OPEN FOR CHEATERS&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerWrongAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(source, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- the vulnerability lies here...&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerWrongAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerWrongAdminEvent&amp;quot;, root, onServerWrongAdminEvent)&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	onServerCorrectAdminEvent IS PERFECTLY SECURED, AS IT SHOULD BE&lt;br /&gt;
	NO ISSUE HERE: WE'VE USED 'client' IN hasObjectPermissionTo WHICH MAKES IT SAFE FROM FAKING PLAYER WHO CALLED EVENT&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerCorrectAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(client, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- is player allowed to do that?&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerCorrectAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerCorrectAdminEvent&amp;quot;, root, onServerCorrectAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing setElementData==&lt;br /&gt;
&lt;br /&gt;
* You should refrain from using [[element data]] everywhere, it should be only used when really necessary. It is advised to replace it with [[triggerClientEvent]] instead.&lt;br /&gt;
* If you still insist on using it, it is recommended to set '''4th''' argument in [[setElementData]] to '''false''' (disabling sync for this, certain data) and use subscriber mode - [[addElementDataSubscriber]], for both security &amp;amp; performance reasons described in [https://wiki.multitheftauto.com/wiki/Script_security#Securing_triggerServerEvent event section.]&lt;br /&gt;
{{Important Note|Disabling sync however, doesn't fully protect data key. It would be still vulnerable by default, but in this case you are not leaving it in plain sight. Using [[getAllElementData]] or digging in RAM wouldn't expose it, since it won't be synced to client in first place. Therefore, it needs to be added to anti-cheat as well.}} &lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of basic element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = tostring(sourceElement) -- element which received data&lt;br /&gt;
	local logOldValue = tostring(oldValue) -- old value&lt;br /&gt;
	local logNewValue = tostring(newValue) -- new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;=======================================\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;=======================================&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local logVisibleTo = root -- specify who will see this log in console, in this case each player connected to server&lt;br /&gt;
	local hadData = (oldValue ~= nil) -- check if element had such data before&lt;br /&gt;
&lt;br /&gt;
	if (hadData) then -- if element had such data before&lt;br /&gt;
		setElementData(sourceElement, dataKey, oldValue, true) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
	else&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it completely&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	outputConsole(logText, logVisibleTo) -- print it to console&lt;br /&gt;
&lt;br /&gt;
	return true -- all success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeBasicAC(dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not go further&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkSpecialThing = (dataKey == &amp;quot;special_thing&amp;quot;) -- compare whether dataKey matches &amp;quot;special_thing&amp;quot;&lt;br /&gt;
	local checkFlagWaving = (dataKey == &amp;quot;flag_waving&amp;quot;) -- compare whether dataKey matches &amp;quot;flag_waving&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if (checkSpecialThing) then -- if it does, do our security checks&lt;br /&gt;
		local invalidElement = (client ~= source) -- verify whether source element is different from player which changed data&lt;br /&gt;
&lt;br /&gt;
		if (invalidElement) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;special_thing&amp;quot; can only be set for player himself&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkFlagWaving) then -- if it does, do our security checks&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(client) -- get player's current vehicle&lt;br /&gt;
		local invalidVehicle = (playerVehicle ~= source) -- verify whether source element is different from player's vehicle&lt;br /&gt;
&lt;br /&gt;
		if (invalidVehicle) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;flag_waving&amp;quot; can only be set for player's own vehicle&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeBasicAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of advanced element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan, allowOnlyProtectedKeys to true (as per default configuration)&lt;br /&gt;
	If allowOnlyProtectedKeys is enabled, do not forget to add every client-side element data key to protectedKeys table - otherwise you will face false-positives&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (handleDataChange) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	[&amp;quot;keyName&amp;quot;] = { -- name of key which would be protected&lt;br /&gt;
		onlyForPlayerHimself = true, -- enabling this (true) will make sure that this element data key can only be set on player who synced it (ignores onlyForOwnPlayerVeh and allowForElements), use false/nil to disable this&lt;br /&gt;
		onlyForOwnPlayerVeh = false, -- enabling this (true) will make sure that this element data key can only be set on player's current vehicle who synced it (ignores allowForElements), use false/nil to disable this&lt;br /&gt;
		allowForElements = { -- restrict this key for certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
			[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = { -- restrict this key for certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 32}, -- if value is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
		allowedTableLength = {1, 64}, -- if value is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
		allowedNumberRange = {1, 128}, -- if value is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
	}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering element data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local allowOnlyProtectedKeys = true -- disallow (remove by using removeElementData, if it didn't existed before) every element data besides those given in protectedKeys table; in case someone wanted to flood server with garbage keys, which would be kept in memory until server restart or manual remove - setElementData(source, key, nil) won't remove it; it has to be removeElementData&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
local protectedKeys = {&lt;br /&gt;
	[&amp;quot;vehicleNumber&amp;quot;] = { -- we want vehicleNumber to be set only on vehicles, with stricte numbers in range of 1-100&lt;br /&gt;
		allowForElements = {&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedNumberRange = {1, 100},&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;personalVehData&amp;quot;] = { -- we want be able to set personalVehData only on current vehicle, also it should be a string with length between 1-24&lt;br /&gt;
		onlyForOwnPlayerVeh = true,&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 24},&lt;br /&gt;
	},&lt;br /&gt;
	-- perform security checks on keys stored in this table, in a convenient way&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of element which received data&lt;br /&gt;
	local logOldValue = inspect(oldValue) -- in-depth view of old value&lt;br /&gt;
	local logNewValue = inspect(newValue) -- in-depth view of new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Fail reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (forceRemove) then -- we don't want this element data key to exist at all&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it&lt;br /&gt;
&lt;br /&gt;
		return true -- return success and stop here, we don't need further checks&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	setElementData(sourceElement, dataKey, oldValue, true) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
&lt;br /&gt;
	return true -- return success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function handleDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from protectedKeys), false otherwise&lt;br /&gt;
	local protectedKey = protectedKeys[dataKey] -- look up whether key changed is stored in protectedKeys table&lt;br /&gt;
&lt;br /&gt;
	if (not protectedKey) then -- if it's not&lt;br /&gt;
&lt;br /&gt;
		if (allowOnlyProtectedKeys) then -- if we don't want garbage keys&lt;br /&gt;
			local failReason = &amp;quot;Key isn't present in protectedKeys&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = true -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return true -- this key isn't protected, let it through&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local onlyForPlayerHimself = protectedKey.onlyForPlayerHimself -- if key has &amp;quot;self-set&amp;quot; lock&lt;br /&gt;
	local onlyForOwnPlayerVeh = protectedKey.onlyForOwnPlayerVeh -- if key has &amp;quot;self-vehicle&amp;quot; lock&lt;br /&gt;
	local allowForElements = protectedKey.allowForElements -- if key has element type check&lt;br /&gt;
	local allowedDataTypes = protectedKey.allowedDataTypes -- if key has allowed data type check&lt;br /&gt;
&lt;br /&gt;
	if (onlyForPlayerHimself) then -- if &amp;quot;self-set&amp;quot; lock is active&lt;br /&gt;
		local matchingElement = (clientElement == sourceElement) -- verify whether player who set data is equal to element which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElement) then -- if it's not matching&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player himself&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (onlyForOwnPlayerVeh) then -- if &amp;quot;self-vehicle&amp;quot; lock is active&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(clientElement) -- get current vehicle of player which set data&lt;br /&gt;
		local matchingVehicle = (playerVehicle == sourceElement) -- check whether it matches the one which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingVehicle) then -- if it doesn't match&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player's own vehicle&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowForElements) then -- check if it's one of them&lt;br /&gt;
		local elementType = getElementType(sourceElement) -- get type of element whose data changed&lt;br /&gt;
		local matchingElementType = allowForElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElementType) then -- this isn't matching&lt;br /&gt;
			local failReason = &amp;quot;Invalid element type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowedDataTypes) then -- if there's allowed data types&lt;br /&gt;
		local valueType = type(newValue) -- get data type of value&lt;br /&gt;
		local matchingType = allowedDataTypes[valueType] -- check if it's one of allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingType) then -- if it's not then&lt;br /&gt;
			local failReason = &amp;quot;Invalid data type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedStringLength = protectedKey.allowedStringLength -- if key has specified string length check&lt;br /&gt;
		local dataString = (valueType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
		if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
			local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
			local stringLength = utf8.len(newValue) -- get length of data string&lt;br /&gt;
			local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedTableLength = protectedKey.allowedTableLength -- if key has table length check&lt;br /&gt;
		local dataTable = (valueType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
		if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
			local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
			local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
			local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
			local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
			for _, _ in pairs(newValue) do -- loop through whole table&lt;br /&gt;
				tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
				minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
				maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
				if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
					break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
				local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedNumberRange = protectedKey.allowedNumberRange -- if key has allowed number range check&lt;br /&gt;
		local dataNumber = (valueType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
		if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
			local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
			local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
			local matchingRange = (newValue &amp;gt;= minRange) and (newValue &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingRange) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this data key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeAdvancedAC(dataKey, oldValue, newValue) -- this event makes use of handleDataChange, the code was split for better readability&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not continue&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedChange = handleDataChange(client, source, dataKey, oldValue, newValue) -- run our security checks&lt;br /&gt;
&lt;br /&gt;
	if (approvedChange) then -- it's all cool and good&lt;br /&gt;
		return false -- we don't need further action&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(client, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(client, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeAdvancedAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing triggerServerEvent==&lt;br /&gt;
&lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player (client) '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
* Do '''not''' use the same name for your custom event as MTA native server events (which aren't remotely triggerable by default), e.g: '''onPlayerLogin'''; doing so would open door for cheaters manipulations.&lt;br /&gt;
* Be aware to which players event is sent via [[triggerClientEvent]]. For both security &amp;amp; performance reasons, admin like events should be received by admins only (to prevent confidential data being accessed), in the same time you shouldn't send each event to everyone on server (e.g: login success event which hides login panel for certain player). [[triggerClientEvent]] allows you to specify the event receiver as first (optional) argument. It defaults to [[root]], meaning if you don't specify it, it will be sent to everyone connected to server - even those who are still downloading server cache (which results in ''Server triggered clientside event eventName, but event is not added clientside.''). You can either pass player element or table with receivers:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playersToReceiveEvent = {player1, player2, player3} -- each playerX is player element&lt;br /&gt;
&lt;br /&gt;
triggerClientEvent(playersToReceiveEvent, ...) -- do not forget to fill the latter part of arguments&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of anti-cheat function designed for events, used for data validation for both normal, and admin events which are called from client-side.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan to true (as per default configuration)&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (processServerEventData) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	checkACLGroup = { -- check whether player who called event belongs to at least one group below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;Admin&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkPermissions = { -- check whether player who called event has permission to at least one thing below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;function.kickPlayer&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkEventData = {&lt;br /&gt;
		{&lt;br /&gt;
			debugData = &amp;quot;source&amp;quot;, -- optional details for report shown in debug message&lt;br /&gt;
			eventData = source, -- data we want to verify&lt;br /&gt;
			equalTo = client, -- compare whether eventData == equalTo&lt;br /&gt;
			allowedElements = { -- restrict eventData to be certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
				[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedDataTypes = { -- restrict eventData to be certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
				[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedStringLength = {1, 32}, -- if eventData is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
			allowedTableLength = {1, 64}, -- if eventData is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
			allowedNumberRange = {1, 128}, -- if eventData is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering server event data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
function processServerEventData(clientElement, sourceElement, serverEvent, securityChecks) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from securityChecks), false otherwise&lt;br /&gt;
	if (not securityChecks) then -- if we haven't passed any security checks&lt;br /&gt;
		return true -- nothing to check, let code go further&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (not clientElement) then -- if client variable isn't available for some reason (although it should never happen)&lt;br /&gt;
		local failReason = &amp;quot;Client variable not present&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkACLGroup = securityChecks.checkACLGroup -- if there's any ACL groups to check&lt;br /&gt;
	local checkPermissions = securityChecks.checkPermissions -- if there's any permissions to check&lt;br /&gt;
	local checkEventData = securityChecks.checkEventData -- if there's any data checks&lt;br /&gt;
&lt;br /&gt;
	if (checkACLGroup) then -- let's check player ACL groups&lt;br /&gt;
		local playerAccount = getPlayerAccount(clientElement) -- get current account of player&lt;br /&gt;
		local guestAccount = isGuestAccount(playerAccount) -- if account is guest (meaning player is not logged in)&lt;br /&gt;
&lt;br /&gt;
		if (guestAccount) then -- it's the case&lt;br /&gt;
			local failReason = &amp;quot;Can't retrieve player login - guest account&amp;quot; -- reason shown in report&lt;br /&gt;
			local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
			reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local accountName = getAccountName(playerAccount) -- get name of player's current account&lt;br /&gt;
		local aclString = &amp;quot;user.&amp;quot;..accountName -- format it for further use in isObjectInACLGroup function&lt;br /&gt;
&lt;br /&gt;
		for groupID = 1, #checkACLGroup do -- iterate over table of given groups&lt;br /&gt;
			local groupName = checkACLGroup[groupID] -- get each group name&lt;br /&gt;
			local aclGroup = aclGetGroup(groupName) -- check if such group exists&lt;br /&gt;
&lt;br /&gt;
			if (not aclGroup) then -- it doesn't&lt;br /&gt;
				local failReason = &amp;quot;ACL group '&amp;quot;..groupName..&amp;quot;' is missing&amp;quot; -- reason shown in report&lt;br /&gt;
				local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
				reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local playerInACLGroup = isObjectInACLGroup(aclString, aclGroup) -- check if player belong to the group&lt;br /&gt;
&lt;br /&gt;
			if (playerInACLGroup) then -- yep, it's the case&lt;br /&gt;
				return true -- so it's a success&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Player doesn't belong to any given ACL group&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkPermissions) then -- check if player has at least one desired permission&lt;br /&gt;
		local allowedByDefault = false -- does he have access by default&lt;br /&gt;
&lt;br /&gt;
		for permissionID = 1, #checkPermissions do -- iterate over all permissions&lt;br /&gt;
			local permissionName = checkPermissions[permissionID] -- get permission name&lt;br /&gt;
			local hasPermission = hasObjectPermissionTo(clientElement, permissionName, allowedByDefault) -- check whether player is allowed to perform certain action&lt;br /&gt;
&lt;br /&gt;
			if (hasPermission) then -- if player has access&lt;br /&gt;
				return true -- one is available (and enough), server won't bother to check others (as return keywords also breaks loop)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Not enough permissions&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkEventData) then -- if there is some data to verify&lt;br /&gt;
&lt;br /&gt;
		for dataID = 1, #checkEventData do -- iterate over each of data&lt;br /&gt;
			local dataToCheck = checkEventData[dataID] -- get each data set&lt;br /&gt;
			local eventData = dataToCheck.eventData -- this is the one we'll be verifying&lt;br /&gt;
			local equalTo = dataToCheck.equalTo -- we want to compare whether eventData == equalTo&lt;br /&gt;
			local allowedElements = dataToCheck.allowedElements -- check whether is element, and whether belongs to certain element types&lt;br /&gt;
			local allowedDataTypes = dataToCheck.allowedDataTypes -- do we restrict data to be certain type?&lt;br /&gt;
			local debugData = dataToCheck.debugData -- additional helper data&lt;br /&gt;
			local debugText = debugData and &amp;quot; (&amp;quot;..debugData..&amp;quot;)&amp;quot; or &amp;quot;&amp;quot; -- if it's present, format it nicely&lt;br /&gt;
&lt;br /&gt;
			if (equalTo) then -- equal check exists&lt;br /&gt;
				local matchingData = (eventData == equalTo) -- compare whether those two values are equal&lt;br /&gt;
&lt;br /&gt;
				if (not matchingData) then -- they aren't&lt;br /&gt;
					local failReason = &amp;quot;Data isn't equal @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedElements) then -- we do check whether is an element, and belongs to at least one given in the list&lt;br /&gt;
				local validElement = isElement(eventData) -- check if it's actual element&lt;br /&gt;
&lt;br /&gt;
				if (not validElement) then -- it's not&lt;br /&gt;
					local failReason = &amp;quot;Data isn't element @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local elementType = getElementType(eventData) -- it's element, so we want to know it's type&lt;br /&gt;
				local matchingElementType = allowedElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingElementType) then -- it's not allowed&lt;br /&gt;
					local failReason = &amp;quot;Invalid element type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedDataTypes) then -- let's check allowed data types&lt;br /&gt;
				local dataType = type(eventData) -- get data type&lt;br /&gt;
				local matchingType = allowedDataTypes[dataType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingType) then -- it isn't&lt;br /&gt;
					local failReason = &amp;quot;Invalid data type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedStringLength = dataToCheck.allowedStringLength -- if data has string length check&lt;br /&gt;
				local dataString = (dataType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
				if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
					local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
					local stringLength = utf8.len(eventData) -- get length of data string&lt;br /&gt;
					local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedTableLength = dataToCheck.allowedTableLength -- if data has table length check&lt;br /&gt;
				local dataTable = (dataType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
				if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
					local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
					local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
					local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
					local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
					for _, _ in pairs(eventData) do -- loop through whole table&lt;br /&gt;
						tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
						minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
						maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
						if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
							break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
						local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedNumberRange = dataToCheck.allowedNumberRange -- if data has number range check&lt;br /&gt;
				local dataNumber = (dataType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
				if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
					local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
					local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
					local matchingRange = (eventData &amp;gt;= minRange) and (eventData &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingRange) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this event call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- helper function to log and handle accidents&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view player which called event&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of source element&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected event abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Event: &amp;quot;..serverEvent..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect or skipPunishment) then -- we don't want to punish player for some reason&lt;br /&gt;
		return true -- stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(clientElement, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(clientElement, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- all done, report success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onServerEvent(clientData)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local dataToPass = 10&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerEvent&amp;quot;, localPlayer, dataToPass)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = clientData, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;number&amp;quot;] = true, -- we want it to be only number&lt;br /&gt;
					},&lt;br /&gt;
					allowedNumberRange = {1, 100}, -- in range of 1 to 100&lt;br /&gt;
					debugData = &amp;quot;clientData&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerEvent&amp;quot;, root, onServerEvent)&lt;br /&gt;
&lt;br /&gt;
function onServerAdminEvent(playerToBan)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server admin event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local playerToBan = getPlayerFromName(&amp;quot;playerToBan&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerAdminEvent&amp;quot;, localPlayer, playerToBan)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerAdminEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkACLGroup = { -- we need to check whether player who called event belongs to ACL groups&lt;br /&gt;
				&amp;quot;Admin&amp;quot;, -- in this case admin group&lt;br /&gt;
			},&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = playerToBan, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;player&amp;quot;] = true, -- we want it to be player&lt;br /&gt;
					},&lt;br /&gt;
					debugData = &amp;quot;playerToBan&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerAdminEvent&amp;quot;, root, onServerAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing server-only events==&lt;br /&gt;
* It is very important to '''disable remote triggering''' ability in [https://wiki.multitheftauto.com/wiki/AddEvent addEvent], to prevent calling server-side only events from client-side.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example shows how you should make event server-side only.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onServerSideOnlyEvent()&lt;br /&gt;
	-- do some server-side stuff&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerSideOnlyEvent&amp;quot;, false) -- set second argument (allowRemoteTriger) to false, so it can't be called from client&lt;br /&gt;
addEventHandler(&amp;quot;onServerSideOnlyEvent&amp;quot;, root, onServerSideOnlyEvent) -- associate our event with function onServerSideOnlyEvent&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing projectiles &amp;amp; explosions==&lt;br /&gt;
This section (and '''code''' is '''work in progress''') - '''use at your own risk'''.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile ammo tracker:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerProjectileAmmo = {} -- store player-held weapons ammo here&lt;br /&gt;
local playerWeaponsToTrack = { -- keep track of ammo for certain player-held weapon types, basically those which create projectile; [weaponID] = weaponSlot&lt;br /&gt;
	[16] = 8, -- grenade&lt;br /&gt;
	[17] = 8, -- teargas&lt;br /&gt;
	[18] = 8, -- molotov&lt;br /&gt;
	[35] = 7, -- rocket launcher&lt;br /&gt;
	[36] = 7, -- rocket launcher (heat-seeking)&lt;br /&gt;
	[39] = 8, -- satchel charge&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for weaponID, weaponSlot in pairs(playerWeaponsToTrack) do&lt;br /&gt;
		local weaponInSlot = getPedWeapon(playerElement, weaponSlot)&lt;br /&gt;
		local weaponTotalAmmo = getPedTotalAmmo(playerElement, weaponSlot)&lt;br /&gt;
		local weaponHasAmmo = (weaponTotalAmmo &amp;gt; 0)&lt;br /&gt;
		local weaponMatching = (weaponInSlot == weaponID)&lt;br /&gt;
		local updateWeaponAmmo = (weaponMatching and weaponHasAmmo)&lt;br /&gt;
&lt;br /&gt;
		if (updateWeaponAmmo) then&lt;br /&gt;
			local storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			local newWeaponAmmo = (updateWeaponAmmo and weaponTotalAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
			if (not storedProjectileAmmo) then&lt;br /&gt;
				playerProjectileAmmo[playerElement] = {}&lt;br /&gt;
				storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			storedProjectileAmmo[weaponID] = newWeaponAmmo&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function hasPlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
	local projectileAmmo = (projectileData and projectileData[projectileWeapon])&lt;br /&gt;
&lt;br /&gt;
	return projectileAmmo&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectileData) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileWeaponAmmo = playerProjectileData[projectileWeapon]&lt;br /&gt;
	local tempProjectileAmmo = (projectileWeaponAmmo - 1)&lt;br /&gt;
	local newProjectileAmmo = (tempProjectileAmmo &amp;gt; 0 and tempProjectileAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectileData[projectileWeapon] = newProjectileAmmo&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerWeaponSwitchAntiCheat(previousWeaponID, currentWeaponID)&lt;br /&gt;
	setTimer(updateProjectileAmmoForPlayer, 50, 1, source)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWeaponSwitch&amp;quot;, root, onPlayerWeaponSwitchAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onResourceStartAntiCheat()&lt;br /&gt;
	local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	for playerID = 1, #playersTable do&lt;br /&gt;
		local playerElement = playersTable[playerID]&lt;br /&gt;
&lt;br /&gt;
		updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, resourceRoot, onResourceStartAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerWastedQuitAntiCheat()&lt;br /&gt;
	playerProjectileAmmo[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWasted&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerCreatedProjectiles = {} -- store count of legitimately created player projectiles; [playerElement] = {[projectileType] = activeProjectiles}&lt;br /&gt;
local projectileTypes = {&lt;br /&gt;
	[16] = { -- Grenade&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[17] = { -- Teargas&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[17] = true, -- teargas&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[18] = { -- Molotov&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[19] = { -- Rocket&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[425] = true, -- hunter&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[20] = { -- Rocket (heat-seeking)&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[21] = { -- Airbomb&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[39] = { -- Satchel charge&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[39] = true, -- satchel charge&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[58] = { -- Hydra flare&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportProjectileAbnormality(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	local projectileSyncer = inspect(playerElement)&lt;br /&gt;
	local projectilePosition = projectileX..&amp;quot;, &amp;quot;..projectileY..&amp;quot;, &amp;quot;..projectileZ&lt;br /&gt;
	local projectileZoneName = getZoneName(projectileX, projectileY, projectileZ, false)&lt;br /&gt;
	local projectileCityName = getZoneName(projectileX, projectileY, projectileZ, true)&lt;br /&gt;
	local projectileLog =&lt;br /&gt;
		&amp;quot;* Detected projectile abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile syncer: &amp;quot;..projectileSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile type: &amp;quot;..projectileType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile position: &amp;quot;..projectilePosition.. &amp;quot; (&amp;quot;..projectileZoneName..&amp;quot;, &amp;quot;..projectileCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(projectileLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processProjectileChecks(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
	local projectileAllowed = projectileData.projectileAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not projectileAllowed) then&lt;br /&gt;
		return false, &amp;quot;Projectile not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileAllowedWeapons = projectileData.projectileAllowedWeapons&lt;br /&gt;
&lt;br /&gt;
	if (projectileAllowedWeapons) then&lt;br /&gt;
		local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
		local allowedWeapon = projectileAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedWeapon) then&lt;br /&gt;
			return false, &amp;quot;Player is not holding correct weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
		local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
		if (not playerHasAmmo) then&lt;br /&gt;
			return false, &amp;quot;Player doesn't have ammo for weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerVehicle) then&lt;br /&gt;
		local projectileAllowedVehicles = projectileData.projectileAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
		if (projectileAllowedVehicles) then&lt;br /&gt;
			local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
			local allowedVehicle = projectileAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedVehicle) then&lt;br /&gt;
				return false, &amp;quot;Player is not inside allowed vehicles&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
			local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
			if (not playerDriver) then&lt;br /&gt;
				return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Player in vehicle&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxDistanceFromCreator = projectileData.projectileMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToProjectile = getDistanceBetweenPoints3D(playerX, playerY, playerZ, projectileX, projectileY, projectileZ)&lt;br /&gt;
		local matchingProjectileDistance = (distanceToProjectile &amp;lt;= projectileMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileDistance) then&lt;br /&gt;
			return false, &amp;quot;Projectile distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxVelocity = projectileData.projectileMaxVelocity&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxVelocity) then&lt;br /&gt;
		local projectileVelocity = (projectileVX ^ 2 + projectileVY ^ 2 + projectileVZ ^ 2)&lt;br /&gt;
		local projectileSpeed = math.sqrt(projectileVelocity)&lt;br /&gt;
		local matchingProjectileVelocity = (projectileSpeed &amp;lt;= projectileMaxVelocity)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileVelocity) then&lt;br /&gt;
			return false, &amp;quot;Projectile velocity mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function trackPlayerProjectile(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		playerCreatedProjectiles[playerElement] = {}&lt;br /&gt;
		playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID] or 0&lt;br /&gt;
	local newProjectilesCount = (projectilesByType + 1)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
&lt;br /&gt;
	if (not projectileData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileBehaviour = projectileData.projectileOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not projectileBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = projectileBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = projectileBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = projectileBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID]&lt;br /&gt;
&lt;br /&gt;
	if (not projectilesByType) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local tempProjectilesCount = (projectilesByType - 1)&lt;br /&gt;
	local newProjectilesCount = (tempProjectilesCount &amp;gt; 0 and tempProjectilesCount or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerProjectileCreationAntiCheat(projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local approvedProjectile, detectionCode = processProjectileChecks(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedProjectile) then&lt;br /&gt;
		trackPlayerProjectile(source, projectileType)&lt;br /&gt;
&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportProjectileAbnormality(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerProjectileCreation&amp;quot;, root, onPlayerProjectileCreationAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerQuitAntiCheat()&lt;br /&gt;
	playerCreatedProjectiles[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Explosions handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local rocketInstantExplosionDistanceThreshold = 1.55 -- distance below which only explosion will be created (and not rocket projectile, hence not calling onPlayerProjectileCreation); do not change it&lt;br /&gt;
local explosionTypes = { -- more specific info on explosion, and whether it is allowed&lt;br /&gt;
	[0] = { -- Grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[1] = { -- Molotov&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[2] = { -- Rocket&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[3] = { -- Rocket weak&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[4] = { -- Car&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[5] = { -- Car quick&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[6] = { -- Boat&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[7] = { -- Heli&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[8] = { -- Mine&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[9] = { -- Object&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[10] = { -- Tank grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionMaxDistanceFromCreator = 80,&lt;br /&gt;
		explosionAllowedVehicles = {&lt;br /&gt;
			[432] = true,&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	[11] = { -- Small&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[12] = { -- Tiny&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportExplosionAbnormality(playerElement, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	local explosionSyncer = inspect(playerElement)&lt;br /&gt;
	local explosionType = explosionType&lt;br /&gt;
	local explosionPosition = explosionX..&amp;quot;, &amp;quot;..explosionY..&amp;quot;, &amp;quot;..explosionZ&lt;br /&gt;
	local explosionZoneName = getZoneName(explosionX, explosionY, explosionZ, false)&lt;br /&gt;
	local explosionCityName = getZoneName(explosionX, explosionY, explosionZ, true)&lt;br /&gt;
	local explosionLog =&lt;br /&gt;
		&amp;quot;* Detected explosion abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion syncer: &amp;quot;..explosionSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion type: &amp;quot;..explosionType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion position: &amp;quot;..explosionPosition.. &amp;quot; (&amp;quot;..explosionZoneName..&amp;quot;, &amp;quot;..explosionCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(explosionLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processExplosionChecks(playerElement, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
	local explosionAllowed = explosionData.explosionAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not explosionAllowed) then&lt;br /&gt;
		return false, &amp;quot;Explosion type not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local rocketExplosion = (explosionType == 2)&lt;br /&gt;
&lt;br /&gt;
	if (rocketExplosion) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local instantExplosion = (distanceToExplosion &amp;lt; rocketInstantExplosionDistanceThreshold)&lt;br /&gt;
&lt;br /&gt;
		if (instantExplosion) then&lt;br /&gt;
			local explosionAllowedWeapons = explosionData.explosionAllowedWeapons&lt;br /&gt;
			local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
			local allowedWeapon = explosionAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedWeapon) then&lt;br /&gt;
				return false, &amp;quot;Player is not holding rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
			local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
			if (not playerHasAmmo) then&lt;br /&gt;
				return false, &amp;quot;Player doesn't have ammo for rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedProjectiles = explosionData.explosionAllowedProjectiles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedProjectiles) then&lt;br /&gt;
&lt;br /&gt;
		for projectileID, _ in pairs(explosionAllowedProjectiles) do&lt;br /&gt;
			local atleastOneProjectile = decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
&lt;br /&gt;
			if (atleastOneProjectile) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Explosion created without respective projectile&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedVehicles = explosionData.explosionAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedVehicles) then&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
		if (not playerVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is not in vehicle&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
		local allowedVehicle = explosionAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is inside not allowed vehicles&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
		local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
		if (not playerDriver) then&lt;br /&gt;
			return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionMaxDistanceFromCreator = explosionData.explosionMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (explosionMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local matchingExplosionDistance = (distanceToExplosion &amp;lt; explosionMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingExplosionDistance) then&lt;br /&gt;
			return false, &amp;quot;Explosion distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
&lt;br /&gt;
	if (not explosionData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionBehaviour = explosionData.explosionOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not explosionBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = explosionBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = explosionBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = explosionBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onExplosionAntiCheat(explosionX, explosionY, explosionZ, explosionType)&lt;br /&gt;
	local serverSyncExplosion = (source == root)&lt;br /&gt;
&lt;br /&gt;
	if (serverSyncExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedExplosion, detectionCode = processExplosionChecks(source, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportExplosionAbnormality(source, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onExplosion&amp;quot;, root, onExplosionAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handling non-registered events==&lt;br /&gt;
&lt;br /&gt;
See: [[onPlayerTriggerInvalidEvent]]&lt;br /&gt;
&lt;br /&gt;
==Handling events spam==&lt;br /&gt;
See: [[onPlayerTriggerEventThreshold]]&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Texture_pixels&amp;diff=81896</id>
		<title>Texture pixels</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Texture_pixels&amp;diff=81896"/>
		<updated>2025-04-01T19:15:44Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Pixels more */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__====Pixels====&lt;br /&gt;
-----------------&lt;br /&gt;
'''*''' MTA refers to the raw information that a [[texture]] contains as 'pixels'.&lt;br /&gt;
&lt;br /&gt;
'''*''' Pixels can be retrieved from any [[texture]] type including [[dxCreateRenderTarget|render targets]] and [[dxCreateScreenSource|screen sources]] by using the function [[dxGetTexturePixels]].&lt;br /&gt;
&lt;br /&gt;
'''*''' Pixels are just a string to Lua, so they can be saved to a file or even sent over the 'internet'.&lt;br /&gt;
&lt;br /&gt;
====Pixels properties====&lt;br /&gt;
-----------------&lt;br /&gt;
Pixels have two properties:&lt;br /&gt;
*'''dimensions''' (width and height) which is retrieved by using the function [[dxGetPixelsSize]]&lt;br /&gt;
*'''format''' (plain,jpeg,png,dds) which is retrieved by using the function [[dxGetPixelsFormat]]&lt;br /&gt;
**''plain'' - Fastest and simplest - It's default format of the pixels returned by [[dxGetTexturePixels]] and the only one that can be used with [[dxSetTexturePixels]], [[dxGetPixelColor]] and [[dxSetPixelColor]]. But it also uses a lot of bytes, so internet transfers will be longer. Also can't be read by Photoshop or browsers etc.&lt;br /&gt;
**''png'' - A few less bytes, still quite big for net transfers. Can be saved to a file and read by Photoshop and browsers etc.&lt;br /&gt;
**''jpeg'' - A lot less bytes, so best for net transfers. Can be saved to a file and read by Photoshop and browsers etc.&lt;br /&gt;
**''dds'' - DirectDraw Surface. Game's native texture format with various compressed and uncompressed options. Used to store standard, cube or volume textures. Compressed pixels in this format can be loaded nearly instantly by [[dxCreateTexture]].&lt;br /&gt;
   &lt;br /&gt;
To convert between the 3 different formats, use the function [[dxConvertPixels]]&lt;br /&gt;
&lt;br /&gt;
====Pixels more====&lt;br /&gt;
-----------&lt;br /&gt;
Pixels can also be loaded from any png/jpeg file just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local fileHandler = fileOpen(&amp;quot;hello.jpg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if (not fileHandler) then&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local fileSize = fileGetSize(fileHandler)&lt;br /&gt;
local filePixels = fileRead(fileHandler, fileSize)&lt;br /&gt;
&lt;br /&gt;
fileClose(fileHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pixels can be used to create textures just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local newTexture = dxCreateTexture(pixelsData)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pixels can be used to save textures just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local texturePixels = dxGetTexturePixels(myRenderTarget)&lt;br /&gt;
local texturePixelsConverted = dxConvertPixels(texturePixels, &amp;quot;jpeg&amp;quot;)&lt;br /&gt;
local fileHandler = fileCreate(&amp;quot;piccy.jpg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if (not fileHandler) then&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
fileWrite(fileHandler, texturePixelsConverted)&lt;br /&gt;
fileClose(fileHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Pixels performance====&lt;br /&gt;
------------------&lt;br /&gt;
Getting/setting pixels from textures is not quick and not something you want to be doing every frame (in onClientRender for example).&lt;br /&gt;
Setting pixels to a render target is especially slow. Pixels are ideal however for transferring composite images built on a render target into a normal texture for later use. For example, making a custom radar map.&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Texture_pixels&amp;diff=81895</id>
		<title>Texture pixels</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Texture_pixels&amp;diff=81895"/>
		<updated>2025-04-01T19:15:14Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: /* Pixels more */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__====Pixels====&lt;br /&gt;
-----------------&lt;br /&gt;
'''*''' MTA refers to the raw information that a [[texture]] contains as 'pixels'.&lt;br /&gt;
&lt;br /&gt;
'''*''' Pixels can be retrieved from any [[texture]] type including [[dxCreateRenderTarget|render targets]] and [[dxCreateScreenSource|screen sources]] by using the function [[dxGetTexturePixels]].&lt;br /&gt;
&lt;br /&gt;
'''*''' Pixels are just a string to Lua, so they can be saved to a file or even sent over the 'internet'.&lt;br /&gt;
&lt;br /&gt;
====Pixels properties====&lt;br /&gt;
-----------------&lt;br /&gt;
Pixels have two properties:&lt;br /&gt;
*'''dimensions''' (width and height) which is retrieved by using the function [[dxGetPixelsSize]]&lt;br /&gt;
*'''format''' (plain,jpeg,png,dds) which is retrieved by using the function [[dxGetPixelsFormat]]&lt;br /&gt;
**''plain'' - Fastest and simplest - It's default format of the pixels returned by [[dxGetTexturePixels]] and the only one that can be used with [[dxSetTexturePixels]], [[dxGetPixelColor]] and [[dxSetPixelColor]]. But it also uses a lot of bytes, so internet transfers will be longer. Also can't be read by Photoshop or browsers etc.&lt;br /&gt;
**''png'' - A few less bytes, still quite big for net transfers. Can be saved to a file and read by Photoshop and browsers etc.&lt;br /&gt;
**''jpeg'' - A lot less bytes, so best for net transfers. Can be saved to a file and read by Photoshop and browsers etc.&lt;br /&gt;
**''dds'' - DirectDraw Surface. Game's native texture format with various compressed and uncompressed options. Used to store standard, cube or volume textures. Compressed pixels in this format can be loaded nearly instantly by [[dxCreateTexture]].&lt;br /&gt;
   &lt;br /&gt;
To convert between the 3 different formats, use the function [[dxConvertPixels]]&lt;br /&gt;
&lt;br /&gt;
====Pixels more====&lt;br /&gt;
-----------&lt;br /&gt;
Pixels can also be loaded from any png/jpeg file just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local fileHandler = fileOpen(&amp;quot;hello.jpg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if (not fileHandler) then&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local fileSize = fileGetSize(fileHandler)&lt;br /&gt;
local filePixels = fileRead(fileHandler, fileSize)&lt;br /&gt;
&lt;br /&gt;
fileClose(fileHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pixels can be used to create textures just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local myNewTexture = dxCreateTexture(pixelsData)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pixels can be used to save textures just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local texturePixels = dxGetTexturePixels(myRenderTarget)&lt;br /&gt;
local texturePixelsConverted = dxConvertPixels(texturePixels, &amp;quot;jpeg&amp;quot;)&lt;br /&gt;
local fileHandler = fileCreate(&amp;quot;piccy.jpg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if (not fileHandler) then&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
fileWrite(fileHandler, texturePixelsConverted)&lt;br /&gt;
fileClose(fileHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Pixels performance====&lt;br /&gt;
------------------&lt;br /&gt;
Getting/setting pixels from textures is not quick and not something you want to be doing every frame (in onClientRender for example).&lt;br /&gt;
Setting pixels to a render target is especially slow. Pixels are ideal however for transferring composite images built on a render target into a normal texture for later use. For example, making a custom radar map.&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Texture_pixels&amp;diff=81894</id>
		<title>Texture pixels</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Texture_pixels&amp;diff=81894"/>
		<updated>2025-04-01T19:13:33Z</updated>

		<summary type="html">&lt;p&gt;Srslyyyy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__====Pixels====&lt;br /&gt;
-----------------&lt;br /&gt;
'''*''' MTA refers to the raw information that a [[texture]] contains as 'pixels'.&lt;br /&gt;
&lt;br /&gt;
'''*''' Pixels can be retrieved from any [[texture]] type including [[dxCreateRenderTarget|render targets]] and [[dxCreateScreenSource|screen sources]] by using the function [[dxGetTexturePixels]].&lt;br /&gt;
&lt;br /&gt;
'''*''' Pixels are just a string to Lua, so they can be saved to a file or even sent over the 'internet'.&lt;br /&gt;
&lt;br /&gt;
====Pixels properties====&lt;br /&gt;
-----------------&lt;br /&gt;
Pixels have two properties:&lt;br /&gt;
*'''dimensions''' (width and height) which is retrieved by using the function [[dxGetPixelsSize]]&lt;br /&gt;
*'''format''' (plain,jpeg,png,dds) which is retrieved by using the function [[dxGetPixelsFormat]]&lt;br /&gt;
**''plain'' - Fastest and simplest - It's default format of the pixels returned by [[dxGetTexturePixels]] and the only one that can be used with [[dxSetTexturePixels]], [[dxGetPixelColor]] and [[dxSetPixelColor]]. But it also uses a lot of bytes, so internet transfers will be longer. Also can't be read by Photoshop or browsers etc.&lt;br /&gt;
**''png'' - A few less bytes, still quite big for net transfers. Can be saved to a file and read by Photoshop and browsers etc.&lt;br /&gt;
**''jpeg'' - A lot less bytes, so best for net transfers. Can be saved to a file and read by Photoshop and browsers etc.&lt;br /&gt;
**''dds'' - DirectDraw Surface. Game's native texture format with various compressed and uncompressed options. Used to store standard, cube or volume textures. Compressed pixels in this format can be loaded nearly instantly by [[dxCreateTexture]].&lt;br /&gt;
   &lt;br /&gt;
To convert between the 3 different formats, use the function [[dxConvertPixels]]&lt;br /&gt;
&lt;br /&gt;
====Pixels more====&lt;br /&gt;
-----------&lt;br /&gt;
Pixels can also be loaded from any png/jpeg file just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local fileHandler = fileOpen(&amp;quot;hello.jpg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if (not fileHandler) then&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local fileSize = fileGetSize(fileHandler)&lt;br /&gt;
local filePixels = fileRead(fileHandler, fileSize)&lt;br /&gt;
&lt;br /&gt;
fileClose(filePixels)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pixels can be used to create textures just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local myNewTexture = dxCreateTexture(pixelsData)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pixels can be used to save textures just like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local texturePixels = dxGetTexturePixels(myRenderTarget)&lt;br /&gt;
local texturePixelsConverted = dxConvertPixels(texturePixels, &amp;quot;jpeg&amp;quot;)&lt;br /&gt;
local fileHandler = fileCreate(&amp;quot;piccy.jpg&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if (not fileHandler) then&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
fileWrite(fileHandler, texturePixelsConverted)&lt;br /&gt;
fileClose(fileHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Pixels performance====&lt;br /&gt;
------------------&lt;br /&gt;
Getting/setting pixels from textures is not quick and not something you want to be doing every frame (in onClientRender for example).&lt;br /&gt;
Setting pixels to a render target is especially slow. Pixels are ideal however for transferring composite images built on a render target into a normal texture for later use. For example, making a custom radar map.&lt;/div&gt;</summary>
		<author><name>Srslyyyy</name></author>
	</entry>
</feed>