Skip to content

Commit

Permalink
Merge branch 'master' into pr-530-addendum
Browse files Browse the repository at this point in the history
  • Loading branch information
jlillis authored Sep 1, 2024
2 parents 50c57d9 + b40f27b commit e42970a
Show file tree
Hide file tree
Showing 17 changed files with 474 additions and 68 deletions.
11 changes: 11 additions & 0 deletions [admin]/security/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*** DISCLAIMER ***

This resource is very barebone and should be used as a learning foundation for security on your server.
It only covers the most basic server events for detecting abusive behaviour and logs them without taking any action.
There are many more ways to combat bad players with server and client scripting adapted to your server/gamemode.

As a general rule of thumb, following points should be considered:
- never trust the client, if you accept data from client, validate it on server if they make any sense
- use the variable "client" instead of "source" for custom server events, source can be faked, client not
- try to avoid elementdatas, if you need elementdata to be synced to client and they should remain read only on client,
add them to tblProtectedElementDatas in players.lua to prevent clients from updating them
15 changes: 15 additions & 0 deletions [admin]/security/events.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- https://wiki.multitheftauto.com/wiki/OnPlayerTriggerInvalidEvent
-- gets triggered when a remote clients triggers an invalid event on server
function clientTriggersInvalidEvent(strEventName, bIsAdded, bIsRemote)
logViolation(source, "Triggered invalid event \""..strEventName.."\" - bIsAdded: "..tostring(bIsAdded).." - bIsRemote: "..tostring(bIsRemote));
end
addEventHandler("onPlayerTriggerInvalidEvent", root, clientTriggersInvalidEvent);



-- https://wiki.multitheftauto.com/wiki/OnPlayerTriggerEventThreshold
-- gets triggered when a remote clients exceeds the event trigger treshold set by server in config -> max_player_triggered_events_per_interval
function clientTriggersEventThreshold()
logViolation(source, "Exceeded event trigger threshold of "..tostring(getServerConfigSetting("max_player_triggered_events_per_interval")));
end
addEventHandler("onPlayerTriggerEventThreshold", root, clientTriggersEventThreshold);
63 changes: 63 additions & 0 deletions [admin]/security/logging.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
-- log messages triggered by player
function logViolation(uPlayer, strMessage)
local strPlayerName, strPlayerIP, strPlayerSerial = getPlayerName(uPlayer), getPlayerIP(uPlayer), getPlayerSerial(uPlayer);
local strLogFileName = "violations.txt";
local uFileHandle = fileExists(strLogFileName) and fileOpen(strLogFileName);

if(not uFileHandle) then
uFileHandle = fileCreate(strLogFileName);
fileFlush(uFileHandle);
else
fileSetPos(uFileHandle, fileGetSize(uFileHandle));
end

local strViolationMessage = getDateTime().." CLIENT: "..strPlayerName.." | IP: "..strPlayerIP.." | SERIAL: "..strPlayerSerial.." | "..strMessage;

outputDebugString(strViolationMessage, 4, 255, 255, 255);
outputServerLog(strViolationMessage);
fileWrite(uFileHandle, strViolationMessage.."\n");
fileClose(uFileHandle);
end



-- log messages without player element
function logAction(strMessage)
local strLogFileName = "actions.txt";
local uFileHandle = fileExists(strLogFileName) and fileOpen(strLogFileName);

if(not uFileHandle) then
uFileHandle = fileCreate(strLogFileName);
fileFlush(uFileHandle);
else
fileSetPos(uFileHandle, fileGetSize(uFileHandle));
end

local strActionMessage = getDateTime().." "..strMessage;

outputDebugString(strActionMessage, 4, 255, 255, 255);
outputServerLog(strActionMessage);
fileWrite(uFileHandle, strActionMessage.."\n");
fileClose(uFileHandle);
end



-- get the current date and time for logging
function getDateTime()
local tblRealTime = getRealTime();
local iDay = tblRealTime.monthday;
local iMonth = tblRealTime.month + 1;
local iYear = tblRealTime.year + 1900;
local iHour = tblRealTime.hour;
local iMinute = tblRealTime.minute;
local iSecond = tblRealTime.second;

