Jump to content

fileExists returns false after resource restart


JeViCo

Recommended Posts

Just now, IIYAMA said:

That doesn't happen for me.

Are you editing the files or something like that? (Or doing this before the resource has started?)

 

i tried to encode it. I download it, get data, then delete it. After that i create new file with the same path, encode saved data and write to file

Link to comment
  • Moderators

@JeViCo

Once you change the file, it is no longer valid for MTA and will be re-downloaded.(your previous problem, which is related to file security)

 

Please show me your code. Because it looks like you either didn't close the file in time or deleted it too fast.

 

 

Edited by IIYAMA
  • Thanks 1
Link to comment
  • Discord Moderators

So you download the file and then encode it?
What if it downloads the file and then I close my MTA?
The file'll stay there.

So really isn't a good solution, maybe send thru the file's content instead with triggerLatentClientEvent
And then just simply encode and save it(you should store a hash on client side to check whenever the file is valid or not)

Edited by Pirulax
Link to comment
52 minutes ago, Pirulax said:

So you download the file and then encode it?
What if it downloads the file and then I close my MTA?
The file'll stay there.

So really isn't a good solution, maybe send thru the file's content instead with triggerLatentClientEvent
And then just simply encode and save it(you should store a hash on client side to check whenever the file is valid or not)

it's hard for me to understand the difference between triggerClientEvent and triggerLatentClientEvent and how can i use it in this situation. Anyway you advice me to encode files serverside and then download it? Am i right? I rewrote that (script creates encoded file server-side in separate folder and downloads it) and got this screenshot_1.jpg 

I used fileOpen + fileGetSize to read encoded files. Maybe i should use original file size to solve this problem

1 hour ago, IIYAMA said:

Once you change the file, it is no longer valid for MTA and will be re-downloaded.(your previous problem, which is related to file security)

i guess that's it

1 hour ago, IIYAMA said:

Please show me your code. Because it looks like you either didn't close the file in time or deleted it too fast.

function saveFile(path, data)
    if not path then
        return false
    end
    if fileExists(path) then
        fileDelete(path)
    end
    local file = fileCreate(path)
    fileWrite(file, data)
    fileClose(file)
    return true
end

function loadFile(path)
    local file = fileOpen(path)
    if not file then
        return false
    end
    local count = fileGetSize(file)
    local data = fileRead(file, count)
    fileClose(file)
    return data
end

-- some functions --
		downloadFile(txdpath)
		addEventHandler("onClientFileDownloadComplete",getRootElement(),function(fil)
			if fil == txdpath then
				print("downloaded file: "..txdpath)
				local rawdat = loadFile(txdpath)
				local txd = engineLoadTXD(rawdat)
				if txd then		
					engineImportTXD(txd, model)
				end
				fileDelete(txdpath)
				
				local txd = teaEncode(rawdat,pass)
				saveFile(txdpath,txd)
				local txd = nil
				local rawdat = nil
			end
		end)
-- another functions --

 

Link to comment

Because non-latent events are guaranteed to arrive in order, a side effect is that a large payload (such as a file) in such event will hang the event manager, since subsequent events need to wait and yield to this big event, so that they arrive after that big one, ensuring order. Using latent events, however, allows you to forego this guarantee, and also limit transfer rates among other things. Latent events are suited for sending over large data that isn't sync-like, such as file contents.

As to fileDownload, it downloads the file as-is on the server, and at every reconnect or restart, it compares the server's hash; if the file is different on the client (outdated, for example), it will re-download; so if you encrypt the file after downloading, it's no longer identical to the server file and thus will be re-downloaded on restart. You should, as suggested above, encrypt it on the server and send to the client via a latent event, later caching the contents into some file on the client's computer. You will also need manual hash checks to make sure the client didn't replace, edit or break the file, on onClientResourceStart.

Further, the loading errors are almost definitely because you did not Base64 the TEA input (required for binary data in teaEncode); preferably move towards encodeString and decodeString as these do not require Base64ing (thus lower CPU and bandwidth use).

Finally, I'd ultimately recommend just pre-encryping rather than encrypting on-the-go whenever a client demands either a hash check or the encrypted contents from the server, as that causes the server becomes busy encrypting what could have just as easily been encrypted earlier.

  • Thanks 1
Link to comment

Well, i'll try to learn it and make some experiments ^_^

@MrTasty i tested triggerLatentClientEvent. it returned true but nothing happened. Client-side function doesn't respond. I attached it to root

I tried this

triggerLatentClientEvent(source,"loadClientModel",50000,false,source,txd)

edit 2

triggerLatentClientEvent(source,"loadClientModel",source,txd)

 

Edited by JeViCo
Link to comment
  • Discord Moderators

@MrTasty @JeViCo

What I thought was to actually store decoded files and such server-side, then at resource start:

  1. Read
  2. Store raw data
  3. sha256(Encode(T.E.A.)) (store the hash of the encoded data, bc only the encoded data'll be stored client-side)

Now, when the resource starts client-side:

  1. Check if the files exist(The server should send a table(k = file path, v = hash) with all the files that the specified resource should have)
  2. Collect every file that is missing(or has a bad hash) and send a table with the missing files to the server
  3. The server sends the requested files(non-encoded) 

Now, just encoded the files you got from the server and store it on the client's computer.

you need to do this this way bc of how T.E.A works(it returns a base64 string which adds +33% to the size)

Edited by Pirulax
Link to comment
11 hours ago, Pirulax said:

you need to do this this way bc of how T.E.A works(it returns a base64 string which adds +33% to the size)

that's why MrTasty advised me to use encodeString 

11 hours ago, Pirulax said:

Now, just encoded the files you got from the server and store it on the client's computer.

i totally rewrote everything and did something like that

Link to comment
  • Discord Moderators

No, it still ads +33% to the size of it with encodeString, doesn't it?
 

Quote

i totally rewrote everything and did something like that

You just encoded it and put that in the meta.xml, didn't you?

Link to comment
3 hours ago, Pirulax said:

No, it still ads +33% to the size of it with encodeString, doesn't it?

nope

3 hours ago, Pirulax said:

You just encoded it and put that in the meta.xml, didn't you?

yep

Thanks everyone for replies. I got what i wanted, even better.

Link to comment

TeaEncode returns a base64 representation of the encoded payload that's about 33% inflated in size from the original text. When dealing with DFFs or other binary, TeaEncode needs a base64 encoded input, a ~33% larger input. The output size with base64'd input is ~76.89% larger.

encodeString doesn't base64 the output nor does it need the input to be base64'd, and seems to return a barely inflated output; Specifically, 100.00168517551% of the original size in my quick test using a vehicle model DFF for input.

Edited by MrTasty
  • Thanks 1
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...