Skip to main content
gamedev.net
🔒 Locked

Patch Engine?

Started by DrHalan Dec 13, 2008 at 10:46 AM 14 replies 3.1k views
Original Post
DrHalan
DrHalan
Hey, i am looking for a framwork that handles updateing of my games executeable. I guess the easiest way would be a webspace and a script that updates md5 hashes the client can check against. Whatever i am wondering wheter something like this exists as i can't find anything on sourceforge. greets, Halan
My Blog - http://www.freakybytes.org
hplus0603
hplus0603
There are some libraries that do this, but they are typically commercial.

Each game typically has slightly different requirements, though, so a standard open source library might have not arisen because of that.

In general, you want the patcher to be a separate executable from the executable itself, because you can't re-write a running binary on Windows. Also, if you are Windows only, I would highly recommend building your patching and installing on top of the Windows Installer (msi) framework -- it's quite well tested, quite powerful, and well worth the time it takes to learn it.
enum Bool { True, False, FileNotFound };
DrHalan
DrHalan
I can't rewrite a running binary on windows??? what the hell.

But no i am running linux and wanted to implent the patchign directly into the game executeable.

So on windows how do i patch the patcher then?

EDIT: but in general is it more common to use a standart webspace and patch trough HTML or do you write a "Patch Server" and use your own TCP/UDP-based protocol?
My Blog - http://www.freakybytes.org
Sim9
Sim9
Could you have the patcher be a separate executable that is launched from your app? Then it would feel seamless to the user, even though it's actually a separate exe. As for needing to patch the patcher... I'm not sure why you would need to?

Also, for using a custom protocol vs http/ftp, it'll depend on the solution you use. If you write it yourself, http/ftp is easy and standard, so would be a good choice :)
Archive Games - Distribute Your Game Now!
DrHalan
DrHalan
Well it seems common for games to update the patcher but it seems to be kinda wierd to do.
My Blog - http://www.freakybytes.org
hplus0603
hplus0603
Quote:
As for needing to patch the patcher... I'm not sure why you would need to?


No software is free of bugs, and all software will eventually need upgrading for one reason or another.

To patch the patcher, what you do is typically download a new executable, and have your main game remove the old patcher executable and install the new.

In general, using HTTP means that you can use existing infrastructure to download files (including byte-range gets, restartable reloads, etc). Some games, though (like WoW) will also try to do the bittorrent distributed download thing, where clients get data from each other, using hashed checksums for each segment.
enum Bool { True, False, FileNotFound };
Nypyren
Nypyren
Quote:
Original post by hplus0603
In general, you want the patcher to be a separate executable from the executable itself, because you can't re-write a running binary on Windows.


Sure you can... it's just REALLY REALLY difficult compared to just shutting the EXE down then replacing the file.

- Have a section of pseudo-shutdown code in the original EXE which calls a small, separate reloader DLL whenever you need to patch.

- Use VirtualProtect to make the entire EXE memory area writable (normally the code pages are ExecuteRead).

- Completely overwrite the EXE in memory with the new one.

- Load any new DLLs required by the EXE and fix up relocatable addresses.

- Reinitialize the call stack and jump to the entry point of the new EXE.

- Cross your fingers that you don't have to implement any obscure loader features.


Alternatively, you could put your entire game in a DLL and have the main EXE reload it, which would solve the manual loading nightmare.



I apologise for not being able to help with Linux - I've never looked into the low level stuff required for this on those OSes.
Servant of the Lord
Servant of the Lord
I've heard you can have a .zip file, with a .exe inside of it that runs when you double click the .zip. (I forgot where I read it, but it was somewhere on GameDev)

Perhaps you could have two sections to the .zip, one as the .exe of your game, and one as the .exe your patcher. When someone runs the .zip file, it runs the patcher which checks that the game is up to date, and if it's not, writes over the part of the .zip file that holds the game's executable. Once updated, then you run the game's .exe.

From a user's perspective, it would look like a single file, and you wouldn't have to give it a .zip extension, so they wouldn't realize it's a zipped folder (unless they are clever).

I've never done such a thing though, so the above is just theorizing on my part. (I'm still young and naive when it comes to programming [smile])

If it works, you could even keep some or all of your content in that one zip-exe-hybrid file, so even your game's resources look like it's part of a single file. I'm not sure how practical that would be, but it should work for a small game. Or you could just keep player settings and keybindings in it, and load the rest of your resources like normal.
Leaedas
Leaedas
Didn't read everything but, a simple solution to patch the patcher would be just to have a pre-patcher run before the patcher, that launches the patcher after it checks/downloads the updates for the patcher, then proceed like normal. I've seen plenty of examples. All SOE games (Sony Launcher) and some other ones.
Nairou
Nairou
Game engine:
1. Check website for updates
2. Download the appropriate update executable
3. Launch the updater
4. Exit