if(iDay < 10) then iDay = "0"..iDay end;
if(iMonth < 10) then iMonth = "0"..iMonth end;
if(iHour < 10) then iHour = "0"..iHour end;
if(iMinute < 10) then iMinute = "0"..iMinute end;
if(iSecond < 10) then iSecond = "0"..iSecond end;

return "["..tostring(iDay).."."..tostring(iMonth).."."..tostring(iYear).." - "..tostring(iHour)..":"..tostring(iMinute)..":"..tostring(iSecond).."]";
end
10 changes: 10 additions & 0 deletions [admin]/security/meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<meta>
<info name="Security" author="-ffs-PLASMA" type="misc" version="1.0" description="Basic security functionality" />

<min_mta_version server="1.6.0-9.22470" />

<script src="logging.lua" type="server"/>
<script src="events.lua" type="server"/>
<script src="misc.lua" type="server"/>
<script src="players.lua" type="server"/>
</meta>
15 changes: 15 additions & 0 deletions [admin]/security/misc.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- https://wiki.multitheftauto.com/wiki/OnSettingChange
-- gets triggered when a resource setting has been changed
function resourceSettingChanged(strSetting, strOldValue, strNewValue)
logAction("Setting \""..strSetting.."\" has been changed from \""..fromJSON(strOldValue).."\" to \""..fromJSON(strNewValue).."\"");
end
addEventHandler("onSettingChange", root, resourceSettingChanged);



-- https://wiki.multitheftauto.com/wiki/OnAccountDataChange
-- gets triggered when account has been changed
function accountDataChanged(uAccount, strKey, strValue)
logAction("Data \""..strKey.."\" of account \""..getAccountName(uAccount).."\" has been changed to \""..strValue.."\"");
end
addEventHandler("onAccountDataChange", root, accountDataChanged);
58 changes: 58 additions & 0 deletions [admin]/security/players.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
-- add the elementdatas you want to protect from client updates in here
local tblProtectedElementDatas = {["Score"] = true};



-- https://wiki.multitheftauto.com/wiki/OnElementDataChange
-- gets triggered when a client tries to change a synced elementdata, check if client is permitted to change that specific data
-- also prevents one client changing the elementdata of another client
function clientChangesElementData(strKey, varOldValue, varNewValue)
if(client and (tblProtectedElementDatas[strKey] or client ~= source)) then
logViolation(client, "Tried to change elementdata \""..tostring(strKey).."\" of resource \""..tostring(sourceResource).."\" from \""..tostring(varOldValue).."\" to \""..tostring(varNewValue).."\"");
setElementData(source, strKey, varOldValue);
end
end
addEventHandler("onElementDataChange", root, clientChangesElementData);



-- https://wiki.multitheftauto.com/wiki/OnPlayerACInfo
-- gets triggered when AC detects something for client on connect
function clientNotifyACInfo(tblDetectedACList, iD3D9Size, strD3D9MD5, strD3D9SHA256)
logViolation(source, "AC list detected: "..table.concat(tblDetectedACList, ",").." - D3D9Size: "..tostring(iD3D9Size).." - D3D9MD5: "..tostring(strD3D9MD5));
end
addEventHandler("onPlayerACInfo", root, clientNotifyACInfo);



-- https://wiki.multitheftauto.com/wiki/OnPlayerModInfo
-- gets triggered when client joins server with modified game files
function clientNotifyModInfo(strFileName, tblItemList)
for _, strItemName in ipairs(tblItemList) do
logViolation(source, "Mod detected - file: "..strFileName.." - GTA ID: "..strItemName.id.." - GTA name: "..strItemName.name);
end
end
addEventHandler("onPlayerModInfo", root, clientNotifyModInfo);



-- force all connected players to send their AC/Mod info on resource start
addEventHandler("onResourceStart", resourceRoot, function()
for _, uPlayer in ipairs(getElementsByType("player")) do
resendPlayerModInfo(uPlayer);
resendPlayerACInfo(uPlayer);
end
end);



