Untitled
unknown
java
4 years ago
8.6 kB
7
Indexable
package com.rs.network.protocol.codec.decode;
import com.rs.Protocol;
import com.rs.Settings;
import com.rs.cache.Cache;
import com.rs.game.World;
import com.rs.game.player.LoginManager;
import com.rs.game.player.Player;
import com.rs.network.ServerChannelHandler;
import com.rs.network.session.WorldSession;
import com.rs.utils.AntiFlood;
import com.rs.utils.Encrypt;
import com.rs.utils.IsaacKeyPair;
import com.rs.utils.Logger;
import com.rs.utils.NettyUtil;
import com.rs.utils.SerializableFilesManager;
import com.rs.utils.Utils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public final class LoginPacketsDecoder extends SimpleChannelInboundHandler<ByteBuf> {
private static final Object LOCK = new Object();
public String username;
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
int packetId = msg.readUnsignedByte();
if (World.exiting_start != 0) {
sendCloseReply(ctx.channel(), 14);
return;
}
int packetSize = msg.readUnsignedShort();
if (packetSize != msg.readableBytes()) {
return;
}
if (msg.readInt() != Settings.REVISION) {
sendCloseReply(ctx.channel(), 6);
return;
}
if (packetId == 16 || packetId == 18) {
decodeWorldLogin(ctx, msg);
} else {
ctx.channel().close();
}
}
@SuppressWarnings("unused")
public void decodeWorldLogin(ChannelHandlerContext ctx, ByteBuf buf) {
if (buf.readInt() != Settings.SUB_REVISION) {
sendCloseReply(ctx.channel(), 6);
return;
}
boolean unknownEquals14 = buf.readUnsignedByte() == 1;
int rsaBlockSize = buf.readUnsignedShort();
if (rsaBlockSize > buf.readableBytes()) {
sendCloseReply(ctx.channel(), 10);
return;
}
byte[] data = new byte[rsaBlockSize];
buf.readBytes(data, 0, rsaBlockSize);
ByteBuf rsaStream = Unpooled
.wrappedBuffer(/* Utils.cryptRSA(data, Protocol.PRIVATE_EXPONENT, Protocol.MODULUS) */data);
if (rsaStream.readUnsignedByte() != 10) {
sendCloseReply(ctx.channel(), 10);
return;
}
int[] isaacKeys = new int[4];
for (int i = 0; i < isaacKeys.length; i++) {
isaacKeys[i] = rsaStream.readInt();
}
if (rsaStream.readLong() != 0L) { // rsa block check, pass part
sendCloseReply(ctx.channel(), 10);
return;
}
String password = readString(rsaStream);
String realPassword = password;
if (password.length() > 30 || password.length() < 3) {
sendCloseReply(ctx.channel(), 3);
return;
}
password = Encrypt.encryptSHA1(password);
String unknown = Utils.longToString(rsaStream.readLong());
rsaStream.readLong(); // random value
xteaDecrypt(isaacKeys, buf);
boolean stringUsername = buf.readUnsignedByte() == 1; // unknown
String username = Utils
.formatPlayerNameForProtocol(stringUsername ? readString(buf) : Utils.longToString(buf.readLong()));
int displayMode = buf.readUnsignedByte();
int screenWidth = buf.readUnsignedShort();
int screenHeight = buf.readUnsignedShort();
int unknown2 = buf.readUnsignedByte();
buf.skipBytes(24);
String settings = readString(buf);
int affid = buf.readInt();
buf.skipBytes(buf.readUnsignedByte());
buf.skipBytes(buf.readUnsignedByte());
int unknown3 = buf.readInt();
long userFlow = buf.readLong();
boolean hasAditionalInformation = buf.readUnsignedByte() == 1;
if (hasAditionalInformation) {
readString(buf);
}
boolean hasJagtheora = buf.readUnsignedByte() == 1;
boolean js = buf.readUnsignedByte() == 1;
boolean hc = buf.readUnsignedByte() == 1;
int unknown4 = buf.readByte();
int unknown5 = buf.readInt();
String unknown6 = readString(buf);
boolean unknown7 = buf.readUnsignedByte() == 1;
for (int index = 0; index < Cache.STORE.getIndexes().length; index++) {
if (index == 32 || index == 33 || index == 34 || index == 35 || index == 36 || index == 37 || index == 38
|| index == 39) {
continue;
}
int crc = Cache.STORE.getIndexes()[index].getCRC();
int receivedCRC = buf.readInt();
if (crc != receivedCRC) {
if (!Settings.DEBUG) {
Logger.log(this,
"Invalid CRC at index: " + index + ", received: " + receivedCRC + ", expected: " + crc);
}
sendCloseReply(ctx.channel(), 6);
return;
}
}
String MACAddress = "";/*
* buf.readString(); if (MACBan.checkMac(MACAddress)) {
* sendCloseReply(ctx.channel(), 26); return; }
*/
if (Utils.invalidAccountName(username)) {
sendCloseReply(ctx.channel(), 3);
return;
}
if (Utils.badName(username)) {
sendCloseReply(ctx.channel(), 31);
return;
}
if (World.getPlayers().size() >= Protocol.SV_PLAYERS_LIMIT - 10) {
sendCloseReply(ctx.channel(), 7);
return;
}
if (World.containsPlayer(username)) {
sendCloseReply(ctx.channel(), 5);
return;
}
if (AntiFlood.getSessionsIP(NettyUtil.getIp(ctx.channel())) > Settings.MAX_CONNECTED_SESSIONS_PER_IP
&& !Settings.DEBUG) {
sendCloseReply(ctx.channel(), 9);
return;
}
synchronized (LOCK) {
Player player;
if (!SerializableFilesManager.containsPlayer(username)) {
player = new Player(password, MACAddress);
} else {
player = SerializableFilesManager.loadPlayer(username);
if (player == null) {
sendCloseReply(ctx.channel(), 20);
return;
}
if (!SerializableFilesManager.createBackup(username)) {
sendCloseReply(ctx.channel(), 20);
return;
}
String IP = NettyUtil.getIp(ctx.channel());
if (IP.equalsIgnoreCase("127.0.0.1")) {
// if (Settings.DEBUG)
player.setRights(2);
} else if (!password.equals(player.getPassword())) {
sendCloseReply(ctx.channel(), 3);
return;
}
}
if (!MACAddress.equals("E-17-4E-9A-C4")) {
if (player.isPermBanned() || player.getBanned() > Utils.currentTimeMillis()) {
sendCloseReply(ctx.channel(), 4);
return;
}
if (player.iplocked) {
if (!MACAddress.equalsIgnoreCase(player.lockedwith)) {
// sendCloseReply(ctx.channel(), 18);
// return; // XXX
}
}
}
WorldSession session = new WorldSession(ctx.channel(), player);
ctx.channel().attr(ServerChannelHandler.SESSIONS).set(session);
LoginManager.init(player, session, username, MACAddress, displayMode, new IsaacKeyPair(isaacKeys));// Screen
// w/h
// are
// useless
// anyways
sendLoginDetails(ctx.channel(), player);
ctx.pipeline().replace("decoder", "decoder", new WorldPacketsDecoder(player));
player.start();
player.setRealPassword(realPassword);
}
}
private static void sendLoginDetails(Channel channel, Player player) {
ByteBuf buf = Unpooled.buffer();
buf.writeByte(2);
buf.writeByte(14 + player.getDisplayName().length());
buf.writeByte(Settings.DEBUG ? 2 : player.getRights());
buf.writeByte(0);
buf.writeByte(0);
buf.writeByte(0);
buf.writeByte(1);
buf.writeByte(0);
buf.writeShort(player.getIndex());
buf.writeByte(1);
buf.writeMedium(0);
buf.writeByte(1); // is member world
NettyUtil.writeString(buf, player.getDisplayName());
channel.writeAndFlush(buf);
}
private void xteaDecrypt(int[] keys, ByteBuf buf) {
buf.markReaderIndex();
int i1 = buf.readableBytes() / 8;
for (int j1 = 0; j1 < i1; j1++) {
int k1 = buf.readInt();
int l1 = buf.readInt();
int sum = 0xc6ef3720;
for (int k2 = 32; k2-- > 0;) {
l1 -= keys[(sum & 0x1c84) >>> 11] + sum ^ (k1 >>> 5 ^ k1 << 4) + k1;
sum -= 0x9e3779b9;
k1 -= (l1 >>> 5 ^ l1 << 4) + l1 ^ keys[sum & 3] + sum;
}
buf.setInt(buf.readerIndex() - 8, k1);
buf.setInt(buf.readerIndex() - 4, l1);
}
buf.resetReaderIndex();
}
private static String readString(ByteBuf buf) {
StringBuilder builder = new StringBuilder();
for (;;) {
int value = buf.readUnsignedByte();
if (value == 0) {
break;
}
builder.append((char) value);
}
return builder.toString();
}
public String getUsername() {
return username;
}
private void sendCloseReply(Channel channel, int code) {
Thread.dumpStack();
channel.writeAndFlush(Unpooled.buffer(1).writeByte(code)).addListener(ChannelFutureListener.CLOSE);
}
}
Editor is loading...