Jump to content

[TUT] Protect your client-sided code with fileDelete


NeXTreme

Recommended Posts

Protect your client-sided code

This is a short tutorial on how to "protect" your client-sided scripts, using very basic LUA code.

Like any other protection method, it isn't 100% secure, so combining this method with compiling or similar is recommended.

Now, if you're scripting yourself, you know the importance of having your scripts safe. We don't want anyone to steal our code, right? And, even though users can only steal client-sided code (since it's downloaded to their computer), it can give you a headache when you see another server using similar scripts.

Compiling only gets you so far, it's fairly easy to decompile any script and extract some chunks of code from it. While not perfect, it makes it easier for that person to "make" the script themselves; sometimes you can decompile the whole code, and it will work flawlessly.

With the release of MTA 1.1, this method became possible (cheers to MTA developers for that :mrgreen: ). There is a simple way of "preventing the scripts from downloading to the player's PC". Okay, don't hold me for that literaly. The scripts still get downloaded, but the user can't find them in his downloaded resources folder. How? Well, here's the "magic" behind it.

Whenever the player joins your server, he downloads any necessary files, images, sounds, and also client-sided scripts (if he joined for the first time). Afterwards, the client-sided scripts are loaded, and from that moment on, they are no longer required on the player's hard drive. Why do they stay there? I don't know, seems like we're just offering others to steal them.

How do we prevent that? Using simple LUA code, we delete the downloaded scripts after they are loaded into memory. It is as simple as it sounds. Anyone looking in the folder of your resource won't find any scripts.

It is VERY IMPORTANT to place this code client-side, otherwise your original files that reside on the server will be deleted.

Place the following code at the VERY END of your client script file. Replace the "script_name.lua" with the name of your client-sided script, of course.

  
-- Delete file 
fileDelete("script_name.lua") 
  

* Thanks to SDK for pointing out this better solution, which is more failproof.

Note: Using an event handler "onClientResourceStart" and cramming all delete functions in there also works, but if the player would disconnect before the entire script is downloaded, they would not get deleted. Hence you have to put a single fileDelete at the end of every lua file you have.

The downside with this method is the scripts have to be redownloaded every time the player joins. If you have a small code, that's not such a problem. About 3000 lines of code takes up 157kb of space (in my own resource), and that's not alot to download in my opinion.

As I mentioned earlier, it is a very simple method to remove the scripts after getting downloaded, and you could call it "protecting" your scripts. It's an efficient way of keeping your work from other players.

Edited by Guest
Link to comment
Other issues:

  • * If the player disconnects before the scripts are started (loaded into memory), the scripts won't get deleted, because the resource hasn't started yet.

You could try to not use onClientResourceStart. Just add fileDelete("this_file.lua") to the end of a script file. If I remember correctly a script file is executed right after it's downloaded, before the client resource starts.

Link to comment

Wow. Thanks you for help, Nextreme.

Here is opensource:

DeleteFiles.lua:

  
deletefiles =  
            { "DeleteFiles.lua", 
              "WinnerClient.lua", 
              "TriggerClient.lua", 
              "MessagesClient.lua" } 
  
function onStartResourceDeleteFiles() 
    for i=0, #deletefiles do 
        fileDelete(deletefiles[i]) 
    end 
end 
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), onStartResourceDeleteFiles) 
  

Link to comment
But they will have to download it again, again and again.

Waiting for some experienced reply.

True. I don't see such a big problem in this unless you have a really huge script. In my own resource, players have to download around 152kb of scripts every time they connect. I obviously don't delete images or sounds, or the size would increase to over 3MB. In my opinion those 152kb are downloaded almost instantaniously, even with a slower connection speed. Would also like to hear some other opinion about this.

Link to comment

[not-rly-ontopic]

I've got a better solution:

Develop a scripting style by yourself so when someone will read your code they'd think "WTF HAPPENS HERE". Welcome to OpenFrame 2.0 o,o

[/not-rly-ontopic]

Can someone make a lua obsfucator? It'll be a lot better

Link to comment
deletefiles = 
            { "DeleteFiles.lua", 
              "WinnerClient.lua", 
              "TriggerClient.lua", 
              "MessagesClient.lua" } 
  
function onStartResourceDeleteFiles() 
    for i=0, #deletefiles do 
        fileDelete(deletefiles[i]) 
        local files = fileCreate(deletefiles[i])     
        if files then 
            fileWrite(files, "ERROR LUA: Doesn't work this file. Please report on contact in [url=http://www.lua.org/contact.html]http://www.lua.org/contact.html[/url]") 
            fileClose(files) 
        end 
    end 
end 
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), onStartResourceDeleteFiles) 
  

I dont have idea what I will write text U_u

Link to comment
deletefiles = 
            { "DeleteFiles.lua", 
              "WinnerClient.lua", 
              "TriggerClient.lua", 
              "MessagesClient.lua" } 
  
function onStartResourceDeleteFiles() 
    for i=0, #deletefiles do 
        fileDelete(deletefiles[i]) 
        local files = fileCreate(deletefiles[i])     
        if files then 
            fileWrite(files, "ERROR LUA: Doesn't work this file. Please report on contact in [url=http://www.lua.org/contact.html]http://www.lua.org/contact.html[/url]") 
            fileClose(files) 
        end 
    end 
end 
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), onStartResourceDeleteFiles) 
  

I dont have idea what I will write text U_u

What's the point in that?

Simply using fileDelete(file.lua) at the end of all files you want to 'protect' should do the job

Link to comment

I have a much better solution, but this would only work if we had a fileCompile() function, which a dev (not only mta devs) can make a module on...

  
on first time: 
in the server file we have a list of files, that are scripts stored on the server but not in the meta listed as scripts. 
It will jumble the file with an algorithm (modifiable via setttings) and send it to client. 
  
we have the file jumbled on the client, the client unjumbles the script and loads it, then saves the jumbled scriptt on the client. 
  
next time player downloads: 
the client sends the server the current file, server unjumbles it and compares, if it is different then they send the file to client for the same procedure - else it tells the client to just load it. 
  
downloads and uploads - these are customly managed, check the resource 'resedit' to see how uploads and downloads are customly managed 
  

Link to comment
  • 1 month later...
If you need to protect your client side resources, you are giving them too much rights.

I just can imagine what happens if someone steals mine: Well, they would fail hard, since the serverside counterpart is the most important part...

unfortunately this dont work that well, because some of the scripts(syncing of something the most) requires approval and data from client, that server just cant get without client input.

so this cant work on all solutions, unless you do really complicated and not well working matching between various players and etc.

Link to comment
MTA developers may create flag "protected resource";

this resource remains in memory while playing session and not saved to disk like non-protected resources.

What for? It's already scriptable. It was posted somewhere already.

The server sends a string of code to execute and the client uses loadstring to run it. I'm sure you'll find it if you search for it.

Link to comment
  • Recently Browsing   0 members

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