Files
2006Scape/2006Redone Server/src/redone/net/RS2ProtocolDecoder.java
T
2019-06-18 15:04:35 -04:00

146 lines
3.1 KiB
Java

package redone.net;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import redone.game.players.Client;
import redone.util.ISAACRandomGen;
public class RS2ProtocolDecoder extends CumulativeProtocolDecoder {
private final ISAACRandomGen isaac;
/**
* To make sure only the CodecFactory can initialise us.
*/
protected RS2ProtocolDecoder(ISAACRandomGen isaac) {
this.isaac = isaac;
}
/**
* Decodes a message.
*
* @param session
* @param in
* @param out
* @return
*/
@Override
protected boolean doDecode(IoSession session, ByteBuffer in,
ProtocolDecoderOutput out) throws Exception {
synchronized (session) {
/*
* Fetch the ISAAC cipher for this session.
*/
// ISAACRandomGen inCipher = ((Player)
// session.getAttribute("player")).getInStreamDecryption();
/*
* Fetch any cached opcodes and sizes, reset to -1 if not present.
*/
int opcode = (Integer) session.getAttribute("opcode");
int size = (Integer) session.getAttribute("size");
/*
* If the opcode is not present.
*/
if (opcode == -1) {
/*
* Check if it can be read.
*/
if (in.remaining() >= 1) {
/*
* Read and decrypt the opcode.
*/
opcode = in.get() & 0xFF;
opcode = opcode - isaac.getNextKey() & 0xFF;
/*
* Find the packet size.
*/
size = Client.PACKET_SIZES[opcode];
/*
* Set the cached opcode and size.
*/
session.setAttribute("opcode", opcode);
session.setAttribute("size", size);
} else {
/*
* We need to wait for more data.
*/
return false;
}
}
/*
* If the packet is variable-length.
*/
if (size == -1) {
/*
* Check if the size can be read.
*/
if (in.remaining() >= 1) {
/*
* Read the packet size and cache it.
*/
size = in.get() & 0xFF;
session.setAttribute("size", size);
} else {
/*
* We need to wait for more data.
*/
return false;
}
}
/*
* If the packet payload (data) can be read.
*/
if (in.remaining() >= size) {
/*
* Read it.
*/
byte[] data = new byte[size];
in.get(data);
ByteBuffer payload = ByteBuffer.allocate(data.length);
payload.put(data);
payload.flip();
/*
* Produce and write the packet object.
*/
out.write(new Packet(session, opcode, data));
/*
* Reset the cached opcode and sizes.
*/
session.setAttribute("opcode", -1);
session.setAttribute("size", -1);
/*
* Indicate we are ready to read another packet.
*/
return true;
}
/*
* We need to wait for more data.
*/
return false;
}
}
@Override
/**
* Releases resources used by this decoder.
* @param session
*/
public void dispose(IoSession session) throws Exception {
super.dispose(session);
}
}