Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

The Structure of OdinMS and its Relatives

Newbie Spellweaver
Joined
Aug 9, 2011
Messages
15
Reaction score
3
How OdinMS and Related Sources Work
This exploration details the heart of the OdinMS server, MINA.
If you want to get a better understanding of the inner workings of a server, this exploration is for you.
This exploration assumes you know a little about basic java terminology and coding.
The main files I will be exploring are MapleServerHandler and PacketProcessor
Please tell me if I can improve this "guide"​
Terms:
server: the java program running on your computer or vps
client: the localhost.exe or maplestory.exe on the player's computer
packet: a series of numbers representing information which is sent from the client to the server or from the server to the client
MINA: Apache MINA is the network code that an OdinMS server uses to deal with sending and receiving packets
console: (AKA bat or batch file) the black window that serves as the administrator's window into the server
packet handler: a java file which extracts information out of a packet and does "things" based on that information
"things": loading something from the database, getting information from an instantiated object, sending a packet back to the client, starting an event, etc.
heading: a number (short) that identifies the packet's category (meso drop, player move, etc.)
IOSession: an object that represents the connection between the server and the client
little-endian: Maple packets are little-endian so a sequence of numbers: 1, 2, 3, 4 in a packet would be "header, 4, 3, 2, 1". A little-endian accessor reads the packet from right to left so humans don't have to be confused doing it.

Sequence of events:
The client starts up and tries to establish a connection with the server (an IOSession).
If it is successful MINA calls the sessionOpened method of MapleServerHandler which usually displays a message to the console.
A MapleClient object is created which contains the player's account data and packet encryption data. It can be retrieved from the IOSession using the CLIENT_KEY.

Almost every action a player can perform on the client sends a packet to the server. When that happens, MINA calls the messageReceived method of MapleServerHandler.
If this is the first packet received for this client, the PacketProcessor is initialized.
Initializing the packet processor eventually calls the reset() method of PacketProcessor which assigns all the packet handlers to an array in order of their headings.
The messageReceived method extracts the header and sends the packet to the matching handler using its handlePacket method.

Once the packet arrives at the packet handler, various information is extracted from it using a little-endian accessor.
The structure of each packet varies wildly from header to header. Updating each packet handler is what takes the most time while updating a server to a new version.

Most packet handlers send a packet back to the client. They do this by calling the correct packet method from the MaplePacketCreator class and announcing the packet to the session.(IOSession.write(packet), MapleClient.announce(packet), MapleCharacter.announce(packet), etc.)

Hopefully this guide will give a basic sense of direction to new developers.
 
I'm sexy and I know it :)
Joined
Oct 21, 2008
Messages
811
Reaction score
350
Please tell me if I can improve this "guide"[/CENTER]

The client starts up and tries to establish a connection with the server (an IOSession).
If it is successful MINA calls the sessionOpened method of MapleServerHandler which usually displays a message to the console.
A MapleClient object is created which contains the player's account data and packet encryption data. It can be retrieved from the IOSession using the CLIENT_KEY.

Updating each packet handler is what takes the most time while updating a server to a new version.

You can make this guide so much better..
Come with examples of packets the client sends to the server and show exactly which methods are invoked, quote them literally, fill the packets in so people can see what they actually do with the packets.

What you're saying right now is "oh and this class is used and this method", without quoting those methods and showing how it's of any use.
Btw, updating packet handlers is not what takes the most time when updating a server to another version; the packet structures are.

I was going to write something like this for my tutorial but couldn't be fucked.
It is a nice tutorial but should be expanded with examples.
 
Joined
Aug 10, 2008
Messages
858
Reaction score
516
First of all, I feel there is no point to this guide since it really does not help anyone. The code is pretty easy to read and pretty much self-explanatory if you take the time to find how exactly everything works. Trying to educate people who would either care less/abuse material posted is a lose-lose situation.

A client can be any program that can readily interact with MapleStory server software.

Packets are a series of bytes (bytes, 8-bit data types, have a range of 0 to 255 unsigned, and -128 to 127 signed) that contain information relating to a specific operation (i.e. a specific opcode/header). Now, data types beyond a byte are stored in however many bytes they would need to be represented with (short - 16 bits (32 / 16 = 2 bytes), int - 32 bits (32 / 8 = 4 bytes), long - 64 bits (64 / 8 = 8 bytes)).
You can really just think of packets as instructions (that vary in the operation by header/opcode and sub-operations based on data inside the instruction) for a remote entity, since that is all they really are.

