From 3a3b6b6f98de98e8d3a277a4160a238951f607d8 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 7 May 2019 23:32:51 +0100 Subject: [PATCH 01/39] Initial RakNet refactor --- pom.xml | 23 +- src/main/java/cn/nukkit/Player.java | 26 +- src/main/java/cn/nukkit/Server.java | 81 +-- .../nukkit/command/defaults/BanIpCommand.java | 8 +- .../command/defaults/PardonIpCommand.java | 10 +- .../event/player/PlayerCreationEvent.java | 19 +- .../network/AdvancedSourceInterface.java | 13 +- .../network/CacheEncapsulatedPacket.java | 25 - .../nukkit/network/CompressBatchedPacket.java | 10 +- .../nukkit/network/CompressBatchedTask.java | 10 +- src/main/java/cn/nukkit/network/Network.java | 35 +- .../cn/nukkit/network/RakNetInterface.java | 361 +++++------- .../nukkit/network/protocol/BatchPacket.java | 9 - .../nukkit/network/protocol/DataPacket.java | 7 +- .../cn/nukkit/network/query/QueryHandler.java | 58 +- src/main/java/cn/nukkit/raknet/RakNet.java | 120 ---- .../raknet/protocol/AcknowledgePacket.java | 107 ---- .../cn/nukkit/raknet/protocol/DataPacket.java | 65 -- .../raknet/protocol/EncapsulatedPacket.java | 138 ----- .../cn/nukkit/raknet/protocol/Packet.java | 186 ------ .../cn/nukkit/raknet/protocol/packet/ACK.java | 27 - .../protocol/packet/ADVERTISE_SYSTEM.java | 25 - .../packet/CLIENT_CONNECT_DataPacket.java | 45 -- .../packet/CLIENT_DISCONNECT_DataPacket.java | 25 - .../packet/CLIENT_HANDSHAKE_DataPacket.java | 54 -- .../raknet/protocol/packet/DATA_PACKET_0.java | 27 - .../raknet/protocol/packet/DATA_PACKET_1.java | 27 - .../raknet/protocol/packet/DATA_PACKET_2.java | 27 - .../raknet/protocol/packet/DATA_PACKET_3.java | 27 - .../raknet/protocol/packet/DATA_PACKET_4.java | 27 - .../raknet/protocol/packet/DATA_PACKET_5.java | 27 - .../raknet/protocol/packet/DATA_PACKET_6.java | 27 - .../raknet/protocol/packet/DATA_PACKET_7.java | 27 - .../raknet/protocol/packet/DATA_PACKET_8.java | 27 - .../raknet/protocol/packet/DATA_PACKET_9.java | 27 - .../raknet/protocol/packet/DATA_PACKET_A.java | 27 - .../raknet/protocol/packet/DATA_PACKET_B.java | 27 - .../raknet/protocol/packet/DATA_PACKET_C.java | 27 - .../raknet/protocol/packet/DATA_PACKET_D.java | 27 - .../raknet/protocol/packet/DATA_PACKET_E.java | 27 - .../raknet/protocol/packet/DATA_PACKET_F.java | 27 - .../nukkit/raknet/protocol/packet/NACK.java | 27 - .../packet/OPEN_CONNECTION_REPLY_1.java | 47 -- .../packet/OPEN_CONNECTION_REPLY_2.java | 54 -- .../packet/OPEN_CONNECTION_REQUEST_1.java | 46 -- .../packet/OPEN_CONNECTION_REQUEST_2.java | 53 -- .../protocol/packet/PING_DataPacket.java | 39 -- .../protocol/packet/PONG_DataPacket.java | 39 -- .../packet/SERVER_HANDSHAKE_DataPacket.java | 59 -- .../protocol/packet/UNCONNECTED_PING.java | 41 -- .../UNCONNECTED_PING_OPEN_CONNECTIONS.java | 25 - .../protocol/packet/UNCONNECTED_PONG.java | 48 -- .../cn/nukkit/raknet/server/RakNetServer.java | 106 ---- .../nukkit/raknet/server/ServerHandler.java | 182 ------ .../nukkit/raknet/server/ServerInstance.java | 22 - .../java/cn/nukkit/raknet/server/Session.java | 555 ------------------ .../nukkit/raknet/server/SessionManager.java | 513 ---------------- .../nukkit/raknet/server/UDPServerSocket.java | 101 ---- 58 files changed, 314 insertions(+), 3562 deletions(-) delete mode 100644 src/main/java/cn/nukkit/network/CacheEncapsulatedPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/RakNet.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/AcknowledgePacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/EncapsulatedPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/Packet.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/ACK.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/ADVERTISE_SYSTEM.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_CONNECT_DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_DISCONNECT_DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_HANDSHAKE_DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_0.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_1.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_2.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_3.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_4.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_5.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_6.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_7.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_8.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_9.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_A.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_B.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_C.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_D.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_E.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_F.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/NACK.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_1.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_2.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_1.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_2.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/PING_DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/PONG_DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/SERVER_HANDSHAKE_DataPacket.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING_OPEN_CONNECTIONS.java delete mode 100644 src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PONG.java delete mode 100644 src/main/java/cn/nukkit/raknet/server/RakNetServer.java delete mode 100644 src/main/java/cn/nukkit/raknet/server/ServerHandler.java delete mode 100644 src/main/java/cn/nukkit/raknet/server/ServerInstance.java delete mode 100644 src/main/java/cn/nukkit/raknet/server/Session.java delete mode 100644 src/main/java/cn/nukkit/raknet/server/SessionManager.java delete mode 100644 src/main/java/cn/nukkit/raknet/server/UDPServerSocket.java diff --git a/pom.xml b/pom.xml index 9464bcd0b4b..7231177a461 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ nukkitx-repo-release - https://repo.nukkitx.com/release/ + https://repo.nukkitx.com/maven-releases/ true @@ -30,7 +30,7 @@ nukkitx-repo-snapshot - https://repo.nukkitx.com/snapshot/ + https://repo.nukkitx.com/maven-snapshots/ false @@ -54,6 +54,12 @@ + + com.nukkitx.network + raknet + 1.3.4 + compile + com.nukkitx fastutil-lite @@ -90,19 +96,6 @@ - - io.netty - netty-handler - 4.1.6.Final - compile - - - io.netty - netty-transport-native-epoll - 4.1.6.Final - compile - linux-x86_64 - org.junit.jupiter junit-jupiter-api diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index b73bcc61a0e..8d3048d7a91 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -162,10 +162,9 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde protected Vector3 teleportPosition = null; protected boolean connected = true; - protected final String ip; + protected final InetSocketAddress socketAddress; protected boolean removeFormat = true; - protected final int port; protected String username; protected String iusername; protected String displayName; @@ -596,14 +595,13 @@ public Map getEffectivePermissions() { return this.perm.getEffectivePermissions(); } - public Player(SourceInterface interfaz, Long clientID, String ip, int port) { + public Player(SourceInterface interfaz, Long clientID, InetSocketAddress socketAddress) { super(null, new CompoundTag()); this.interfaz = interfaz; this.perm = new PermissibleBase(this); this.server = Server.getInstance(); this.lastBreak = -1; - this.ip = ip; - this.port = port; + this.socketAddress = socketAddress; this.clientID = clientID; this.loaderId = Level.generateChunkLoaderId(this); this.chunksPerTick = this.server.getConfig("chunk-sending.per-tick", 4); @@ -665,11 +663,15 @@ public void setSkin(Skin skin) { } public String getAddress() { - return this.ip; + return this.socketAddress.getAddress().getHostAddress(); } public int getPort() { - return port; + return this.socketAddress.getPort(); + } + + public InetSocketAddress getSocketAddress() { + return this.socketAddress; } public Position getNextPosition() { @@ -2040,8 +2042,8 @@ protected void completeLoginSequence() { this.server.getLogger().info(this.getServer().getLanguage().translateString("nukkit.player.logIn", TextFormat.AQUA + this.username + TextFormat.WHITE, - this.ip, - String.valueOf(this.port), + this.getAddress(), + String.valueOf(this.getPort()), String.valueOf(this.id), this.level.getName(), String.valueOf(NukkitMath.round(this.x, 4)), @@ -2174,7 +2176,7 @@ public void handleDataPacket(DataPacket packet) { @Override public void onRun() { - e = new PlayerAsyncPreLoginEvent(username, uuid, ip, port); + e = new PlayerAsyncPreLoginEvent(username, uuid, Player.this.getAddress(), Player.this.getPort()); server.getPluginManager().callEvent(e); } @@ -3574,8 +3576,8 @@ public void close(TextContainer message, String reason, boolean notify) { this.spawned = false; this.server.getLogger().info(this.getServer().getLanguage().translateString("nukkit.player.logOut", TextFormat.AQUA + (this.getName() == null ? "" : this.getName()) + TextFormat.WHITE, - this.ip, - String.valueOf(this.port), + this.getAddress(), + String.valueOf(this.getPort()), this.getServer().getLanguage().translateString(reason))); this.windows.clear(); this.usedChunks.clear(); diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 241479b94f7..bfa2d0fe1f5 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -78,6 +78,7 @@ import co.aikar.timings.Timings; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; +import io.netty.buffer.ByteBuf; import lombok.extern.log4j.Log4j2; import org.iq80.leveldb.CompressionType; import org.iq80.leveldb.DB; @@ -88,6 +89,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; @@ -200,12 +204,10 @@ public class Server { private Config properties; private Config config; - private final Map players = new HashMap<>(); + private final Map players = new HashMap<>(); private final Map playerList = new HashMap<>(); - private final Map identifier = new HashMap<>(); - private final Map levels = new HashMap() { public Level put(Integer key, Level value) { Level result = super.put(key, value); @@ -418,13 +420,13 @@ public Level remove(Object key) { Nukkit.DEBUG = Math.max(this.getConfig("debug.level", 1), 1); - int logLevel = (Nukkit.DEBUG + 3) * 100; - for (org.apache.logging.log4j.Level level : org.apache.logging.log4j.Level.values()) { - if (level.intLevel() == logLevel) { - Nukkit.setLogLevel(level); - break; - } - } +// int logLevel = (Nukkit.DEBUG + 3) * 100; +// for (org.apache.logging.log4j.Level level : org.apache.logging.log4j.Level.values()) { +// if (level.intLevel() == logLevel) { +// Nukkit.setLogLevel(level); +// break; +// } +// } if (this.getConfig().getBoolean("bug-report", true)) { ExceptionHandler.registerExceptionHandler(); @@ -648,10 +650,6 @@ public static void broadcastPacket(Player[] players, DataPacket packet) { } else { getInstance().batchPackets(players, new DataPacket[]{packet}, true); } - - if (packet.encapsulatedPacket != null) { - packet.encapsulatedPacket = null; - } } public void batchPackets(Player[] players, DataPacket[] packets) { @@ -685,10 +683,10 @@ public void batchPackets(Player[] players, DataPacket[] packets, boolean forceSy size += payload[i * 2 + 1].length; } - List targets = new ArrayList<>(); + List targets = new ArrayList<>(); for (Player p : players) { if (p.isConnected()) { - targets.add(this.identifier.get(p.rawHashCode())); + targets.add(p.getSocketAddress()); } } @@ -705,11 +703,11 @@ public void batchPackets(Player[] players, DataPacket[] packets, boolean forceSy Timings.playerNetworkSendTimer.stopTiming(); } - public void broadcastPacketsCallback(byte[] data, List identifiers) { + public void broadcastPacketsCallback(byte[] data, List targets) { BatchPacket pk = new BatchPacket(); pk.payload = data; - for (String i : identifiers) { + for (InetSocketAddress i : targets) { if (this.players.containsKey(i)) { this.players.get(i).dataPacket(pk); } @@ -789,7 +787,11 @@ public void reload() { this.operators.reload(); for (BanEntry entry : this.getIPBans().getEntires().values()) { - this.getNetwork().blockAddress(entry.getName(), -1); + try { + this.getNetwork().blockAddress(InetAddress.getByName(entry.getName()), -1); + } catch (UnknownHostException e) { + // ignore + } } this.pluginManager.registerInterface(JavaPluginLoader.class); @@ -867,7 +869,11 @@ public void start() { } for (BanEntry entry : this.getIPBans().getEntires().values()) { - this.network.blockAddress(entry.getName(), -1); + try { + this.network.blockAddress(InetAddress.getByName(entry.getName()), -1); + } catch (UnknownHostException e) { + // ignore + } } //todo send usage setting @@ -881,15 +887,24 @@ public void start() { this.forceShutdown(); } - public void handlePacket(String address, int port, byte[] payload) { + public void handlePacket(InetSocketAddress address, ByteBuf payload) { try { - if (payload.length > 2 && Arrays.equals(Binary.subBytes(payload, 0, 2), new byte[]{(byte) 0xfe, (byte) 0xfd}) && this.queryHandler != null) { - this.queryHandler.handle(address, port, payload); + if (!payload.isReadable(3)) { + return; + } + byte[] prefix = new byte[2]; + payload.readBytes(prefix); + + if (!Arrays.equals(prefix, new byte[]{(byte) 0xfe, (byte) 0xfd})) { + return; + } + if (this.queryHandler != null) { + this.queryHandler.handle(address, payload); } } catch (Exception e) { log.error("Error whilst handling packet", e); - this.getNetwork().blockAddress(address, 600); + this.network.blockAddress(address.getAddress(), -1); } } @@ -946,9 +961,8 @@ public void onPlayerLogin(Player player) { } } - public void addPlayer(String identifier, Player player) { - this.players.put(identifier, player); - this.identifier.put(player.rawHashCode(), identifier); + public void addPlayer(InetSocketAddress socketAddress, Player player) { + this.players.put(socketAddress, player); } public void addOnlinePlayer(Player player) { @@ -1779,18 +1793,15 @@ public Player[] matchPlayer(String partialName) { } public void removePlayer(Player player) { - if (this.identifier.containsKey(player.rawHashCode())) { - String identifier = this.identifier.get(player.rawHashCode()); - this.players.remove(identifier); - this.identifier.remove(player.rawHashCode()); + Player toRemove = this.players.remove(player.getSocketAddress()); + if (toRemove != null) { return; } - for (String identifier : new ArrayList<>(this.players.keySet())) { - Player p = this.players.get(identifier); + for (InetSocketAddress socketAddress : new ArrayList<>(this.players.keySet())) { + Player p = this.players.get(socketAddress); if (player == p) { - this.players.remove(identifier); - this.identifier.remove(player.rawHashCode()); + this.players.remove(socketAddress); break; } } diff --git a/src/main/java/cn/nukkit/command/defaults/BanIpCommand.java b/src/main/java/cn/nukkit/command/defaults/BanIpCommand.java index 44a6c65d9f7..3a6f9f404fc 100644 --- a/src/main/java/cn/nukkit/command/defaults/BanIpCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/BanIpCommand.java @@ -13,6 +13,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.regex.Pattern; @@ -101,6 +103,10 @@ private void processIPBan(String ip, CommandSender sender, String reason) { } } - sender.getServer().getNetwork().blockAddress(ip, -1); + try { + sender.getServer().getNetwork().blockAddress(InetAddress.getByName(ip), -1); + } catch (UnknownHostException e) { + // ignore + } } } diff --git a/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java b/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java index 0fea580f328..bc61968664f 100644 --- a/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java @@ -5,6 +5,8 @@ import cn.nukkit.command.data.CommandParameter; import cn.nukkit.lang.TranslationContainer; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.regex.Pattern; /** @@ -39,7 +41,13 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args) if (Pattern.matches("^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$", value)) { sender.getServer().getIPBans().remove(value); - sender.getServer().getNetwork().unblockAddress(value); + + try { + sender.getServer().getNetwork().unblockAddress(InetAddress.getByName(value)); + } catch (UnknownHostException e) { + sender.sendMessage(new TranslationContainer("commands.unbanip.invalid")); + return true; + } Command.broadcastCommandMessage(sender, new TranslationContainer("commands.unbanip.success", value)); } else { diff --git a/src/main/java/cn/nukkit/event/player/PlayerCreationEvent.java b/src/main/java/cn/nukkit/event/player/PlayerCreationEvent.java index dd408ec13b5..be48b28a203 100644 --- a/src/main/java/cn/nukkit/event/player/PlayerCreationEvent.java +++ b/src/main/java/cn/nukkit/event/player/PlayerCreationEvent.java @@ -5,6 +5,8 @@ import cn.nukkit.event.HandlerList; import cn.nukkit.network.SourceInterface; +import java.net.InetSocketAddress; + /** * author: MagicDroidX * Nukkit Project @@ -21,19 +23,16 @@ public static HandlerList getHandlers() { private final Long clientId; - private final String address; - - private final int port; + private final InetSocketAddress socketAddress; private Class baseClass; private Class playerClass; - public PlayerCreationEvent(SourceInterface interfaz, Class baseClass, Class playerClass, Long clientId, String address, int port) { + public PlayerCreationEvent(SourceInterface interfaz, Class baseClass, Class playerClass, Long clientId, InetSocketAddress socketAddress) { this.interfaz = interfaz; this.clientId = clientId; - this.address = address; - this.port = port; + this.socketAddress = socketAddress; this.baseClass = baseClass; this.playerClass = playerClass; @@ -44,11 +43,15 @@ public SourceInterface getInterface() { } public String getAddress() { - return address; + return this.socketAddress.getAddress().toString(); } public int getPort() { - return port; + return this.socketAddress.getPort(); + } + + public InetSocketAddress getSocketAddress() { + return socketAddress; } public Long getClientId() { diff --git a/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java b/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java index 6902856b74c..6a982696c63 100644 --- a/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java +++ b/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java @@ -1,18 +1,23 @@ package cn.nukkit.network; +import io.netty.buffer.ByteBuf; + +import java.net.InetAddress; +import java.net.InetSocketAddress; + /** * author: MagicDroidX * Nukkit Project */ public interface AdvancedSourceInterface extends SourceInterface { - void blockAddress(String address); + void blockAddress(InetAddress address); - void blockAddress(String address, int timeout); + void blockAddress(InetAddress address, int timeout); - void unblockAddress(String address); + void unblockAddress(InetAddress address); void setNetwork(Network network); - void sendRawPacket(String address, int port, byte[] payload); + void sendRawPacket(InetSocketAddress socketAddress, ByteBuf payload); } diff --git a/src/main/java/cn/nukkit/network/CacheEncapsulatedPacket.java b/src/main/java/cn/nukkit/network/CacheEncapsulatedPacket.java deleted file mode 100644 index 4272d0d41e8..00000000000 --- a/src/main/java/cn/nukkit/network/CacheEncapsulatedPacket.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.nukkit.network; - -import cn.nukkit.raknet.protocol.EncapsulatedPacket; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class CacheEncapsulatedPacket extends EncapsulatedPacket { - - public byte[] internalData = null; - - @Override - public byte[] toBinary() { - return this.toBinary(false); - } - - @Override - public byte[] toBinary(boolean internal) { - if (this.internalData == null) { - this.internalData = super.toBinary(internal); - } - return this.internalData; - } -} \ No newline at end of file diff --git a/src/main/java/cn/nukkit/network/CompressBatchedPacket.java b/src/main/java/cn/nukkit/network/CompressBatchedPacket.java index 6cc6ab3f738..b45811951e2 100644 --- a/src/main/java/cn/nukkit/network/CompressBatchedPacket.java +++ b/src/main/java/cn/nukkit/network/CompressBatchedPacket.java @@ -4,7 +4,7 @@ import cn.nukkit.scheduler.AsyncTask; import cn.nukkit.utils.Zlib; -import java.util.ArrayList; +import java.net.InetSocketAddress; import java.util.List; /** @@ -17,17 +17,17 @@ public class CompressBatchedPacket extends AsyncTask { public byte[] data; public byte[] finalData; public int channel = 0; - public List targets = new ArrayList<>(); + public List targets; - public CompressBatchedPacket(byte[] data, List targets) { + public CompressBatchedPacket(byte[] data, List targets) { this(data, targets, 7); } - public CompressBatchedPacket(byte[] data, List targets, int level) { + public CompressBatchedPacket(byte[] data, List targets, int level) { this(data, targets, level, 0); } - public CompressBatchedPacket(byte[] data, List targets, int level, int channel) { + public CompressBatchedPacket(byte[] data, List targets, int level, int channel) { this.data = data; this.targets = targets; this.level = level; diff --git a/src/main/java/cn/nukkit/network/CompressBatchedTask.java b/src/main/java/cn/nukkit/network/CompressBatchedTask.java index bafffba677d..5f0880f4248 100644 --- a/src/main/java/cn/nukkit/network/CompressBatchedTask.java +++ b/src/main/java/cn/nukkit/network/CompressBatchedTask.java @@ -4,7 +4,7 @@ import cn.nukkit.scheduler.AsyncTask; import cn.nukkit.utils.Zlib; -import java.util.ArrayList; +import java.net.InetSocketAddress; import java.util.List; /** @@ -17,17 +17,17 @@ public class CompressBatchedTask extends AsyncTask { public byte[][] data; public byte[] finalData; public int channel = 0; - public List targets = new ArrayList<>(); + public List targets; - public CompressBatchedTask(byte[][] data, List targets) { + public CompressBatchedTask(byte[][] data, List targets) { this(data, targets, 7); } - public CompressBatchedTask(byte[][] data, List targets, int level) { + public CompressBatchedTask(byte[][] data, List targets, int level) { this(data, targets, level, 0); } - public CompressBatchedTask(byte[][] data, List targets, int level, int channel) { + public CompressBatchedTask(byte[][] data, List targets, int level, int channel) { this.data = data; this.targets = targets; this.level = level; diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java index 61191083c31..a5bac5936ef 100644 --- a/src/main/java/cn/nukkit/network/Network.java +++ b/src/main/java/cn/nukkit/network/Network.java @@ -7,7 +7,10 @@ import cn.nukkit.utils.Binary; import cn.nukkit.utils.BinaryStream; import cn.nukkit.utils.Zlib; +import io.netty.buffer.ByteBuf; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -95,9 +98,11 @@ public void registerInterface(SourceInterface interfaz) { interfaz.setName(this.name + "!@#" + this.subName); } - public void unregisterInterface(SourceInterface interfaz) { - this.interfaces.remove(interfaz); - this.advancedInterfaces.remove(interfaz); + public void unregisterInterface(SourceInterface sourceInterface) { + this.interfaces.remove(sourceInterface); + if (sourceInterface instanceof AdvancedSourceInterface) { + this.advancedInterfaces.remove(sourceInterface); + } } public void setName(String name) { @@ -198,25 +203,27 @@ public DataPacket getPacket(byte id) { return null; } - public void sendPacket(String address, int port, byte[] payload) { - for (AdvancedSourceInterface interfaz : this.advancedInterfaces) { - interfaz.sendRawPacket(address, port, payload); + public void sendPacket(InetSocketAddress socketAddress, ByteBuf payload) { + for (AdvancedSourceInterface sourceInterface : this.advancedInterfaces) { + sourceInterface.sendRawPacket(socketAddress, payload); } } - public void blockAddress(String address) { - this.blockAddress(address, 300); + public void blockAddress(InetAddress address) { + for (AdvancedSourceInterface sourceInterface : this.advancedInterfaces) { + sourceInterface.blockAddress(address); + } } - public void blockAddress(String address, int timeout) { - for (AdvancedSourceInterface interfaz : this.advancedInterfaces) { - interfaz.blockAddress(address, timeout); + public void blockAddress(InetAddress address, int timeout) { + for (AdvancedSourceInterface sourceInterface : this.advancedInterfaces) { + sourceInterface.blockAddress(address, timeout); } } - public void unblockAddress(String address) { - for (AdvancedSourceInterface interfaz : this.advancedInterfaces) { - interfaz.unblockAddress(address); + public void unblockAddress(InetAddress address) { + for (AdvancedSourceInterface sourceInterface : this.advancedInterfaces) { + sourceInterface.unblockAddress(address); } } diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 1f0ebbe1b5a..b2597db4091 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -1,6 +1,5 @@ package cn.nukkit.network; -import cn.nukkit.Nukkit; import cn.nukkit.Player; import cn.nukkit.Server; import cn.nukkit.event.player.PlayerCreationEvent; @@ -8,27 +7,38 @@ import cn.nukkit.network.protocol.BatchPacket; import cn.nukkit.network.protocol.DataPacket; import cn.nukkit.network.protocol.ProtocolInfo; -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.EncapsulatedPacket; -import cn.nukkit.raknet.protocol.packet.PING_DataPacket; -import cn.nukkit.raknet.server.RakNetServer; -import cn.nukkit.raknet.server.ServerHandler; -import cn.nukkit.raknet.server.ServerInstance; import cn.nukkit.utils.Binary; -import cn.nukkit.utils.MainLogger; import cn.nukkit.utils.Utils; import cn.nukkit.utils.Zlib; +import com.google.common.base.Strings; +import com.nukkitx.network.raknet.*; +import com.nukkitx.network.util.DisconnectReason; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.Map; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.Queue; +import java.util.Set; +import java.util.StringJoiner; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.TimeUnit; /** * author: MagicDroidX * Nukkit Project */ -public class RakNetInterface implements ServerInstance, AdvancedSourceInterface { +@Log4j2 +public class RakNetInterface implements RakNetServerListener, AdvancedSourceInterface { private final Server server; @@ -36,23 +46,18 @@ public class RakNetInterface implements ServerInstance, AdvancedSourceInterface private final RakNetServer raknet; - private final Map players = new ConcurrentHashMap<>(); + private Set sessionListeners = Collections.newSetFromMap(new ConcurrentHashMap<>()); - private final Map networkLatency = new ConcurrentHashMap<>(); - - private final Map identifiers = new ConcurrentHashMap<>(); - - private final Map identifiersACK = new ConcurrentHashMap<>(); - - private final ServerHandler handler; - - private int[] channelCounts = new int[256]; + private byte[] advertisement; public RakNetInterface(Server server) { this.server = server; - this.raknet = new RakNetServer(this.server.getLogger(), this.server.getPort(), this.server.getIp().equals("") ? "0.0.0.0" : this.server.getIp()); - this.handler = new ServerHandler(this.raknet, this); + InetSocketAddress bindAddress = new InetSocketAddress(Strings.isNullOrEmpty(this.server.getIp()) ? "0.0.0.0" : this.server.getIp(), this.server.getPort()); + + this.raknet = new RakNetServer(bindAddress); + this.raknet.bind().join(); + this.raknet.setListener(this); } @Override @@ -62,32 +67,19 @@ public void setNetwork(Network network) { @Override public boolean process() { - boolean work = false; - if (this.handler.handlePacket()) { - work = true; - while (this.handler.handlePacket()) { - + for (NukkitSessionListener listener : sessionListeners) { + DataPacket packet; + while ((packet = listener.packets.poll()) != null) { + listener.player.handleDataPacket(packet); } } - - return work; - } - - @Override - public void closeSession(String identifier, String reason) { - if (this.players.containsKey(identifier)) { - Player player = this.players.get(identifier); - this.identifiers.remove(player.rawHashCode()); - this.players.remove(identifier); - this.networkLatency.remove(identifier); - this.identifiersACK.remove(identifier); - player.close(player.getLeaveMessage(), reason); - } + return true; } @Override public int getNetworkLatency(Player player) { - return this.networkLatency.get(this.identifiers.get(player.rawHashCode())); + RakNetServerSession session = this.raknet.getSession(player.getSocketAddress()); + return session == null ? -1 : (int) session.getPing(); } @Override @@ -97,141 +89,61 @@ public void close(Player player) { @Override public void close(Player player, String reason) { - if (this.identifiers.containsKey(player.rawHashCode())) { - String id = this.identifiers.get(player.rawHashCode()); - this.players.remove(id); - this.networkLatency.remove(id); - this.identifiersACK.remove(id); - this.closeSession(id, reason); - this.identifiers.remove(player.rawHashCode()); + RakNetServerSession session = this.raknet.getSession(player.getSocketAddress()); + if (session != null) { + session.disconnect(); } } @Override public void shutdown() { - this.handler.shutdown(); + this.raknet.close(); } @Override public void emergencyShutdown() { - this.handler.emergencyShutdown(); + this.raknet.close(); } @Override - public void openSession(String identifier, String address, int port, long clientID) { - PlayerCreationEvent ev = new PlayerCreationEvent(this, Player.class, Player.class, null, address, port); - this.server.getPluginManager().callEvent(ev); - Class clazz = ev.getPlayerClass(); - - try { - Constructor constructor = clazz.getConstructor(SourceInterface.class, Long.class, String.class, int.class); - Player player = (Player) constructor.newInstance(this, ev.getClientId(), ev.getAddress(), ev.getPort()); - this.players.put(identifier, player); - this.networkLatency.put(identifier, 0); - this.identifiersACK.put(identifier, 0); - this.identifiers.put(player.rawHashCode(), identifier); - this.server.addPlayer(identifier, player); - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - Server.getInstance().getLogger().logException(e); - } + public void blockAddress(InetAddress address) { + this.raknet.block(address); } @Override - public void handleEncapsulated(String identifier, EncapsulatedPacket packet, int flags) { - if (this.players.containsKey(identifier)) { - DataPacket pk = null; - try { - if (packet.buffer.length > 0) { - if (packet.buffer[0] == PING_DataPacket.ID) { - PING_DataPacket pingPacket = new PING_DataPacket(); - pingPacket.buffer = packet.buffer; - pingPacket.decode(); - - this.networkLatency.put(identifier, (int) pingPacket.pingID); - return; - } - - pk = this.getPacket(packet.buffer); - if (pk != null) { - pk.decode(); - this.players.get(identifier).handleDataPacket(pk); - } - } - } catch (Exception e) { - this.server.getLogger().logException(e); - if (Nukkit.DEBUG > 1 && pk != null) { - MainLogger logger = this.server.getLogger(); -// if (logger != null) { - logger.debug("Packet " + pk.getClass().getName() + " 0x" + Binary.bytesToHexString(packet.buffer)); - //logger.logException(e); -// } - } - - if (this.players.containsKey(identifier)) { - this.handler.blockAddress(this.players.get(identifier).getAddress(), 5); - } - } - } - } - - @Override - public void blockAddress(String address) { - this.blockAddress(address, 300); - } - - @Override - public void blockAddress(String address, int timeout) { - this.handler.blockAddress(address, timeout); - } - - @Override - public void unblockAddress(String address) { - this.handler.unblockAddress(address); - } - - @Override - public void handleRaw(String address, int port, byte[] payload) { - this.server.handlePacket(address, port, payload); + public void blockAddress(InetAddress address, int timeout) { + this.raknet.block(address, timeout, TimeUnit.SECONDS); } @Override - public void sendRawPacket(String address, int port, byte[] payload) { - this.handler.sendRaw(address, port, payload); + public void unblockAddress(InetAddress address) { + this.raknet.unblock(address); } @Override - public void notifyACK(String identifier, int identifierACK) { - // TODO: Better ACK notification implementation! - for (Player p : server.getOnlinePlayers().values()) { - p.notifyACK(identifierACK); - } + public void sendRawPacket(InetSocketAddress socketAddress, ByteBuf payload) { + this.raknet.send(socketAddress, payload); } @Override public void setName(String name) { QueryRegenerateEvent info = this.server.getQueryInformation(); String[] names = name.split("!@#"); //Split double names within the program - this.handler.sendOption("name", - "MCPE;" + Utils.rtrim(names[0].replace(";", "\\;"), '\\') + ";" + - ProtocolInfo.CURRENT_PROTOCOL + ";" + - ProtocolInfo.MINECRAFT_VERSION_NETWORK + ";" + - info.getPlayerCount() + ";" + - info.getMaxPlayerCount() + ";" + - this.server.getServerUniqueId().toString() + ";" + - (names.length > 1 ? Utils.rtrim(names[1].replace(";", "\\;"), '\\') : "") + ";" + - Server.getGamemodeString(this.server.getDefaultGamemode(), true) + ";"); - } - - public void setPortCheck(boolean value) { - this.handler.sendOption("portChecking", String.valueOf(value)); - } - - @Override - public void handleOption(String name, String value) { - if ("bandwidth".equals(name)) { - String[] v = value.split(";"); - this.network.addStatistics(Double.valueOf(v[0]), Double.valueOf(v[1])); - } + String motd = Utils.rtrim(names[0].replace(";", "\\;"), '\\'); + String subMotd = names.length > 1 ? Utils.rtrim(names[1].replace(";", "\\;"), '\\') : ""; + StringJoiner joiner = new StringJoiner(";") + .add("MCPE") + .add(motd) + .add(Integer.toString(ProtocolInfo.CURRENT_PROTOCOL)) + .add(ProtocolInfo.MINECRAFT_VERSION_NETWORK) + .add(Integer.toString(info.getPlayerCount())) + .add(Integer.toString(info.getMaxPlayerCount())) + .add(Long.toString(this.raknet.getGuid())) + .add(subMotd) + .add(Server.getGamemodeString(this.server.getDefaultGamemode(), true)) + .add("1"); + + this.advertisement = joiner.toString().getBytes(StandardCharsets.UTF_8); } @Override @@ -246,86 +158,105 @@ public Integer putPacket(Player player, DataPacket packet, boolean needACK) { @Override public Integer putPacket(Player player, DataPacket packet, boolean needACK, boolean immediate) { - if (this.identifiers.containsKey(player.rawHashCode())) { - byte[] buffer; - if (packet.pid() == ProtocolInfo.BATCH_PACKET) { - buffer = ((BatchPacket) packet).payload; - } else if (!needACK) { - this.server.batchPackets(new Player[]{player}, new DataPacket[]{packet}, true); - return null; - } else { - if (!packet.isEncoded) { - packet.encode(); - packet.isEncoded = true; - } - buffer = packet.getBuffer(); - try { - buffer = Zlib.deflate( - Binary.appendBytes(Binary.writeUnsignedVarInt(buffer.length), buffer), - Server.getInstance().networkCompressionLevel); - } catch (Exception e) { - throw new RuntimeException(e); - } + RakNetServerSession session = this.raknet.getSession(player.getSocketAddress()); + if (session == null) { + return null; + } + + byte[] buffer; + if (packet.pid() == ProtocolInfo.BATCH_PACKET) { + buffer = ((BatchPacket) packet).payload; + } else if (!needACK) { + this.server.batchPackets(new Player[]{player}, new DataPacket[]{packet}, true); + return null; + } else { + if (!packet.isEncoded) { + packet.encode(); + packet.isEncoded = true; } - String identifier = this.identifiers.get(player.rawHashCode()); - EncapsulatedPacket pk = null; - if (!needACK) { - if (packet.encapsulatedPacket == null) { - packet.encapsulatedPacket = new CacheEncapsulatedPacket(); - packet.encapsulatedPacket.identifierACK = null; - packet.encapsulatedPacket.buffer = Binary.appendBytes((byte) 0xfe, buffer); - if (packet.getChannel() != 0) { - packet.encapsulatedPacket.reliability = 3; - packet.encapsulatedPacket.orderChannel = packet.getChannel(); - packet.encapsulatedPacket.orderIndex = 0; - } else { - packet.encapsulatedPacket.reliability = 2; - } - } - pk = packet.encapsulatedPacket; + buffer = packet.getBuffer(); + try { + buffer = Zlib.deflate( + Binary.appendBytes(Binary.writeUnsignedVarInt(buffer.length), buffer), + Server.getInstance().networkCompressionLevel); + } catch (Exception e) { + throw new RuntimeException(e); } + } + ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(); + byteBuf.writeByte(0xfe); + byteBuf.writeBytes(buffer); - if (pk == null) { - pk = new EncapsulatedPacket(); - pk.buffer = Binary.appendBytes((byte) 0xfe, buffer); - if (packet.getChannel() != 0) { - packet.reliability = 3; - packet.orderChannel = packet.getChannel(); - packet.orderIndex = 0; - } else { - packet.reliability = 2; - } + session.send(byteBuf, packet.reliability, packet.getChannel()); - if (needACK) { - int iACK = this.identifiersACK.get(identifier); - iACK++; - pk.identifierACK = iACK; - this.identifiersACK.put(identifier, iACK); - } - } + return null; + } + + @Override + public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) { + return true; + } + + @Override + public byte[] onQuery(InetSocketAddress inetSocketAddress) { + return this.advertisement; + } - this.handler.sendEncapsulated(identifier, pk, (needACK ? RakNet.FLAG_NEED_ACK : 0) | (immediate ? RakNet.PRIORITY_IMMEDIATE : RakNet.PRIORITY_NORMAL)); + @Override + public void onSessionCreation(RakNetServerSession session) { + PlayerCreationEvent ev = new PlayerCreationEvent(this, Player.class, Player.class, null, session.getAddress()); + this.server.getPluginManager().callEvent(ev); + Class clazz = ev.getPlayerClass(); - return pk.identifierACK; + try { + Constructor constructor = clazz.getConstructor(SourceInterface.class, Long.class, InetSocketAddress.class); + Player player = (Player) constructor.newInstance(this, ev.getClientId(), ev.getSocketAddress()); + this.server.addPlayer(session.getAddress(), player); + NukkitSessionListener listener = new NukkitSessionListener(player); + this.sessionListeners.add(listener); + session.setListener(listener); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { + Server.getInstance().getLogger().logException(e); } + } - return null; + @Override + public void onUnhandledDatagram(ChannelHandlerContext ctx, DatagramPacket datagramPacket) { + this.server.handlePacket(datagramPacket.sender(), datagramPacket.content()); } - private DataPacket getPacket(byte[] buffer) { - int start = 0; + @RequiredArgsConstructor + private class NukkitSessionListener implements RakNetSessionListener { + private final Player player; + private final Queue packets = new ConcurrentLinkedQueue<>(); + + @Override + public void onSessionChangeState(RakNetState rakNetState) { - if (buffer[0] == (byte) 0xfe) { - start++; } - DataPacket data = this.network.getPacket(ProtocolInfo.BATCH_PACKET); - if (data == null) { - return null; + @Override + public void onDisconnect(DisconnectReason disconnectReason) { + this.player.close(player.getLeaveMessage(), "Disconnected from Server"); + RakNetInterface.this.sessionListeners.remove(this); } - data.setBuffer(buffer, start); + @Override + public void onUserPacket(ByteBuf buffer) { + short packetId = buffer.readUnsignedByte(); + if (packetId == 0xfe) { + DataPacket batchPacket = RakNetInterface.this.network.getPacket(ProtocolInfo.BATCH_PACKET); + if (batchPacket == null) { + return; + } + + byte[] packetBuffer = new byte[buffer.readableBytes()]; + buffer.readBytes(packetBuffer); + batchPacket.setBuffer(packetBuffer); + batchPacket.decode(); - return data; + packets.offer(batchPacket); + } + } } } diff --git a/src/main/java/cn/nukkit/network/protocol/BatchPacket.java b/src/main/java/cn/nukkit/network/protocol/BatchPacket.java index c6ba45f9c2d..5e67c79ef79 100644 --- a/src/main/java/cn/nukkit/network/protocol/BatchPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BatchPacket.java @@ -1,7 +1,5 @@ package cn.nukkit.network.protocol; -import cn.nukkit.network.CacheEncapsulatedPacket; - /** * author: MagicDroidX * Nukkit Project @@ -28,12 +26,5 @@ public void encode() { public void trim() { setBuffer(null); - if (encapsulatedPacket != null) { - payload = null; - if (encapsulatedPacket instanceof CacheEncapsulatedPacket && !encapsulatedPacket.hasSplit) { - CacheEncapsulatedPacket cached = (CacheEncapsulatedPacket) encapsulatedPacket; - if (cached.internalData != null) cached.buffer = null; - } - } } } diff --git a/src/main/java/cn/nukkit/network/protocol/DataPacket.java b/src/main/java/cn/nukkit/network/protocol/DataPacket.java index 0817b02ce59..d3a2f8c0941 100644 --- a/src/main/java/cn/nukkit/network/protocol/DataPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/DataPacket.java @@ -1,10 +1,10 @@ package cn.nukkit.network.protocol; import cn.nukkit.Server; -import cn.nukkit.raknet.protocol.EncapsulatedPacket; import cn.nukkit.utils.Binary; import cn.nukkit.utils.BinaryStream; import cn.nukkit.utils.Zlib; +import com.nukkitx.network.raknet.RakNetReliability; /** * author: MagicDroidX @@ -15,10 +15,7 @@ public abstract class DataPacket extends BinaryStream implements Cloneable { public boolean isEncoded = false; private int channel = 0; - public EncapsulatedPacket encapsulatedPacket; - public byte reliability; - public Integer orderIndex = null; - public Integer orderChannel = null; + public RakNetReliability reliability = RakNetReliability.RELIABLE_ORDERED; public abstract byte pid(); diff --git a/src/main/java/cn/nukkit/network/query/QueryHandler.java b/src/main/java/cn/nukkit/network/query/QueryHandler.java index c0e886e7a03..d755748901d 100644 --- a/src/main/java/cn/nukkit/network/query/QueryHandler.java +++ b/src/main/java/cn/nukkit/network/query/QueryHandler.java @@ -3,7 +3,12 @@ import cn.nukkit.Server; import cn.nukkit.event.server.QueryRegenerateEvent; import cn.nukkit.utils.Binary; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; @@ -54,12 +59,12 @@ public void regenerateToken() { this.token = token; } - public static String getTokenString(byte[] token, String salt) { - return getTokenString(new String(token), salt); + public static String getTokenString(byte[] token, InetAddress address) { + return getTokenString(new String(token), address); } - - public static String getTokenString(String token, String salt) { + public static String getTokenString(String token, InetAddress address) { + String salt = address.toString(); try { return String.valueOf(Binary.readInt(Binary.subBytes(MessageDigest.getInstance("SHA-512").digest((salt + ":" + token).getBytes()), 7, 4))); } catch (NoSuchAlgorithmException e) { @@ -67,40 +72,39 @@ public static String getTokenString(String token, String salt) { } } - public void handle(String address, int port, byte[] packet) { - int offset = 2; //skip MAGIC - byte packetType = packet[offset++]; - int sessionID = Binary.readInt(Binary.subBytes(packet, offset, 4)); - offset += 4; - byte[] payload = Binary.subBytes(packet, offset); + public void handle(InetSocketAddress address, ByteBuf packet) { + short packetId = packet.readUnsignedByte(); + int sessionId = packet.readInt(); - switch (packetType) { + switch (packetId) { case HANDSHAKE: - byte[] reply = Binary.appendBytes( - HANDSHAKE, - Binary.writeInt(sessionID), - getTokenString(this.token, address).getBytes(), - new byte[]{0x00} - ); - - this.server.getNetwork().sendPacket(address, port, reply); + ByteBuf reply = PooledByteBufAllocator.DEFAULT.directBuffer(); + reply.writeByte(HANDSHAKE); + reply.writeInt(sessionId); + reply.writeBytes(getTokenString(this.token, address.getAddress()).getBytes(StandardCharsets.UTF_8)); + reply.writeByte(0); + + this.server.getNetwork().sendPacket(address, reply); break; case STATISTICS: - String token = String.valueOf(Binary.readInt(Binary.subBytes(payload, 0, 4))); - if (!token.equals(getTokenString(this.token, address)) && !token.equals(getTokenString(this.lastToken, address))) { + String token = String.valueOf(packet.readInt()); + if (!token.equals(getTokenString(this.token, address.getAddress())) && !token.equals(getTokenString(this.lastToken, address.getAddress()))) { break; } if (this.timeout < System.currentTimeMillis()) { this.regenerateInfo(); } - reply = Binary.appendBytes( - STATISTICS, - Binary.writeInt(sessionID), - payload.length == 8 ? this.longData : this.shortData - ); + reply = PooledByteBufAllocator.DEFAULT.directBuffer(); + reply.writeByte(STATISTICS); + reply.writeInt(sessionId); + if (packet.readableBytes() == 8) { + reply.writeBytes(this.longData); + } else { + reply.writeBytes(this.shortData); + } - this.server.getNetwork().sendPacket(address, port, reply); + this.server.getNetwork().sendPacket(address, reply); break; } } diff --git a/src/main/java/cn/nukkit/raknet/RakNet.java b/src/main/java/cn/nukkit/raknet/RakNet.java deleted file mode 100644 index 29d52788602..00000000000 --- a/src/main/java/cn/nukkit/raknet/RakNet.java +++ /dev/null @@ -1,120 +0,0 @@ -package cn.nukkit.raknet; - -/** - * author: MagicDroidX - * Nukkit Project - * UDP network library that follows the RakNet protocol for Nukkit Project - * This is not affiliated with Jenkins Software LLC nor RakNet. - */ -public abstract class RakNet { - - public static final String VERSION = "1.1.0"; - public static final byte PROTOCOL = 9; - public static final byte[] MAGIC = new byte[]{ - (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x00, - (byte) 0xfe, (byte) 0xfe, (byte) 0xfe, (byte) 0xfe, - (byte) 0xfd, (byte) 0xfd, (byte) 0xfd, (byte) 0xfd, - (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78 - }; - - public static final byte PRIORITY_NORMAL = 0; - public static final byte PRIORITY_IMMEDIATE = 1; - - public static final byte FLAG_NEED_ACK = 0b00001000; - - /* - * ENCAPSULATED payload: - * byte (identifier length) - * byte[] (identifier) - * byte (flags, last 3 bits, priority) - * payload (binary internal EncapsulatedPacket) - */ - public static final byte PACKET_ENCAPSULATED = 0x01; - - /* - * OPEN_SESSION payload: - * byte (identifier length) - * byte[] (identifier) - * byte (address length) - * byte[] (address) - * short (port) - * long (clientID) - */ - public static final byte PACKET_OPEN_SESSION = 0x02; - - /* - * CLOSE_SESSION payload: - * byte (identifier length) - * byte[] (identifier) - * string (reason) - */ - public static final byte PACKET_CLOSE_SESSION = 0x03; - - /* - * INVALID_SESSION payload: - * byte (identifier length) - * byte[] (identifier) - */ - public static final byte PACKET_INVALID_SESSION = 0x04; - - /* SEND_QUEUE payload: - * byte (identifier length) - * byte[] (identifier) - */ - public static final byte PACKET_SEND_QUEUE = 0x05; - - /* - * ACK_NOTIFICATION payload: - * byte (identifier length) - * byte[] (identifier) - * int (identifierACK) - */ - public static final byte PACKET_ACK_NOTIFICATION = 0x06; - - /* - * SET_OPTION payload: - * byte (option name length) - * byte[] (option name) - * byte[] (option value) - */ - public static final byte PACKET_SET_OPTION = 0x07; - - /* - * RAW payload: - * byte (address length) - * byte[] (address from/to) - * short (port) - * byte[] (payload) - */ - public static final byte PACKET_RAW = 0x08; - - /* - * BLOCK_ADDRESS payload: - * byte (address length) - * byte[] (address) - * int (timeout) - */ - public static final byte PACKET_BLOCK_ADDRESS = 0x09; - - /* - * UNBLOCK_ADDRESS payload: - * byte (adress length) - * byte[] (address) - */ - public static final byte PACKET_UNBLOCK_ADDRESS = 0x10; - - /* - * No payload - * - * Sends the disconnect message, removes sessions correctly, closes sockets. - */ - public static final byte PACKET_SHUTDOWN = 0x7e; - - /* - * No payload - * - * Leaves everything as-is and halts, other Threads can be in a post-crash condition. - */ - public static final byte PACKET_EMERGENCY_SHUTDOWN = 0x7f; - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/AcknowledgePacket.java b/src/main/java/cn/nukkit/raknet/protocol/AcknowledgePacket.java deleted file mode 100644 index c61ba24fbf5..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/AcknowledgePacket.java +++ /dev/null @@ -1,107 +0,0 @@ -package cn.nukkit.raknet.protocol; - -import cn.nukkit.utils.Binary; -import cn.nukkit.utils.BinaryStream; - -import java.util.TreeMap; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public abstract class AcknowledgePacket extends Packet { - - public TreeMap packets; - - @Override - public void encode() { - super.encode(); - int count = this.packets.size(); - int[] packets = new int[count]; - - int index = 0; - for (int i : this.packets.values()) { - packets[index++] = i; - } - short records = 0; - BinaryStream payload = new BinaryStream(); - - if (count > 0) { - int pointer = 1; - int start = packets[0]; - int last = packets[0]; - - while (pointer < count) { - int current = packets[pointer++]; - int diff = current - last; - if (diff == 1) { - last = current; - } else if (diff > 1) { - - if (start == last) { - payload.putByte((byte) 0x01); - payload.put(Binary.writeLTriad(start)); - start = last = current; - } else { - payload.putByte((byte) 0x00); - payload.put(Binary.writeLTriad(start)); - payload.put(Binary.writeLTriad(last)); - start = last = current; - } - ++records; - } - } - - if (start == last) { - payload.putByte((byte) 0x01); - payload.put(Binary.writeLTriad(start)); - } else { - payload.putByte((byte) 0x00); - payload.put(Binary.writeLTriad(start)); - payload.put(Binary.writeLTriad(last)); - } - ++records; - } - - this.putShort(records); - this.buffer = Binary.appendBytes( - this.buffer, - payload.getBuffer() - ); - } - - @Override - public void decode() { - super.decode(); - short count = this.getSignedShort(); - this.packets = new TreeMap<>(); - int cnt = 0; - for (int i = 0; i < count && !this.feof() && cnt < 4096; ++i) { - if (this.getByte() == 0) { - int start = this.getLTriad(); - int end = this.getLTriad(); - if ((end - start) > 512) { - end = start + 512; - } - for (int c = start; c <= end; ++c) { - packets.put(cnt++, c); - } - } else { - this.packets.put(cnt++, this.getLTriad()); - } - } - } - - @Override - public Packet clean() { - this.packets = new TreeMap<>(); - return super.clean(); - } - - @Override - public AcknowledgePacket clone() throws CloneNotSupportedException { - AcknowledgePacket packet = (AcknowledgePacket) super.clone(); - packet.packets = new TreeMap<>(this.packets); - return packet; - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/DataPacket.java deleted file mode 100644 index 5ab3dfda0d8..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/DataPacket.java +++ /dev/null @@ -1,65 +0,0 @@ -package cn.nukkit.raknet.protocol; - -import cn.nukkit.utils.Binary; - -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public abstract class DataPacket extends Packet { - - public ConcurrentLinkedQueue packets = new ConcurrentLinkedQueue<>(); - - public Integer seqNumber; - - @Override - public void encode() { - super.encode(); - this.putLTriad(this.seqNumber); - for (Object packet : this.packets) { - this.put(packet instanceof EncapsulatedPacket ? ((EncapsulatedPacket) packet).toBinary() : (byte[]) packet); - } - } - - public int length() { - int length = 4; - for (Object packet : this.packets) { - length += packet instanceof EncapsulatedPacket ? ((EncapsulatedPacket) packet).getTotalLength() : ((byte[]) packet).length; - } - - return length; - } - - @Override - public void decode() { - super.decode(); - this.seqNumber = this.getLTriad(); - - while (!this.feof()) { - byte[] data = Binary.subBytes(this.buffer, this.offset); - EncapsulatedPacket packet = EncapsulatedPacket.fromBinary(data, false); - this.offset += packet.getOffset(); - if (packet.buffer.length == 0) { - break; - } - this.packets.add(packet); - } - } - - @Override - public Packet clean() { - this.packets = new ConcurrentLinkedQueue<>(); - this.seqNumber = null; - return super.clean(); - } - - @Override - public DataPacket clone() throws CloneNotSupportedException { - DataPacket packet = (DataPacket) super.clone(); - packet.packets = new ConcurrentLinkedQueue<>(this.packets); - return packet; - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/EncapsulatedPacket.java b/src/main/java/cn/nukkit/raknet/protocol/EncapsulatedPacket.java deleted file mode 100644 index a836dfb3919..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/EncapsulatedPacket.java +++ /dev/null @@ -1,138 +0,0 @@ -package cn.nukkit.raknet.protocol; - -import cn.nukkit.utils.Binary; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class EncapsulatedPacket implements Cloneable { - - public int reliability; - public boolean hasSplit = false; - public int length = 0; - public Integer messageIndex = null; - public Integer orderIndex = null; - public Integer orderChannel = null; - public Integer splitCount = null; - public Integer splitID = null; - public Integer splitIndex = null; - public byte[] buffer; - public boolean needACK = false; - public Integer identifierACK = null; - - private int offset; - - public int getOffset() { - return offset; - } - - public static EncapsulatedPacket fromBinary(byte[] binary) { - return fromBinary(binary, false); - } - - public static EncapsulatedPacket fromBinary(byte[] binary, boolean internal) { - EncapsulatedPacket packet = new EncapsulatedPacket(); - - int flags = binary[0] & 0xff; - - packet.reliability = ((flags & 0b11100000) >> 5); - packet.hasSplit = (flags & 0b00010000) > 0; - int length, offset; - if (internal) { - length = Binary.readInt(Binary.subBytes(binary, 1, 4)); - packet.identifierACK = Binary.readInt(Binary.subBytes(binary, 5, 4)); - offset = 9; - } else { - length = (int) Math.ceil(((double) Binary.readShort(Binary.subBytes(binary, 1, 2)) / 8)); - offset = 3; - packet.identifierACK = null; - } - - if (packet.reliability > 0) { - if (packet.reliability >= 2 && packet.reliability != 5) { - packet.messageIndex = Binary.readLTriad(Binary.subBytes(binary, offset, 3)); - offset += 3; - } - - if (packet.reliability <= 4 && packet.reliability != 2) { - packet.orderIndex = Binary.readLTriad(Binary.subBytes(binary, offset, 3)); - offset += 3; - packet.orderChannel = binary[offset++] & 0xff; - } - } - - if (packet.hasSplit) { - packet.splitCount = Binary.readInt(Binary.subBytes(binary, offset, 4)); - offset += 4; - packet.splitID = Binary.readShort(Binary.subBytes(binary, offset, 2)); - offset += 2; - packet.splitIndex = Binary.readInt(Binary.subBytes(binary, offset, 4)); - offset += 4; - } - - packet.buffer = Binary.subBytes(binary, offset, length); - offset += length; - packet.offset = offset; - - return packet; - } - - public int getTotalLength() { - return 3 + this.buffer.length + (this.messageIndex != null ? 3 : 0) + (this.orderIndex != null ? 4 : 0) + (this.hasSplit ? 10 : 0); - } - - public byte[] toBinary() { - return toBinary(false); - } - - public byte[] toBinary(boolean internal) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - stream.write((reliability << 5) | (hasSplit ? 0b00010000 : 0)); - if (internal) { - stream.write(Binary.writeInt(buffer.length)); - stream.write(Binary.writeInt(identifierACK == null ? 0 : identifierACK)); - } else { - stream.write(Binary.writeShort(buffer.length << 3)); - } - - if (reliability > 0) { - if (reliability >= 2 && reliability != 5) { - stream.write(Binary.writeLTriad(messageIndex == null ? 0 : messageIndex)); - } - if (reliability <= 4 && reliability != 2) { - stream.write(Binary.writeLTriad(orderIndex)); - stream.write((byte) (orderChannel & 0xff)); - } - } - - if (hasSplit) { - stream.write(Binary.writeInt(splitCount)); - stream.write(Binary.writeShort(splitID)); - stream.write(Binary.writeInt(splitIndex)); - } - - stream.write(buffer); - } catch (IOException e) { - throw new RuntimeException(e); - } - - return stream.toByteArray(); - } - - @Override - public String toString() { - return Binary.bytesToHexString(this.toBinary()); - } - - @Override - public EncapsulatedPacket clone() throws CloneNotSupportedException { - EncapsulatedPacket packet = (EncapsulatedPacket) super.clone(); - packet.buffer = this.buffer.clone(); - return packet; - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/Packet.java b/src/main/java/cn/nukkit/raknet/protocol/Packet.java deleted file mode 100644 index 0020998d433..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/Packet.java +++ /dev/null @@ -1,186 +0,0 @@ -package cn.nukkit.raknet.protocol; - -import cn.nukkit.utils.Binary; - -import java.net.InetSocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public abstract class Packet implements Cloneable { - - protected int offset = 0; - public byte[] buffer; - public Long sendTime; - - public abstract byte getID(); - - protected byte[] get(int len) { - if (len < 0) { - this.offset = this.buffer.length - 1; - return new byte[0]; - } - - byte[] buffer = new byte[len]; - for (int i = 0; i < len; i++) { - buffer[i] = this.buffer[this.offset++]; - } - return buffer; - } - - protected byte[] getAll() { - return this.get(); - } - - protected byte[] get() { - try { - return Arrays.copyOfRange(this.buffer, this.offset, this.buffer.length - 1); - } catch (Exception e) { - return new byte[0]; - } - } - - protected long getLong() { - return Binary.readLong(this.get(8)); - } - - protected int getInt() { - return Binary.readInt(this.get(4)); - } - - protected short getSignedShort() { - return (short) this.getShort(); - } - - protected int getShort() { - return Binary.readShort(this.get(2)); - } - - protected int getTriad() { - return Binary.readTriad(this.get(3)); - } - - protected int getLTriad() { - return Binary.readLTriad(this.get(3)); - } - - protected byte getByte() { - return this.buffer[this.offset++]; - } - - protected String getString() { - return new String(this.get(this.getSignedShort()), StandardCharsets.UTF_8); - } - - protected InetSocketAddress getAddress() { - byte version = this.getByte(); - if (version == 4) { - String addr = ((~this.getByte()) & 0xff) + "." + ((~this.getByte()) & 0xff) + "." + ((~this.getByte()) & 0xff) + "." + ((~this.getByte()) & 0xff); - int port = this.getShort(); - return new InetSocketAddress(addr, port); - } else { - //todo IPV6 SUPPORT - return null; - } - } - - protected boolean feof() { - return !(this.offset >= 0 && this.offset + 1 <= this.buffer.length); - } - - protected void put(byte[] b) { - this.buffer = Binary.appendBytes(this.buffer, b); - } - - protected void putLong(long v) { - this.put(Binary.writeLong(v)); - } - - protected void putInt(int v) { - this.put(Binary.writeInt(v)); - } - - protected void putShort(int v) { - this.put(Binary.writeShort(v)); - } - - protected void putSignedShort(short v) { - this.put(Binary.writeShort(v & 0xffff)); - } - - protected void putTriad(int v) { - this.put(Binary.writeTriad(v)); - } - - protected void putLTriad(int v) { - this.put(Binary.writeLTriad(v)); - } - - protected void putByte(byte b) { - byte[] newBytes = new byte[this.buffer.length + 1]; - System.arraycopy(this.buffer, 0, newBytes, 0, this.buffer.length); - newBytes[this.buffer.length] = b; - this.buffer = newBytes; - } - - protected void putString(String str) { - byte[] b = str.getBytes(StandardCharsets.UTF_8); - this.putShort(b.length); - this.put(b); - } - - protected void putAddress(String addr, int port) { - this.putAddress(addr, port, (byte) 4); - } - - protected void putAddress(String addr, int port, byte version) { - this.putByte(version); - if (version == 4) { - for (String b : addr.split("\\.")) { - this.putByte((byte) ((~Integer.valueOf(b)) & 0xff)); - } - this.putShort(port); - } else { - //todo ipv6 - } - } - - protected void putAddress(InetSocketAddress address) { - this.putAddress(address.getHostString(), address.getPort()); - } - - public void encode() { - this.buffer = new byte[]{getID()}; - } - - public void decode() { - this.offset = 1; - } - - public Packet clean() { - this.buffer = null; - this.offset = 0; - this.sendTime = null; - return this; - } - - @Override - public Packet clone() throws CloneNotSupportedException { - Packet packet = (Packet) super.clone(); - packet.buffer = this.buffer.clone(); - return packet; - } - - /** - * A factory to create new packet instances - */ - public interface PacketFactory { - /** - * Creates the packet - */ - Packet create(); - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/ACK.java b/src/main/java/cn/nukkit/raknet/protocol/packet/ACK.java deleted file mode 100644 index 1c8fa169d86..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/ACK.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.AcknowledgePacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class ACK extends AcknowledgePacket { - - public static final byte ID = (byte) 0xc0; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new ACK(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/ADVERTISE_SYSTEM.java b/src/main/java/cn/nukkit/raknet/protocol/packet/ADVERTISE_SYSTEM.java deleted file mode 100644 index 2f7a50fbb37..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/ADVERTISE_SYSTEM.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class ADVERTISE_SYSTEM extends UNCONNECTED_PONG { - public static final byte ID = (byte) 0x1d; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new ADVERTISE_SYSTEM(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_CONNECT_DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_CONNECT_DataPacket.java deleted file mode 100644 index dbe5b01f452..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_CONNECT_DataPacket.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class CLIENT_CONNECT_DataPacket extends Packet { - public static final byte ID = (byte) 0x09; - - @Override - public byte getID() { - return ID; - } - - public long clientID; - public long sendPing; - public boolean useSecurity = false; - - @Override - public void encode() { - super.encode(); - this.putLong(this.clientID); - this.putLong(this.sendPing); - this.putByte((byte) (this.useSecurity ? 1 : 0)); - } - - @Override - public void decode() { - super.decode(); - this.clientID = this.getLong(); - this.sendPing = this.getLong(); - this.useSecurity = this.getByte() > 0; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new CLIENT_CONNECT_DataPacket(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_DISCONNECT_DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_DISCONNECT_DataPacket.java deleted file mode 100644 index b3f12ff3c99..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_DISCONNECT_DataPacket.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class CLIENT_DISCONNECT_DataPacket extends Packet { - public static final byte ID = (byte) 0x15; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new CLIENT_DISCONNECT_DataPacket(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_HANDSHAKE_DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_HANDSHAKE_DataPacket.java deleted file mode 100644 index 92f065bbe16..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/CLIENT_HANDSHAKE_DataPacket.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -import java.net.InetSocketAddress; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class CLIENT_HANDSHAKE_DataPacket extends Packet { - public static final byte ID = (byte) 0x13; - - @Override - public byte getID() { - return ID; - } - - public String address; - public int port; - public final InetSocketAddress[] systemAddresses = new InetSocketAddress[10]; - - public long sendPing; - public long sendPong; - - @Override - public void encode() { - } - - @Override - public void decode() { - super.decode(); - InetSocketAddress addr = this.getAddress(); - this.address = addr.getHostString(); - this.port = addr.getPort(); - - for (int i = 0; i < 10; i++) { - this.systemAddresses[i] = this.getAddress(); - } - - this.sendPing = this.getLong(); - this.sendPong = this.getLong(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new CLIENT_HANDSHAKE_DataPacket(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_0.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_0.java deleted file mode 100644 index 5ed30433399..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_0.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_0 extends DataPacket { - public static final byte ID = (byte) 0x80; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_0(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_1.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_1.java deleted file mode 100644 index 746cd36f8b4..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_1.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_1 extends DataPacket { - public static final byte ID = (byte) 0x81; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_1(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_2.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_2.java deleted file mode 100644 index 784324e42bf..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_2.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_2 extends DataPacket { - public static final byte ID = (byte) 0x82; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_2(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_3.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_3.java deleted file mode 100644 index 947e3f6683d..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_3.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_3 extends DataPacket { - public static final byte ID = (byte) 0x83; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_3(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_4.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_4.java deleted file mode 100644 index 5e982e97e9c..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_4.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_4 extends DataPacket { - public static final byte ID = (byte) 0x84; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_4(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_5.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_5.java deleted file mode 100644 index 8c4eb4d7fc5..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_5.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_5 extends DataPacket { - public static final byte ID = (byte) 0x85; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_5(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_6.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_6.java deleted file mode 100644 index 80264017e47..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_6.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_6 extends DataPacket { - public static final byte ID = (byte) 0x86; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_6(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_7.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_7.java deleted file mode 100644 index e91b81d3fdb..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_7.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_7 extends DataPacket { - public static final byte ID = (byte) 0x87; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_7(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_8.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_8.java deleted file mode 100644 index 1e751215eba..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_8.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_8 extends DataPacket { - public static final byte ID = (byte) 0x88; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_8(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_9.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_9.java deleted file mode 100644 index ea64ae49ea4..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_9.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_9 extends DataPacket { - public static final byte ID = (byte) 0x89; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_9(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_A.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_A.java deleted file mode 100644 index 0505dbc8e61..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_A.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_A extends DataPacket { - public static final byte ID = (byte) 0x8a; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_A(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_B.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_B.java deleted file mode 100644 index d2ee52794c5..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_B.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_B extends DataPacket { - public static final byte ID = (byte) 0x8b; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_B(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_C.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_C.java deleted file mode 100644 index 704e6a7c519..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_C.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_C extends DataPacket { - public static final byte ID = (byte) 0x8c; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_C(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_D.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_D.java deleted file mode 100644 index cb30600a6d2..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_D.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_D extends DataPacket { - public static final byte ID = (byte) 0x8d; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_D(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_E.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_E.java deleted file mode 100644 index e6f7930f066..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_E.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_E extends DataPacket { - public static final byte ID = (byte) 0x8e; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_E(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_F.java b/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_F.java deleted file mode 100644 index 17d2b5467fc..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/DATA_PACKET_F.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class DATA_PACKET_F extends DataPacket { - public static final byte ID = (byte) 0x8f; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new DATA_PACKET_F(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/NACK.java b/src/main/java/cn/nukkit/raknet/protocol/packet/NACK.java deleted file mode 100644 index 2ff9403000c..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/NACK.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.AcknowledgePacket; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class NACK extends AcknowledgePacket { - - public static final byte ID = (byte) 0xa0; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new NACK(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_1.java b/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_1.java deleted file mode 100644 index feaba3fdc2e..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_1.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class OPEN_CONNECTION_REPLY_1 extends Packet { - public static final byte ID = (byte) 0x06; - - @Override - public byte getID() { - return ID; - } - - public long serverID; - public short mtuSize; - - @Override - public void encode() { - super.encode(); - this.put(RakNet.MAGIC); - this.putLong(this.serverID); - this.putByte((byte) 0); //server security - this.putShort(this.mtuSize); - } - - @Override - public void decode() { - super.decode(); - this.offset += 16; //skip magic bytes - this.serverID = this.getLong(); - this.getByte(); //skip security - this.mtuSize = this.getSignedShort(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new OPEN_CONNECTION_REPLY_1(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_2.java b/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_2.java deleted file mode 100644 index b9290c4ed29..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REPLY_2.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.Packet; - -import java.net.InetSocketAddress; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class OPEN_CONNECTION_REPLY_2 extends Packet { - public static final byte ID = (byte) 0x08; - - @Override - public byte getID() { - return ID; - } - - public long serverID; - public String clientAddress; - public int clientPort; - public short mtuSize; - - @Override - public void encode() { - super.encode(); - this.put(RakNet.MAGIC); - this.putLong(this.serverID); - this.putAddress(this.clientAddress, this.clientPort); - this.putShort(this.mtuSize); - this.putByte((byte) 0); //server security - } - - @Override - public void decode() { - super.decode(); - this.offset += 16; //skip magic bytes - this.serverID = this.getLong(); - InetSocketAddress address = this.getAddress(); - this.clientAddress = address.getHostString(); - this.clientPort = address.getPort(); - this.mtuSize = this.getSignedShort(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new OPEN_CONNECTION_REPLY_2(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_1.java b/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_1.java deleted file mode 100644 index 3379830b448..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_1.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class OPEN_CONNECTION_REQUEST_1 extends Packet { - public static final byte ID = (byte) 0x05; - - @Override - public byte getID() { - return ID; - } - - public byte protocol = RakNet.PROTOCOL; - public short mtuSize; - - @Override - public void encode() { - super.encode(); - this.put(RakNet.MAGIC); - this.putByte(this.protocol); - this.put(new byte[this.mtuSize - 18]); - } - - @Override - public void decode() { - super.decode(); - this.offset += 16; //skip magic bytes - this.protocol = this.getByte(); - this.mtuSize = (short) this.buffer.length; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new OPEN_CONNECTION_REQUEST_1(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_2.java b/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_2.java deleted file mode 100644 index 845d55e017a..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/OPEN_CONNECTION_REQUEST_2.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.Packet; - -import java.net.InetSocketAddress; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class OPEN_CONNECTION_REQUEST_2 extends Packet { - public static final byte ID = (byte) 0x07; - - @Override - public byte getID() { - return ID; - } - - public long clientID; - public String serverAddress; - public int serverPort; - public short mtuSize; - - @Override - public void encode() { - super.encode(); - this.put(RakNet.MAGIC); - this.putAddress(this.serverAddress, this.serverPort); - this.putShort(this.mtuSize); - this.putLong(this.clientID); - } - - @Override - public void decode() { - super.decode(); - this.offset += 16; //skip magic bytes - InetSocketAddress address = this.getAddress(); - this.serverAddress = address.getHostString(); - this.serverPort = address.getPort(); - this.mtuSize = this.getSignedShort(); - this.clientID = this.getLong(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new OPEN_CONNECTION_REQUEST_2(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/PING_DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/packet/PING_DataPacket.java deleted file mode 100644 index 626426be310..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/PING_DataPacket.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class PING_DataPacket extends Packet { - public static final byte ID = (byte) 0x00; - - @Override - public byte getID() { - return ID; - } - - public long pingID; - - @Override - public void encode() { - super.encode(); - this.putLong(this.pingID); - } - - @Override - public void decode() { - super.decode(); - this.pingID = this.getLong(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new PING_DataPacket(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/PONG_DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/packet/PONG_DataPacket.java deleted file mode 100644 index 643e9c79c8b..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/PONG_DataPacket.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class PONG_DataPacket extends Packet { - public static final byte ID = (byte) 0x03; - - @Override - public byte getID() { - return ID; - } - - public long pingID; - - @Override - public void encode() { - super.encode(); - this.putLong(this.pingID); - } - - @Override - public void decode() { - super.decode(); - this.pingID = this.getLong(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new PONG_DataPacket(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/SERVER_HANDSHAKE_DataPacket.java b/src/main/java/cn/nukkit/raknet/protocol/packet/SERVER_HANDSHAKE_DataPacket.java deleted file mode 100644 index 85a9f22d120..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/SERVER_HANDSHAKE_DataPacket.java +++ /dev/null @@ -1,59 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -import java.net.InetSocketAddress; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class SERVER_HANDSHAKE_DataPacket extends Packet { - public static final byte ID = (byte) 0x10; - - @Override - public byte getID() { - return ID; - } - - public String address; - public int port; - public final InetSocketAddress[] systemAddresses = new InetSocketAddress[]{ - new InetSocketAddress("127.0.0.1", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0), - new InetSocketAddress("0.0.0.0", 0) - }; - - public long sendPing; - public long sendPong; - - @Override - public void encode() { - super.encode(); - this.putAddress(new InetSocketAddress(this.address, this.port)); - this.putShort(0); - for (int i = 0; i < 10; ++i) { - this.putAddress(this.systemAddresses[i]); - } - - this.putLong(this.sendPing); - this.putLong(this.sendPong); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new SERVER_HANDSHAKE_DataPacket(); - } - - } - -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING.java b/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING.java deleted file mode 100644 index 00f6b15e553..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class UNCONNECTED_PING extends Packet { - public static final byte ID = (byte) 0x01; - - @Override - public byte getID() { - return ID; - } - - public long pingID; - - @Override - public void encode() { - super.encode(); - this.putLong(this.pingID); - this.put(RakNet.MAGIC); - } - - @Override - public void decode() { - super.decode(); - this.pingID = this.getLong(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new UNCONNECTED_PING(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING_OPEN_CONNECTIONS.java b/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING_OPEN_CONNECTIONS.java deleted file mode 100644 index 9e7be154a78..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PING_OPEN_CONNECTIONS.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class UNCONNECTED_PING_OPEN_CONNECTIONS extends UNCONNECTED_PING { - public static final byte ID = (byte) 0x02; - - @Override - public byte getID() { - return ID; - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new UNCONNECTED_PING_OPEN_CONNECTIONS(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PONG.java b/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PONG.java deleted file mode 100644 index 16d210b7875..00000000000 --- a/src/main/java/cn/nukkit/raknet/protocol/packet/UNCONNECTED_PONG.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.nukkit.raknet.protocol.packet; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.Packet; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class UNCONNECTED_PONG extends Packet { - public static final byte ID = (byte) 0x1c; - - @Override - public byte getID() { - return ID; - } - - public long pingID; - public long serverID; - public String serverName; - - @Override - public void encode() { - super.encode(); - this.putLong(this.pingID); - this.putLong(this.serverID); - this.put(RakNet.MAGIC); - this.putString(this.serverName); - } - - @Override - public void decode() { - super.decode(); - this.pingID = this.getLong(); - this.serverID = this.getLong(); - this.offset += 16; //skip magic bytes todo:check magic? - this.serverName = this.getString(); - } - - public static final class Factory implements Packet.PacketFactory { - - @Override - public Packet create() { - return new UNCONNECTED_PONG(); - } - - } -} diff --git a/src/main/java/cn/nukkit/raknet/server/RakNetServer.java b/src/main/java/cn/nukkit/raknet/server/RakNetServer.java deleted file mode 100644 index 0858334de04..00000000000 --- a/src/main/java/cn/nukkit/raknet/server/RakNetServer.java +++ /dev/null @@ -1,106 +0,0 @@ -package cn.nukkit.raknet.server; - -import cn.nukkit.Server; -import cn.nukkit.utils.ThreadedLogger; - -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class RakNetServer extends Thread { - protected final int port; - protected String interfaz; - - protected ThreadedLogger logger; - - protected ConcurrentLinkedQueue externalQueue; - protected ConcurrentLinkedQueue internalQueue; - - protected boolean shutdown; - - - public RakNetServer(ThreadedLogger logger, int port) { - this(logger, port, "0.0.0.0"); - } - - public RakNetServer(ThreadedLogger logger, int port, String interfaz) { - this.port = port; - if (port < 1 || port > 65536) { - throw new IllegalArgumentException("Invalid port range"); - } - - this.interfaz = interfaz; - this.logger = logger; - - this.externalQueue = new ConcurrentLinkedQueue<>(); - this.internalQueue = new ConcurrentLinkedQueue<>(); - - this.start(); - } - - public boolean isShutdown() { - return shutdown; - } - - public void shutdown() { - this.shutdown = true; - } - - public int getPort() { - return port; - } - - public String getInterface() { - return interfaz; - } - - public ThreadedLogger getLogger() { - return logger; - } - - public ConcurrentLinkedQueue getExternalQueue() { - return externalQueue; - } - - public ConcurrentLinkedQueue getInternalQueue() { - return internalQueue; - } - - public void pushMainToThreadPacket(byte[] data) { - this.internalQueue.add(data); - } - - public byte[] readMainToThreadPacket() { - return this.internalQueue.poll(); - } - - public void pushThreadToMainPacket(byte[] data) { - this.externalQueue.add(data); - } - - public byte[] readThreadToMainPacket() { - return this.externalQueue.poll(); - } - - private class ShutdownHandler extends Thread { - public void run() { - if (!shutdown) { - logger.emergency("RakNet crashed!"); - } - } - } - - @Override - public void run() { - this.setName("RakNet Thread #" + Thread.currentThread().getId()); - Runtime.getRuntime().addShutdownHook(new ShutdownHandler()); - UDPServerSocket socket = new UDPServerSocket(this.getLogger(), port, this.interfaz); - try { - new SessionManager(this, socket); - } catch (Exception e) { - Server.getInstance().getLogger().logException(e); - } - } -} diff --git a/src/main/java/cn/nukkit/raknet/server/ServerHandler.java b/src/main/java/cn/nukkit/raknet/server/ServerHandler.java deleted file mode 100644 index c75e462d8c9..00000000000 --- a/src/main/java/cn/nukkit/raknet/server/ServerHandler.java +++ /dev/null @@ -1,182 +0,0 @@ -package cn.nukkit.raknet.server; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.EncapsulatedPacket; -import cn.nukkit.utils.Binary; - -import java.nio.charset.StandardCharsets; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class ServerHandler { - - protected final RakNetServer server; - - protected final ServerInstance instance; - - public ServerHandler(RakNetServer server, ServerInstance instance) { - this.server = server; - this.instance = instance; - } - - public void sendEncapsulated(String identifier, EncapsulatedPacket packet) { - this.sendEncapsulated(identifier, packet, RakNet.PRIORITY_NORMAL); - } - - public void sendEncapsulated(String identifier, EncapsulatedPacket packet, int flags) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_ENCAPSULATED, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8), - new byte[]{(byte) (flags & 0xff)}, - packet.toBinary(true) - ); - this.server.pushMainToThreadPacket(buffer); - } - - public void sendRaw(String address, int port, byte[] payload) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_RAW, - new byte[]{(byte) (address.length() & 0xff)}, - address.getBytes(StandardCharsets.UTF_8), - Binary.writeShort(port), - payload - ); - this.server.pushMainToThreadPacket(buffer); - } - - public void closeSession(String identifier, String reason) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_CLOSE_SESSION, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8), - new byte[]{(byte) (reason.length() & 0xff)}, - reason.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushMainToThreadPacket(buffer); - } - - public void sendOption(String name, String value) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_SET_OPTION, - new byte[]{(byte) (name.length() & 0xff)}, - name.getBytes(StandardCharsets.UTF_8), - value.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushMainToThreadPacket(buffer); - } - - public void blockAddress(String address, int timeout) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_BLOCK_ADDRESS, - new byte[]{(byte) (address.length() & 0xff)}, - address.getBytes(StandardCharsets.UTF_8), - Binary.writeInt(timeout) - ); - this.server.pushMainToThreadPacket(buffer); - } - - public void unblockAddress(String address) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_UNBLOCK_ADDRESS, - new byte[]{(byte) (address.length() & 0xff)}, - address.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushMainToThreadPacket(buffer); - } - - public void shutdown() { - this.server.pushMainToThreadPacket(new byte[]{RakNet.PACKET_SHUTDOWN}); - this.server.shutdown(); - synchronized (this) { - try { - this.wait(20); - } catch (InterruptedException e) { - //ignore - } - } - try { - this.server.join(); - } catch (InterruptedException e) { - //ignore - } - } - - public void emergencyShutdown() { - this.server.shutdown(); - this.server.pushMainToThreadPacket(new byte[]{RakNet.PACKET_EMERGENCY_SHUTDOWN}); - } - - protected void invalidSession(String identifier) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_INVALID_SESSION, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushMainToThreadPacket(buffer); - } - - public boolean handlePacket() { - byte[] packet = this.server.readThreadToMainPacket(); - if (packet != null && packet.length > 0) { - byte id = packet[0]; - int offset = 1; - if (id == RakNet.PACKET_ENCAPSULATED) { - int len = packet[offset++]; - String identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - int flags = packet[offset++]; - byte[] buffer = Binary.subBytes(packet, offset); - this.instance.handleEncapsulated(identifier, EncapsulatedPacket.fromBinary(buffer, true), flags); - } else if (id == RakNet.PACKET_RAW) { - int len = packet[offset++]; - String address = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - int port = Binary.readShort(Binary.subBytes(packet, offset, 2)) & 0xffff; - offset += 2; - byte[] payload = Binary.subBytes(packet, offset); - this.instance.handleRaw(address, port, payload); - } else if (id == RakNet.PACKET_SET_OPTION) { - int len = packet[offset++]; - String name = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - String value = new String(Binary.subBytes(packet, offset), StandardCharsets.UTF_8); - this.instance.handleOption(name, value); - } else if (id == RakNet.PACKET_OPEN_SESSION) { - int len = packet[offset++]; - String identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - len = packet[offset++]; - String address = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - int port = Binary.readShort(Binary.subBytes(packet, offset, 2)) & 0xffff; - offset += 2; - long clientID = Binary.readLong(Binary.subBytes(packet, offset, 8)); - this.instance.openSession(identifier, address, port, clientID); - } else if (id == RakNet.PACKET_CLOSE_SESSION) { - int len = packet[offset++]; - String identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - len = packet[offset++]; - String reason = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - this.instance.closeSession(identifier, reason); - } else if (id == RakNet.PACKET_INVALID_SESSION) { - int len = packet[offset++]; - String identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - this.instance.closeSession(identifier, "Invalid session"); - } else if (id == RakNet.PACKET_ACK_NOTIFICATION) { - int len = packet[offset++]; - String identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - int identifierACK = Binary.readInt(Binary.subBytes(packet, offset, 4)); - this.instance.notifyACK(identifier, identifierACK); - } - return true; - } - - return false; - } - -} diff --git a/src/main/java/cn/nukkit/raknet/server/ServerInstance.java b/src/main/java/cn/nukkit/raknet/server/ServerInstance.java deleted file mode 100644 index 8b55c696e2b..00000000000 --- a/src/main/java/cn/nukkit/raknet/server/ServerInstance.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.nukkit.raknet.server; - -import cn.nukkit.raknet.protocol.EncapsulatedPacket; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public interface ServerInstance { - - void openSession(String identifier, String address, int port, long clientID); - - void closeSession(String identifier, String reason); - - void handleEncapsulated(String identifier, EncapsulatedPacket packet, int flags); - - void handleRaw(String address, int port, byte[] payload); - - void notifyACK(String identifier, int identifierACK); - - void handleOption(String option, String value); -} diff --git a/src/main/java/cn/nukkit/raknet/server/Session.java b/src/main/java/cn/nukkit/raknet/server/Session.java deleted file mode 100644 index 867afc249ac..00000000000 --- a/src/main/java/cn/nukkit/raknet/server/Session.java +++ /dev/null @@ -1,555 +0,0 @@ -package cn.nukkit.raknet.server; - -import cn.nukkit.math.NukkitMath; -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.DataPacket; -import cn.nukkit.raknet.protocol.EncapsulatedPacket; -import cn.nukkit.raknet.protocol.Packet; -import cn.nukkit.raknet.protocol.packet.*; -import cn.nukkit.utils.Binary; -import cn.nukkit.utils.BinaryStream; - -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class Session { - public final static int STATE_UNCONNECTED = 0; - public final static int STATE_CONNECTING_1 = 1; - public final static int STATE_CONNECTING_2 = 2; - public final static int STATE_CONNECTED = 3; - - public final static int MAX_SPLIT_SIZE = 128; - public final static int MAX_SPLIT_COUNT = 4; - - public static final int WINDOW_SIZE = 2048; - - private static final int MAX_MTU_SIZE = 1492; - private static final int MIN_MTU_SIZE = 400; - - private int messageIndex = 0; - private final Map channelIndex = new ConcurrentHashMap<>(); - - private SessionManager sessionManager; - private final String address; - private final int port; - private int state = STATE_UNCONNECTED; - //private List preJoinQueue = new ArrayList<>(); - private int mtuSize = MIN_MTU_SIZE; - private long id = 0; - private int splitID = 0; - - private int sendSeqNumber = 0; - private int lastSeqNumber = -1; - - private long lastUpdate; - private final long startTime; - - private boolean isTemporal = true; - - private final List packetToSend = new ArrayList<>(); - - private boolean isActive; - - private Map ACKQueue = new HashMap<>(); - private Map NACKQueue = new HashMap<>(); - - private final Map recoveryQueue = new TreeMap<>(); - - private final Map> splitPackets = new HashMap<>(); - - private final Map> needACK = new TreeMap<>(); - - private DataPacket sendQueue; - - private int windowStart; - private final Map receivedWindow = new TreeMap<>(); - private int windowEnd; - - private int reliableWindowStart; - private int reliableWindowEnd; - private final Map reliableWindow = new TreeMap<>(); - private int lastReliableIndex = -1; - - public Session(SessionManager sessionManager, String address, int port) { - this.sessionManager = sessionManager; - this.address = address; - this.port = port; - this.sendQueue = new DATA_PACKET_4(); - this.lastUpdate = System.currentTimeMillis(); - this.startTime = System.currentTimeMillis(); - this.isActive = false; - this.windowStart = -1; - this.windowEnd = WINDOW_SIZE; - - this.reliableWindowStart = 0; - this.reliableWindowEnd = WINDOW_SIZE; - - for (int i = 0; i < 32; i++) { - this.channelIndex.put(i, 0); - } - } - - public String getAddress() { - return this.address; - } - - public int getPort() { - return this.port; - } - - public long getID() { - return this.id; - } - - public void update(long time) throws Exception { - if (!this.isActive && (this.lastUpdate + 10000) < time) { //10 second timeout - this.disconnect("timeout"); - - return; - } - this.isActive = false; - - if (!this.ACKQueue.isEmpty()) { - ACK pk = new ACK(); - pk.packets = new TreeMap<>(this.ACKQueue); - this.sendPacket(pk); - this.ACKQueue = new HashMap<>(); - } - - if (!this.NACKQueue.isEmpty()) { - NACK pk = new NACK(); - pk.packets = new TreeMap<>(this.NACKQueue); - this.sendPacket(pk); - this.NACKQueue = new HashMap<>(); - } - - if (!this.packetToSend.isEmpty()) { - int limit = 16; - for (int i = 0; i < this.packetToSend.size(); i++) { - DataPacket pk = this.packetToSend.get(i); - pk.sendTime = time; - pk.encode(); - this.recoveryQueue.put(pk.seqNumber, pk); - this.packetToSend.remove(pk); - this.sendPacket(pk); - - if (limit-- <= 0) { - break; - } - } - } - - if (this.packetToSend.size() > WINDOW_SIZE) { - this.packetToSend.clear(); - } - - if (!this.needACK.isEmpty()) { - for (int identifierACK : new ArrayList<>(this.needACK.keySet())) { - Map indexes = this.needACK.get(identifierACK); - if (indexes.isEmpty()) { - this.needACK.remove(identifierACK); - this.sessionManager.notifyACK(this, identifierACK); - } - } - } - - for (int seq : new ArrayList<>(this.recoveryQueue.keySet())) { - DataPacket pk = this.recoveryQueue.get(seq); - if (pk.sendTime < System.currentTimeMillis() - 8000) { - this.packetToSend.add(pk); - this.recoveryQueue.remove(seq); - } else { - break; - } - } - - for (int seq : new ArrayList<>(this.receivedWindow.keySet())) { - if (seq < this.windowStart) { - this.receivedWindow.remove(seq); - } else { - break; - } - } - - this.sendQueue(); - } - - public void disconnect() throws Exception { - this.disconnect("unknown"); - } - - public void disconnect(String reason) throws Exception { - this.sessionManager.removeSession(this, reason); - } - - private void sendPacket(Packet packet) throws IOException { - this.sessionManager.sendPacket(packet, this.address, this.port); - } - - public void sendQueue() throws IOException { - if (!this.sendQueue.packets.isEmpty()) { - this.sendQueue.seqNumber = sendSeqNumber++; - this.sendPacket(sendQueue); - this.sendQueue.sendTime = System.currentTimeMillis(); - this.recoveryQueue.put(this.sendQueue.seqNumber, this.sendQueue); - this.sendQueue = new DATA_PACKET_4(); - } - } - - private void addToQueue(EncapsulatedPacket pk) throws Exception { - addToQueue(pk, RakNet.PRIORITY_NORMAL); - } - - private void addToQueue(EncapsulatedPacket pk, int flags) throws Exception { - int priority = flags & 0b0000111; - if (pk.needACK && pk.messageIndex != null) { - if (!this.needACK.containsKey(pk.identifierACK)) { - this.needACK.put(pk.identifierACK, new HashMap<>()); - } - this.needACK.get(pk.identifierACK).put(pk.messageIndex, pk.messageIndex); - } - - if (priority == RakNet.PRIORITY_IMMEDIATE) { //Skip queues - DataPacket packet = new DATA_PACKET_0(); - packet.seqNumber = this.sendSeqNumber++; - if (pk.needACK) { - packet.packets.add(pk.clone()); - pk.needACK = false; - } else { - packet.packets.add(pk.toBinary()); - } - - this.sendPacket(packet); - packet.sendTime = System.currentTimeMillis(); - this.recoveryQueue.put(packet.seqNumber, packet); - - return; - } - int length = this.sendQueue.length(); - if (length + pk.getTotalLength() > this.mtuSize) { - this.sendQueue(); - } - - if (pk.needACK) { - this.sendQueue.packets.add(pk.clone()); - pk.needACK = false; - } else { - this.sendQueue.packets.add(pk.toBinary()); - } - } - - public void addEncapsulatedToQueue(EncapsulatedPacket packet) throws Exception { - addEncapsulatedToQueue(packet, RakNet.PRIORITY_NORMAL); - } - - public void addEncapsulatedToQueue(EncapsulatedPacket packet, int flags) throws Exception { - if ((packet.needACK = (flags & RakNet.FLAG_NEED_ACK) > 0)) { - this.needACK.put(packet.identifierACK, new HashMap<>()); - } - - if (packet.reliability == 2 || - packet.reliability == 3 || - packet.reliability == 4 || - packet.reliability == 6 || - packet.reliability == 7) { - packet.messageIndex = this.messageIndex++; - - if (packet.reliability == 3) { - int index = this.channelIndex.get(packet.orderChannel) + 1; - packet.orderIndex = index; - channelIndex.put(packet.orderChannel, index); - } - } - - if (packet.getTotalLength() + 4 > this.mtuSize) { - byte[][] buffers = Binary.splitBytes(packet.buffer, this.mtuSize - 34); - int splitID = ++this.splitID % 65536; - for (int count = 0; count < buffers.length; count++) { - byte[] buffer = buffers[count]; - EncapsulatedPacket pk = new EncapsulatedPacket(); - pk.splitID = splitID; - pk.hasSplit = true; - pk.splitCount = buffers.length; - pk.reliability = packet.reliability; - pk.splitIndex = count; - pk.buffer = buffer; - if (count > 0) { - pk.messageIndex = this.messageIndex++; - } else { - pk.messageIndex = packet.messageIndex; - } - if (pk.reliability == 3) { - pk.orderChannel = packet.orderChannel; - pk.orderIndex = packet.orderIndex; - } - this.addToQueue(pk, flags | RakNet.PRIORITY_IMMEDIATE); - } - } else { - this.addToQueue(packet, flags); - } - } - - private void handleSplit(EncapsulatedPacket packet) throws Exception { - if (packet.splitCount >= MAX_SPLIT_SIZE || packet.splitIndex >= MAX_SPLIT_SIZE || packet.splitIndex < 0) { - return; - } - - if (!this.splitPackets.containsKey(packet.splitID)) { - if (this.splitPackets.size() >= MAX_SPLIT_COUNT) { - return; - } - this.splitPackets.put(packet.splitID, new HashMap() {{ - put(packet.splitIndex, packet); - }}); - } else { - this.splitPackets.get(packet.splitID).put(packet.splitIndex, packet); - } - - if (this.splitPackets.get(packet.splitID).size() == packet.splitCount) { - EncapsulatedPacket pk = new EncapsulatedPacket(); - BinaryStream stream = new BinaryStream(); - for (int i = 0; i < packet.splitCount; i++) { - stream.put(this.splitPackets.get(packet.splitID).get(i).buffer); - } - pk.buffer = stream.getBuffer(); - pk.length = pk.buffer.length; - this.splitPackets.remove(packet.splitID); - - this.handleEncapsulatedPacketRoute(pk); - } - } - - private void handleEncapsulatedPacket(EncapsulatedPacket packet) throws Exception { - if (packet.messageIndex == null) { - this.handleEncapsulatedPacketRoute(packet); - } else { - if (packet.messageIndex < this.reliableWindowStart || packet.messageIndex > this.reliableWindowEnd) { - return; - } - - if ((packet.messageIndex - this.lastReliableIndex) == 1) { - this.lastReliableIndex++; - this.reliableWindowStart++; - this.reliableWindowEnd++; - this.handleEncapsulatedPacketRoute(packet); - - if (!this.reliableWindow.isEmpty()) { - TreeMap sortedMap = new TreeMap<>(this.reliableWindow); - - for (int index : sortedMap.keySet()) { - EncapsulatedPacket pk = this.reliableWindow.get(index); - - if ((index - this.lastReliableIndex) != 1) { - break; - } - - this.lastReliableIndex++; - this.reliableWindowStart++; - this.reliableWindowEnd++; - this.handleEncapsulatedPacketRoute(pk); - this.reliableWindow.remove(index); - } - } - } else { - this.reliableWindow.put(packet.messageIndex, packet); - } - } - - } - - public int getState() { - return state; - } - - public boolean isTemporal() { - return isTemporal; - } - - private void handleEncapsulatedPacketRoute(EncapsulatedPacket packet) throws Exception { - if (this.sessionManager == null) { - return; - } - - if (packet.hasSplit) { - if (this.state == STATE_CONNECTED) { - this.handleSplit(packet); - } - return; - } - - byte id = packet.buffer[0]; - if ((id & 0xff) < 0x80) { //internal data packet - if (state == STATE_CONNECTING_2) { - if (id == CLIENT_CONNECT_DataPacket.ID) { - CLIENT_CONNECT_DataPacket dataPacket = new CLIENT_CONNECT_DataPacket(); - dataPacket.buffer = packet.buffer; - dataPacket.decode(); - SERVER_HANDSHAKE_DataPacket pk = new SERVER_HANDSHAKE_DataPacket(); - pk.address = this.address; - pk.port = this.port; - pk.sendPing = dataPacket.sendPing; - pk.sendPong = dataPacket.sendPing + 1000L; - pk.encode(); - - EncapsulatedPacket sendPacket = new EncapsulatedPacket(); - sendPacket.reliability = 0; - sendPacket.buffer = pk.buffer; - this.addToQueue(sendPacket, RakNet.PRIORITY_IMMEDIATE); - } else if (id == CLIENT_HANDSHAKE_DataPacket.ID) { - CLIENT_HANDSHAKE_DataPacket dataPacket = new CLIENT_HANDSHAKE_DataPacket(); - dataPacket.buffer = packet.buffer; - dataPacket.decode(); - - if (dataPacket.port == this.sessionManager.getPort() || !this.sessionManager.portChecking) { - this.state = STATE_CONNECTED; //FINALLY! - this.isTemporal = false; - this.sessionManager.openSession(this); - } - } - } else if (id == CLIENT_DISCONNECT_DataPacket.ID) { - disconnect("client disconnect"); - } else if (id == PING_DataPacket.ID) { - PING_DataPacket dataPacket = new PING_DataPacket(); - dataPacket.buffer = packet.buffer; - dataPacket.decode(); - - PONG_DataPacket pk = new PONG_DataPacket(); - pk.pingID = dataPacket.pingID; - pk.encode(); - - EncapsulatedPacket sendPacket = new EncapsulatedPacket(); - sendPacket.reliability = 0; - sendPacket.buffer = pk.buffer; - this.addToQueue(sendPacket); - - //Latency measurement - PING_DataPacket pingPacket = new PING_DataPacket(); - pingPacket.pingID = System.currentTimeMillis(); - pingPacket.encode(); - - sendPacket = new EncapsulatedPacket(); - sendPacket.reliability = 0; - sendPacket.buffer = pingPacket.buffer; - this.addToQueue(sendPacket); - } else if (id == PONG_DataPacket.ID) { - if (state == STATE_CONNECTED) { - PONG_DataPacket dataPacket = new PONG_DataPacket(); - dataPacket.buffer = packet.buffer; - dataPacket.decode(); - - if (state == STATE_CONNECTED) { - PING_DataPacket pingPacket = new PING_DataPacket(); - pingPacket.pingID = (System.currentTimeMillis() - dataPacket.pingID) / 10; - pingPacket.encode(); - packet.buffer = pingPacket.buffer; - this.sessionManager.streamEncapsulated(this, packet); - } - } - } - } else if (state == STATE_CONNECTED) { - this.sessionManager.streamEncapsulated(this, packet); - } else { - //this.sessionManager.getLogger().notice("Received packet before connection: "+Binary.bytesToHexString(packet.buffer)); - } - } - - public void handlePacket(Packet packet) throws Exception { - this.isActive = true; - this.lastUpdate = System.currentTimeMillis(); - if (this.state == STATE_CONNECTED || this.state == STATE_CONNECTING_2) { - if (((packet.buffer[0] & 0xff) >= 0x80 || (packet.buffer[0] & 0xff) <= 0x8f) && packet instanceof DataPacket) { - DataPacket dp = (DataPacket) packet; - dp.decode(); - - if (dp.seqNumber < this.windowStart || dp.seqNumber > this.windowEnd || this.receivedWindow.containsKey(dp.seqNumber)) { - return; - } - - int diff = dp.seqNumber - this.lastSeqNumber; - - this.NACKQueue.remove(dp.seqNumber); - this.ACKQueue.put(dp.seqNumber, dp.seqNumber); - this.receivedWindow.put(dp.seqNumber, dp.seqNumber); - - if (diff != 1) { - for (int i = this.lastSeqNumber + 1; i < dp.seqNumber; i++) { - if (!this.receivedWindow.containsKey(i)) { - this.NACKQueue.put(i, i); - } - } - } - - if (diff >= 1) { - this.lastSeqNumber = dp.seqNumber; - this.windowStart += diff; - this.windowEnd += diff; - } - - for (Object pk : dp.packets) { - if (pk instanceof EncapsulatedPacket) { - this.handleEncapsulatedPacket((EncapsulatedPacket) pk); - } - } - } else { - if (packet instanceof ACK) { - packet.decode(); - for (int seq : new ArrayList<>(((ACK) packet).packets.values())) { - if (this.recoveryQueue.containsKey(seq)) { - for (Object pk : this.recoveryQueue.get(seq).packets) { - if (pk instanceof EncapsulatedPacket && ((EncapsulatedPacket) pk).needACK && ((EncapsulatedPacket) pk).messageIndex != null) { - if (this.needACK.containsKey(((EncapsulatedPacket) pk).identifierACK)) { - this.needACK.get(((EncapsulatedPacket) pk).identifierACK).remove(((EncapsulatedPacket) pk).messageIndex); - } - } - } - this.recoveryQueue.remove(seq); - } - } - } else if (packet instanceof NACK) { - packet.decode(); - for (int seq : new ArrayList<>(((NACK) packet).packets.values())) { - if (this.recoveryQueue.containsKey(seq)) { - DataPacket pk = this.recoveryQueue.get(seq); - pk.seqNumber = this.sendSeqNumber++; - this.packetToSend.add(pk); - this.recoveryQueue.remove(seq); - } - } - } - } - } else if ((packet.buffer[0] & 0xff) > 0x00 || (packet.buffer[0] & 0xff) < 0x80) { //Not Data packet :) - packet.decode(); - if (packet instanceof OPEN_CONNECTION_REQUEST_1) { - //TODO: check protocol number and refuse connections - OPEN_CONNECTION_REPLY_1 pk = new OPEN_CONNECTION_REPLY_1(); - pk.mtuSize = ((OPEN_CONNECTION_REQUEST_1) packet).mtuSize; - pk.serverID = sessionManager.getID(); - this.sendPacket(pk); - this.state = STATE_CONNECTING_1; - } else if (this.state == STATE_CONNECTING_1 && packet instanceof OPEN_CONNECTION_REQUEST_2) { - this.id = ((OPEN_CONNECTION_REQUEST_2) packet).clientID; - if (((OPEN_CONNECTION_REQUEST_2) packet).serverPort == this.sessionManager.getPort() || !this.sessionManager.portChecking) { - this.mtuSize = NukkitMath.clamp(Math.abs(((OPEN_CONNECTION_REQUEST_2) packet).mtuSize), MIN_MTU_SIZE, MAX_MTU_SIZE); - OPEN_CONNECTION_REPLY_2 pk = new OPEN_CONNECTION_REPLY_2(); - pk.mtuSize = (short) this.mtuSize; - pk.serverID = this.sessionManager.getID(); - pk.clientAddress = this.address; - pk.clientPort = this.port; - this.sendPacket(pk); - this.state = STATE_CONNECTING_2; - } - } - } - } - - public void close() throws Exception { - byte[] data = new byte[]{0x60, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15}; //CLIENT_DISCONNECT packet 0x15 - this.addEncapsulatedToQueue(EncapsulatedPacket.fromBinary(data)); - this.sessionManager = null; - } -} diff --git a/src/main/java/cn/nukkit/raknet/server/SessionManager.java b/src/main/java/cn/nukkit/raknet/server/SessionManager.java deleted file mode 100644 index df6053554e8..00000000000 --- a/src/main/java/cn/nukkit/raknet/server/SessionManager.java +++ /dev/null @@ -1,513 +0,0 @@ -package cn.nukkit.raknet.server; - -import cn.nukkit.raknet.RakNet; -import cn.nukkit.raknet.protocol.EncapsulatedPacket; -import cn.nukkit.raknet.protocol.Packet; -import cn.nukkit.raknet.protocol.packet.*; -import cn.nukkit.utils.Binary; -import cn.nukkit.utils.ThreadedLogger; -import io.netty.buffer.ByteBuf; -import io.netty.channel.socket.DatagramPacket; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.*; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class SessionManager { - protected final Packet.PacketFactory[] packetPool = new Packet.PacketFactory[256]; - - protected final RakNetServer server; - - protected final UDPServerSocket socket; - - protected int receiveBytes = 0; - protected int sendBytes = 0; - - protected final Map sessions = new HashMap<>(); - - protected String name = ""; - - protected int packetLimit = 1000; - - protected boolean shutdown = false; - - protected long ticks = 0; - protected long lastMeasure; - - protected final Map block = new HashMap<>(); - protected final Map ipSec = new HashMap<>(); - - public boolean portChecking = true; - - public final long serverId; - - protected String currentSource = ""; - - public SessionManager(RakNetServer server, UDPServerSocket socket) throws Exception { - this.server = server; - this.socket = socket; - this.registerPackets(); - - this.serverId = new Random().nextLong(); - - this.run(); - } - - public int getPort() { - return this.server.port; - } - - public ThreadedLogger getLogger() { - return this.server.getLogger(); - } - - public void run() throws Exception { - this.tickProcessor(); - } - - private void tickProcessor() throws Exception { - this.lastMeasure = System.currentTimeMillis(); - while (!this.shutdown) { - long start = System.currentTimeMillis(); - int max = 5000; - while (max > 0) { - try { - if (!this.receivePacket()) { - break; - } - --max; - } catch (Exception e) { - if (!currentSource.isEmpty()) { - this.blockAddress(currentSource); - } - // else ignore - } - } - while (this.receiveStream()) ; - - long time = System.currentTimeMillis() - start; - if (time < 50) { - try { - Thread.sleep(50 - time); - } catch (InterruptedException e) { - //ignore - } - } - this.tick(); - } - } - - private void tick() throws Exception { - long time = System.currentTimeMillis(); - for (Session session : new ArrayList<>(this.sessions.values())) { - session.update(time); - } - - for (String address : this.ipSec.keySet()) { - int count = this.ipSec.get(address); - if (count >= this.packetLimit) { - this.blockAddress(address); - } - } - this.ipSec.clear(); - - if ((this.ticks & 0b1111) == 0) { - double diff = Math.max(5d, (double) time - this.lastMeasure); - this.streamOption("bandwidth", this.sendBytes / diff + ";" + this.receiveBytes / diff); - this.lastMeasure = time; - this.sendBytes = 0; - this.receiveBytes = 0; - - if (!this.block.isEmpty()) { - long now = System.currentTimeMillis(); - for (String address : new ArrayList<>(this.block.keySet())) { - long timeout = this.block.get(address); - if (timeout <= now) { - this.block.remove(address); - this.getLogger().notice("Unblocked " + address); - } else { - break; - } - } - } - } - - ++this.ticks; - } - - private boolean receivePacket() throws Exception { - DatagramPacket datagramPacket = this.socket.readPacket(); - if (datagramPacket != null) { - // Check this early - try { - String source = datagramPacket.sender().getHostString(); - currentSource = source; //in order to block address - if (this.block.containsKey(source)) { - return true; - } - - if (this.ipSec.containsKey(source)) { - this.ipSec.put(source, this.ipSec.get(source) + 1); - } else { - this.ipSec.put(source, 1); - } - - ByteBuf byteBuf = datagramPacket.content(); - if (byteBuf.readableBytes() == 0) { - // Exit early to process another packet - return true; - } - byte[] buffer = new byte[byteBuf.readableBytes()]; - byteBuf.readBytes(buffer); - int len = buffer.length; - int port = datagramPacket.sender().getPort(); - - this.receiveBytes += len; - - byte pid = buffer[0]; - - if (pid == UNCONNECTED_PONG.ID) { - return false; - } - - Packet packet = this.getPacketFromPool(pid); - if (packet != null) { - packet.buffer = buffer; - this.getSession(source, port).handlePacket(packet); - return true; - } else if (pid == UNCONNECTED_PING.ID) { - packet = new UNCONNECTED_PING(); - packet.buffer = buffer; - packet.decode(); - - UNCONNECTED_PONG pk = new UNCONNECTED_PONG(); - pk.serverID = this.getID(); - pk.pingID = ((UNCONNECTED_PING) packet).pingID; - pk.serverName = this.getName(); - this.sendPacket(pk, source, port); - } else if (buffer.length != 0) { - this.streamRAW(source, port, buffer); - return true; - } else { - return false; - } - } finally { - datagramPacket.release(); - } - } - - return false; - } - - public void sendPacket(Packet packet, String dest, int port) throws IOException { - packet.encode(); - this.sendBytes += this.socket.writePacket(packet.buffer, dest, port); - } - - public void sendPacket(Packet packet, InetSocketAddress dest) throws IOException { - packet.encode(); - this.sendBytes += this.socket.writePacket(packet.buffer, dest); - } - - public void streamEncapsulated(Session session, EncapsulatedPacket packet) { - this.streamEncapsulated(session, packet, RakNet.PRIORITY_NORMAL); - } - - public void streamEncapsulated(Session session, EncapsulatedPacket packet, int flags) { - String id = session.getAddress() + ":" + session.getPort(); - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_ENCAPSULATED, - new byte[]{(byte) (id.length() & 0xff)}, - id.getBytes(StandardCharsets.UTF_8), - new byte[]{(byte) (flags & 0xff)}, - packet.toBinary(true) - ); - this.server.pushThreadToMainPacket(buffer); - } - - public void streamRAW(String address, int port, byte[] payload) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_RAW, - new byte[]{(byte) (address.length() & 0xff)}, - address.getBytes(StandardCharsets.UTF_8), - Binary.writeShort(port), - payload - ); - this.server.pushThreadToMainPacket(buffer); - } - - protected void streamClose(String identifier, String reason) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_CLOSE_SESSION, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8), - new byte[]{(byte) (reason.length() & 0xff)}, - reason.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushThreadToMainPacket(buffer); - } - - protected void streamInvalid(String identifier) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_INVALID_SESSION, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushThreadToMainPacket(buffer); - } - - protected void streamOpen(Session session) { - String identifier = session.getAddress() + ":" + session.getPort(); - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_OPEN_SESSION, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8), - new byte[]{(byte) (session.getAddress().length() & 0xff)}, - session.getAddress().getBytes(StandardCharsets.UTF_8), - Binary.writeShort(session.getPort()), - Binary.writeLong(session.getID()) - ); - this.server.pushThreadToMainPacket(buffer); - } - - protected void streamACK(String identifier, int identifierACK) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_ACK_NOTIFICATION, - new byte[]{(byte) (identifier.length() & 0xff)}, - identifier.getBytes(StandardCharsets.UTF_8), - Binary.writeInt(identifierACK) - ); - this.server.pushThreadToMainPacket(buffer); - } - - protected void streamOption(String name, String value) { - byte[] buffer = Binary.appendBytes( - RakNet.PACKET_SET_OPTION, - new byte[]{(byte) (name.length() & 0xff)}, - name.getBytes(StandardCharsets.UTF_8), - value.getBytes(StandardCharsets.UTF_8) - ); - this.server.pushThreadToMainPacket(buffer); - } - - private void checkSessions() { - int size = this.sessions.size(); - if (size > 4096) { - List keyToRemove = new ArrayList<>(); - for (String i : this.sessions.keySet()) { - Session s = this.sessions.get(i); - if (s.isTemporal()) { - keyToRemove.add(i); - size--; - if (size <= 4096) { - break; - } - } - } - - for (String i : keyToRemove) { - this.sessions.remove(i); - } - } - } - - public boolean receiveStream() throws Exception { - byte[] packet = this.server.readMainToThreadPacket(); - if (packet != null && packet.length > 0) { - byte id = packet[0]; - int offset = 1; - switch (id) { - case RakNet.PACKET_ENCAPSULATED: - int len = packet[offset++]; - String identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - if (this.sessions.containsKey(identifier)) { - byte flags = packet[offset++]; - byte[] buffer = Binary.subBytes(packet, offset); - this.sessions.get(identifier).addEncapsulatedToQueue(EncapsulatedPacket.fromBinary(buffer, true), flags); - } else { - this.streamInvalid(identifier); - } - break; - case RakNet.PACKET_RAW: - len = packet[offset++]; - String address = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - int port = Binary.readShort(Binary.subBytes(packet, offset, 2)); - offset += 2; - byte[] payload = Binary.subBytes(packet, offset); - this.socket.writePacket(payload, address, port); - break; - case RakNet.PACKET_CLOSE_SESSION: - len = packet[offset++]; - identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - if (this.sessions.containsKey(identifier)) { - this.removeSession(this.sessions.get(identifier)); - } else { - this.streamInvalid(identifier); - } - break; - case RakNet.PACKET_INVALID_SESSION: - len = packet[offset++]; - identifier = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - if (this.sessions.containsKey(identifier)) { - this.removeSession(this.sessions.get(identifier)); - } - break; - case RakNet.PACKET_SET_OPTION: - len = packet[offset++]; - String name = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - String value = new String(Binary.subBytes(packet, offset), StandardCharsets.UTF_8); - switch (name) { - case "name": - this.name = value; - break; - case "portChecking": - this.portChecking = Boolean.valueOf(value); - break; - case "packetLimit": - this.packetLimit = Integer.valueOf(value); - break; - } - break; - case RakNet.PACKET_BLOCK_ADDRESS: - len = packet[offset++]; - address = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - offset += len; - int timeout = Binary.readInt(Binary.subBytes(packet, offset, 4)); - this.blockAddress(address, timeout); - break; - case RakNet.PACKET_UNBLOCK_ADDRESS: - len = packet[offset++]; - address = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8); - this.unblockAddress(address); - break; - case RakNet.PACKET_SHUTDOWN: - for (Session session : new ArrayList<>(this.sessions.values())) { - this.removeSession(session); - } - - this.socket.close(); - this.shutdown = true; - break; - case RakNet.PACKET_EMERGENCY_SHUTDOWN: - this.shutdown = true; - default: - return false; - } - return true; - } - - return false; - } - - public void blockAddress(String address) { - this.blockAddress(address, 300); - } - - public void blockAddress(String address, int timeout) { - long finalTime = System.currentTimeMillis() + timeout * 1000; - if (!this.block.containsKey(address) || timeout == -1) { - if (timeout == -1) { - finalTime = Long.MAX_VALUE; - } else { - this.getLogger().notice("Blocked " + address + " for " + timeout + " seconds"); - } - this.block.put(address, finalTime); - } else if (this.block.get(address) < finalTime) { - this.block.put(address, finalTime); - } - } - - public void unblockAddress(String address) { - this.block.remove(address); - } - - public Session getSession(String ip, int port) { - String id = ip + ":" + port; - if (!this.sessions.containsKey(id)) { - this.checkSessions(); - Session session = new Session(this, ip, port); - this.sessions.put(id, session); - - return session; - } - - return this.sessions.get(id); - } - - public void removeSession(Session session) throws Exception { - this.removeSession(session, "unknown"); - } - - public void removeSession(Session session, String reason) throws Exception { - String id = session.getAddress() + ":" + session.getPort(); - if (this.sessions.containsKey(id)) { - this.sessions.get(id).close(); - this.sessions.remove(id); - this.streamClose(id, reason); - } - } - - public void openSession(Session session) { - this.streamOpen(session); - } - - public void notifyACK(Session session, int identifierACK) { - this.streamACK(session.getAddress() + ":" + session.getPort(), identifierACK); - } - - public String getName() { - return name; - } - - public long getID() { - return this.serverId; - } - - private void registerPacket(byte id, Packet.PacketFactory factory) { - this.packetPool[id & 0xFF] = factory; - } - - public Packet getPacketFromPool(byte id) { - return this.packetPool[id & 0xFF].create(); - } - - private void registerPackets() { - // fill with dummy returning null - Arrays.fill(this.packetPool, (Packet.PacketFactory) () -> null); - - //this.registerPacket(UNCONNECTED_PING.ID, UNCONNECTED_PING.class); - this.registerPacket(UNCONNECTED_PING_OPEN_CONNECTIONS.ID, new UNCONNECTED_PING_OPEN_CONNECTIONS.Factory()); - this.registerPacket(OPEN_CONNECTION_REQUEST_1.ID, new OPEN_CONNECTION_REQUEST_1.Factory()); - this.registerPacket(OPEN_CONNECTION_REPLY_1.ID, new OPEN_CONNECTION_REPLY_1.Factory()); - this.registerPacket(OPEN_CONNECTION_REQUEST_2.ID, new OPEN_CONNECTION_REQUEST_2.Factory()); - this.registerPacket(OPEN_CONNECTION_REPLY_2.ID, new OPEN_CONNECTION_REPLY_2.Factory()); - this.registerPacket(UNCONNECTED_PONG.ID, new UNCONNECTED_PONG.Factory()); - this.registerPacket(ADVERTISE_SYSTEM.ID, new ADVERTISE_SYSTEM.Factory()); - this.registerPacket(DATA_PACKET_0.ID, new DATA_PACKET_0.Factory()); - this.registerPacket(DATA_PACKET_1.ID, new DATA_PACKET_1.Factory()); - this.registerPacket(DATA_PACKET_2.ID, new DATA_PACKET_2.Factory()); - this.registerPacket(DATA_PACKET_3.ID, new DATA_PACKET_3.Factory()); - this.registerPacket(DATA_PACKET_4.ID, new DATA_PACKET_4.Factory()); - this.registerPacket(DATA_PACKET_5.ID, new DATA_PACKET_5.Factory()); - this.registerPacket(DATA_PACKET_6.ID, new DATA_PACKET_6.Factory()); - this.registerPacket(DATA_PACKET_7.ID, new DATA_PACKET_7.Factory()); - this.registerPacket(DATA_PACKET_8.ID, new DATA_PACKET_8.Factory()); - this.registerPacket(DATA_PACKET_9.ID, new DATA_PACKET_9.Factory()); - this.registerPacket(DATA_PACKET_A.ID, new DATA_PACKET_A.Factory()); - this.registerPacket(DATA_PACKET_B.ID, new DATA_PACKET_B.Factory()); - this.registerPacket(DATA_PACKET_C.ID, new DATA_PACKET_C.Factory()); - this.registerPacket(DATA_PACKET_D.ID, new DATA_PACKET_D.Factory()); - this.registerPacket(DATA_PACKET_E.ID, new DATA_PACKET_E.Factory()); - this.registerPacket(DATA_PACKET_F.ID, new DATA_PACKET_F.Factory()); - this.registerPacket(NACK.ID, new NACK.Factory()); - this.registerPacket(ACK.ID, new ACK.Factory()); - } -} diff --git a/src/main/java/cn/nukkit/raknet/server/UDPServerSocket.java b/src/main/java/cn/nukkit/raknet/server/UDPServerSocket.java deleted file mode 100644 index 9547a5bde10..00000000000 --- a/src/main/java/cn/nukkit/raknet/server/UDPServerSocket.java +++ /dev/null @@ -1,101 +0,0 @@ -package cn.nukkit.raknet.server; - -import cn.nukkit.utils.ThreadedLogger; -import io.netty.bootstrap.Bootstrap; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelOption; -import io.netty.channel.epoll.Epoll; -import io.netty.channel.epoll.EpollDatagramChannel; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.DatagramPacket; -import io.netty.channel.socket.nio.NioDatagramChannel; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class UDPServerSocket extends ChannelInboundHandlerAdapter { - - protected final ThreadedLogger logger; - protected Bootstrap bootstrap; - protected Channel channel; - - protected ConcurrentLinkedQueue packets = new ConcurrentLinkedQueue<>(); - - public UDPServerSocket(ThreadedLogger logger) { - this(logger, 19132, "0.0.0.0"); - } - - public UDPServerSocket(ThreadedLogger logger, int port) { - this(logger, port, "0.0.0.0"); - } - - public UDPServerSocket(ThreadedLogger logger, int port, String interfaz) { - this.logger = logger; - try { - if (Epoll.isAvailable()) { - bootstrap = new Bootstrap() - .channel(EpollDatagramChannel.class) - .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .handler(this) - .group(new EpollEventLoopGroup()); - this.logger.info("Epoll is available. EpollEventLoop will be used."); - } else { - bootstrap = new Bootstrap() - .group(new NioEventLoopGroup()) - .channel(NioDatagramChannel.class) - .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .handler(this); - this.logger.info("Epoll is unavailable. Reverting to NioEventLoop."); - } - channel = bootstrap.bind(interfaz, port).sync().channel(); - } catch (Exception e) { - this.logger.critical("**** FAILED TO BIND TO " + interfaz + ":" + port + "!"); - this.logger.critical("Perhaps a server is already running on that port?"); - System.exit(1); - } - } - - public void close() { - bootstrap.config().group().shutdownGracefully(); - if (channel != null) { - channel.close().syncUninterruptibly(); - } - } - - public void clearPacketQueue() { - this.packets.clear(); - } - - public DatagramPacket readPacket() throws IOException { - return this.packets.poll(); - } - - public int writePacket(byte[] data, String dest, int port) throws IOException { - return this.writePacket(data, new InetSocketAddress(dest, port)); - } - - public int writePacket(byte[] data, InetSocketAddress dest) throws IOException { - channel.writeAndFlush(new DatagramPacket(Unpooled.wrappedBuffer(data), dest)); - return data.length; - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - this.packets.add((DatagramPacket) msg); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - this.logger.warning(cause.getMessage(), cause); - } -} From 95af22174061d5bd95f936ebe6694dc8190b7a5e Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 7 May 2019 23:34:49 +0100 Subject: [PATCH 02/39] Uncomment log level config setting. --- src/main/java/cn/nukkit/Server.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index bfa2d0fe1f5..02117d53b6f 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -420,13 +420,13 @@ public Level remove(Object key) { Nukkit.DEBUG = Math.max(this.getConfig("debug.level", 1), 1); -// int logLevel = (Nukkit.DEBUG + 3) * 100; -// for (org.apache.logging.log4j.Level level : org.apache.logging.log4j.Level.values()) { -// if (level.intLevel() == logLevel) { -// Nukkit.setLogLevel(level); -// break; -// } -// } + int logLevel = (Nukkit.DEBUG + 3) * 100; + for (org.apache.logging.log4j.Level level : org.apache.logging.log4j.Level.values()) { + if (level.intLevel() == logLevel) { + Nukkit.setLogLevel(level); + break; + } + } if (this.getConfig().getBoolean("bug-report", true)) { ExceptionHandler.registerExceptionHandler(); From fc5eafba157439b1867c4351f854902db9177e26 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 8 May 2019 09:10:56 +0100 Subject: [PATCH 03/39] Release packet once finished. --- src/main/java/cn/nukkit/network/RakNetInterface.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index b2597db4091..64848d03373 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -184,12 +184,16 @@ public Integer putPacket(Player player, DataPacket packet, boolean needACK, bool } } ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(); - byteBuf.writeByte(0xfe); - byteBuf.writeBytes(buffer); + try { + byteBuf.writeByte(0xfe); + byteBuf.writeBytes(buffer); - session.send(byteBuf, packet.reliability, packet.getChannel()); + session.send(byteBuf, packet.reliability, packet.getChannel()); - return null; + return null; + } finally { + byteBuf.release(); + } } @Override From 141f47564aa4280c9261cd6417ae649a4ee81e27 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 8 May 2019 09:25:34 +0100 Subject: [PATCH 04/39] No need to check for AvailableCommandsPacket ack. Everything is sent reliable ordered so it's guaranteed to get there. --- src/main/java/cn/nukkit/Player.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 8d3048d7a91..5abc5e54ad4 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -64,7 +64,6 @@ import cn.nukkit.potion.Potion; import cn.nukkit.resourcepacks.ResourcePack; import cn.nukkit.scheduler.AsyncTask; -import cn.nukkit.scheduler.Task; import cn.nukkit.utils.*; import co.aikar.timings.Timing; import co.aikar.timings.Timings; @@ -577,16 +576,7 @@ public void sendCommandData() { if (count > 0) { //TODO: structure checking pk.commands = data; - int identifier = this.dataPacket(pk, true); // We *need* ACK so we can be sure that the client received the packet or not - Server.getInstance().getScheduler().scheduleDelayedTask(new Task() { - @Override - public void onRun(int currentTick) { - Boolean status = needACK.get(identifier); - if ((status == null || !status) && isOnline()) { - sendCommandData(); - } - } - }, 60, true); + this.dataPacket(pk, true); } } From aed559dbd2d3e01bd47572657ee27ab5e89ff8d3 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 8 May 2019 09:52:21 +0100 Subject: [PATCH 05/39] Remove all ACK related code from Player. --- src/main/java/cn/nukkit/Player.java | 58 ++++++------------- .../cn/nukkit/network/RakNetInterface.java | 20 ++----- 2 files changed, 23 insertions(+), 55 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 5abc5e54ad4..3c99516ec27 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -201,8 +201,6 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde protected boolean checkMovement = true; - private final Int2ObjectOpenHashMap needACK = new Int2ObjectOpenHashMap<>(); - private final Map> batchedPackets = new TreeMap<>(); private PermissibleBase perm = null; @@ -576,7 +574,7 @@ public void sendCommandData() { if (count > 0) { //TODO: structure checking pk.commands = data; - this.dataPacket(pk, true); + this.dataPacket(pk); } } @@ -1037,29 +1035,24 @@ public boolean batchDataPacket(DataPacket packet) { * @return packet successfully sent */ public boolean dataPacket(DataPacket packet) { - return this.dataPacket(packet, false) != -1; - } - - public int dataPacket(DataPacket packet, boolean needACK) { if (!this.connected) { - return -1; + return false; } - try (Timing timing = Timings.getSendDataPacketTiming(packet)) { DataPacketSendEvent ev = new DataPacketSendEvent(this, packet); this.server.getPluginManager().callEvent(ev); if (ev.isCancelled()) { - return -1; + return false; } - Integer identifier = this.interfaz.putPacket(this, packet, needACK, false); - - if (needACK && identifier != null) { - this.needACK.put(identifier, Boolean.FALSE); - return identifier; - } + this.interfaz.putPacket(this, packet, false, false); } - return 0; + return true; + } + + @Deprecated + public int dataPacket(DataPacket packet, boolean needACK) { + return this.dataPacket(packet) ? 0 : -1; } /** @@ -1070,29 +1063,25 @@ public int dataPacket(DataPacket packet, boolean needACK) { * @return packet successfully sent */ public boolean directDataPacket(DataPacket packet) { - return this.directDataPacket(packet, false) != -1; - } - - public int directDataPacket(DataPacket packet, boolean needACK) { if (!this.connected) { - return -1; + return false; } try (Timing timing = Timings.getSendDataPacketTiming(packet)) { DataPacketSendEvent ev = new DataPacketSendEvent(this, packet); this.server.getPluginManager().callEvent(ev); if (ev.isCancelled()) { - return -1; + return false; } - Integer identifier = this.interfaz.putPacket(this, packet, needACK, true); - - if (needACK && identifier != null) { - this.needACK.put(identifier, Boolean.FALSE); - return identifier; - } + this.interfaz.putPacket(this, packet, false, true); } - return 0; + return true; + } + + @Deprecated + public int directDataPacket(DataPacket packet, boolean needACK) { + return this.directDataPacket(packet) ? 0 : -1; } public int getPing() { @@ -4795,15 +4784,6 @@ public boolean equals(Object obj) { return Objects.equals(this.getUniqueId(), other.getUniqueId()) && this.getId() == other.getId(); } - /** - * Notifies an ACK response from the client - * - * @param identification packet identity - */ - public void notifyACK(int identification) { - needACK.put(identification, Boolean.TRUE); - } - public boolean isBreakingBlock() { return this.breakingBlock != null; } diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 64848d03373..68103812aa4 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -7,9 +7,7 @@ import cn.nukkit.network.protocol.BatchPacket; import cn.nukkit.network.protocol.DataPacket; import cn.nukkit.network.protocol.ProtocolInfo; -import cn.nukkit.utils.Binary; import cn.nukkit.utils.Utils; -import cn.nukkit.utils.Zlib; import com.google.common.base.Strings; import com.nukkitx.network.raknet.*; import com.nukkitx.network.util.DisconnectReason; @@ -166,22 +164,12 @@ public Integer putPacket(Player player, DataPacket packet, boolean needACK, bool byte[] buffer; if (packet.pid() == ProtocolInfo.BATCH_PACKET) { buffer = ((BatchPacket) packet).payload; - } else if (!needACK) { + if (buffer == null) { + return null; + } + } else { this.server.batchPackets(new Player[]{player}, new DataPacket[]{packet}, true); return null; - } else { - if (!packet.isEncoded) { - packet.encode(); - packet.isEncoded = true; - } - buffer = packet.getBuffer(); - try { - buffer = Zlib.deflate( - Binary.appendBytes(Binary.writeUnsignedVarInt(buffer.length), buffer), - Server.getInstance().networkCompressionLevel); - } catch (Exception e) { - throw new RuntimeException(e); - } } ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(); try { From 29d997267aebc3365eba82528c8e7ab0d479f014 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 15 May 2019 22:23:00 +0100 Subject: [PATCH 06/39] Bump RakNet to 1.4.0 and give fixed buffer length on allocation. --- pom.xml | 20 +++++++++++---- src/main/java/cn/nukkit/Nukkit.java | 5 ++++ .../cn/nukkit/network/RakNetInterface.java | 25 +++++++++++-------- .../protocol/ResourcePacksInfoPacket.java | 6 ++--- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index 7231177a461..0c89f7a0ee1 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.3.4 + 1.4.0 compile @@ -184,6 +184,20 @@ + + org.apache.maven.plugins + maven-jar-plugin + LATEST + + + + true + lib/ + cn.nukkit.Nukkit + + + + maven-compiler-plugin 3.1 @@ -250,14 +264,10 @@ - - cn.nukkit.Nukkit - - ${project.build.directory}/dependency-reduced-pom.xml diff --git a/src/main/java/cn/nukkit/Nukkit.java b/src/main/java/cn/nukkit/Nukkit.java index e87f6711876..98c9e27afe7 100644 --- a/src/main/java/cn/nukkit/Nukkit.java +++ b/src/main/java/cn/nukkit/Nukkit.java @@ -3,6 +3,8 @@ import cn.nukkit.network.protocol.ProtocolInfo; import cn.nukkit.utils.ServerKiller; import com.google.common.base.Preconditions; +import io.netty.util.internal.logging.InternalLoggerFactory; +import io.netty.util.internal.logging.Log4J2LoggerFactory; import joptsimple.OptionParser; import joptsimple.OptionSet; import joptsimple.OptionSpec; @@ -63,6 +65,9 @@ public static void main(String[] args) { // Force Mapped ByteBuffers for LevelDB till fixed. System.setProperty("leveldb.mmap", "true"); + // Netty logger for debug info + InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); + // Define args OptionParser parser = new OptionParser(); parser.allowsUnrecognizedOptions(); diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 68103812aa4..01fc0a99f58 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -171,17 +171,16 @@ public Integer putPacket(Player player, DataPacket packet, boolean needACK, bool this.server.batchPackets(new Player[]{player}, new DataPacket[]{packet}, true); return null; } - ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(); - try { - byteBuf.writeByte(0xfe); - byteBuf.writeBytes(buffer); - session.send(byteBuf, packet.reliability, packet.getChannel()); + ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(1 + buffer.length); + byteBuf.writeByte(0xfe); + byteBuf.writeBytes(buffer); + byteBuf.readerIndex(0); - return null; - } finally { - byteBuf.release(); - } + session.send(byteBuf, immediate ? RakNetPriority.IMMEDIATE : RakNetPriority.MEDIUM, packet.reliability, + packet.getChannel()); + + return null; } @Override @@ -234,7 +233,8 @@ public void onDisconnect(DisconnectReason disconnectReason) { } @Override - public void onUserPacket(ByteBuf buffer) { + public void onEncapsulated(EncapsulatedPacket packet) { + ByteBuf buffer = packet.getBuffer(); short packetId = buffer.readUnsignedByte(); if (packetId == 0xfe) { DataPacket batchPacket = RakNetInterface.this.network.getPacket(ProtocolInfo.BATCH_PACKET); @@ -250,5 +250,10 @@ public void onUserPacket(ByteBuf buffer) { packets.offer(batchPacket); } } + + @Override + public void onDirect(ByteBuf byteBuf) { + // We don't allow any direct packets so ignore. + } } } diff --git a/src/main/java/cn/nukkit/network/protocol/ResourcePacksInfoPacket.java b/src/main/java/cn/nukkit/network/protocol/ResourcePacksInfoPacket.java index 9a01f9e2f14..9bce9daee48 100644 --- a/src/main/java/cn/nukkit/network/protocol/ResourcePacksInfoPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ResourcePacksInfoPacket.java @@ -9,7 +9,7 @@ public class ResourcePacksInfoPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.RESOURCE_PACKS_INFO_PACKET; public boolean mustAccept; - public boolean unknownBool; + public boolean scripting; public ResourcePack[] behaviourPackEntries = new ResourcePack[0]; public ResourcePack[] resourcePackEntries = new ResourcePack[0]; @@ -22,7 +22,7 @@ public void decode() { public void encode() { this.reset(); this.putBoolean(this.mustAccept); - this.putBoolean(this.unknownBool); + this.putBoolean(this.scripting); encodePacks(this.resourcePackEntries); encodePacks(this.behaviourPackEntries); @@ -37,7 +37,7 @@ private void encodePacks(ResourcePack[] packs) { this.putString(""); // encryption key this.putString(""); // sub-pack name this.putString(""); // content identity - this.putBoolean(false); // ??? + this.putBoolean(false); // scripting } } From e78b5b6383d5be74fb35969931f9898f368d7924 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 15 May 2019 22:50:51 +0100 Subject: [PATCH 07/39] Fix maven-jar-plugin versioning --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0c89f7a0ee1..e2e573f2a70 100644 --- a/pom.xml +++ b/pom.xml @@ -187,7 +187,7 @@ org.apache.maven.plugins maven-jar-plugin - LATEST + 3.1.2 From d0ad05b69f7d5067f1bfeba3b7952da890fc3f44 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 27 May 2019 20:58:05 +0100 Subject: [PATCH 08/39] Bump to the latest RakNet 1.4.3 --- pom.xml | 2 +- src/main/resources/lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e2e573f2a70..0742d5a06ef 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.0 + 1.4.3 compile diff --git a/src/main/resources/lang b/src/main/resources/lang index 6bc53fad382..6f9b6bf3145 160000 --- a/src/main/resources/lang +++ b/src/main/resources/lang @@ -1 +1 @@ -Subproject commit 6bc53fad382c615843fcb2adaf2b05839b64e7e6 +Subproject commit 6f9b6bf314599ffa14a72c0f3949e515d938d738 From 72dc690ec9c8cab4ebde82558b5670e1e75ff14f Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 28 May 2019 11:52:10 +0100 Subject: [PATCH 09/39] Bump RakNet and use 4 worker threads. --- pom.xml | 2 +- src/main/java/cn/nukkit/Nukkit.java | 2 ++ src/main/java/cn/nukkit/network/RakNetInterface.java | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0742d5a06ef..6e5305fba11 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.3 + 1.4.4 compile diff --git a/src/main/java/cn/nukkit/Nukkit.java b/src/main/java/cn/nukkit/Nukkit.java index 98c9e27afe7..ec0ac8e31f4 100644 --- a/src/main/java/cn/nukkit/Nukkit.java +++ b/src/main/java/cn/nukkit/Nukkit.java @@ -3,6 +3,7 @@ import cn.nukkit.network.protocol.ProtocolInfo; import cn.nukkit.utils.ServerKiller; import com.google.common.base.Preconditions; +import io.netty.util.ResourceLeakDetector; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.Log4J2LoggerFactory; import joptsimple.OptionParser; @@ -67,6 +68,7 @@ public static void main(String[] args) { // Netty logger for debug info InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID); // Define args OptionParser parser = new OptionParser(); diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 01fc0a99f58..616799cebd7 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -29,8 +29,11 @@ import java.util.StringJoiner; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import static cn.nukkit.scheduler.ServerScheduler.WORKERS; + /** * author: MagicDroidX * Nukkit Project @@ -53,7 +56,7 @@ public RakNetInterface(Server server) { InetSocketAddress bindAddress = new InetSocketAddress(Strings.isNullOrEmpty(this.server.getIp()) ? "0.0.0.0" : this.server.getIp(), this.server.getPort()); - this.raknet = new RakNetServer(bindAddress); + this.raknet = new RakNetServer(bindAddress, Runtime.getRuntime().availableProcessors(), Executors.newScheduledThreadPool(WORKERS)); this.raknet.bind().join(); this.raknet.setListener(this); } From 789a2f852564fca3e1a8e4fb23d95d6416344e30 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 28 May 2019 12:32:52 +0100 Subject: [PATCH 10/39] Bump RakNet to 1.4.5 --- pom.xml | 2 +- src/main/java/cn/nukkit/network/RakNetInterface.java | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 6e5305fba11..33599c11a9a 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.4 + 1.4.5 compile diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 616799cebd7..2502ef22a9a 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -29,11 +29,8 @@ import java.util.StringJoiner; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import static cn.nukkit.scheduler.ServerScheduler.WORKERS; - /** * author: MagicDroidX * Nukkit Project @@ -56,7 +53,7 @@ public RakNetInterface(Server server) { InetSocketAddress bindAddress = new InetSocketAddress(Strings.isNullOrEmpty(this.server.getIp()) ? "0.0.0.0" : this.server.getIp(), this.server.getPort()); - this.raknet = new RakNetServer(bindAddress, Runtime.getRuntime().availableProcessors(), Executors.newScheduledThreadPool(WORKERS)); + this.raknet = new RakNetServer(bindAddress, Runtime.getRuntime().availableProcessors()); this.raknet.bind().join(); this.raknet.setListener(this); } From 7190fa64acbac056228cfe0518a439e09f7f76bd Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 28 May 2019 21:13:05 +0100 Subject: [PATCH 11/39] Bump RakNet to 1.4.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33599c11a9a..1e610f6c963 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.5 + 1.4.6 compile From 448b53a8e787433c7863816a63791ab67b6c722f Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 28 May 2019 22:20:10 +0100 Subject: [PATCH 12/39] Bump RakNet to 1.4.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1e610f6c963..ae8be8fa4d7 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.6 + 1.4.7 compile From 12fbaf698ac00fba51e95fbce5b311d7159e1456 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 29 May 2019 11:24:59 +0100 Subject: [PATCH 13/39] Bump RakNet to 1.4.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ae8be8fa4d7..0ef8aaa6ca9 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.7 + 1.4.8 compile From e6527ac883f48b177e34ebe2bafe56dd749dddab Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 29 May 2019 12:30:46 +0100 Subject: [PATCH 14/39] Bump to RakNet 1.4.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ef8aaa6ca9..df8012081d1 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.8 + 1.4.10 compile From 9ea4af7d2a0c19a705e34736c030818adfc2e8e5 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Thu, 30 May 2019 16:57:46 +0100 Subject: [PATCH 15/39] Bump to RakNet 1.5.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index df8012081d1..fd4dd9eba35 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ Nukkit cn.nukkit nukkit - 1.0-SNAPSHOT + 1.0-RAKNET 1.8 @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.4.10 + 1.5.1 compile From 3451e56db16d6fed9286972be0a385ceeaf9b05e Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Thu, 30 May 2019 16:59:22 +0100 Subject: [PATCH 16/39] Revert version change --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fd4dd9eba35..a4e7dd55f9f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ Nukkit cn.nukkit nukkit - 1.0-RAKNET + 1.0-SNAPSHOT 1.8 From dc7e67b90004e4b85e75d5121d21b5f043e6554e Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Sun, 9 Jun 2019 15:11:32 +0100 Subject: [PATCH 17/39] Bump RakNet to 1.5.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4e7dd55f9f..631d1022ccf 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.5.1 + 1.5.4 compile From 87496fa851d34d7f214842e2d704901a3ba4e04e Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Wed, 19 Jun 2019 21:13:25 +0100 Subject: [PATCH 18/39] Bump RakNet to 1.6.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 631d1022ccf..f4243570120 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.5.4 + 1.6.2 compile From 7a49e30e19a494b8f7fd32318ddaad3f0e4a63ff Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Thu, 20 Jun 2019 11:26:03 +0100 Subject: [PATCH 19/39] Don't send a DisconnectPacket after disconnection. --- src/main/java/cn/nukkit/network/RakNetInterface.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 2502ef22a9a..afb32103daf 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -228,7 +228,7 @@ public void onSessionChangeState(RakNetState rakNetState) { @Override public void onDisconnect(DisconnectReason disconnectReason) { - this.player.close(player.getLeaveMessage(), "Disconnected from Server"); + this.player.close(player.getLeaveMessage(), "Disconnected from Server", false); RakNetInterface.this.sessionListeners.remove(this); } From 9a80e18a6994a82bcf904bdad1901d0711872c71 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Fri, 28 Jun 2019 12:00:09 +0100 Subject: [PATCH 20/39] Bump RakNet to 1.6.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f4243570120..ffda45b9e39 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.2 + 1.6.3 compile From 63d0429f313d0f2680b351c1252a44718f759016 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Sun, 7 Jul 2019 20:04:01 +0100 Subject: [PATCH 21/39] Bump RakNet to 1.6.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ffda45b9e39..0125a431a83 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.3 + 1.6.4 compile From 00d0f4fdc11b501e11bda4741203eb6939f568e7 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Thu, 18 Jul 2019 20:29:31 +0100 Subject: [PATCH 22/39] Bump RakNet to 1.6.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0125a431a83..bf487218f13 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.4 + 1.6.6 compile From d60fa02280861081657c7649a49a884b28610d33 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 22 Jul 2019 15:59:43 +0100 Subject: [PATCH 23/39] Bump RakNet to 1.6.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bf487218f13..4bb2fb29fad 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.6 + 1.6.7 compile From 3e2a466daccf4506af5120a329a161db61c88537 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 22 Jul 2019 16:01:40 +0100 Subject: [PATCH 24/39] Call player.close() on main thread --- .../cn/nukkit/network/RakNetInterface.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index afb32103daf..f1a913ef607 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -23,10 +23,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.Queue; -import java.util.Set; -import java.util.StringJoiner; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; @@ -65,7 +62,15 @@ public void setNetwork(Network network) { @Override public boolean process() { - for (NukkitSessionListener listener : sessionListeners) { + Iterator iterator = this.sessionListeners.iterator(); + while (iterator.hasNext()) { + NukkitSessionListener listener = iterator.next(); + Player player = listener.player; + if (listener.disconnectReason != null) { + player.close(player.getLeaveMessage(), listener.disconnectReason, false); + iterator.remove(); + continue; + } DataPacket packet; while ((packet = listener.packets.poll()) != null) { listener.player.handleDataPacket(packet); @@ -220,6 +225,7 @@ public void onUnhandledDatagram(ChannelHandlerContext ctx, DatagramPacket datagr private class NukkitSessionListener implements RakNetSessionListener { private final Player player; private final Queue packets = new ConcurrentLinkedQueue<>(); + private String disconnectReason = null; @Override public void onSessionChangeState(RakNetState rakNetState) { @@ -228,8 +234,11 @@ public void onSessionChangeState(RakNetState rakNetState) { @Override public void onDisconnect(DisconnectReason disconnectReason) { - this.player.close(player.getLeaveMessage(), "Disconnected from Server", false); - RakNetInterface.this.sessionListeners.remove(this); + if (disconnectReason == DisconnectReason.TIMED_OUT) { + this.disconnectReason = "Timed out"; + } else { + this.disconnectReason = "Disconnected from Server"; + } } @Override From 9811b685275b5474cc7ec09557996083d8d14722 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 22 Jul 2019 16:02:02 +0100 Subject: [PATCH 25/39] Other fixes --- src/main/java/cn/nukkit/Nukkit.java | 2 -- src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/cn/nukkit/Nukkit.java b/src/main/java/cn/nukkit/Nukkit.java index ec0ac8e31f4..98c9e27afe7 100644 --- a/src/main/java/cn/nukkit/Nukkit.java +++ b/src/main/java/cn/nukkit/Nukkit.java @@ -3,7 +3,6 @@ import cn.nukkit.network.protocol.ProtocolInfo; import cn.nukkit.utils.ServerKiller; import com.google.common.base.Preconditions; -import io.netty.util.ResourceLeakDetector; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.Log4J2LoggerFactory; import joptsimple.OptionParser; @@ -68,7 +67,6 @@ public static void main(String[] args) { // Netty logger for debug info InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); - ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID); // Define args OptionParser parser = new OptionParser(); diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java index 4e234fc32d4..b6ebec2ec91 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java @@ -259,7 +259,7 @@ public boolean pickupItems() { boolean pickedUpItem = false; for (Entity entity : this.level.getCollidingEntities(this.pickupArea)) { - if (!entity.isClosed() && !(entity instanceof EntityItem)) { + if (entity.isClosed() || !(entity instanceof EntityItem)) { continue; } From 08db297769ce881ab07f8da7a3247c791798fea2 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 6 Aug 2019 10:04:23 +0100 Subject: [PATCH 26/39] Set resource leak detector to advanced. --- src/main/java/cn/nukkit/Nukkit.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/cn/nukkit/Nukkit.java b/src/main/java/cn/nukkit/Nukkit.java index 98c9e27afe7..1e187e91d7d 100644 --- a/src/main/java/cn/nukkit/Nukkit.java +++ b/src/main/java/cn/nukkit/Nukkit.java @@ -3,6 +3,7 @@ import cn.nukkit.network.protocol.ProtocolInfo; import cn.nukkit.utils.ServerKiller; import com.google.common.base.Preconditions; +import io.netty.util.ResourceLeakDetector; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.Log4J2LoggerFactory; import joptsimple.OptionParser; @@ -67,6 +68,7 @@ public static void main(String[] args) { // Netty logger for debug info InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED); // Define args OptionParser parser = new OptionParser(); From 8e1be4af5a7327285bcb7b85a958fb78be28c9bb Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Thu, 8 Aug 2019 10:04:31 +0100 Subject: [PATCH 27/39] Bump RakNet to 1.6.8 and use I/O buffers. --- pom.xml | 2 +- src/main/java/cn/nukkit/network/RakNetInterface.java | 2 +- src/main/java/cn/nukkit/network/query/QueryHandler.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 4bb2fb29fad..99236eecb8b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.7 + 1.6.8 compile diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index f1a913ef607..9df49177595 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -177,7 +177,7 @@ public Integer putPacket(Player player, DataPacket packet, boolean needACK, bool return null; } - ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(1 + buffer.length); + ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.ioBuffer(1 + buffer.length); byteBuf.writeByte(0xfe); byteBuf.writeBytes(buffer); byteBuf.readerIndex(0); diff --git a/src/main/java/cn/nukkit/network/query/QueryHandler.java b/src/main/java/cn/nukkit/network/query/QueryHandler.java index d755748901d..3751bccdc9e 100644 --- a/src/main/java/cn/nukkit/network/query/QueryHandler.java +++ b/src/main/java/cn/nukkit/network/query/QueryHandler.java @@ -78,7 +78,7 @@ public void handle(InetSocketAddress address, ByteBuf packet) { switch (packetId) { case HANDSHAKE: - ByteBuf reply = PooledByteBufAllocator.DEFAULT.directBuffer(); + ByteBuf reply = PooledByteBufAllocator.DEFAULT.ioBuffer(); reply.writeByte(HANDSHAKE); reply.writeInt(sessionId); reply.writeBytes(getTokenString(this.token, address.getAddress()).getBytes(StandardCharsets.UTF_8)); @@ -95,7 +95,7 @@ public void handle(InetSocketAddress address, ByteBuf packet) { if (this.timeout < System.currentTimeMillis()) { this.regenerateInfo(); } - reply = PooledByteBufAllocator.DEFAULT.directBuffer(); + reply = PooledByteBufAllocator.DEFAULT.ioBuffer(); reply.writeByte(STATISTICS); reply.writeInt(sessionId); if (packet.readableBytes() == 8) { From fb52c1d21f4d1f2dbbea0bb227e643d06becb12c Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 12 Aug 2019 10:33:07 +0100 Subject: [PATCH 28/39] Bump raknet and set capacity of allocated buffers. --- pom.xml | 2 +- .../cn/nukkit/network/query/QueryHandler.java | 32 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 99236eecb8b..9007fb2f0f3 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.8 + 1.6.9 compile diff --git a/src/main/java/cn/nukkit/network/query/QueryHandler.java b/src/main/java/cn/nukkit/network/query/QueryHandler.java index 3751bccdc9e..daa92a7cca7 100644 --- a/src/main/java/cn/nukkit/network/query/QueryHandler.java +++ b/src/main/java/cn/nukkit/network/query/QueryHandler.java @@ -2,16 +2,18 @@ import cn.nukkit.Server; import cn.nukkit.event.server.QueryRegenerateEvent; -import cn.nukkit.utils.Binary; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Arrays; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; /** * author: MagicDroidX @@ -59,16 +61,19 @@ public void regenerateToken() { this.token = token; } - public static String getTokenString(byte[] token, InetAddress address) { - return getTokenString(new String(token), address); + public static byte[] getTokenString(String token, InetAddress address) { + return getTokenString(token.getBytes(StandardCharsets.UTF_8), address); } - public static String getTokenString(String token, InetAddress address) { - String salt = address.toString(); + public static byte[] getTokenString(byte[] token, InetAddress address) { + try { - return String.valueOf(Binary.readInt(Binary.subBytes(MessageDigest.getInstance("SHA-512").digest((salt + ":" + token).getBytes()), 7, 4))); + MessageDigest digest = MessageDigest.getInstance("MD5"); + digest.update(address.toString().getBytes(StandardCharsets.UTF_8)); + digest.update(token); + return Arrays.copyOfRange(digest.digest(), 7, 4); } catch (NoSuchAlgorithmException e) { - return String.valueOf(new Random().nextInt()); + return ByteBuffer.allocate(4).putInt(ThreadLocalRandom.current().nextInt()).array(); } } @@ -78,24 +83,27 @@ public void handle(InetSocketAddress address, ByteBuf packet) { switch (packetId) { case HANDSHAKE: - ByteBuf reply = PooledByteBufAllocator.DEFAULT.ioBuffer(); + ByteBuf reply = PooledByteBufAllocator.DEFAULT.ioBuffer(10); // 1 + 4 + 4 + 1 reply.writeByte(HANDSHAKE); reply.writeInt(sessionId); - reply.writeBytes(getTokenString(this.token, address.getAddress()).getBytes(StandardCharsets.UTF_8)); + reply.writeBytes(getTokenString(this.token, address.getAddress())); reply.writeByte(0); this.server.getNetwork().sendPacket(address, reply); break; case STATISTICS: - String token = String.valueOf(packet.readInt()); - if (!token.equals(getTokenString(this.token, address.getAddress())) && !token.equals(getTokenString(this.lastToken, address.getAddress()))) { + byte[] token = new byte[4]; + packet.readBytes(token); + + if (!Arrays.equals(token, getTokenString(this.token, address.getAddress())) && + !Arrays.equals(token, getTokenString(this.lastToken, address.getAddress()))) { break; } if (this.timeout < System.currentTimeMillis()) { this.regenerateInfo(); } - reply = PooledByteBufAllocator.DEFAULT.ioBuffer(); + reply = PooledByteBufAllocator.DEFAULT.ioBuffer(64); reply.writeByte(STATISTICS); reply.writeInt(sessionId); if (packet.readableBytes() == 8) { From e67a5de76b0dbf9e420acb2f18843a099f7c7844 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 12 Aug 2019 10:55:15 +0100 Subject: [PATCH 29/39] Set leak detection to paranoid. --- src/main/java/cn/nukkit/Nukkit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Nukkit.java b/src/main/java/cn/nukkit/Nukkit.java index 1e187e91d7d..ec0ac8e31f4 100644 --- a/src/main/java/cn/nukkit/Nukkit.java +++ b/src/main/java/cn/nukkit/Nukkit.java @@ -68,7 +68,7 @@ public static void main(String[] args) { // Netty logger for debug info InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); - ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED); + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID); // Define args OptionParser parser = new OptionParser(); From 3200fbe3b54fc2b0c78845f1467ebb7af8b0ab46 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 12 Aug 2019 18:08:04 +0100 Subject: [PATCH 30/39] Bump raknet to 1.6.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9007fb2f0f3..def82e43ad5 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.9 + 1.6.10 compile From 7ce911bf52e11b5a6d1c2ed19cdc4b27013add00 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Mon, 12 Aug 2019 19:14:01 +0100 Subject: [PATCH 31/39] Bump Raknet to 1.6.11 and use default ByteBufAllocator. --- pom.xml | 2 +- src/main/java/cn/nukkit/network/RakNetInterface.java | 4 ++-- src/main/java/cn/nukkit/network/query/QueryHandler.java | 6 +++--- src/main/resources/lang | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index def82e43ad5..5cf050e8f81 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.10 + 1.6.11 compile diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 9df49177595..9936273d110 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -12,7 +12,7 @@ import com.nukkitx.network.raknet.*; import com.nukkitx.network.util.DisconnectReason; import io.netty.buffer.ByteBuf; -import io.netty.buffer.PooledByteBufAllocator; +import io.netty.buffer.ByteBufAllocator; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.socket.DatagramPacket; import lombok.RequiredArgsConstructor; @@ -177,7 +177,7 @@ public Integer putPacket(Player player, DataPacket packet, boolean needACK, bool return null; } - ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.ioBuffer(1 + buffer.length); + ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer(1 + buffer.length); byteBuf.writeByte(0xfe); byteBuf.writeBytes(buffer); byteBuf.readerIndex(0); diff --git a/src/main/java/cn/nukkit/network/query/QueryHandler.java b/src/main/java/cn/nukkit/network/query/QueryHandler.java index daa92a7cca7..c517b1918a6 100644 --- a/src/main/java/cn/nukkit/network/query/QueryHandler.java +++ b/src/main/java/cn/nukkit/network/query/QueryHandler.java @@ -3,7 +3,7 @@ import cn.nukkit.Server; import cn.nukkit.event.server.QueryRegenerateEvent; import io.netty.buffer.ByteBuf; -import io.netty.buffer.PooledByteBufAllocator; +import io.netty.buffer.ByteBufAllocator; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -83,7 +83,7 @@ public void handle(InetSocketAddress address, ByteBuf packet) { switch (packetId) { case HANDSHAKE: - ByteBuf reply = PooledByteBufAllocator.DEFAULT.ioBuffer(10); // 1 + 4 + 4 + 1 + ByteBuf reply = ByteBufAllocator.DEFAULT.ioBuffer(10); // 1 + 4 + 4 + 1 reply.writeByte(HANDSHAKE); reply.writeInt(sessionId); reply.writeBytes(getTokenString(this.token, address.getAddress())); @@ -103,7 +103,7 @@ public void handle(InetSocketAddress address, ByteBuf packet) { if (this.timeout < System.currentTimeMillis()) { this.regenerateInfo(); } - reply = PooledByteBufAllocator.DEFAULT.ioBuffer(64); + reply = ByteBufAllocator.DEFAULT.ioBuffer(64); reply.writeByte(STATISTICS); reply.writeInt(sessionId); if (packet.readableBytes() == 8) { diff --git a/src/main/resources/lang b/src/main/resources/lang index 6bc53fad382..49caa033925 160000 --- a/src/main/resources/lang +++ b/src/main/resources/lang @@ -1 +1 @@ -Subproject commit 6bc53fad382c615843fcb2adaf2b05839b64e7e6 +Subproject commit 49caa033925b316d6a5738c6cb221253c4f70dc9 From 820b1f38c8568277ab2430c63b0c67c309cd0419 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 13 Aug 2019 16:52:37 +0100 Subject: [PATCH 32/39] Fix query handler bug. --- src/main/java/cn/nukkit/network/query/QueryHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/cn/nukkit/network/query/QueryHandler.java b/src/main/java/cn/nukkit/network/query/QueryHandler.java index c517b1918a6..d9b45fb9c06 100644 --- a/src/main/java/cn/nukkit/network/query/QueryHandler.java +++ b/src/main/java/cn/nukkit/network/query/QueryHandler.java @@ -66,12 +66,11 @@ public static byte[] getTokenString(String token, InetAddress address) { } public static byte[] getTokenString(byte[] token, InetAddress address) { - try { MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(address.toString().getBytes(StandardCharsets.UTF_8)); digest.update(token); - return Arrays.copyOfRange(digest.digest(), 7, 4); + return Arrays.copyOf(digest.digest(), 4); } catch (NoSuchAlgorithmException e) { return ByteBuffer.allocate(4).putInt(ThreadLocalRandom.current().nextInt()).array(); } From 7c48b6790887db8c46bd6d7b2c10a6dde3ee7a31 Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Tue, 13 Aug 2019 21:39:07 +0100 Subject: [PATCH 33/39] Bump to RakNet 1.6.12 --- pom.xml | 2 +- src/main/java/cn/nukkit/network/RakNetInterface.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5cf050e8f81..ba13b4ebd2a 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.11 + 1.6.12 compile diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 9936273d110..1bda4d466f8 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -94,7 +94,7 @@ public void close(Player player) { public void close(Player player, String reason) { RakNetServerSession session = this.raknet.getSession(player.getSocketAddress()); if (session != null) { - session.disconnect(); + session.close(); } } From ab95d47a8941102f852f06967ba0a871e1bd6a0d Mon Sep 17 00:00:00 2001 From: DaMatrix Date: Sat, 24 Aug 2019 15:44:53 +0200 Subject: [PATCH 34/39] remove mutex on ground cover populator --- .../impl/extremehills/ExtremeHillsMBiome.java | 21 +++-- .../level/biome/impl/mesa/MesaBiome.java | 66 +++++++------- .../nukkit/level/biome/type/CoveredBiome.java | 88 ++++++++++++++++--- .../cn/nukkit/level/generator/Normal.java | 74 ++++++++-------- .../populator/impl/PopulatorGroundCover.java | 56 ++---------- .../populator/impl/PopulatorOre.java | 18 ++-- 6 files changed, 172 insertions(+), 151 deletions(-) diff --git a/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java b/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java index c14909d49a5..c959698b2c9 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java @@ -33,23 +33,32 @@ public String getName() { @Override public int getSurfaceBlock(int y) { - return isGravel ? GRAVEL : super.getSurfaceBlock(y); + return this.getSurfaceBlock(0, y, 0); + } + + @Override + public int getSurfaceBlock(int x, int y, int z) { + return gravelNoise.noise2D(x, z, true) < -0.75f ? GRAVEL : super.getSurfaceBlock(x, y, z); } @Override public int getSurfaceDepth(int y) { - return isGravel ? 4 : super.getSurfaceDepth(y); + return this.getSurfaceDepth(0, y, 0); + } + + @Override + public int getSurfaceDepth(int x, int y, int z) { + return gravelNoise.noise2D(x, z, true) < -0.75f ? 4 : super.getSurfaceDepth(x, y, z); } @Override public int getGroundDepth(int y) { - return isGravel ? 0 : super.getGroundDepth(y); + return this.getGroundDepth(0, y, 0); } @Override - public void preCover(int x, int z) { - //-0.75 is farily rare, so there'll be much more gravel than grass - isGravel = gravelNoise.noise2D(x, z, true) < -0.75f; + public int getGroundDepth(int x, int y, int z) { + return gravelNoise.noise2D(x, z, true) < -0.75f ? 0 : super.getGroundDepth(x, y, z); } @Override diff --git a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java index 3bf8fbd84e4..bc3593796a7 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java @@ -16,11 +16,9 @@ * Handles the placement of stained clay for all mesa variants */ public class MesaBiome extends CoveredBiome { - static final int[] colorLayer = new int[64]; + static final int[] colorLayer = new int[64]; static final SimplexF redSandNoise = new SimplexF(new NukkitRandom(937478913), 2f, 1 / 4f, 1 / 4f); - static final SimplexF colorNoise = new SimplexF(new NukkitRandom(193759875), 2f, 1 / 4f, 1 / 32f); - private SimplexF moundNoise = new SimplexF(new NukkitRandom(347228794), 2f, 1 / 4f, getMoundFrequency()); - protected int moundHeight; + static final SimplexF colorNoise = new SimplexF(new NukkitRandom(193759875), 2f, 1 / 4f, 1 / 32f); static { Random random = new Random(29864); @@ -32,7 +30,7 @@ public class MesaBiome extends CoveredBiome { setRandomLayerColor(random, 10, 14); // red for (int i = 0, j = 0; i < random.nextInt(3) + 3; i++) { j += random.nextInt(6) + 4; - if (j >= colorLayer.length -3) { + if (j >= colorLayer.length - 3) { break; } if (random.nextInt(2) == 0 || j < colorLayer.length - 1 && random.nextInt(2) == 0) { @@ -54,12 +52,8 @@ private static void setRandomLayerColor(Random random, int sliceCount, int color } } - int randY = 0; - int redSandThreshold = 0; - boolean isRedSand = false; - //cache this too so we can access it in getSurfaceBlock and getSurfaceMeta without needing to calculate it twice - int currMeta = 0; - int startY = 0; + private SimplexF moundNoise = new SimplexF(new NukkitRandom(347228794), 2f, 1 / 4f, getMoundFrequency()); + protected int moundHeight; public MesaBiome() { PopulatorCactus cactus = new PopulatorCactus(); @@ -75,40 +69,57 @@ public MesaBiome() { this.setMoundHeight(17); } - public void setMoundHeight(int height) { + public void setMoundHeight(int height) { this.moundHeight = height; } @Override public int getSurfaceDepth(int y) { - isRedSand = y < redSandThreshold; - startY = y; - //if true, we'll be generating red sand - return isRedSand ? 3 : y - 66; + return this.getSurfaceDepth(0, y, 0); + } + + @Override + public int getSurfaceDepth(int x, int y, int z) { + return y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f)) ? 3 : y - 66; } @Override public int getSurfaceBlock(int y) { - if (isRedSand) { + return this.getSurfaceBlock(0, y, 0); + } + + @Override + public int getSurfaceBlock(int x, int y, int z) { + if (y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f))) { return SAND; } else { - currMeta = colorLayer[(y + randY) & 0x3F]; - return currMeta == -1 ? TERRACOTTA : STAINED_TERRACOTTA; + int meta = colorLayer[(y + Math.round((colorNoise.noise2D(x, z, true) + 1) * 1.5f)) & 0x3F]; + return meta == -1 ? TERRACOTTA : STAINED_TERRACOTTA; } } @Override public int getSurfaceMeta(int y) { - if (isRedSand) { + return this.getSurfaceMeta(0, y, 0); + } + + @Override + public int getSurfaceMeta(int x, int y, int z) { + if (y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f))) { return BlockSand.RED; } else { - return Math.max(0, currMeta); + return Math.max(0, colorLayer[(y + Math.round((colorNoise.noise2D(x, z, true) + 1) * 1.5f)) & 0x3F]); } } @Override public int getGroundDepth(int y) { - return isRedSand ? 2 : 0; + return this.getGroundDepth(0, y, 0); + } + + @Override + public int getGroundDepth(int x, int y, int z) { + return y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f)) ? 2 : 0; } @Override @@ -121,14 +132,7 @@ public String getName() { return "Mesa"; } - @Override - public void preCover(int x, int z) { - //random noise from 0-3 - randY = Math.round((colorNoise.noise2D(x, z, true) + 1) * 1.5f); - redSandThreshold = 71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f); - } - - protected float getMoundFrequency() { + protected float getMoundFrequency() { return 1 / 128f; } @@ -139,7 +143,7 @@ public int getHeightOffset(int x, int z) { return (n > a && n < a + 0.2f) ? (int) ((n - a) * 5f * moundHeight) : n < a + 0.1f ? 0 : moundHeight; } - protected float minHill() { + protected float minHill() { return -0.1f; } } diff --git a/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java b/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java index 9a5ad67cd92..60a498a9445 100644 --- a/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java +++ b/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java @@ -1,6 +1,8 @@ package cn.nukkit.level.biome.type; import cn.nukkit.level.biome.Biome; +import cn.nukkit.level.format.FullChunk; +import cn.nukkit.level.generator.Normal; /** * author: DaPorkchop_ @@ -10,8 +12,6 @@ *

