Developing the Battle.net Emulator BNETDby Howard Wen
The legal status of emulation programming took a very precarious turn when Blizzard Entertainment and its parent company, media conglomerate Vivendi Universal, filed suit against the volunteer developers of the BNETD Project on April 5, 2002.
Developed under open source, BNETD is server software which emulates most of the functionality of Blizzard's online game network, Battle.net. Irvine, Calif.-based Blizzard is the developer and publisher of the enormously successful StarCraft, Warcraft and Diablo role-playing game franchises, and its Battle.net service enables fans of these games to play with others on the Internet.
BNETD's origins date back to 1998. Created by Mark Baysinger, who at the time was a student at the University of California, San Diego, BNETD was then known as StarHack and was meant to emulate enough of Battle.net so that fans could play StarCraft online on their own servers. The project went into the open source model, and several contributors over the years have enhanced the BNETD code so that other Battle.net-enabled games, like Warcraft and Diablo, can be used with it.
Today, the project is under the aegis of Ross Combs, a 27-year-old computer security programmer/analyst from Austin, Texas. Rob Crittenden, a 34-year-old programmer in Lithicum, Md., is the second lead developer of BNETD behind Combs.
The number of presently active contributors consists of one administrator (Combs) and three coders, but, additionally, Combs says, "There have been 25 to 30 people who have made nontrivial programming, bug investigation, or administrative contributions. If you count small bug reports and suggestions, then that number would be two or three times larger."
The BNETD developers say that BNETD was made as an alternative to Battle.net's oftentimes slow and buggy service. It was also meant to enable friends to play Battle.net-enabled games with each other on a private network, without having to deal with abusive strangers on Battle.net. Written in C and available for the Linux, Win32, BSD and Solaris platforms, the BNETD code, they claim, has been developed over the years through legal, reverse-engineering means. (Since the filing of Blizzard's suit, the code has been removed by the developers from the BNETD site until this matter is resolved.)
In its suit, Blizzard claims, among its list of grievances, that BNETD infringes upon its Battle.net trademark, violates its copyrights since use of BNETD constitutes an unauthorized public performance of its games, and -- most damning of all -- that BNETD was created through code stolen from Battle.net.
The ISP hosting the BNETD site, Combs, and 50 "John Does" (presumably, anyone who has contributed significantly to BNETD's development) are listed in the suit. The stakes here -- regarding legal reverse engineering, creating emulation technology, and encouraging or discouraging contributions to open source projects -- are high enough that the Electronic Frontier Foundation (EFF) decided to take up the defending of BNETD and its developers.
The overall facts of BNETD's predicament have made news in the open source community, been analyzed in the legal community, and been covered in other media (full disclosure: I myself wrote such a piece).
But for O'Reilly Network, Combs and Crittenden wanted to speak candidly about the technical aspects of BNETD's development and, to help clear the legal air about how they reverse engineered the inner workings of Battle.net.
BNETD's Level of Compatibility With Battle.net
Howard Wen: Up until the moment when you chose to temporarily remove the BNETD code from the project's Web site, what was the then-current progress with it?
Rob Crittenden: BNETD has support for all of the major features of Battle.net, including:
- User icons
- Game play
- File transfer
- Support for StarCraft, Diablo II, Brood War, Warcraft II (Battle.net Edition)
- Ladders (tournament play)
- Accounts and passwords
- Server connectivity so servers can share users/games, etc.
- Automated client patching (auto-update)
To a large extent, from the user's perspective, it is difficult to distinguish [BNETD] from Battle.net in functionality.
Ross Combs: One major user-visible feature that we recently added is an internal mail system, so players can send messages to friends who are not logged in.
We also reworked the "ipban" code, which allows administrators to ban IPs and subnets from connecting to the server. In the past, the list of IPs to ban was kept in a configuration file. This was not optimal because BNETD administrators would need shell access to the server and permission to
kill -HUP the BNETD process. Now the administrators can add and delete entries from the chat interface at runtime.
We also added the
/reply command which makes replying to "whispers" much easier.
There are always more changes below the surface which improve the server but which aren't always directly visible to the average user. I improved the hashing algorithm for accounts to have a better distribution, which should help speed up servers with many accounts.
There is also some work that seems to be never-ending. One of those items is keeping up with Blizzard's recent patches. The patches often involve slight protocol changes or the introduction of new "packets," which require new code on the server side. Since we can't be sure of the actual purpose for these packets, we have to either guess what they do or we have to blindly mimic what Battle.net does. Sometimes the purpose of the packets becomes obvious due to other protocol changes, or because we see enough examples to figure out the pattern. A further complication is that we have to maintain compatibility with older clients, which may send different packets or send them in a different order.
We are trying to work toward a new, major revision 0.6. The last serious bug holding up that release is the handling of the status field of the STARTGAME4 packet. This field tells us if the game is open for additional players, full, started, or if the game has completed. The server sometimes gets this wrong, which results in people trying to join games that have already started.
Wen: Currently, what are BNETD's limitations, compared to Battle.net?
Crittenden: The biggest limitation is scalability. Some ISPs host game servers that have tens of thousands of users, but we use flat files for user accounts, which is a real limitation. I wrote a GDBM back-end for [BNETD] long ago, but that is now deprecated. (It never really worked very well.) We have a design for database-based user storage, but there has been no coding on it yet.
Wen: Has the plan always been to develop BNETD into a 100-percent-compatible version of Battle.net?
Combs: The original goal was to make a personal StarCraft server for people to play a game or two with their friends. That amount of functionality was achieved early on. After that point, the goal changed and our new efforts went toward implementing all the user-visible features of Battle.net. We still haven't completed that task.
Of course, we don't always stick with the way Blizzard does things [with Battle.net]. For example, we implemented online help for chat commands before it was available on Battle.net. Unlike Battle.net, our users also see the server-side configuration, so much of our work goes toward making the server configuration simple and flexible. It is possible to designate certain accounts to have the ability to connect with "bots" without giving all users access. It is also possible to keep some users from ever being selected as channel operators. We've even added support for IRC and telnet clients.
Our goal these days is to provide the best set of features for both players and server administrators. If Blizzard comes up with new things which support that goal, then we will also implement them.
Figuring Out How Battle.net Works
Wen: What's the technique you used to figure out how Battle.net works, in order to make BNETD compatible with the Battle.net clients (the games)?
Crittenden: I used a Windows NT-based network scanner to capture packets between my client and the real Battle.net server. Then I'd examine the packet dumps to see how they did it, then re-implement it in [the BNETD] server. It was a real iterative process that consisted of:
- Start network scan
- Print results
- Do a little coding
- Test it
- Do some more scanning
Some of the packets were easy to figure out; others we guessed at.
Combs: I use
tcpdump to log packets. When I try to analyze an unknown protocol, I follow these steps:
- Figure out what protocols and ports were used
- Figure out which direction(s) connections were initiated
- Figure out the framing of the data stream
- Attempt to identify and classify the different frame types
- Determine which frames were responsible for triggering responses and changing the internal state of the client or server
Of course, the first thing that was noticed is that the client connects to port 6112 on the server. Registry entries in the client select which server to connect to. When the client connects to the server, it sends a single byte (control-a). The meaning of that byte wasn't obvious at first but we later found that it is selecting the type of connection. There were two other types of connections, each with different formats: file connections and bot connections.
The server replies by sending two identical UDP packets back to the client. We originally thought these were to test the connection latency, but they later turned out to be testing for UDP connectivity (looking for dropped packets due to a firewall or network misconfiguration).
After that, all the traffic has a nice fixed-record format (framing). We like to call these records "packets" even though they are just part of a TCP connection stream. These packets all have the same 32-bit header. The first two bytes are a packet type, and the next two are the packet length in bytes. Strangely, the packet types all start with "0xff." Maybe the packet type is just one byte and the other byte is a value to check for invalid packets.
We have implemented about 100 of these packets. There are no doubt a few currently in use on Battle.net that we don't support, and a few used at one time which Battle.net no longer uses. In any case, we were lucky because the basic protocol was pretty simple. We found a few twists and turns later because there are some additional connection types which the server has to implement which don't use the same format (file downloads are an example).
As things progressed, we were often able to test with clients connected directly to BNETD servers, and try different game types and different buttons on the screen. The protocol was regular enough that we could often guess the proper response packet. Of course, this lead to some bad guesses, which would cause client-side lockups or crashes. An early example was that the client would freeze if the ladder button was pressed.
Once all the functionality was working with StarCraft and Brood War, we added Diablo support. We used a recently patched Diablo install and the work went much faster than expected. It only took two hours, since there were few protocol differences.
Warcraft II (Battle.net Edition) support was even easier than Diablo. Adding Diablo II support was somewhat more difficult because Blizzard was making a lot of new changes on Battle.net at the time. They added a kind of "sub account" which [required] changes to be made all over the BNETD source.
Pages: 1, 2