Adding autoupdater to an RPG

Started by
13 comments, last by Ruben Torres Bonet (The Gamedev Guru) 19 years, 2 months ago
I've been a MUD programmer for about 7 years, and in the past year I've finally started working on a graphical client and server app for my next project. Unlike MUDs, this means I will have to make sure that the people connecting have everything they need, and since I haven't worked with this aspect, I need a little help. I'm just wondering if there is any type of guide/tutorial on how to create an app similar to an MMORPG, where you clicked the executable which connects to the server, receives a list of updated files, downloads them, verifies them, THEN launches the client. Thanks, Kaiousama
Advertisement
If it were me, I'd set up a server-side script on your game's webserver to produce an XML file of updates to download. The client would HTTP GET the file, using their current version as a querystring parameter; eg: http://www.rgpgame.com/updates.asp?version=1001

The server would then take this version passed by the client and use it to look up the correct upgrade path in a database.

Table to hold the update possibilities
upd_Update  upd_ID       identity  upd_OldVer   text  upd_NewVer   text


Table to hold the version filenames:
ver_VersionPaths  ver_ID         identity  ver_Version    text  ver_FileName   text           // Filename on server  ver_Released   date


For example, imagine your client is running version 1001 and the newest version is actually 1200; there might not be a direct update to the new version meaning the client may have to install 1050 and then upgrade from there. The script would find all these versions and build an XML file to send back to the client for downloading. The resulting XML file of this upgrade might look like:

 <yourgame>   <update verFrom="1001" verTo="1050" fileURL="http://www.rpggame.com/upd/ver1050upd.exe" />   <update verFrom="1050" verTo="1200" fileURL="http://www.rpggame.com/upd/ver1200upd.exe" /> </yourgame>


You'll naturally have to add your own security and validation routines as well as creating the relevant program/scripts to administer the version database, but hopefully this should provide a way to help your thinking on the subject. By the way, I'm only using XML because I like it - there's other ways you could achieve a similar thing.
There are plenty of open standards for this kind of thing. I can't recommend any in particular, since I only use one, and it's not perfect, but it is VERY widely deployed: Java Webstart. It:

- compares the currently installed binaries to the server versions
- downloads any new or changed archives
- (if correctly configured) auto-patches the archives by only downloading the files within the archives that have changed
- automatically installs any third-party libraries, including native libraries
- automatically runs "additional" installers for libraries and your own app as needed
- lazily streams data that is not needed to launch the app. E.g. if your game is an RPG with 5 major cities and all players start in City 1, you can mark the textures + map files for cities 2 to 5 as "lazy" and it will launch before they've finished downloading. By the time the player gets to cities 2-5 the streamed download of their data will probably have completed. As far as I know no current commercial MMOG has an updater as good as this. This is depressing.

FYI the unique advantages of webstart games (shame about the stupid name; they should have named it "autoinstall" instead or something like that) were a driving force in the creation of the http://javagamesfactory.org - we only allow distribute games that use webstart, so you're guaranteed all the above advantages for every game on the site. Very nice.

Webstart is an open standard with reference implementations (from Sun, distributed automatically with every copy of java) and open-source alternative implemetnations (on sourceforge.net IIRC).

