搜索替換：

package handling.mina;

import client.MapleClient;
import constants.ServerConstants;
import handling.SendPacketOpcode;

import tools.MapleAESOFB;
import tools.MapleCustomEncryption;
import tools.HexTool;
import tools.StringUtil;
import tools.data.input.GenericLittleEndianAccessor;
import tools.data.input.ByteArrayByteStream;

import java.util.concurrent.locks.Lock;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

public class MaplePacketEncoder implements ProtocolEncoder {

    @Override
    public void encode(final IoSession session, final Object message, final ProtocolEncoderOutput out) throws Exception {
	final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);

	if (client != null) {
	    final MapleAESOFB send_crypto = client.getSendCrypto();

	    final byte[] inputInitialPacket = ((byte[]) message);
            
	    if (ServerConstants.DEBUG) {
	        int packetLen = inputInitialPacket.length;
	        int pHeader = readFirstShort(inputInitialPacket);
	        String pHeaderStr = Integer.toHexString(pHeader).toUpperCase();
	        pHeaderStr = StringUtil.getLeftPaddedStr(pHeaderStr, '0', 4);
	        String op = lookupRecv(pHeader);
	        String Recv = "伺服端發送 " + op + " [" + pHeaderStr + "] (" + packetLen + ")\r\n";
	        if (packetLen <= 50000) {
	            //String RecvTo = Recv + HexTool.toString(inputInitialPacket) + "\r\n" + HexTool.toStringFromAscii(inputInitialPacket);//數據包解析
	            String RecvTo = Recv + HexTool.toString(inputInitialPacket);
	            System.out.println(RecvTo + "\r\n");
	        }
	    }
	    final byte[] unencrypted = new byte[inputInitialPacket.length];
	    System.arraycopy(inputInitialPacket, 0, unencrypted, 0, inputInitialPacket.length); // Copy the input > "unencrypted"
	    final byte[] ret = new byte[unencrypted.length + 4]; // Create new bytes with length = "unencrypted" + 4

	    final Lock mutex = client.getLock();
	    mutex.lock();
	    try {
		final byte[] header = send_crypto.getPacketHeader(unencrypted.length);
		MapleCustomEncryption.encryptData(unencrypted); // Encrypting Data
		send_crypto.crypt(unencrypted); // Crypt it with IV
		System.arraycopy(header, 0, ret, 0, 4); // Copy the header > "Ret", first 4 bytes
		System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length); // Copy the unencrypted > "ret"
                
		session.write(IoBuffer.wrap(ret));//除了第一次的封包發送, 其餘使用 IoSession 而不是 ProtocolEncoderOutput
	    } finally {
		mutex.unlock();
	    }
	} else { // no client object created yet, send unencrypted (hello)
	    out.write(IoBuffer.wrap(((byte[]) message)));
	}
    }

    @Override
    public void dispose(IoSession session) throws Exception {
	// nothing to do
    }

    private String lookupRecv(int val) {
        for (SendPacketOpcode op : SendPacketOpcode.values()) {
          if (op.getValue() == val) {
            return op.name();
          }
        }
        return "UNKNOWN";
      }

      private int readFirstShort(byte[] arr) {
        return new GenericLittleEndianAccessor(new ByteArrayByteStream(arr)).readShort();
      }
    }



搜索替換：

    @Override
    public void messageReceived(final IoSession session, final Object message) {
        if (message == null || session == null) {
            return;
        }
        final LittleEndianAccessor slea = new LittleEndianAccessor(new ByteArrayByteStream((byte[]) message));
        if (ServerConstants.DEBUG) {
            System.out.println("接收封包:[" + HexTool.toString((byte[]) message) + "]");
        }
        if (slea.available() < 2) {
            return;
        }
        final MapleClient c = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
        if (c == null || !c.isReceiving()) {
            return;
        }
        /*
        final StringBuilder sb = new StringBuilder("R: \n");
        sb.append(HexTool.toString((byte[]) message)).append("\n").append(HexTool.toStringFromAscii((byte[]) message));
        System.out.println(sb);
        */
        final short header_num = slea.readShort();

        for (final RecvPacketOpcode recv : RecvPacketOpcode.values()) {
            if (recv.getValue() == header_num) {
                if (recv.NeedsChecking()) {
                    if (ServerConstants.DEBUG) {
                    System.out.println("接收封包包頭:" + recv.name());
                    }
                    if (!c.isLoggedIn()) {
                        return;
                    }
                }
                try {
                    if (c.getPlayer() != null && c.isMonitored() && !blocked.contains(recv)) {
                        
                    }
                    //no login packets
                    if (Log_Packets && !blocked.contains(recv) && !sBlocked.contains(recv) && (cs || channel > -1)) {
                        //log(slea.toString(), recv.toString(), c, session);
                    }
                    handlePacket(recv, slea, c, cs);
                    //Log after the packet is handle. You'll see why =]
                } catch (NegativeArraySizeException e) {
                    //swallow, no one cares
                    if (!ServerConstants.Use_Fixed_IV) {
                        FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
                        FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\n" + slea.toString(true));
                    }
                } catch (ArrayIndexOutOfBoundsException e) {
                    //swallow, no one cares
                    if (!ServerConstants.Use_Fixed_IV) {
                        FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
                        FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\n" + slea.toString(true));
                    }
                } catch (Exception e) {
                    FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
                    FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\n" + slea.toString(true));
                }

                return;
            }
        }
    }