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!

Building a Custom Source from Scratch but have hit a issue

Junior Spellweaver
Joined
Jun 29, 2009
Messages
139
Reaction score
12
EDIT: Managed to fix it. My IV's were mixed up. Thanks all!

I'm currently creating a maplestory source from essentially scratch. I say essentially because I am ripping some of the encryption related stuff from Moople because I think it would be a waste of time for me to not.
I can currently decode packets perfectly but am having trouble sending a packet of any time. The only packet the client will accept is the handshake and after that anything will cause it to crash.
This is my packet encoder which is very, very similar to Moople's:
Code:
	@Override
	protected void encode(ChannelHandlerContext ctx, byte[] message, ByteBuf out) throws Exception {
		MapleClient client = handler.getClient();
		if (client != null) {
			final MapleAESOFB send_crypto = client.getCryptSend();
			final byte[] input = (byte[]) message;
			final byte[] unencrypted = new byte[input.length];
			System.arraycopy(input, 0, unencrypted, 0, input.length);
			final byte[] ret = new byte[unencrypted.length + 4];
			final byte[] header = send_crypto
					.getPacketHeader(unencrypted.length);
			MapleCustomEncryption.encryptData(unencrypted);

			send_crypto.crypt(unencrypted);
			System.arraycopy(header, 0, ret, 0, 4);
			System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length);
			out.writeBytes(ret);

		} else {
			out.writeBytes(message);
		}

	}

There's nothing to fancy about it. All the encryption classes are completely untouched from the ones from Moople so I am almost sure it has to be something I am doing wrong in the encoder. Any ideas or knowledge on something the client requires before I can send it packets?
 
Last edited:
Elite Diviner
Joined
Mar 24, 2015
Messages
426
Reaction score
416
Are you using the iv's you sent them with your handshake? Have you tried stepping through it with the debugger to check if everything comes out right?
Also that's alot of unneccessary copying for one packet.
 
Upvote 0
Custom Title Activated
Loyal Member
Joined
Jan 18, 2010
Messages
3,108
Reaction score
1,140
If you're going to use beautiful Netty, don't copy MINA's abilities directly.

PHP:
@Override
    protected void encode(ChannelHandlerContext ctx, byte[] message, ByteBuf out) throws Exception {
        byte[] input = (byte[]) message;
        byte[] unencrypted = Arrays.copyOf(input, input.length);
        out.writeBytes(client.getSendCrypto().getPacketHeader(unencrypted.length));
        SeedEncrypt(unencrypted);//this is shanda encryption here; OdinMS calls the class MapleCustomEncryption.
        client.getSendCrypto().crypt(unencrypted);
        out.writeBytes(unencrypted);
    }

Also, your implementation of Netty must be wrong. The handshake is never sent within the encode, it is specifically called when a channel becomes active; you just write (and flush!) an unwrapped buffer of the handshake directly there.

As Journey said, make sure you're using correct IV's. Odin hardcodes the same IV btw, even though you're supposed to randomize the sequence; you can do this if you're writing your source from scratch and care to. But your IV shifts have to be exact so that they change when the client changes them. If your MapleAES is correct and untouched, and you've properly sent the handshake packet, then the packets should be sent properly. Try debugging it a bit.
 
Upvote 0
Junior Spellweaver
Joined
Jun 29, 2009
Messages
139
Reaction score
12
Thanks for the advice. My code was originally 'netty-er' but because it never seemed to work I tried to copy Mooples encoder as exactly as possible. I'll double check my send IV to make sure it is being done correctly. I was originally debugging it by stepping through each part of the encoding but I don't have any data to cross-check it with.

I tried using MapleShark but it automatically decodes packets so I couldn't use that to compare it to a Moople Source. However, I can probably just force a moople source to print out some encoded data. I'll give it another go and report back here if I can manage to get it to work.

Thanks for the advice :)

Here's my code for constructing the Handshake Packet:
Code:
 [USER=2000182178]Sneaky[/USER]Throws
	public static byte[] getHandshakePacket(int version, byte[] recvIv, byte[] sendIv, int locale){
		ByteBuf buf = Unpooled.buffer(16).order(ByteOrder.LITTLE_ENDIAN);
		
        buf.writeShort(0x0E);
        buf.writeShort(version);
        buf.writeShort(1);
        buf.writeByte(49);
        buf.writeBytes(recvIv);
        buf.writeBytes(sendIv);
        buf.writeByte(8);
		
		return buf.array();

	}
 
Last edited:
Upvote 0
Junior Spellweaver
Joined
Jun 29, 2009
Messages
139
Reaction score
12
[STRIKE]Thanks for your help earlier, but I have run into another problem, maybe you might know how to fix it? I've got the character creator working with PIC working as well. However, once a player actually enters the pic and connects to the Channel I run into an issue. As soon as I send the SET_FIELD packet the client crashes. I've checked my packet with another servers packet and they are similar enough that I believe its structured correctly. I even tried sending the exact packet that the other server used. Could this be another problem with IV? I'm unsure because reconnecting to the login screen works so I wouldn't know why the channel wouldn't work since they are using the same code. Any ideas? Is there a prerequisite packet that needs to be sent before the SET_FIELD packet?

EDIT: It looks like the IV's are working because if I send a ping packet I immediately get one back.[/STRIKE]

FIXED IT! I didn't realize I wasn't initializing the players hp / max hp variable. It was telling the client the player had 0 max hp so my hunch is that the client tried to divide by 0 then crashed.
 
Last edited:
Upvote 0
Joined
Nov 9, 2012
Messages
608
Reaction score
164
Thanks for the advice. My code was originally 'netty-er' but because it never seemed to work I tried to copy Mooples encoder as exactly as possible. I'll double check my send IV to make sure it is being done correctly. I was originally debugging it by stepping through each part of the encoding but I don't have any data to cross-check it with.

I tried using MapleShark but it automatically decodes packets so I couldn't use that to compare it to a Moople Source. However, I can probably just force a moople source to print out some encoded data. I'll give it another go and report back here if I can manage to get it to work.

Thanks for the advice :)

Here's my code for constructing the Handshake Packet:
Code:
 [USER=2000182178]Sneaky[/USER]Throws
	public static byte[] getHandshakePacket(int version, byte[] recvIv, byte[] sendIv, int locale){
		ByteBuf buf = Unpooled.buffer(16).order(ByteOrder.LITTLE_ENDIAN);
		
        buf.writeShort(0x0E);
        buf.writeShort(version);
        buf.writeShort(1);
        buf.writeByte(49);
        buf.writeBytes(recvIv);
        buf.writeBytes(sendIv);
        buf.writeByte(8);
		
		return buf.array();

	}
What I would do is I would send the ByteBuf instead of an array of bytes. The reason why I would do that is because with ByteBuf you can both read and write whats in the byte stream.

Code:
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		Client c = new Client(ctx.channel());
		ByteBuf buffer = (ByteBuf) msg;
		if (buffer.readableBytes() < 1) {
			return;
		}
		short code = buffer.readShort();
		PacketHandler handler = processor.getHandler(code);
		if (handler != null && handler.isLoggedIn(c)) {
			handler.handlePacket(c, buffer);
		}
	}
 
Upvote 0
Back
Top