At the very least, read the detailed docs from Sun describing the format of the JNLP file (XML file describing the app and it's requird libraries + versions) and the docs describing the various download protocols - that should give you a good idea of minimal features for any system you choose to use.

You could even hijack webstart, use the protocol just don't use it for java games. Or you could write your clients in java ;)

redmilamber
hey guys,

im starting to think about doing an auto-patcher for my game. i really liked evolutionals idea, except one thing i dont get.

what if version "1050" is not needed to get to "1200" ? what if we are at "1001" and want to update to the latest version (1200), however 1050 is a redundant update. how do we skip over 1050?
FTA, my 2D futuristic action MMORPG
What we do is store a release number, and let the client identify this on login. If the release number is different from the current release number, then we look for an updater called "update_<clientversion>_to_<currentversion>". If this exists, we send it. If not, we point the client at the full installer, "install_<currentversion>".

Thus, we can go as far back in the upgrading as we feel is justified. If someone stays away for a year and then comes back, he won't get an incremental upgrade; he'll get the full installer. Now, we don't charge for the binary (Free Download! Free Trial!) so we can do this. If you care about store sales revenue, this would need some tweaking.

We also only update the "base" assets -- more than half of our assets is content that either is user-submitted through our auctions system, or that is delay-downloaded on discovery by the client. We can add new stuff pretty easily that way, without having to patch anything.

The main draw-back is that there's more work for us, to generate more than one updater (patcher) package.
enum Bool { True, False, FileNotFound };
hey hplus,

thanks for the reply. i have a plan on what im going to do now, and it seems like it would work.

anyway, im planning on using Python for the auto-patcher program (can you believe in Python its only 4 lines of code to connect to a website and download a file [smile]). basically like you said, the server would see if the version numbers matched, and if not said "hey, run the autopatcher and update to version XYZ". the client would then run the autopatcher (a Python script) which downloaded from my website a file named something like

http://www.ftaonline.info/fta/patch/versionXtoY.txt

where X was the version the client had and Y was the version the server told him to update to. this file would look something like:

game.exe
some_texture.png
other_stuff.whatever

the script would then download those files in the text file from my website.

anyway, just wanted to make sure there werent any obvious flaws in my setup. also, do you think i could get away with keeping the client running and then have the client execute the python script? that way i wouldnt have to tell the user to close the program and run the patcher. EDIT: im not sure if this will work though, unless i actually embedded Python into my client (how else would the script tell the client "im done downloading the files"?)

thanks again.

EDIT: i noticed you mentioned you let the players download the entire client from the patcher/client. this actually seems like a good idea and more professional. it also makes sence since the users are going to donwload the base client from my site anyway, why not just download it all from my bare client / autopatcher?

well, theres one flaw. having users download the base client directly from my site allows me to .zip my files or use installers. this would save on download times and bandwith. i guess i could just use zlib and compress everything before i uploaded it, and have the client download everything directly, however, i think this is more hassle to have to make a zipper utility and zip everything up when i add things. EDIT: actually, i believe the click team patcher actually will delete any files that i tell it to.

[Edited by - graveyard filla on January 9, 2005 2:01:24 PM]
FTA, my 2D futuristic action MMORPG
The problem with keeping the client open is that Windows doesn't let you overwrite an EXE that is currently running. Thus, what the patcher part should probably do is to download an EXE which is a self-extracting archive, then launch that archive and quit itself. The archive would, in turn, ideally wait for the application to go away, then start extracting itself. When it's done, it would re-launch the client.

Look for a self-extractor where you can insert code, because you'd want to customize the splash screen, and sometimes also run custom code to, say, update registry entries or delete old outdated files. Not to mention re-launch the client when done.

Be VERY careful when you download executables, though. Someone might hack your web site, and insert a link to a malicious download (or just upload a malicious file), to infect all your users' machines. Ideally, you verify the URL you get back, so the domain name is one you approve of, and you might also want to use a digital signature on the self-extractor.
enum Bool { True, False, FileNotFound };
hey hplus,

i hadnt even thought about about just having the client download the actual installer / some sort of patcher program using the python script. i found that click team makes a really nice and free patcher program. you cant insert code from what i looked at, however, it allows you to customize the splash screen and can actually delete old files that i want it to i believe.

so, instead of having the client download a txt file, he would just directly download a file called

www.mysite.com/patches/patchXtoY.exe

then the patch would contain all the files needed. the advantage to this is that i dont have to manually code finding what directory the files belong in and putting them there (although thats probably trivial in python), also, and mainly, i get the benefits of compression.

i am a little worried about the security aspect though. i wouldnt know where to begin on inserting a digitial signature, and its probably not possible with this program. also, im not sure what URL you are referring to that i should verify. do you mean the URL thats in the python script? e.g., before i download the file, verify the URL im about to download is indeed pointing to my domain? but, im not sure what this accomplishes. if a user can get into my script and change the URL to something malicious, couldnt they also remove the check to make sure it points to my domain? furthermore, if a user could somehow hack a clients auto-patcher script, doesnt this mean he already has access to the users computer and could do malicious things anyway? im just not sure i understand that part.

also, do you think its a serious threat that someone could replace my patch file with a virus? i really, really, do not want to lose half my users because somebody with too much time on their hands hacked into my website and replaced my patch file with some virus. although, for this to effect ALL of my users, they would have to upload a virus to a patch that i just released.

[Edited by - graveyard filla on January 9, 2005 2:58:02 PM]
FTA, my 2D futuristic action MMORPG
The reason you want to somehow vet/protect URLs (and other data) is that, sometimes, there are bugs in programs that allow you to overwrite local data files, but not necessary local code. Being very cautious about all code that writes to local disk works to reduce the chance of this happening. The kind of check I was suggesting was modifying the Python web-getting library to ONLY allow getting URLs that start with "http://www.yourserver.com/".

For attackers to modify your binaries, they would have to affect a file you just uploaded, OR they would have to create their new update version, and hack your site to add it. It CAN happen, although the chance is probably remote. Making sure you have good security on your web server goes the first 90% of the way towards guaranteed security, and for indies, that might be enough.

To get to 100%, you could store a digital signature separate from the patch, and hard-code the public key in your executable. Thus, you would download:

1) yourserver.com/patches/fromXtoY.exe
2) your-other-server.com/signatures/fromXtoY.sig

The point of downloading the sig from another server is to make it harder on the intruder -- he'd have to crack two, presumably different, hosts to actually make it go, IF he could steal your private key used to sign the patcg. Typically, private keys are not stored online at all, so that would be kind-of hard for a remote to do (but also worry about disgruntled employees ;-)

Then, before running the exe, you would verify that the signature of the .exe matches what the .sig file says, using the public key hard-coded into your executable.

Note that most commercial games with patches don't seem to do this, so if you also didn't, you'd be in good hands. I don't know if this is a good thing or not ...
enum Bool { True, False, FileNotFound };
that would be pretty funny if, say, somene hacked the WoW or EQ2 servers and had millions of players download some horrible virus.

my guess is they have some good security on them though. not to mention, these companies can actually afford to have your ass thrown in jail [grin].

thanks for the help hplus.
FTA, my 2D futuristic action MMORPG

This topic is closed to new replies.

Advertisement