auto-Updater + patcher in a C++ program

Started by
6 comments, last by retroworld 14 years, 2 months ago
hello everyone. I have learnt C++ and now I am making my own programs. But the thing that I got stuck on and couldn't get any information anywhere on google is how to make and auto-updater and a patcher? I am talking about like if I make a game and some-one with no proogramming experience downloads it to play, if the game is outdated or has a problem then how could he update it or get the update automatically without downloading extra software to download or run the patches. I hope some one could help me. thankyou
Advertisement
Usually you have some server programming running on a machine owned by you, the game developer. It is programmed to be able to accept requests in a certain format. The game client also understands this format. Basically it works something like this:

1) Client contains a list of files that it thinks are important. This is installed with the game

-----SYNCHRONIZATION-----
2) When the client tries to update, it first sends the list to the server. This allows the server to determine if there are any *new* files that the client didn't even know about.
3) The client then loops through each of the files in the list and sends the version information to the server.
4) The server compares this version information to information in its database for the most recent version of the software.


----UPDATING----
5) Any files which are newer according to the server's database get sent to the client.
6) Any files which are completely new (determined in step 2 above) get sent to the client
7) The server's list of important files (as mentioned in step 1) get sent to the client.



I'm sure there are other ways, but this one works pretty well and handles the case of being able to update from ANY prior version to any later version.

In some cases you may need more complex functionality than just copying over new data / code files. Maybe you changed a file format, for example. In that case you need to change your communication protocol slightly so that either you can send scripts to run or something like that.
First off, you should rely on you, the developer, knowing what the client needs. It helps save them from downloading files all day.
This means keeping 3 things around on your end:
*Origional Release. It's nice to have patches from original->latest without all the in-between stuff. You could also just make a way to quickly concatenate your patches to make one big patch for this.
*Previous Release. You'll need this to make a diff.
*Current Release. You'll need this to make a diff.

Once you have that, you can take several approaches:

1) A simple approach, if your data is free floating files, would be to as cash_hit said, just copy over any file that doesn't match the hash of the newest version. Delete all the files that don't exist anymore, and add any new files. To figure out this listing, you'd either ask the client for his local list of files. Or, better yet, you'd just ask for a version number. Remember you are keeping around data, so you can build up a diff between the previous and current versions, as well as send previous patches.

2) A better way of doing that would be on the server, build up not just a listing of what files are different, but actually run a tool like bsdiff/bspatch to create small "patch" files for every change. This way you'd be sending a lot less data to the client. Instead of copying over files, they'd just bspatch the file.

3) #1 and #2 aren't going to be good if you store all your data in big archives (.pak, .zip, etc). Patching an archive doesn't work as well as patching individual files. BUT you are kinda in luck. If you use a file system like PhysFS you can resort back to step #1 in a sense. You build up a new archive with all the new files, send it down to the client. The client uses PhysFS to know that when loading foo.zip patch01.zip patch02.zip patch03.zip, that it can load newer versions of a file from the patchXX.zip files if they have that file.

Finally, whatever choice you make on the patching, you'll need to make a separate "patcher", since you can't patch a running executable. The game will have to close then
patch, then reopen the patched executable.

Then for the auto-updater part, you'll need some sort of networking code, and talk to a server to ask it for patches. In theory, you'd only have to send up a version number. To be a little more secure than that, you may want to do as cache_hit suggested, and just send up a hash for every file to make sure the client hasn't "hacked" some resources.
Something like RakNet could suffice for this. As a plus side, RakNet comes with a demo using their code as a auto-patcher.
Quote:Original post by KulSeran
Finally, whatever choice you make on the patching, you'll need to make a separate "patcher", since you can't patch a running executable.

Note that it's only true on Windows - on other operating systems (OS X, Linux) you can patch a running executable without a problem (so a executable can patch itself), though you still need to restart for the changes to take effect.
thanks everyone that was really helpful but does the person that has the client have to download any other software to update the file?
If you're on windows, you could look into ClickOnce deployment. It's not very flexible, but it's pretty easy to use.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
On one of the MMO's I worked on, I simply made a PHP script that looped the game dirs and output a list of files along with their CRC.

The client then checked it's own files for updates, new and deleted files.
When this was done, it simply downloaded each file through a HTTP request from a regular apache server.

That way we could use proven server technology and since the PHP pages where cached, it could deliver the entire file in less than a second.

The simple solution that requires the least bit of coding is often the best :)

Oh and the hosting provider could simply cluster out the data directory for great speed and reliability ;)

With regards to executable patching, this was easy, since the patcher was it's own application. It could however also patch itself but that required it to restart. (Windows)

If anyone is interested I might be able to dig up a CRC based patcher prototype I developed years ago using SDL :)
thanks alot everyone for all your help that really helped me

This topic is closed to new replies.

Advertisement