The hosting / port forwarding / firewall hole punching thing has been an issue since BNE came out.
I started on a fix for this last year, however my current work commitments mean that I am unlikely to find the time to finish this in the forseeable future.
I have completed what is probably the trickiest part of the project which is to provide an interface between the appropriate parts of the wc2 process and an external program, so I have decided to release this in the hope that someone else can put the time into developing and testing the rest of it.What is here:
- Warcraft II LCE.exe
(just for lols)
This is a modded version of the standard Warcraft II BNE.exe 22.214.171.124
It is modded in 2 ways
1) It has a small amount of injected code that loads and links the LC.dll interface module, and hooks the join game proc.
2)It has the no-cd patch detailed earlier in this thread applied, which just makes it easier for development/testing. Note this patch only works for multiplayer not for single player campaigns. It is quite easy to reverse if required, or I can help port the other mods to another version of the .exe.
A modded version of the standard BNE storm.dll module that has a hook for the game hosting proc.
The ASM interface module that provides info and handles the low-level balancing/correction in and out of the hosting module.
An example hosting fix module that does pretty much nothing apart from write the game names on the screen when you join/create a game.
Source for the example host.dll
---------------------------------------------------So how does this work?
If you copy the included PE files into an existing BNE installation you should find that when you join a game you will get a message on the screen saying "JOINING" then the game name, and likewise when you create a game you will get a message saying "HOSTING" then the game name.
If you look at the host.dll source code you will see where these messages are being generated.
The host.dll module is required to export 3 functions called "host0", "host1" and "host2".
> host0 has no arguments and is called when the exe is first started. Any initialization code should go here.
> host1 will be passed a pointer to the game name and called when the player creates a game.
> host2 will be passed a pointer to the game name and called when the player joins a game.
----------------------------------------So what needs to be done with this to fix the hosting problem?
There's a bit of work to do yet, but its all bread & butter networking stuff so I'm hoping there are people in the community that can do the job....
You will need to make a custom server, and your own "host.dll" that exports those 3 functions. The example source is in C++, however any language capable of building a normal windows dll can be used.host0()
will just have whatever initialization code is required to support the rest of the project. Possibly a TCP connection to the hosting server could be started here, but personally I think this would be more reliable being done on a game-by-game basis.host2()
should be fairly simple, it just needs to send a message (probably over TCP) to the server saying "im trying to join this game" with the player's name, the game name, and the client's game port, the terminate the connection. Probably the server should be able to find the ip address from the incoming message, or possibly the client will have to obtain its own external address and supply it as part of the message. host1()
when hosting, the client will need to negotiate a TCP connection with the server and supply the name of the game it is hosting, then start a thread that listens to that connection for messages from the server. It should get a message from the server over the TCP connection when a player is trying to join with the IP address and game port of the joining client. When this message is received it will need to ping the joining cllient with appropriate UDP packets to facillitate the hole-punching. Finally it will need to notify the server when the game is starting then terminate the listening thread.The Server:
The server will need to listen for and accept incoming TCP connection from clients, and maintain a list of the active hosting connections.
When a client notifies that it is hosting a game, the game name should be stored in the list.
When a hosting client notifies that the game has started, terminate the connection and remove the game from the list.
When a client notifies that it is joining a game, look up the game name in the list, then notify the hosting client of the joining clients IP address and game port.
Joining clients are not required to be stored in the list for basic functionality, however it might be a god idea to store the info for a short amount of time to protect against faulty clients or DDOS etc.
There will no doubt be lots of lots of dev and testing required, but I think it is quite achievable. I am very happy to offer whatever technical support I can, but I simply don't have the time right now to develop the whole thing on my own.
one, two, three ..... GO!