Updater:
1. Wait for the game to exit
2. Install the updated files
3. Re-launch the game

Leaedas
Leaedas
Quote:
Original post by Nairou
Game engine:
1. Check website for updates
2. Download the appropriate update executable
3. Launch the updater
4. Exit

Updater:
1. Wait for the game to exit
2. Install the updated files
3. Re-launch the game


Now I'm just being a jerk but, wouldn't that create a loop:)?
Lord Darkblade
Lord Darkblade
No, because eventually you will have an up to date copy, and the loop will break.

For WoW you see:

Launcher -> Updates launcher (possibly patcher as well?)

Game -> Downloads updates to patcher / loads patcher

Patcher -> Downloads updates to game, patches game, reloads game.

So that simple loop is there, but there is an additional launcher step that can be used it seems to pre-patch certain things (or possible just updated content for the launcher).
hplus0603
hplus0603
When I said you can't re-write a running executable, I meant the on-disk file, not the in-memory exeuctable. The Windows Kernel will lock a file that is currently being used as executable text.

Actually, the UNIX kernel does that too, but because the UNIX file system semantic allows for "orphan" anonymous inodes, replacing a running binary can be done by unlinking the running inode, and re-linking the replacement. No such luck on Windows.
enum Bool { True, False, FileNotFound };
Antheus
Antheus
Quote:
Original post by Nairou
Game engine:
1. Check website for updates
2. Download the appropriate update executable
3. Launch the updater
4. Exit

Updater:
1. Wait for the game to exit
2. Install the updated files
3. Re-launch the game


That would IMHO be the "proper" way to approach this problem.

If the main executable is relatively large, using a separate light-weight patcher might be beneficial.

There is however a subtle detail to look out for. User will expect main executable to be entry point into their application.

The patch process will therefore invariable look something like:
move main.exe main.bak*rename main.new main.exedelete main.bak


Unfortunately, there is no rename+replace under Windows (AFAIK), which means that if this process fails at (*), user will end up without entry point, and will consider application to be broken.

The best (and likely only) guarantee to solve this problem is to use MoveFileEx with MOVEFILE_REPLACE_EXISTING and MOVEFILE_WRITE_THROUGH flags.

Under linux, this shouldn't be a problem since rename can be used for that purpose, but under Windows it cannot replace existing file.

Patcher itself is only needed to perform two functions. Wait till main executable can be moved, and perform atomic rename. As such, patching of resources and download can be moved completely into main executable. This may be beneficial for applications which are mostly off-line in nature.
Evil Steve
Evil Steve
You can also do away with the patcher at the cost of making the patch process a little more awkward. A client I wront for a MUD/chatter updates in the following way:
1. Start app, and start a thread checking for updates (Just does a HTTP GET to get a version file on a server).
2. If there's a newer version available, inform user and ask if they want to download the new version. If the user says no, bail here.
3. Download the new version (Which is in a packfile for my purposes) in a new thread so the application can still be used during the download. Downloads into a file in the Windows temp directory (Using GetSpecialFolderPath() or whatever the function is - not assuming anything about the users directory structure).
4. When new version is downloaded, inform user and ask if they want to install now (And bail here if they say no).
5. Unpack downloaded file into a temp directory
6. Spawn new .exe file from temp directory, passing a flag to tell the EXE it's being updated, a path to the current exe (GetModuleFileName(NULL, ...)), and the process handle (as an int). Terminate this EXE.
7. Inside the EXE in the temp directory, wait for the parent process to exit (By waiting on the handle passed on the command line) copy contents of the directory the EXE is in into the path passed on the command line (Which is the source EXE). Pass a flag indicating it's "update, stage 2", a path to the current EXE, and the process handle.
8. Inside the new, updated EXE in the correct location, wait for the parent process to exit (Using the handle on the command line), then delete it and the contents of that directory.
9. Current EXE is now running as an updated version, in the correct location and has cleaned up all temp. files. Show "What's new in this version?" dialog box and then continue normally.

It's a bit longer, but it's really quite straightforward (Especially since steps 1-5 above are just about downloading the new version), and avoids requiring two EXE files - which could be useful in some cases (No alternative EXE the user could incorrectly run, no need to patch the patcher sincer the EXE is the patcher).
DrHalan
DrHalan
Yeah i think its the easiest way to create a seperate patch-executable. Then i can also use delta patches :)
Of course this only works if the client has exaclty the prior versions. I still don't know if i should develop a full blown patcher. It seems like a lot of work but on the other hand worth it.

On Linux I will consider using a repository for updateing.

Thanks for your support.

[Edited by - DrHalan on December 17, 2008 11:12:26 AM]
My Blog - http://www.freakybytes.org

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.