OpenMeridian105 / Meridian59

The MMORPG Meridian 59 - Server 105
https://www.meridiannext.com
Other
16 stars 16 forks source link

Future updater (club.exe) and update process work. #127

Open skittles1 opened 8 years ago

skittles1 commented 8 years ago

Improved in-client update process by @cyberjunk.

Current process:
cyberjunk commented 8 years ago

I noticed the MD5 is only generated on the first 1024 bytes of the club.exe file in the changes you made for OgreClient.

Is this the same for the patching all files in club.exe? I don't think this is sufficient enough to catch a changed file. Just think about a file which is changed but not in the first 1024 bytes (easy - like adding to Meridian59.layout file at the end).

Also I didn't get why the filename is/was included. What's the idea behind that?

cyberjunk commented 8 years ago

I didn't review the latest club.exe, but it feels like this is still fully sequential. One Download after the other?

Looking at the small sizes of M59 files and the overhead for HTTP connections, I guess patching could be speeded up a lot by downloading multiple files at once.

Suggestion for club.exe: 1) Use a threadsafe/concurrent "queue (ordered)" or "bag of things (unordered)" collection. 2) Make the mainthread parse the JSON and create a task for each file-entry in the JSON. (task = instance of class/struct, which provides data and code to compare md5, download if different.) 3) Add all the task-object/struct instances to the collection from (1) 4) Fire up N worker-threads which loop and take out a remaining task-object from the collection 5) Work-Loop: (a) Compare MD5 (b) Possibly Download (c) Post-Feedback 6) ...

cyberjunk commented 8 years ago

Overall-Progress (not sure if this is in yet?): Sum up all file sizes from json = 100%. Sum up downloaded/checked file-sizes from json: = current %

skittles1 commented 8 years ago

Think we covered most of this in IRC but posting here for reference.

I noticed the MD5 is only generated on the first 1024 bytes of the club.exe file in the changes you made for OgreClient.

Will take care of this ASAP. This is the way it was done in the patcher (for speed), originally it hashed the whole file but was quite slow and then it was changed to 64 bytes which didn't catch all files. I chose 1024 as an amount that caught all classic client file changes, but would prefer hashing the whole file (and we don't really have a choice). We probably need to change this in the patcher also regardless of the performance hit, but in the meantime the server operators can have separate patchinfo.txt files - one for the 1024 byte patcher hashes, one for full file in-client updater hashes.

Also I didn't get why the filename is/was included. What's the idea behind that?

For club's hashing algorithm I just used the one in the patcher hence the filename addition, so I'm unsure why that was added. Any situation I can think of where the filename would matter (e.g. it changes) would cause the file to be downloaded again anyway. I'll remove this unless you can think of a reason to keep it.

I didn't review the latest club.exe, but it feels like this is still fully sequential.

Downloads are sequential, I'll have to learn threading and set up the solution you outlined.

Overall-Progress (not sure if this is in yet?): Sum up all file sizes from json = 100%. Sum up downloaded/checked file-sizes from json: = current %

Currently club first sees the file to download as it iterates through objects in the JSON array, and finishes downloading that before moving on to the next one. I think even in the threaded approach scanning would be happening alongside downloads so a valid % won't be immediately available. The UI does need work and could eventually have "% files scanned", and "Calculating total downloads" which switches to "% of downloads completed" once all files are scanned.

cyberjunk commented 8 years ago

Currently club first sees the file to download as it iterates through objects in the JSON array, and finishes downloading that before moving on to the next one. I think even in the threaded approach scanning would be happening alongside downloads so a valid % won't be immediately available.

You will have to make a first run through all the entries in the JSON file to sum up their file-lengths, but this should be easy...

long max = sum(all file-lengths from json entries)

Then create a bytes-counter to track the finished overall-bytes

long done = 0;

When you iterate through the entries, you increase the "done" bytes value.

At any time, your current overall progress is available by the ratio of:

progress = done / max;

Progress will be a value between 0.0 (start) and 1.0 (end) which can easily be used for an overall-progress bar.

PS: A simpler solution would be to use the ratio of files, but due to different sizes this is not as good:

progress = processed files / overall files

cyberjunk commented 8 years ago

Also:

I think even in the threaded approach scanning would be happening alongside downloads

Not sure if I'm getting this right, technically there are 2 thing to be done per file: a) Calculate MD5 b) Possibly download

And there are two approaches: 1) Calculate MD5 of all files first and afterwards start download of some. 2) Calculate MD5 of a file and immediately download before processing next file

I think option 2 is a bit better for a multithreaded solution where a worker gets one file as a worktask.