mirror of
https://github.com/2006-Scape/2006Scape.git
synced 2026-07-05 00:31:57 +00:00
146 lines
3.1 KiB
Java
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);
|
|
}
|
|
|
|
}
|