MINA is a networking API for use with, most notably, TCP and UDP. It is a fairly powerful API for many reasons, it is scalable (which means that multiple IoSessions are treated as a group for processing instead of treating them separately. This saves resources because it does not create separate threads for each session), and it provides a huge amount of possibilities when working with TCP/UDP.

A handler can be defined by a class in Java so long that it is a child to the supported class(es) used for handling packets.

You could have sufficed in just saying that the handler does a specific action/event with the information it receives, but whatever.

Announcing is sort of wrong to describe writing data, and it really should be just write, but just naming conventions I suppose.
 
Custom Title Activated
Loyal Member
Joined
Apr 29, 2008
Messages
1,297
Reaction score
509
On
little-endian: Maple packets are little-endian so a sequence of numbers: 1, 2, 3, 4 in a packet would be "header, 4, 3, 2, 1". A little-endian accessor reads the packet from right to left so humans don't have to be confused doing it.

So you're saying strings are read from right to left as well?
 
Custom Title Activated
Loyal Member
Joined
Aug 21, 2009
Messages
1,149
Reaction score
598
Honestly, I haven't read the whole thing. But I saw post above and wanted to quote this as well.

little-endian: Maple packets are little-endian so a sequence of numbers: 1, 2, 3, 4 in a packet would be "header, 4, 3, 2, 1". A little-endian accessor reads the packet from right to left so humans don't have to be confused doing it.

That's not right.

If you receive "1 2 3 4" as data, the big-endian result is not "4 3 2 1". The result is also 1 2 3 4. They are separated data. You got little-endian wrong.

If the data were "100 320 403 230" the big-endian result would be "001 023 304 032". That's now a big-endian correct conversion of these data.
 
Joined
Aug 10, 2008
Messages
858
Reaction score
516
Honestly, I haven't read the whole thing. But I saw post above and wanted to quote this as well.



That's not right.

If you receive "1 2 3 4" as data, the big-endian result is not "4 3 2 1". The result is also 1 2 3 4. They are separated data. You got little-endian wrong.

If the data were "100 320 403 230" the big-endian result would be "001 023 304 032". That's now a big-endian correct conversion of these data.

Endianess only describes the order of bytes/bits in a series and not the values of the data. For example, take any byte value and have it in both little and big endian format for their bits, the values are still equivalent, it is just the bits are in a different order. Your example could be wrong and right for a couple reasons. It is wrong because the numeric value of data does not change just because of its bit orientation in a sequence, and it is also wrong because if they were individual bytes that form a primitive their order in the series would change based on the format of the series. It could be considered correct, however, if all it utilized was 0s and 1s (since we live in the real world and not Osiris' make-believe world where a single bit can be more than 2 values) like the following transformation:
"0001 1000 0100 0010" to
"1000 0001 0010 0100"
They would still be the same values, just the way it is read and represented is different.

Side note: You could use any type of byte order (little, big, mixed, etc.) for primitives with more than 8 bits as long as the equivalent steps are used to obtain the intended data.

@Xerixe:
You can interpret anything from left to right. It doesn't mean that it is true in this scenario, but it is possible. It is not correct to the definition of little-endian for strings to be read that way of course.

little-endian: Maple packets are little-endian so a sequence of numbers: 1, 2, 3, 4 in a packet would be "header, 4, 3, 2, 1". A little-endian accessor reads the packet from right to left so humans don't have to be confused doing it.
I would also like to comment that hex is fairly easy to work with. In fact, it is fairly easy to plug in hex to get decimal values. It is crucial that you identify what the values of data are for certain packet structures without having to go through an analysis with an interpreter while upgrading versions. Otherwise, you will be stuck trying to decode the same packet for longer than you really should have to.
 
Newbie Spellweaver
Joined
Apr 9, 2019
Messages
8
Reaction score
5
Hey guys, sorry for necroing this thread, but I really wanted to say this: thank you. I had figured much of this by bashing my head at Netbeans and printing everything to see how the flow worked, but it's nice to see a confirmation of what I've found. I've been stuck with a bug and I have been trying to pinpoint it in code, still to no avail. With this thread, I have a new hope of solving it, because I was just looking at packets sent to the server, but not the ones sent to the client.

This tutorial might seem to have no point for people already in the private maple scene, but it helped me, a novice. Thank you.
 
Back
Top