*/ public abstract class CoveredBiome extends Biome { - public final Object synchronizeCover = new Object(); - /** * A single block placed on top of the surface blocks * @@ -21,6 +21,15 @@ public int getCoverBlock() { return AIR; } + /** + * The metadata of the cover block + * + * @return cover block + */ + public int getCoverMeta() { + return 0; + } + /** * The amount of times the surface block should be used *

@@ -34,6 +43,10 @@ public int getSurfaceDepth(int y) { return 1; } + public int getSurfaceDepth(int x, int y, int z) { + return this.getSurfaceDepth(y); + } + /** * Between cover and ground * @@ -42,6 +55,10 @@ public int getSurfaceDepth(int y) { */ public abstract int getSurfaceBlock(int y); + public int getSurfaceBlock(int x, int y, int z) { + return this.getSurfaceBlock(y); + } + /** * The metadata of the surface block * @@ -52,6 +69,10 @@ public int getSurfaceMeta(int y) { return 0; } + public int getSurfaceMeta(int x, int y, int z) { + return this.getSurfaceMeta(y); + } + /** * The amount of times the ground block should be used *

@@ -64,6 +85,10 @@ public int getGroundDepth(int y) { return 4; } + public int getGroundDepth(int x, int y, int z) { + return this.getGroundDepth(y); + } + /** * Between surface and stone * @@ -72,6 +97,10 @@ public int getGroundDepth(int y) { */ public abstract int getGroundBlock(int y); + public int getGroundBlock(int x, int y, int z) { + return this.getGroundBlock(y); + } + /** * The metadata of the ground block * @@ -82,6 +111,10 @@ public int getGroundMeta(int y) { return 0; } + public int getGroundMeta(int x, int y, int z) { + return this.getGroundMeta(y); + } + /** * The block used as stone/below all other surface blocks * @@ -91,16 +124,47 @@ public int getStoneBlock() { return STONE; } - /** - * Called before a new block column is covered. Biomes can update any relevant variables here before covering. - *

- * Biome covering is synchronized on the biome, so thread safety isn't an issue. - *

- * - * @param x x - * @param z z - */ - public void preCover(int x, int z) { + public void doCover(int x, int z, FullChunk chunk) { + final int coverBlock = (this.getCoverBlock() << 4) | this.getCoverMeta(); + + final int fullX = (chunk.getX() << 4) | x; + final int fullZ = (chunk.getZ() << 4) | z; + boolean hasCovered = false; + int realY; + //start one below build limit in case of cover blocks + for (int y = 254; y > 32; y--) { + if (chunk.getFullBlock(x, y, z) == STONE) { + COVER: + if (!hasCovered) { + if (y >= Normal.seaHeight) { + chunk.setFullBlockId(x, y + 1, z, coverBlock); + int surfaceDepth = this.getSurfaceDepth(fullX, y, fullZ); + for (int i = 0; i < surfaceDepth; i++) { + realY = y - i; + if (chunk.getFullBlock(x, realY, z) == STONE) { + chunk.setFullBlockId(x, realY, z, (this.getSurfaceBlock(fullX, realY, fullZ) << 4) | this.getSurfaceMeta(fullX, realY, fullZ)); + } else break COVER; + } + y -= surfaceDepth; + } + int groundDepth = this.getGroundDepth(fullX, y, fullZ); + for (int i = 0; i < groundDepth; i++) { + realY = y - i; + if (chunk.getFullBlock(x, realY, z) == STONE) { + chunk.setFullBlockId(x, realY, z, (this.getGroundBlock(fullX, realY, fullZ) << 4) | this.getGroundMeta(fullX, realY, fullZ)); + } else break COVER; + } + //don't take all of groundDepth away because we do y-- in the loop + y -= groundDepth - 1; + } + hasCovered = true; + } else { + if (hasCovered) { + //reset it if this isn't a valid stone block (allows us to place ground cover on top and below overhangs) + hasCovered = false; + } + } + } } } diff --git a/src/main/java/cn/nukkit/level/generator/Normal.java b/src/main/java/cn/nukkit/level/generator/Normal.java index aa5fdac560c..4ea3b7d52da 100644 --- a/src/main/java/cn/nukkit/level/generator/Normal.java +++ b/src/main/java/cn/nukkit/level/generator/Normal.java @@ -14,6 +14,8 @@ import cn.nukkit.math.MathHelper; import cn.nukkit.math.NukkitRandom; import cn.nukkit.math.Vector3; +import com.google.common.collect.ImmutableList; + import java.util.*; /** @@ -109,8 +111,8 @@ public class Normal extends Generator { } } - private final List populators = new ArrayList<>(); - private final List generationPopulators = new ArrayList<>(); + private List populators = Collections.emptyList(); + private List generationPopulators = Collections.emptyList(); public static final int seaHeight = 64; public NoiseGeneratorOctavesF scaleNoise; public NoiseGeneratorOctavesF depthNoise; @@ -132,7 +134,7 @@ public class Normal extends Generator { private NoiseGeneratorPerlinF surfaceNoise; public Normal() { - this(new HashMap<>()); + this(Collections.emptyMap()); } public Normal(Map options) { @@ -146,7 +148,7 @@ public int getId() { @Override public ChunkManager getChunkManager() { - return level; + return this.level; } @Override @@ -156,7 +158,7 @@ public String getName() { @Override public Map getSettings() { - return new HashMap<>(); + return Collections.emptyMap(); } public Biome pickBiome(int x, int z) { @@ -182,42 +184,37 @@ public void init(ChunkManager level, NukkitRandom random) { this.depthNoise = new NoiseGeneratorOctavesF(random, 16); //this should run before all other populators so that we don't do things like generate ground cover on bedrock or something - PopulatorGroundCover cover = new PopulatorGroundCover(); - this.generationPopulators.add(cover); - - PopulatorBedrock bedrock = new PopulatorBedrock(); - this.generationPopulators.add(bedrock); - - PopulatorOre ores = new PopulatorOre(); - ores.setOreTypes(new OreType[]{ - new OreType(new BlockOreCoal(), 20, 17, 0, 128), - new OreType(new BlockOreIron(), 20, 9, 0, 64), - new OreType(new BlockOreRedstone(), 8, 8, 0, 16), - new OreType(new BlockOreLapis(), 1, 7, 0, 16), - new OreType(new BlockOreGold(), 2, 9, 0, 32), - new OreType(new BlockOreDiamond(), 1, 8, 0, 16), - new OreType(new BlockDirt(), 10, 33, 0, 128), - new OreType(new BlockGravel(), 8, 33, 0, 128), - new OreType(new BlockStone(BlockStone.GRANITE), 10, 33, 0, 80), - new OreType(new BlockStone(BlockStone.DIORITE), 10, 33, 0, 80), - new OreType(new BlockStone(BlockStone.ANDESITE), 10, 33, 0, 80) - }); - this.populators.add(ores); - - PopulatorCaves caves = new PopulatorCaves(); - this.populators.add(caves); - - PopulatorRavines ravines = new PopulatorRavines(); - this.populators.add(ravines); + this.generationPopulators = ImmutableList.of( + new PopulatorBedrock(), + new PopulatorGroundCover() + ); + + this.populators = ImmutableList.of( + new PopulatorOre(STONE, new OreType[]{ + new OreType(new BlockOreCoal(), 20, 17, 0, 128), + new OreType(new BlockOreIron(), 20, 9, 0, 64), + new OreType(new BlockOreRedstone(), 8, 8, 0, 16), + new OreType(new BlockOreLapis(), 1, 7, 0, 16), + new OreType(new BlockOreGold(), 2, 9, 0, 32), + new OreType(new BlockOreDiamond(), 1, 8, 0, 16), + new OreType(new BlockDirt(), 10, 33, 0, 128), + new OreType(new BlockGravel(), 8, 33, 0, 128), + new OreType(new BlockStone(BlockStone.GRANITE), 10, 33, 0, 80), + new OreType(new BlockStone(BlockStone.DIORITE), 10, 33, 0, 80), + new OreType(new BlockStone(BlockStone.ANDESITE), 10, 33, 0, 80) + }), + new PopulatorCaves(), + new PopulatorRavines() + ); } @Override public void generateChunk(final int chunkX, final int chunkZ) { int baseX = chunkX << 4; int baseZ = chunkZ << 4; - this.nukkitRandom.setSeed(chunkX * localSeed1 ^ chunkZ * localSeed2 ^ this.level.getSeed()); + this.nukkitRandom.setSeed(chunkX * this.localSeed1 ^ chunkZ * this.localSeed2 ^ this.level.getSeed()); - BaseFullChunk chunk = level.getChunk(chunkX, chunkZ); + BaseFullChunk chunk = this.level.getChunk(chunkX, chunkZ); //generate base noise values float[] depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion.get(), chunkX * 4, chunkZ * 4, 5, 5, 200f, 200f, 0.5f); @@ -238,11 +235,11 @@ public void generateChunk(final int chunkX, final int chunkZ) { float heightVariationSum = 0.0F; float baseHeightSum = 0.0F; float biomeWeightSum = 0.0F; - Biome biome = pickBiome(baseX + (xSeg * 4), baseZ + (zSeg * 4)); + Biome biome = this.pickBiome(baseX + (xSeg * 4), baseZ + (zSeg * 4)); for (int xSmooth = -2; xSmooth <= 2; ++xSmooth) { for (int zSmooth = -2; zSmooth <= 2; ++zSmooth) { - Biome biome1 = pickBiome(baseX + (xSeg * 4) + xSmooth, baseZ + (zSeg * 4) + zSmooth); + Biome biome1 = this.pickBiome(baseX + (xSeg * 4) + xSmooth, baseZ + (zSeg * 4) + zSmooth); float baseHeight = biome1.getBaseHeight(); float heightVariation = biome1.getHeightVariation(); @@ -371,7 +368,7 @@ public void generateChunk(final int chunkX, final int chunkZ) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { - Biome biome = selector.pickBiome(baseX | x, baseZ | z); + Biome biome = this.selector.pickBiome(baseX | x, baseZ | z); chunk.setBiome(x, z, biome); } @@ -385,12 +382,13 @@ public void generateChunk(final int chunkX, final int chunkZ) { @Override public void populateChunk(int chunkX, int chunkZ) { - BaseFullChunk chunk = level.getChunk(chunkX, chunkZ); + BaseFullChunk chunk = this.level.getChunk(chunkX, chunkZ); this.nukkitRandom.setSeed(0xdeadbeef ^ (chunkX << 8) ^ chunkZ ^ this.level.getSeed()); for (Populator populator : this.populators) { populator.populate(this.level, chunkX, chunkZ, this.nukkitRandom, chunk); } + @SuppressWarnings("deprecation") Biome biome = EnumBiome.getBiome(chunk.getBiomeId(7, 7)); biome.populateChunk(this.level, chunkX, chunkZ, this.nukkitRandom); } diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorGroundCover.java b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorGroundCover.java index 09806df1066..b34290591ca 100644 --- a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorGroundCover.java +++ b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorGroundCover.java @@ -11,63 +11,17 @@ import cn.nukkit.math.NukkitRandom; /** - * author: DaPorkchop_ - * Nukkit Project + * @author DaPorkchop_ */ public class PopulatorGroundCover extends Populator { - public static final int STONE = BlockID.STONE << 4; - @Override public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom random, FullChunk chunk) { - int realX = chunkX << 4; - int realZ = chunkZ << 4; - for (int x = 0; x < 16; ++x) { - for (int z = 0; z < 16; ++z) { + //reverse iteration to 0 is faster + for (int x = 15; x >= 0; x--) { + for (int z = 15; z >= 0; z--) { Biome realBiome = EnumBiome.getBiome(chunk.getBiomeId(x, z)); if (realBiome instanceof CoveredBiome) { - final CoveredBiome biome = (CoveredBiome) realBiome; - //just in case! - synchronized (biome.synchronizeCover) { - biome.preCover(realX | x, realZ | z); - int coverBlock = biome.getCoverBlock() << 4; - - boolean hasCovered = false; - int realY; - //start one below build limit in case of cover blocks - for (int y = 254; y > 32; y--) { - if (chunk.getFullBlock(x, y, z) == STONE) { - COVER: - if (!hasCovered) { - if (y >= Normal.seaHeight) { - chunk.setFullBlockId(x, y + 1, z, coverBlock); - int surfaceDepth = biome.getSurfaceDepth(y); - for (int i = 0; i < surfaceDepth; i++) { - realY = y - i; - if (chunk.getFullBlock(x, realY, z) == STONE) { - chunk.setFullBlockId(x, realY, z, (biome.getSurfaceBlock(realY) << 4) | biome.getSurfaceMeta(realY)); - } else break COVER; - } - y -= surfaceDepth; - } - int groundDepth = biome.getGroundDepth(y); - for (int i = 0; i < groundDepth; i++) { - realY = y - i; - if (chunk.getFullBlock(x, realY, z) == STONE) { - chunk.setFullBlockId(x, realY, z, (biome.getGroundBlock(realY) << 4) | biome.getGroundMeta(realY)); - } else break COVER; - } - //don't take all of groundDepth away because we do y-- in the loop - y -= groundDepth - 1; - } - hasCovered = true; - } else { - if (hasCovered) { - //reset it if this isn't a valid stone block (allows us to place ground cover on top and below overhangs) - hasCovered = false; - } - } - } - } + ((CoveredBiome) realBiome).doCover(x, z, chunk); } } } diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorOre.java b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorOre.java index ee762f6def8..472d587354e 100644 --- a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorOre.java +++ b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorOre.java @@ -9,19 +9,15 @@ import cn.nukkit.math.NukkitRandom; /** - * author: MagicDroidX - * Nukkit Project + * @author DaPorkchop_ */ public class PopulatorOre extends Populator { private final int replaceId; - private OreType[] oreTypes = new OreType[0]; + private final OreType[] oreTypes; - public PopulatorOre() { - this(Block.STONE); - } - - public PopulatorOre(int id) { - this.replaceId = id; + public PopulatorOre(int replaceId, OreType[] oreTypes) { + this.replaceId = replaceId; + this.oreTypes = oreTypes; } @Override @@ -42,8 +38,4 @@ public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom ra } } } - - public void setOreTypes(OreType[] oreTypes) { - this.oreTypes = oreTypes; - } } From 8dc981503b4279059131e5524a0340c0c512d9fd Mon Sep 17 00:00:00 2001 From: SupremeMortal Date: Sat, 24 Aug 2019 15:17:18 +0100 Subject: [PATCH 35/39] Fix compilation issues. --- src/main/java/cn/nukkit/level/generator/Flat.java | 5 ++--- src/main/java/cn/nukkit/level/generator/Nether.java | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/cn/nukkit/level/generator/Flat.java b/src/main/java/cn/nukkit/level/generator/Flat.java index 005b1129513..2739c083a9b 100644 --- a/src/main/java/cn/nukkit/level/generator/Flat.java +++ b/src/main/java/cn/nukkit/level/generator/Flat.java @@ -6,8 +6,8 @@ import cn.nukkit.level.format.FullChunk; import cn.nukkit.level.format.generic.BaseFullChunk; import cn.nukkit.level.generator.object.ore.OreType; -import cn.nukkit.level.generator.populator.type.Populator; import cn.nukkit.level.generator.populator.impl.PopulatorOre; +import cn.nukkit.level.generator.populator.type.Populator; import cn.nukkit.math.NukkitRandom; import cn.nukkit.math.Vector3; @@ -70,8 +70,7 @@ public Flat(Map options) { this.options = options; if (this.options.containsKey("decoration")) { - PopulatorOre ores = new PopulatorOre(); - ores.setOreTypes(new OreType[]{ + PopulatorOre ores = new PopulatorOre(BlockID.STONE, new OreType[]{ new OreType(new BlockOreCoal(), 20, 16, 0, 128), new OreType(new BlockOreIron(), 20, 8, 0, 64), new OreType(new BlockOreRedstone(), 8, 7, 0, 16), diff --git a/src/main/java/cn/nukkit/level/generator/Nether.java b/src/main/java/cn/nukkit/level/generator/Nether.java index 205af838f65..ad1a801def4 100644 --- a/src/main/java/cn/nukkit/level/generator/Nether.java +++ b/src/main/java/cn/nukkit/level/generator/Nether.java @@ -15,6 +15,7 @@ import cn.nukkit.level.generator.populator.type.Populator; import cn.nukkit.math.NukkitRandom; import cn.nukkit.math.Vector3; + import java.util.*; public class Nether extends Generator { @@ -81,8 +82,7 @@ public void init(ChunkManager level, NukkitRandom random) { this.localSeed1 = this.random.nextLong(); this.localSeed2 = this.random.nextLong(); - PopulatorOre ores = new PopulatorOre(Block.NETHERRACK); - ores.setOreTypes(new OreType[]{ + PopulatorOre ores = new PopulatorOre(Block.NETHERRACK, new OreType[]{ new OreType(new BlockOreQuartz(), 20, 16, 0, 128), new OreType(new BlockSoulSand(), 5, 64, 0, 128), new OreType(new BlockGravel(), 5, 64, 0, 128), @@ -100,8 +100,7 @@ public void init(ChunkManager level, NukkitRandom random) { lava.setRandomAmount(2); this.populators.add(lava); this.populators.add(new PopulatorGlowStone()); - PopulatorOre ore = new PopulatorOre(Block.NETHERRACK); - ore.setOreTypes(new OreType[]{ + PopulatorOre ore = new PopulatorOre(Block.NETHERRACK, new OreType[]{ new OreType(new BlockOreQuartz(), 40, 16, 0, 128, NETHERRACK), new OreType(new BlockSoulSand(), 1, 64, 30, 35, NETHERRACK), new OreType(new BlockLava(), 32, 1, 0, 32, NETHERRACK), From 129535bcab8bcc750a5628a1480143a7fc1c7cb7 Mon Sep 17 00:00:00 2001 From: DaMatrix Date: Sat, 24 Aug 2019 17:29:22 +0200 Subject: [PATCH 36/39] fix things that i broke in my previous PR --- .../biome/impl/beach/ColdBeachBiome.java | 4 +- .../impl/extremehills/ExtremeHillsMBiome.java | 19 +-- .../impl/extremehills/StoneBeachBiome.java | 8 +- .../impl/iceplains/IcePlainsSpikesBiome.java | 4 +- .../level/biome/impl/mesa/MesaBiome.java | 39 +----- .../biome/impl/mesa/MesaPlateauFBiome.java | 4 +- .../impl/mushroom/MushroomIslandBiome.java | 4 +- .../biome/impl/taiga/ColdTaigaBiome.java | 4 +- .../nukkit/level/biome/type/CoveredBiome.java | 122 ++---------------- .../nukkit/level/biome/type/GrassyBiome.java | 8 +- .../nukkit/level/biome/type/SandyBiome.java | 13 +- .../nukkit/level/biome/type/SnowyBiome.java | 4 +- .../nukkit/level/biome/type/WateryBiome.java | 10 +- .../populator/impl/PopulatorCaves.java | 2 +- 14 files changed, 52 insertions(+), 193 deletions(-) diff --git a/src/main/java/cn/nukkit/level/biome/impl/beach/ColdBeachBiome.java b/src/main/java/cn/nukkit/level/biome/impl/beach/ColdBeachBiome.java index 8ec3e1c8c55..98c85216fda 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/beach/ColdBeachBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/beach/ColdBeachBiome.java @@ -13,8 +13,8 @@ public ColdBeachBiome() { } @Override - public int getCoverBlock() { - return SNOW_LAYER; + public int getCoverId(int x, int z) { + return SNOW_LAYER << 4; } @Override diff --git a/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java b/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java index c959698b2c9..df49bc00fc1 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/extremehills/ExtremeHillsMBiome.java @@ -32,18 +32,8 @@ public String getName() { } @Override - public int getSurfaceBlock(int y) { - return this.getSurfaceBlock(0, y, 0); - } - - @Override - public int getSurfaceBlock(int x, int y, int z) { - return gravelNoise.noise2D(x, z, true) < -0.75f ? GRAVEL : super.getSurfaceBlock(x, y, z); - } - - @Override - public int getSurfaceDepth(int y) { - return this.getSurfaceDepth(0, y, 0); + public int getSurfaceId(int x, int y, int z) { + return gravelNoise.noise2D(x, z, true) < -0.75f ? GRAVEL << 4 : super.getSurfaceId(x, y, z); } @Override @@ -51,11 +41,6 @@ public int getSurfaceDepth(int x, int y, int z) { return gravelNoise.noise2D(x, z, true) < -0.75f ? 4 : super.getSurfaceDepth(x, y, z); } - @Override - public int getGroundDepth(int y) { - return this.getGroundDepth(0, y, 0); - } - @Override public int getGroundDepth(int x, int y, int z) { return gravelNoise.noise2D(x, z, true) < -0.75f ? 0 : super.getGroundDepth(x, y, z); diff --git a/src/main/java/cn/nukkit/level/biome/impl/extremehills/StoneBeachBiome.java b/src/main/java/cn/nukkit/level/biome/impl/extremehills/StoneBeachBiome.java index 26830acaef5..f5b192bf217 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/extremehills/StoneBeachBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/extremehills/StoneBeachBiome.java @@ -16,22 +16,22 @@ public StoneBeachBiome() { } @Override - public int getSurfaceDepth(int y) { + public int getSurfaceDepth(int x, int y, int z) { return 0; } @Override - public int getSurfaceBlock(int y) { + public int getSurfaceId(int x, int y, int z) { return 0; } @Override - public int getGroundDepth(int y) { + public int getGroundDepth(int x, int y, int z) { return 0; } @Override - public int getGroundBlock(int y) { + public int getGroundId(int x, int y, int z) { return 0; } diff --git a/src/main/java/cn/nukkit/level/biome/impl/iceplains/IcePlainsSpikesBiome.java b/src/main/java/cn/nukkit/level/biome/impl/iceplains/IcePlainsSpikesBiome.java index 7e9aeea8ff5..9675180e674 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/iceplains/IcePlainsSpikesBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/iceplains/IcePlainsSpikesBiome.java @@ -19,8 +19,8 @@ public IcePlainsSpikesBiome() { } @Override - public int getSurfaceBlock(int y) { - return SNOW_BLOCK; + public int getSurfaceId(int x, int y, int z) { + return SNOW_BLOCK << 4; } public String getName() { diff --git a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java index bc3593796a7..67a3867a159 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaBiome.java @@ -73,58 +73,29 @@ public void setMoundHeight(int height) { this.moundHeight = height; } - @Override - public int getSurfaceDepth(int y) { - return this.getSurfaceDepth(0, y, 0); - } - @Override public int getSurfaceDepth(int x, int y, int z) { return y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f)) ? 3 : y - 66; } @Override - public int getSurfaceBlock(int y) { - return this.getSurfaceBlock(0, y, 0); - } - - @Override - public int getSurfaceBlock(int x, int y, int z) { + public int getSurfaceId(int x, int y, int z) { if (y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f))) { - return SAND; + return (SAND << 4) | BlockSand.RED; } else { int meta = colorLayer[(y + Math.round((colorNoise.noise2D(x, z, true) + 1) * 1.5f)) & 0x3F]; - return meta == -1 ? TERRACOTTA : STAINED_TERRACOTTA; - } - } - - @Override - public int getSurfaceMeta(int y) { - return this.getSurfaceMeta(0, y, 0); - } - - @Override - public int getSurfaceMeta(int x, int y, int z) { - if (y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f))) { - return BlockSand.RED; - } else { - return Math.max(0, colorLayer[(y + Math.round((colorNoise.noise2D(x, z, true) + 1) * 1.5f)) & 0x3F]); + return (meta == -1 ? TERRACOTTA << 4 : STAINED_TERRACOTTA << 4) | Math.max(0, meta); } } - @Override - public int getGroundDepth(int y) { - return this.getGroundDepth(0, y, 0); - } - @Override public int getGroundDepth(int x, int y, int z) { return y < (71 + Math.round((redSandNoise.noise2D(x, z, true) + 1) * 1.5f)) ? 2 : 0; } @Override - public int getGroundBlock(int y) { - return RED_SANDSTONE; + public int getGroundId(int x, int y, int z) { + return RED_SANDSTONE << 4; } @Override diff --git a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java index a6cb36cf931..3a5433c70af 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java @@ -17,8 +17,8 @@ public MesaPlateauFBiome() { } @Override - public int getCoverBlock() { - return GRASS; + public int getCoverId(int x, int z) { + return GRASS << 4; } @Override diff --git a/src/main/java/cn/nukkit/level/biome/impl/mushroom/MushroomIslandBiome.java b/src/main/java/cn/nukkit/level/biome/impl/mushroom/MushroomIslandBiome.java index 06b30f9e588..b9e3706034b 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/mushroom/MushroomIslandBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/mushroom/MushroomIslandBiome.java @@ -20,7 +20,7 @@ public String getName() { } @Override - public int getSurfaceBlock(int y) { - return Block.MYCELIUM; + public int getSurfaceId(int x, int y, int z) { + return MYCELIUM << 4; } } diff --git a/src/main/java/cn/nukkit/level/biome/impl/taiga/ColdTaigaBiome.java b/src/main/java/cn/nukkit/level/biome/impl/taiga/ColdTaigaBiome.java index 9b8450cc2a6..54332c48d17 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/taiga/ColdTaigaBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/taiga/ColdTaigaBiome.java @@ -23,8 +23,8 @@ public String getName() { } @Override - public int getCoverBlock() { - return SNOW_LAYER; + public int getCoverId(int x, int z) { + return SNOW_LAYER << 4; } @Override diff --git a/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java b/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java index 60a498a9445..b934cd3b1d1 100644 --- a/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java +++ b/src/main/java/cn/nukkit/level/biome/type/CoveredBiome.java @@ -12,129 +12,33 @@ *

*/ public abstract class CoveredBiome extends Biome { - /** - * A single block placed on top of the surface blocks - * - * @return cover block - */ - public int getCoverBlock() { - return AIR; - } - - /** - * The metadata of the cover block - * - * @return cover block - */ - public int getCoverMeta() { - return 0; - } - - /** - * The amount of times the surface block should be used - *

- * If < 0 bad things will happen! - *

- * - * @param y y - * @return surface depth - */ - public int getSurfaceDepth(int y) { - return 1; + public int getCoverId(int x, int z) { + return AIR << 4; } public int getSurfaceDepth(int x, int y, int z) { - return this.getSurfaceDepth(y); - } - - /** - * Between cover and ground - * - * @param y y - * @return surface block - */ - public abstract int getSurfaceBlock(int y); - - public int getSurfaceBlock(int x, int y, int z) { - return this.getSurfaceBlock(y); - } - - /** - * The metadata of the surface block - * - * @param y y - * @return surface meta - */ - public int getSurfaceMeta(int y) { - return 0; - } - - public int getSurfaceMeta(int x, int y, int z) { - return this.getSurfaceMeta(y); + return 1; } - /** - * The amount of times the ground block should be used - *

- * If < 0 bad things will happen! - * - * @param y y - * @return ground depth - */ - public int getGroundDepth(int y) { - return 4; - } + public abstract int getSurfaceId(int x, int y, int z); public int getGroundDepth(int x, int y, int z) { - return this.getGroundDepth(y); - } - - /** - * Between surface and stone - * - * @param y y - * @return ground block - */ - public abstract int getGroundBlock(int y); - - public int getGroundBlock(int x, int y, int z) { - return this.getGroundBlock(y); - } - - /** - * The metadata of the ground block - * - * @param y y - * @return ground meta - */ - public int getGroundMeta(int y) { - return 0; - } - - public int getGroundMeta(int x, int y, int z) { - return this.getGroundMeta(y); + return 4; } - /** - * The block used as stone/below all other surface blocks - * - * @return stone block - */ - public int getStoneBlock() { - return STONE; - } + public abstract int getGroundId(int x, int y, int z); public void doCover(int x, int z, FullChunk chunk) { - final int coverBlock = (this.getCoverBlock() << 4) | this.getCoverMeta(); - final int fullX = (chunk.getX() << 4) | x; final int fullZ = (chunk.getZ() << 4) | z; + final int coverBlock = this.getCoverId(fullX, fullZ); + boolean hasCovered = false; int realY; //start one below build limit in case of cover blocks for (int y = 254; y > 32; y--) { - if (chunk.getFullBlock(x, y, z) == STONE) { + if (chunk.getFullBlock(x, y, z) == STONE << 4) { COVER: if (!hasCovered) { if (y >= Normal.seaHeight) { @@ -142,8 +46,8 @@ public void doCover(int x, int z, FullChunk chunk) { int surfaceDepth = this.getSurfaceDepth(fullX, y, fullZ); for (int i = 0; i < surfaceDepth; i++) { realY = y - i; - if (chunk.getFullBlock(x, realY, z) == STONE) { - chunk.setFullBlockId(x, realY, z, (this.getSurfaceBlock(fullX, realY, fullZ) << 4) | this.getSurfaceMeta(fullX, realY, fullZ)); + if (chunk.getFullBlock(x, realY, z) == STONE << 4) { + chunk.setFullBlockId(x, realY, z, this.getSurfaceId(fullX, realY, fullZ)); } else break COVER; } y -= surfaceDepth; @@ -151,8 +55,8 @@ public void doCover(int x, int z, FullChunk chunk) { int groundDepth = this.getGroundDepth(fullX, y, fullZ); for (int i = 0; i < groundDepth; i++) { realY = y - i; - if (chunk.getFullBlock(x, realY, z) == STONE) { - chunk.setFullBlockId(x, realY, z, (this.getGroundBlock(fullX, realY, fullZ) << 4) | this.getGroundMeta(fullX, realY, fullZ)); + if (chunk.getFullBlock(x, realY, z) == STONE << 4) { + chunk.setFullBlockId(x, realY, z, this.getGroundId(fullX, realY, fullZ)); } else break COVER; } //don't take all of groundDepth away because we do y-- in the loop diff --git a/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java b/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java index 3d7afbd9369..91048cab4b7 100644 --- a/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java +++ b/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java @@ -20,12 +20,12 @@ public GrassyBiome() { } @Override - public int getSurfaceBlock(int y) { - return GRASS; + public int getSurfaceId(int x, int y, int z) { + return GRASS << 4; } @Override - public int getGroundBlock(int y) { - return DIRT; + public int getGroundId(int x, int y, int z) { + return DIRT << 4; } } diff --git a/src/main/java/cn/nukkit/level/biome/type/SandyBiome.java b/src/main/java/cn/nukkit/level/biome/type/SandyBiome.java index f094309143c..e7b854e0ae8 100644 --- a/src/main/java/cn/nukkit/level/biome/type/SandyBiome.java +++ b/src/main/java/cn/nukkit/level/biome/type/SandyBiome.java @@ -7,24 +7,23 @@ * Nukkit Project */ public abstract class SandyBiome extends CoveredBiome { - @Override - public int getSurfaceDepth(int y) { + public int getSurfaceDepth(int x, int y, int z) { return 3; } @Override - public int getSurfaceBlock(int y) { - return Block.SAND; + public int getSurfaceId(int x, int y, int z) { + return SAND << 4; } @Override - public int getGroundDepth(int y) { + public int getGroundDepth(int x, int y, int z) { return 2; } @Override - public int getGroundBlock(int y) { - return Block.SANDSTONE; + public int getGroundId(int x, int y, int z) { + return SANDSTONE << 4; } } diff --git a/src/main/java/cn/nukkit/level/biome/type/SnowyBiome.java b/src/main/java/cn/nukkit/level/biome/type/SnowyBiome.java index 81445bbf943..686d941e415 100644 --- a/src/main/java/cn/nukkit/level/biome/type/SnowyBiome.java +++ b/src/main/java/cn/nukkit/level/biome/type/SnowyBiome.java @@ -15,7 +15,7 @@ public SnowyBiome() { } @Override - public int getCoverBlock() { - return SNOW_LAYER; + public int getCoverId(int x, int z) { + return SNOW_LAYER << 4; } } diff --git a/src/main/java/cn/nukkit/level/biome/type/WateryBiome.java b/src/main/java/cn/nukkit/level/biome/type/WateryBiome.java index 2caa9e8c834..17ba88e2aa4 100644 --- a/src/main/java/cn/nukkit/level/biome/type/WateryBiome.java +++ b/src/main/java/cn/nukkit/level/biome/type/WateryBiome.java @@ -6,23 +6,23 @@ */ public abstract class WateryBiome extends CoveredBiome { @Override - public int getSurfaceDepth(int y) { + public int getSurfaceDepth(int x, int y, int z) { return 0; } @Override - public int getSurfaceBlock(int y) { + public int getSurfaceId(int x, int y, int z) { //doesn't matter, surface depth is 0 return 0; } @Override - public int getGroundDepth(int y) { + public int getGroundDepth(int x, int y, int z) { return 5; } @Override - public int getGroundBlock(int y) { - return DIRT; + public int getGroundId(int x, int y, int z) { + return DIRT << 4; } } diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java index bfadd32b2a8..59eaed143aa 100644 --- a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java +++ b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java @@ -206,7 +206,7 @@ protected void generateCaveNode(long seed, FullChunk chunk, double x, double y, // If grass was just deleted, try to // move it down if (grassFound && (chunk.getBlockId(xx, yy - 1, zz) == Block.DIRT)) { - chunk.setBlock(xx, yy - 1, zz, ((CoveredBiome) biome).getSurfaceBlock(yy - 1)); + chunk.setFullBlockId(xx, yy - 1, zz, ((CoveredBiome) biome).getSurfaceId(xx, yy - 1, zz)); } } } From e45589127c44b95bb40cfd779ef58f76de40be61 Mon Sep 17 00:00:00 2001 From: SupremeMortal <6178101+SupremeMortal@users.noreply.github.com> Date: Thu, 26 Sep 2019 11:48:37 +0100 Subject: [PATCH 37/39] Bump to RakNet 1.6.14 --- pom.xml | 2 +- src/main/resources/lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ba13b4ebd2a..db1f98ae5fb 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.12 + 1.6.14 compile diff --git a/src/main/resources/lang b/src/main/resources/lang index c63bafbc9ae..49caa033925 160000 --- a/src/main/resources/lang +++ b/src/main/resources/lang @@ -1 +1 @@ -Subproject commit c63bafbc9aea902cac375e48d13944c4232a22c5 +Subproject commit 49caa033925b316d6a5738c6cb221253c4f70dc9 From 1e106e3f7ce2f6fc64bcb1e0c7cfc92bf858918e Mon Sep 17 00:00:00 2001 From: SupremeMortal <6178101+SupremeMortal@users.noreply.github.com> Date: Sat, 30 Nov 2019 16:15:54 +0000 Subject: [PATCH 38/39] Bump to RakNet 1.6.15 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index db1f98ae5fb..b7532d2ad66 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.nukkitx.network raknet - 1.6.14 + 1.6.15 compile From 4f7c4b0fd9621be8cfaafc7faa30e4edac246336 Mon Sep 17 00:00:00 2001 From: SupremeMortal <6178101+SupremeMortal@users.noreply.github.com> Date: Sun, 1 Dec 2019 15:58:07 +0000 Subject: [PATCH 39/39] Fix ocean biome --- .../java/cn/nukkit/level/biome/impl/ocean/OceanBiome.java | 5 ++--- src/main/resources/lang | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/level/biome/impl/ocean/OceanBiome.java b/src/main/java/cn/nukkit/level/biome/impl/ocean/OceanBiome.java index 786e163e2dc..cda7e9df1ea 100644 --- a/src/main/java/cn/nukkit/level/biome/impl/ocean/OceanBiome.java +++ b/src/main/java/cn/nukkit/level/biome/impl/ocean/OceanBiome.java @@ -18,8 +18,7 @@ public String getName() { return "Ocean"; } - @Override - public int getGroundBlock(int y) { - return GRAVEL; + public int getGroundId(int y) { + return GRAVEL << 4; } } diff --git a/src/main/resources/lang b/src/main/resources/lang index e39cdad344e..aa22d15587b 160000 --- a/src/main/resources/lang +++ b/src/main/resources/lang @@ -1 +1 @@ -Subproject commit e39cdad344ee2919e619ef352236489f32fb3cde +Subproject commit aa22d15587b11647d2466ec3739947387ff98296