--- a/net/minecraft/server/HandshakeListener.java +++ b/net/minecraft/server/HandshakeListener.java @@ -1,7 +1,17 @@ package net.minecraft.server; +// CraftBukkit start +import java.net.InetAddress; +import java.util.HashMap; +// CraftBukkit end + public class HandshakeListener implements PacketHandshakingInListener { + // CraftBukkit start - add fields + private static final HashMap throttleTracker = new HashMap(); + private static int throttleCounter = 0; + // CraftBukkit end + private final MinecraftServer a; private final NetworkManager b; @@ -11,21 +21,58 @@ } public void a(PacketHandshakingInSetProtocol packethandshakinginsetprotocol) { + this.b.channel.pipeline().get(PacketEncoder.class).version = packethandshakinginsetprotocol.b(); // CraftBukkit switch (HandshakeListener.SyntheticClass_1.a[packethandshakinginsetprotocol.a().ordinal()]) { case 1: this.b.setProtocol(EnumProtocol.LOGIN); ChatComponentText chatcomponenttext; + // CraftBukkit start - Connection throttle + try { + long currentTime = System.currentTimeMillis(); + long connectionThrottle = MinecraftServer.getServer().server.getConnectionThrottle(); + InetAddress address = ((java.net.InetSocketAddress) this.b.getSocketAddress()).getAddress(); + + synchronized (throttleTracker) { + if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) { + throttleTracker.put(address, currentTime); + chatcomponenttext = new ChatComponentText("Connection throttled! Please wait before reconnecting."); + this.b.sendPacket(new PacketLoginOutDisconnect(chatcomponenttext)); + this.b.close(chatcomponenttext); + return; + } + + throttleTracker.put(address, currentTime); + throttleCounter++; + if (throttleCounter > 200) { + throttleCounter = 0; + + // Cleanup stale entries + java.util.Iterator iter = throttleTracker.entrySet().iterator(); + while (iter.hasNext()) { + java.util.Map.Entry entry = (java.util.Map.Entry) iter.next(); + if (entry.getValue() > connectionThrottle) { + iter.remove(); + } + } + } + } + } catch (Throwable t) { + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); + } + // CraftBukkit end + if (packethandshakinginsetprotocol.b() > 109) { chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.9.2"); this.b.sendPacket(new PacketLoginOutDisconnect(chatcomponenttext)); this.b.close(chatcomponenttext); - } else if (packethandshakinginsetprotocol.b() < 109) { + } else if (packethandshakinginsetprotocol.b() < 107) { chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.9.2"); this.b.sendPacket(new PacketLoginOutDisconnect(chatcomponenttext)); this.b.close(chatcomponenttext); } else { this.b.setPacketListener(new LoginListener(this.a, this.b)); + ((LoginListener) this.b.i()).hostname = packethandshakinginsetprotocol.hostname + ":" + packethandshakinginsetprotocol.port; // CraftBukkit - set hostname } break;