-- https://wiki.multitheftauto.com/wiki/OnPlayerNetworkStatus
-- gets triggered when connection from server to a client is interrupted
function clientNetworkStatus(iStatus, iTicks)
if(iStatus == 0) then
logViolation(source, "Network interruption has began after "..iTicks.." ticks");
elseif(iStatus == 1) then
logViolation(source, "Network interruption has stopped after "..iTicks.." ticks");
end
end
addEventHandler("onPlayerNetworkStatus", root, clientNetworkStatus);
3 changes: 0 additions & 3 deletions [editor]/edf/properties_client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,6 @@ propertySetters = {
end,
breakable = function(element, breakable)
return setObjectBreakable(element, breakable == "true")
end,
collisions = function(element, state)
return setElementCollisionsEnabled(element, state == "true")
end
},
ped = {
Expand Down
1 change: 1 addition & 0 deletions [editor]/editor_gui/client/currentbrowser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ end
function closeCurrentBrowser()
if ( not currentBrowser.showing ) then return end
currentBrowser.showing = false
cSelectedElement = false
if ( callbackFunction ) then
local id = currentBrowserGUI.gridlist:getSelectedText()
if ( not id ) then
Expand Down
6 changes: 6 additions & 0 deletions [editor]/editor_main/server/saveloadtest_server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ addEventHandler("newResource", root,
triggerEvent("onNewMap", resourceRoot)
dumpSave()
editor_gui.outputMessage(getPlayerName(client).." started a new map.", root, 255, 0, 0)

actionList = {}
currentActionIndex = 0
end
)

Expand Down Expand Up @@ -148,6 +151,9 @@ function handleOpenResource()
setElementCollisionsEnabled(obj, true)
end

actionList = {}
currentActionIndex = 0

triggerEvent("onMapOpened", mapContainer, openingResource)
flattenTreeRuns = 0
triggerClientEvent(root, "saveLoadProgressBar", root, true)
Expand Down
77 changes: 15 additions & 62 deletions [editor]/editor_main/server/undoredo_main.lua
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
-- make sure events dont get called more than once in a row!

-- action list
local actionList = {}
local index = 0

-- action states
local justUndid = false
local justRedid = false
local justAdded = false
actionList = {}
currentActionIndex = 0

-- ADD
function insertAction(action) -- messes shit up
-- insert action into list, removing any actions that might come after it
if (not justUndid) then
removeActionsAfterIndex(index)
index = index + 1
else
removeActionsAfterIndex(index-1)
end
table.insert(actionList, index, action)
-- update action state flags
justUndid = false
justRedid = false
justAdded = true
while #actionList > currentActionIndex do
table.remove(actionList, #actionList)
end
currentActionIndex = currentActionIndex + 1
table.insert(actionList, currentActionIndex, action)
end

-- create
Expand Down Expand Up @@ -67,56 +56,20 @@ function addActionElementPropertiesChange(oldProperties, newProperties)
end
addEventHandler("onElementPropertiesChange_undoredo", root, addActionElementPropertiesChange)

-- removes lowIndex??
function removeActionsAfterIndex(lowIndex)
local curIndex = #actionList
while (curIndex > lowIndex) do
actionList[curIndex]:destructor()
table.remove(actionList, curIndex)
curIndex = curIndex - 1
end
end

function undo()
if (justUndid) then
if (index > 1) then
index = index - 1
actionList[index]:performUndo()
-- update action state flags
justUndid = true
justRedid = false
justAdded = false
end
elseif (justRedid or justAdded) then
actionList[index]:performUndo()
-- update action state flags
justUndid = true
justRedid = false
justAdded = false
end
if currentActionIndex > 0 then
actionList[currentActionIndex]:performUndo()
currentActionIndex = currentActionIndex - 1
end
end
addCommandHandler("undo", undo)
addEventHandler("doUndo", root, undo)

function redo()
if (not justAdded) then
if (justRedid) then
if (actionList[index+1]) then
index = index + 1
actionList[index]:performRedo()
-- update action state flags
justUndid = false
justRedid = true
justAdded = false
end
elseif (justUndid) then
actionList[index]:performRedo()
-- update action state flags
justUndid = false
justRedid = true
justAdded = false
end
end
if currentActionIndex < #actionList then
currentActionIndex = currentActionIndex + 1
actionList[currentActionIndex]:performRedo()
end
end
addCommandHandler("redo", redo)
addEventHandler("doRedo", root, redo)
1 change: 1 addition & 0 deletions [gamemodes]/[play]/play/meta.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<info author="MTA contributors (github.com/multitheftauto/mtasa-resources)" description="Launches a basic freeroam mode, together with basic map and extra handling" version="2.0" type="gamemode"/>
<include resource="freeroam"/>
<include resource="internetradio"/>
<include resource="mapfixes"/>
<script src="play_config.lua" type="server"/>
<script src="play_players.lua" type="server"/>
<script src="play_vehicles.lua" type="server"/>
Expand Down
4 changes: 4 additions & 0 deletions [gameplay]/gps/linedrawer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ local linePoints = { }
local renderStuff = { }

function removeLinePoints ( )
if not next(linePoints) then
return false
end
linePoints = { }
for name, data in pairs ( renderStuff ) do
unloadTile ( name )
end
return true
end

function addLinePoint ( posX, posY )
Expand Down
6 changes: 3 additions & 3 deletions [gameplay]/gps/meta.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<meta>
<info author="arc_" type="script" version="1.1.0" description="Calculates and displays the quickest road path between two points/nodes on the map. Commands: /path node1 node2 /path2 x y [z]. Resource contains export functions for custom logic."/>
<info author="arc_" type="script" version="1.1.1" description="Calculates and displays the quickest road path between two points/nodes on the map. Commands: /path node1 node2 /path2 x y [z]. Resource contains export functions for custom logic."/>

<script src="util.lua" type="client"/>
<script src="client.lua" type="client"/>
Expand All @@ -22,9 +22,9 @@
Function returns true if successful otherwise false.
Draws the path on the client HUD mini map in ascending order. For example, if you use the table returned by the calculatePathByCoords
or calculatePathByNodeIDs function.
If you add your own line points points they must be very close to each other, otherwise the path will not be drawn properly.-->
If you add your own line points they must be very close to each other, otherwise the path will not be drawn properly.-->
<export function="removeLinePoints" type="client"/> <!--removeLinePoints()
Function returns nil.
Function returns true if the drawn lines of the client HUD mini map were removed otherwise false if there was nothing to remove.
Removes the line points of the addLinePoint function respectively the drawn lines of the client HUD mini map.
This can be used, for example, when the target node point has been reached or a player gets out of the vehicle.-->
</meta>
16 changes: 16 additions & 0 deletions [gameplay]/mapfixes/meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<meta>
<info author="MTA contributors (github.com/multitheftauto/mtasa-resources)" version="1.0" name="SA Map Fixes" description="This resource patches a few flaws in the default MTA world" type="script" />
<min_mta_version client="1.6.0-9.22505.0" server="1.6.0-9.22505.0"></min_mta_version>

<script src="scripts/shared/data.lua" type="shared"/>
<script src="scripts/client/main.lua" type="client"/>
<script src="scripts/server/main.lua" type="server"/>

<settings>
<setting name="*bs_crack_palace_wall" value="[true]" friendlyname="Crack Palace Wall" desc="Enable Big Smoke Crack Palace wall covering hole" accept="true,false"/>
<setting name="*bs_crack_palace_interior" value="[false]" friendlyname="Crack Palace Interior" desc="Enable Big Smoke Crack Palace open-world interior (DISABLED by default)" accept="true,false"/>
<setting name="*atrium_lobby_interior" value="[true]" friendlyname="Atrium Lobby Interior" desc="Enable Commerce Atrium lobby open-world interior" accept="true,false"/>
<setting name="*doherty_garage_interior" value="[true]" friendlyname="Doherty Garage Interior" desc="Enable Doherty Safehouse Garage open-world interior" accept="true,false"/>
<setting name="*undamaged_crackfactory_with_interior" friendlyname="Undamaged SF Crack Factory" value="[true]" desc="Enable restored Undamaged SF Crack Factory with open-world interior" accept="true,false"/>
</settings>
</meta>
Loading

0 comments on commit e42970a

Please sign in to comment.