Skip to content

Commit e75d756

Browse files
authored
Add recently introduced events, name and explosion/projectile checking (#588)
1 parent 68b10f2 commit e75d756

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

[admin]/security/events.lua

+23-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,26 @@ addEventHandler("onPlayerTriggerInvalidEvent", root, clientTriggersInvalidEvent)
1212
function clientTriggersEventThreshold()
1313
logViolation(source, "Exceeded event trigger threshold of "..tostring(getServerConfigSetting("max_player_triggered_events_per_interval")));
1414
end
15-
addEventHandler("onPlayerTriggerEventThreshold", root, clientTriggersEventThreshold);
15+
addEventHandler("onPlayerTriggerEventThreshold", root, clientTriggersEventThreshold);
16+
17+
18+
19+
-- https://wiki.multitheftauto.com/wiki/OnPlayerConnect
20+
-- we use onPlayerConnect event to check if the player got a valid username
21+
function clientConnectServer(strPlayerNick, strPlayerIP, strPlayerUsername, strPlayerSerial, iPlayerVersionNumber, strPlayerVersionString)
22+
if(not isPlayerNameValid(strPlayerNick)) then
23+
logAction("Client "..strPlayerNick.." with IP "..strPlayerIP.." and Serial "..strPlayerSerial.." tried to join with invalid nickname! Version: "..iPlayerVersionNumber.." | "..strPlayerVersionString);
24+
cancelEvent(true, "INVALID NICKNAME!");
25+
return;
26+
end
27+
end
28+
addEventHandler("onPlayerConnect", root, clientConnectServer);
29+
30+
31+
32+
-- https://wiki.multitheftauto.com/wiki/OnPlayerChangesWorldSpecialProperty
33+
-- gets triggered when client changes world special property
34+
function clientChangesWorldSpecialProperty(strProperty, bEnabled)
35+
logViolation(source, "Changed world special property \""..strProperty.."\" to "..tostring(bEnabled));
36+
end
37+
addEventHandler("onPlayerChangesWorldSpecialProperty", root, clientChangesWorldSpecialProperty);

[admin]/security/meta.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<meta>
22
<info name="Security" author="-ffs-PLASMA" type="misc" version="1.0" description="Basic security functionality" />
33

4-
<min_mta_version server="1.6.0-9.22470" />
4+
<min_mta_version server="1.6.0-9.22790" />
55

6+
<script src="utils.lua" type="server"/>
67
<script src="logging.lua" type="server"/>
78
<script src="events.lua" type="server"/>
89
<script src="misc.lua" type="server"/>

[admin]/security/players.lua

+100-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
-- used to check how many explosion/projectile sync packets a client sends overtime
2+
local iExplosionCheckInterval = 3000; -- the interval in ms to check for players sending too many explosion and projectile sync packets
3+
local tblPlayerProjectiles = {}; -- store players sending projectile sync packets
4+
local tblRegularExplosions = {}; -- store players sending regular explosion sync packets
5+
local tblVehicleExplosions = {}; -- store players sending vehicle explosion sync packets
6+
local iPlayerProjectileThreshold = 10; -- the threshold when we consider client suspicious for projectile creations
7+
local iRegularExplosionThreshold = 10; -- the threshold when we consider client suspicious for regular explosions
8+
local iVehicleExplosionThreshold = 10; -- the threshold when we consider client suspicious for vehicle explosions
9+
10+
11+
112
-- add the elementdatas you want to protect from client updates in here
213
local tblProtectedElementDatas = {["Score"] = true};
314

@@ -16,6 +27,18 @@ addEventHandler("onElementDataChange", root, clientChangesElementData);
1627

1728

1829

30+
-- https://wiki.multitheftauto.com/wiki/OnPlayerChangesProtectedData
31+
-- gets triggered when a client tries to change protected element data
32+
-- see elementdata_whitelisted config https://wiki.multitheftauto.com/wiki/Server_mtaserver.conf#elementdata_whitelisted
33+
-- this needs to be setup in conjunction with your existing elementdatas to take necessary action!
34+
-- the key feature is to prevent the client from updating non synced server elementdatas if they know the key and attached element
35+
function clientChnagesProtectedData(uElement, strKey, unValue)
36+
logViolation(source, "Tried to change protected elementdata for key "..tostring(strKey).." to value "..tostring(unValue).." for element "..tostring(uElement).." ("..getElementType(uElement)..")");
37+
end
38+
addEventHandler("onPlayerChangesProtectedData", root, clientChnagesProtectedData);
39+
40+
41+
1942
-- https://wiki.multitheftauto.com/wiki/OnPlayerACInfo
2043
-- gets triggered when AC detects something for client on connect
2144
function clientNotifyACInfo(tblDetectedACList, iD3D9Size, strD3D9MD5, strD3D9SHA256)
@@ -55,4 +78,80 @@ function clientNetworkStatus(iStatus, iTicks)
5578
logViolation(source, "Network interruption has stopped after "..iTicks.." ticks");
5679
end
5780
end
58-
addEventHandler("onPlayerNetworkStatus", root, clientNetworkStatus);
81+
addEventHandler("onPlayerNetworkStatus", root, clientNetworkStatus);
82+
83+
84+
85+
-- https://wiki.multitheftauto.com/wiki/OnPlayerProjectileCreation
86+
-- gets triggered when a player creates a projectile sync packets (eg. shoots a weapon, vehicle weapon or via createProjectile)
87+
function clientCreateProjectile(iWeaponType, fPX, fPY, fPZ, fForce, uTarget, fRX, fRY, fRZ, fVX, fVY, fVZ)
88+
if(isElement(source)) then
89+
if(tblPlayerProjectiles[source]) then
90+
tblPlayerProjectiles[source] = tblPlayerProjectiles[source] + 1;
91+
else
92+
tblPlayerProjectiles[source] = 1;
93+
end
94+
end
95+
end
96+
addEventHandler("onPlayerProjectileCreation", root, clientCreateProjectile);
97+
98+
99+
100+
-- https://wiki.multitheftauto.com/wiki/OnExplosion
101+
-- gets triggered when an explosion occurs, either via server script or client sync packet
102+
function clientCreateExplosion(fPX, fPY, fPZ, iType)
103+
if(isElement(source)) then
104+
if(getElementType(source) == "player") then
105+
if(tblRegularExplosions[source]) then
106+
tblRegularExplosions[source] = tblRegularExplosions[source] + 1;
107+
else
108+
tblRegularExplosions[source] = 1;
109+
end
110+
end
111+
end
112+
end
113+
addEventHandler("onExplosion", root, clientCreateExplosion);
114+
115+
116+
117+
-- https://wiki.multitheftauto.com/wiki/OnVehicleExplode
118+
-- gets triggered when a vehicle explodes, either via server script or client sync packet
119+
function clientCreateVehicleExplosion(bWithExplosion, uPlayer)
120+
if(isElement(uPlayer)) then
121+
if(tblVehicleExplosions[uPlayer]) then
122+
tblVehicleExplosions[uPlayer] = tblVehicleExplosions[uPlayer] + 1;
123+
else
124+
tblVehicleExplosions[uPlayer] = 1;
125+
end
126+
end
127+
end
128+
addEventHandler("onVehicleExplode", root, clientCreateVehicleExplosion);
129+
130+
131+
132+
-- setup a timer with specified interval above and check if any client sent too many sync packets in the given time
133+
-- thresholds need to be adjusted for your need and actions taken!
134+
setTimer(function()
135+
for uPlayer, iCounter in pairs(tblPlayerProjectiles) do
136+
if(iCounter >= iPlayerProjectileThreshold) then
137+
logViolation(uPlayer, "Exceeded projectile threshold "..tostring(iPlayerProjectileThreshold).." - Count: "..tostring(iCounter));
138+
end
139+
end
140+
141+
for uPlayer, iCounter in pairs(tblRegularExplosions) do
142+
if(iCounter >= iRegularExplosionThreshold) then
143+
logViolation(uPlayer, "Exceeded regular explosions threshold "..tostring(iRegularExplosionThreshold).." - Count: "..tostring(iCounter));
144+
end
145+
end
146+
147+
for uPlayer, iCounter in pairs(tblVehicleExplosions) do
148+
if(iCounter >= iVehicleExplosionThreshold) then
149+
logViolation(uPlayer, "Exceeded vehicle explosions threshold "..tostring(iVehicleExplosionThreshold).." - Count: "..tostring(iCounter));
150+
end
151+
end
152+
153+
tblPlayerProjectiles = {};
154+
tblRegularExplosions = {};
155+
tblVehicleExplosions = {};
156+
157+
end, iExplosionCheckInterval, 0);

[admin]/security/utils.lua

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- checks if a player nickname is valid in terms of length and ascii chars
2+
function isPlayerNameValid(strPlayerName)
3+
if(not strPlayerName) then return false end;
4+
if(not tostring(strPlayerName)) then return false end;
5+
if(#strPlayerName == 0) then return false end;
6+
if(#strPlayerName > 22) then return false end;
7+
8+
for i = 1, #strPlayerName do
9+
local strChar = strPlayerName:sub(i, i);
10+
local iCharByte = strChar:byte();
11+
12+
if(iCharByte < 33 or iCharByte > 126) then return false end;
13+
end
14+
15+
return true;
16+
end

0 commit comments

Comments
 (0)