@Override public void disconnecting(DisconnectingEvent event) { MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol(); if (protocol.getSubProtocol() == SubProtocol.LOGIN) { event.getSession().send(new LoginDisconnectPacket(event.getReason())); } else if (protocol.getSubProtocol() == SubProtocol.GAME) { event.getSession().send(new ServerDisconnectPacket(event.getReason())); } }
@Override public void packetReceived(PacketReceivedEvent event) { MinecraftProtocol protocol = (MinecraftProtocol) event.getSession().getPacketProtocol(); if (protocol.getSubProtocol() == SubProtocol.HANDSHAKE) { if (event.getPacket() instanceof HandshakePacket) { HandshakePacket packet = event.getPacket(); switch (packet.getIntent()) { case STATUS: protocol.setSubProtocol(SubProtocol.STATUS, false, event.getSession()); break; case LOGIN: protocol.setSubProtocol(SubProtocol.LOGIN, false, event.getSession()); if (packet.getProtocolVersion() > MinecraftConstants.PROTOCOL_VERSION) { event .getSession() .disconnect( "Outdated server! I'm still on " + MinecraftConstants.GAME_VERSION + "."); } else if (packet.getProtocolVersion() < MinecraftConstants.PROTOCOL_VERSION) { event .getSession() .disconnect( "Outdated client! Please use " + MinecraftConstants.GAME_VERSION + "."); } break; default: throw new UnsupportedOperationException("Invalid client intent: " + packet.getIntent()); } } } if (protocol.getSubProtocol() == SubProtocol.LOGIN) { if (event.getPacket() instanceof LoginStartPacket) { this.username = event.<LoginStartPacket>getPacket().getUsername(); boolean verify = event.getSession().hasFlag(MinecraftConstants.VERIFY_USERS_KEY) ? event.getSession().<Boolean>getFlag(MinecraftConstants.VERIFY_USERS_KEY) : true; if (verify) { event .getSession() .send( new EncryptionRequestPacket( this.serverId, KEY_PAIR.getPublic(), this.verifyToken)); } else { new Thread(new UserAuthTask(event.getSession(), null)).start(); } } else if (event.getPacket() instanceof EncryptionResponsePacket) { EncryptionResponsePacket packet = event.getPacket(); PrivateKey privateKey = KEY_PAIR.getPrivate(); if (!Arrays.equals(this.verifyToken, packet.getVerifyToken(privateKey))) { event.getSession().disconnect("Invalid nonce!"); return; } SecretKey key = packet.getSecretKey(privateKey); protocol.enableEncryption(key); new Thread(new UserAuthTask(event.getSession(), key)).start(); } } if (protocol.getSubProtocol() == SubProtocol.STATUS) { if (event.getPacket() instanceof StatusQueryPacket) { ServerInfoBuilder builder = event.getSession().getFlag(MinecraftConstants.SERVER_INFO_BUILDER_KEY); if (builder == null) { builder = new ServerInfoBuilder() { @Override public ServerStatusInfo buildInfo(Session session) { return new ServerStatusInfo( VersionInfo.CURRENT, new PlayerInfo(0, 20, new GameProfile[] {}), Message.fromString("A Minecraft Server"), null); } }; } ServerStatusInfo info = builder.buildInfo(event.getSession()); event.getSession().send(new StatusResponsePacket(info)); } else if (event.getPacket() instanceof StatusPingPacket) { event .getSession() .send(new StatusPongPacket(event.<StatusPingPacket>getPacket().getPingTime())); } } if (protocol.getSubProtocol() == SubProtocol.GAME) { if (event.getPacket() instanceof ClientKeepAlivePacket) { ClientKeepAlivePacket packet = event.getPacket(); if (packet.getPingId() == this.lastPingId) { long time = System.currentTimeMillis() - this.lastPingTime; event.getSession().setFlag(MinecraftConstants.PING_KEY, time); } } } }