- Joined
- Apr 10, 2008
- Messages
- 4,087
- Reaction score
- 1,264
How to make a MapleStory Redirector.
Introduction.
After mine got leaked (but I don't really mind), I decided to give something to the community. It's already been released - so why not explain how it's done? It all started a few months ago, when a friend asked me to make one. I had no idea how to do so, so I done a bit of research and got great help from Diamondo. As of today, I understand how they work and how to make them. It's pretty easy if you catch the idea. In this tutorial, I will explain how to make one yourself. No, this won't freely get you a redirector if you don't know what you're doing.
Requirements.
Understanding the Context.
Communication between Client and Server.
Part 1: The Basics.
Part 2: Server and Client classes.
Part 3: Transferring the Data.
Credits:
Please post any questions here, I'd love to answer!
Introduction.
After mine got leaked (but I don't really mind), I decided to give something to the community. It's already been released - so why not explain how it's done? It all started a few months ago, when a friend asked me to make one. I had no idea how to do so, so I done a bit of research and got great help from Diamondo. As of today, I understand how they work and how to make them. It's pretty easy if you catch the idea. In this tutorial, I will explain how to make one yourself. No, this won't freely get you a redirector if you don't know what you're doing.
Requirements.
- Microsoft Visual Studio 2012 (.. or Visual C# Express).
- The ability & will to learn, and not just leech.
Understanding the Context.
Before we even start creating the Redirector, we have to understand what everything means, so we can learn about our tools before we actually use them!
A packet is an array of bytes, used to transfer data between the client and the server. Each packets represents data, there are no "useless" packets. Of course, as a server, we don't take care of certain packets because they're simply not necessarily needed for us (Ex. Character creation date).
A client is an executable file used to connect the user to the server. "The GUI is a projection of the packets", like Moogra once said.
A server is the location where the source code is hosted, and it manages the information and data received by the clients and holds the database information.
Handshake is a common name of a packet to indicate the connection was accepted by the server. The client connects to a certain IP and sends the hello packet. Once the server receives it, the handshake packet is sent and then the client knows the connection has established. The client tries 3 times before giving up if it failed.
A packet is an array of bytes, used to transfer data between the client and the server. Each packets represents data, there are no "useless" packets. Of course, as a server, we don't take care of certain packets because they're simply not necessarily needed for us (Ex. Character creation date).
A client is an executable file used to connect the user to the server. "The GUI is a projection of the packets", like Moogra once said.
A server is the location where the source code is hosted, and it manages the information and data received by the clients and holds the database information.
Handshake is a common name of a packet to indicate the connection was accepted by the server. The client connects to a certain IP and sends the hello packet. Once the server receives it, the handshake packet is sent and then the client knows the connection has established. The client tries 3 times before giving up if it failed.
Communication between Client and Server.
What is a Redirector, actually? A Redirector is a "bridge", to help the client send data to the server back and forth. We need this, because localhosts are no longer available, so we are actually overriding this by loopbacking MapleStory to localhost and connecting to the server as if we were the actual client.
All packets that are sent from the client are re-encrypted and sent back to server, and vice-versa. Here is a little visualization I made to help you better understand the concept.
The arrows are indicating the data being passed through the
redirector to the server. It applies vice-versa as well.
All packets that are sent from the client are re-encrypted and sent back to server, and vice-versa. Here is a little visualization I made to help you better understand the concept.
The arrows are indicating the data being passed through the
redirector to the server. It applies vice-versa as well.
Part 1: The Basics.
I will be using Microsoft Visual Studio 2012 and C# for this project. This can be done in any language, but I prefer C#. Start by creating a new project, named whatever you want - but I prefer "MapleClient". Make it a WinForms application (.. as you will probably make it a launcher in the future).
The next thing to do is add a library to make the communication. You can either use MapleLib or Diamondo's MWLR Logging files. I use Diamondo's, as I like them better in their context, and he also recommended them. But both works fine.
Note: Code may differ if you are using MapleLib. I added them all under a folder named "Connection".
You must be registered to see links
The next thing to do is add a library to make the communication. You can either use MapleLib or Diamondo's MWLR Logging files. I use Diamondo's, as I like them better in their context, and he also recommended them. But both works fine.
Note: Code may differ if you are using MapleLib. I added them all under a folder named "Connection".
You must be registered to see links
Part 2: Server and Client classes.
To make an actual connection to the server, we need to inherit the Session class, which provides us with methods to receive and send data to a connection (whether it's local or remote). That means we will have to create two classes. One for the client, so we can accept the MapleStory's connection and send packets from it to the server - and one for the server, so we can connect to the server and send packets from it to the client.
We will start with the Server. Don't forget to inherit the Session class and import your Connection folder.
There are 3 base constructors for the Session class. We will be using the one that accepts arguments of an IP, a Port and a Type Name. The Type Name is a name given for a Session to differ it from others, to make it more organized. I created the class and just used the keyword base to connect to the given IP and Port. I used the Type Name "Server", of course. I also imported some of the methods of the inherited class: OnDisconnect, which is called when the server is disconnected (Manually or not), OnPacketInbound, which is called when a packet is received from the server, and OnHandshakeInbound, which is called when the Handshake packet is received from the Server.
To access the Server's instance, we will need to store it somewhere. You can simply add a line in Program class to store it, making it static, of course.
Client! That's the next class we will be making. Create this class, and on the constructor, the base requires a socket to be applied - add it in the argument of the constructor and also make a new instance of Program.Server.
The client's instance is created once a connection is accepted (MapleStory's original client). The moment we are creating a new Client instance, we are connecting to the server to make the actual bridge. Don't forget to add the base methods! No need for Handshake as we're not getting one..
To accept a connection from the MapleStory client, we obviously need to listen on the desired port (8484). To do that, declare a static TcpListener variable, and add a method named Listen to start the listener and accept a new socket. Oh and.. don't foget the async EndAccept.
We are creating a new TcpListener instance to listen for connections on Port 8484 from any IP (The MapleStory login port). The async callback will be EndAccept method, which will get the Socket from the listener and apply it to the new Client instance. You may also add debug messages, such as "Listening on Port 8484, Accepted connection on Port 8484" and so on.. Oh and! You're probably wondering what "Instance" is. It's just a variable of a Client so I can quickly access the instance from other classes (Just like what I did with the Server in Program class).
We will start with the Server. Don't forget to inherit the Session class and import your Connection folder.
You must be registered to see links
There are 3 base constructors for the Session class. We will be using the one that accepts arguments of an IP, a Port and a Type Name. The Type Name is a name given for a Session to differ it from others, to make it more organized. I created the class and just used the keyword base to connect to the given IP and Port. I used the Type Name "Server", of course. I also imported some of the methods of the inherited class: OnDisconnect, which is called when the server is disconnected (Manually or not), OnPacketInbound, which is called when a packet is received from the server, and OnHandshakeInbound, which is called when the Handshake packet is received from the Server.
You must be registered to see links
To access the Server's instance, we will need to store it somewhere. You can simply add a line in Program class to store it, making it static, of course.
You must be registered to see links
Client! That's the next class we will be making. Create this class, and on the constructor, the base requires a socket to be applied - add it in the argument of the constructor and also make a new instance of Program.Server.
The client's instance is created once a connection is accepted (MapleStory's original client). The moment we are creating a new Client instance, we are connecting to the server to make the actual bridge. Don't forget to add the base methods! No need for Handshake as we're not getting one..
You must be registered to see links
To accept a connection from the MapleStory client, we obviously need to listen on the desired port (8484). To do that, declare a static TcpListener variable, and add a method named Listen to start the listener and accept a new socket. Oh and.. don't foget the async EndAccept.
You must be registered to see links
We are creating a new TcpListener instance to listen for connections on Port 8484 from any IP (The MapleStory login port). The async callback will be EndAccept method, which will get the Socket from the listener and apply it to the new Client instance. You may also add debug messages, such as "Listening on Port 8484, Accepted connection on Port 8484" and so on.. Oh and! You're probably wondering what "Instance" is. It's just a variable of a Client so I can quickly access the instance from other classes (Just like what I did with the Server in Program class).
Part 3: Transferring the Data.
To send the data received from client to server, and vice-versa, we will have to use the overridden methods now. Let's start with Client. Send the received packet to the Server just like so.
The OnPacketInbound method is called when data is received (a packet). We are not touching the packet, we're sending it straight to the server, as if we were the original client. Remember you can also read the opcode so you can make different stuff.
Do the same with the Server now. For the OnHandshakeInbound method, we will send it to the client using base keyword (The Session class already applies it for us, and already has a SendHandshake method (-: ).
We are done! Almost.. now, what's left to do is listen for the MapleStory connection! The rest will be done for us. You can do it in the Form's Load Event. Not only listen - but to also initialize GMSKeys (A class Diamondo created to obtain MapleStory keys from a remote txt file).
The OnPacketInbound method is called when data is received (a packet). We are not touching the packet, we're sending it straight to the server, as if we were the original client. Remember you can also read the opcode so you can make different stuff.
You must be registered to see links
Do the same with the Server now. For the OnHandshakeInbound method, we will send it to the client using base keyword (The Session class already applies it for us, and already has a SendHandshake method (-: ).
You must be registered to see links
We are done! Almost.. now, what's left to do is listen for the MapleStory connection! The rest will be done for us. You can do it in the Form's Load Event. Not only listen - but to also initialize GMSKeys (A class Diamondo created to obtain MapleStory keys from a remote txt file).
You must be registered to see links
Credits:
- Fraysa - Writing and creating the tutorial.
- Diamondo25 - Great help.
- Unknown - Motivation.. I think.
You must be registered to see links
Please post any questions here, I'd love to answer!
Last edited: