Jump to content

DFF-encryption causes client's breakdowns. Efficient suggestions?


Recommended Posts

Hi all,

I've implemented some simple encoding solutions for vehicle models like "read base64+teaEncoded file->decrypt on client->engineLoadDff() with file's decoded raw data as an argument instead of filename".

But the problem is, that our tuning system is large and makes non-encrypted DFF's sizes in some cases ~50-100MB (all parts are built into the vehicle's DFFs and shown via setVehicleComponentVisible()), so encrypted versions get about +80-90% of their own "weight", e.g. 65MB-DFF will be ~110MB because of encryption.

That  way causes performance troubles, performance browser isn't showing anything "bad" except 1.7GB cache's size. In several minutes after the player logged in the game crashes (obviously because of CPU/memory been flooded). Starting of the resources on clientside while cache is checked is also too "heavy" because of encryption, so many players can finally login only after several MTA client's brakedowns.

Some experiments (using performance browser) have shown that restarting vehicle-resources after the player is ready with cache-check makes their "memory-consumption" be normal ~230-250KB (as non-encrypted analogues) instead of previous hundreds of megabytes.

As I can assume, importing filebuffers in engineLoadDFF is also not that efficient: /reconnect-command is the worst idea for the moment, only complete MTA-restart can allow your 'relogin' without getting in troubles with MTA-crashes. I suspect that MTA can't collect all "trash" from the memory when using raw data instead of DFF-files.

My colleagues don't think, that 1.7GB-cache is the main problem, they sent me tens of examples where the cache size can be about 3GB with no problems of that kind.

Here is my code for that case, if I possibly have done some mistakes. So the main idea was to make client- and serverside files (serverside is needed to avoid visual mentioning of base64's key in client's cache). onClientResourceStart() triggers serverside event which triggers a client's one sending key to start decryption (numerous 'nils' I pasted there to dereference "large" variables manually trying to solve the performance-problem):

function getVehicleKey(key)
	local fName = "model.dff"
	local modelID = 409
	local buffer = ""
	local hFile = fileOpen(fName)             
	if hFile then   
			buffer = fileRead(hFile, fileGetSize(hFile))          
		fileClose(hFile)
		hFile = nil
	else
		outputConsole("DFF couldn't be loaded!")
	end
	local txd = engineLoadTXD('tex.txd',true) 
    engineImportTXD(txd, modelID) 
	local dff = engineLoadDFF(base64Decode( teaDecode( buffer, key ) ))  
    buffer = nil
	engineReplaceModel(dff, modelID) 
	dff = nil	
end
addEvent("decryptCar", true)
addEventHandler("decryptCar", localPlayer, getVehicleKey)

addEventHandler('onClientResourceStart', resourceRoot,  
    function() 
	triggerServerEvent("sendVehicleKey", localPlayer, localPlayer)
    end  
) 

Serverside's the only thing to do:

function sendK(lp)
	local key = "keyishere"
	triggerClientEvent(lp, "decryptCar", lp, key)
end
addEvent("sendVehicleKey", true)
addEventHandler("sendVehicleKey", root, sendK)

Please help.

Edited by maximumdrive
Link to comment
  • Discord Moderators

Actually,  I found a better solution after I wrote that one.
 

function getVehicleKey(key)
	local fName = "model.dff"
	local modelID = 409
	local hFile = fileOpen(fName)             
	if hFile then	
        engineImportTXD(engineLoadTXD('tex.txd',true) , modelID) 
		engineReplaceModel(engineLoadDFF(decodeString("tea", fileRead(hFile, fileGetSize(hFile))  , {key = key})), modelID) 
    	fileClose(hFile)
	else
		outputConsole("DFF couldn't be loaded!")
	end
end

And yeah, you'll need to re-encode every model you have, with encodeString.
I suppose you used waay to much variables, which caused memory allocations in the LuaVM(niling out really does nothing here)
But instead, you can use 'collectgarbage("collect")'

Edited by Pirulax
  • Thanks 1
Link to comment
On 8/17/2018 at 01:24, Pirulax said:

Actually,  I found a better solution after I wrote that one.
 


function getVehicleKey(key)
	local fName = "model.dff"
	local modelID = 409
	local hFile = fileOpen(fName)             
	if hFile then	
        engineImportTXD(engineLoadTXD('tex.txd',true) , modelID) 
		engineReplaceModel(engineLoadDFF(decodeString("tea", fileRead(hFile, fileGetSize(hFile))  , {key = key})), modelID) 
    	fileClose(hFile)
	else
		outputConsole("DFF couldn't be loaded!")
	end
end

And yeah, you'll need to re-encode every model you have, with encodeString.
I suppose you used waay to much variables, which caused memory allocations in the LuaVM(niling out really does nothing here)
But instead, you can use 'collectgarbage("collect")'

Thank you! Great solution, the difference is indisputable, works super!

Link to comment
  • Discord Moderators

As I thought, it was because of those variables you used.
And anyways, the raw data you pass into engineLoadDFF is deleted from the memory(loading a DFF from a file is the same, it needs to read raw data anyways.)
There was a memory leak with those functions, but it got fixed(1 or 2 months ago)

Edited by Pirulax
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...