package handling.mina; import client.MapleClient; import handling.RecvPacketOpcode; import handling.SendPacketOpcode; import java.io.File; 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; import server.ServerProperties; import tools.FileoutputUtil; import tools.HexTool; import tools.StringUtil; import tools.data.input.ByteArrayByteStream; import tools.data.input.GenericLittleEndianAccessor; public final class MaplePacketEncoder implements ProtocolEncoder { @Override public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY); if (client != null) { byte[] input = (byte[]) message; if (ServerProperties.ShowPacket()) { int packetLen = input.length; int pHeader = readFirstByte(input); boolean 记录 = true; for (final SendPacketOpcode recv : SendPacketOpcode.values()) { if (recv.getValue() == pHeader) { if (SendPacketOpcode.isSpamHeader(recv)) {//暂时记录怪物和角色移动 记录 = false; } break; } } if (记录 ) { String pHeaderStr = Integer.toHexString(pHeader).toUpperCase(); pHeaderStr = StringUtil.getLeftPaddedStr(pHeaderStr, '0', 4); String op = lookupRecv(pHeader); String Recv = "[服务端发送] " + op + " [0x" + pHeaderStr + "] (" + packetLen + "字节) " + FileoutputUtil.CurrentReadable_Time() + "\r\n"; if (packetLen <= 60000) { String RecvTo = Recv + HexTool.toString(input) + "\r\n" + HexTool.toStringFromAscii(input); FileoutputUtil.packetLog(FileoutputUtil.PacketLog, RecvTo); System.out.print(Recv); if (!ServerProperties.SendPacket(op, pHeaderStr)) { String SendTos = "\r\n时间:" + FileoutputUtil.CurrentReadable_Time() + "\r\n"; if ((op.equals("GIVE_BUFF")) || (op.equals("CANCEL_BUFF"))) { FileoutputUtil.packetLog(FileoutputUtil.SkillBuff, SendTos + RecvTo); } else if (op.endsWith("PLAYER_INTERACTION")) { FileoutputUtil.packetLog(FileoutputUtil.玩家互动封包, SendTos + RecvTo); } } } else { FileoutputUtil.log(Recv + HexTool.toString(new byte[]{input[0], input[1]}) + "...\r\n"); } } } byte[] unencrypted = new byte[input.length]; System.arraycopy(input, 0, unencrypted, 0, input.length); byte[] ret = new byte[unencrypted.length + 4]; Lock mutex = client.getLock(); mutex.lock(); try { byte[] header = client.getSendCrypto().getPacketHeader(unencrypted.length); client.getSendCrypto().crypt(unencrypted); System.arraycopy(header, 0, ret, 0, 4); } finally { mutex.unlock(); } System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length); out.write(IoBuffer.wrap(ret)); } else { out.write(IoBuffer.wrap((byte[]) message)); } } @Override public void dispose(IoSession session) throws Exception { } private String lookupRecv(int val) { for (SendPacketOpcode op : SendPacketOpcode.values()) { if (op.getValue(false) == val) { return op.name(); } } return "UNKNOWN"; } private int readFirstByte(byte[] arr) { return new GenericLittleEndianAccessor(new ByteArrayByteStream(arr)).readByte(); } }