This commit is contained in:
KennyTV 2021-06-13 11:41:07 +02:00
parent 76a75fc35a
commit d42140148f
No known key found for this signature in database
GPG key ID: 6BE3B555EBC5982B
20 changed files with 466 additions and 594 deletions

View file

@ -1,7 +1,7 @@
plugins { plugins {
java java
id("com.github.johnrengelman.shadow") version "7.0.0" apply false id("com.github.johnrengelman.shadow") version "7.0.0" apply false
id("io.papermc.paperweight.core") version "1.0.0-SNAPSHOT" id("io.papermc.paperweight.core") version "1.0.0-LOCAL-SNAPSHOT"
} }
val mcVersion = providers.gradleProperty("mcVersion") val mcVersion = providers.gradleProperty("mcVersion")

View file

@ -10,13 +10,13 @@ persistenting Living Entity, SPAWNER for spawners,
or DEFAULT since data was not stored. or DEFAULT since data was not stored.
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index 4b1f9b0ad5dc9ad6f33fddafc376b6f983a556ef..5b382091b1466b25ad42325d5808785a8e948552 100644 index 92927b9a90b2a4497dd572f6f752c40cf35dd8b8..4a6d58ef68b782291b4d26a8515be326481f5209 100644
--- a/src/main/java/org/bukkit/entity/Entity.java --- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -708,5 +708,11 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent @@ -711,5 +711,11 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
*/ // TODO remove impl here
@NotNull return getLocation().getChunk();
Chunk getChunk(); }
+ +
+ /** + /**
+ * @return The {@link org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason} that spawned this entity. + * @return The {@link org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason} that spawned this entity.

View file

@ -3,6 +3,8 @@ From: Aikar <aikar@aikar.co>
Date: Fri, 15 Feb 2019 01:08:19 -0500 Date: Fri, 15 Feb 2019 01:08:19 -0500
Subject: [PATCH] Allow Saving of Oversized Chunks Subject: [PATCH] Allow Saving of Oversized Chunks
Note 1.17 update: With 1.17, Entities are no longer stored in chunk slices, so this needs updating!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The Minecraft World Region File format has a hard cap of 1MB per chunk. The Minecraft World Region File format has a hard cap of 1MB per chunk.
This is due to the fact that the header of the file format only allocates This is due to the fact that the header of the file format only allocates
a single byte for sector count, meaning a maximum of 256 sectors, at 4k per sector. a single byte for sector count, meaning a maximum of 256 sectors, at 4k per sector.

View file

@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 6 May 2020 05:00:57 -0400
Subject: [PATCH] Handle Oversized Tile Entities in chunks
Splits out Extra Packets if too many TE's are encountered to prevent
creating too large of a packet to sed.
Co authored by Spottedleaf
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
index b7d303b5f51a35504888933efef74564fa01e59d..b587f774c8f88f2a1c3ea489f7e4fe0bbdeb5a41 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
@@ -34,7 +34,15 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
private boolean fullChunk;
public ClientboundLevelChunkPacket() {}
+ // Paper start
+ private final java.util.List<Packet> extraPackets = new java.util.ArrayList<>();
+ private static final int TE_LIMIT = Integer.getInteger("Paper.excessiveTELimit", 750);
+ @Override
+ public java.util.List<Packet> getExtraPackets() {
+ return extraPackets;
+ }
+ // Paper end
public ClientboundLevelChunkPacket(LevelChunk chunk, int includedSectionsMask) {
ChunkPos chunkcoordintpair = chunk.getPos();
@@ -61,6 +69,7 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
this.availableSections = this.extractChunkData(new FriendlyByteBuf(this.getWriteBuffer()), chunk, includedSectionsMask);
this.blockEntitiesTags = Lists.newArrayList();
iterator = chunk.getBlockEntities().entrySet().iterator();
+ int totalTileEntities = 0; // Paper
while (iterator.hasNext()) {
entry = (Entry) iterator.next();
@@ -69,6 +78,15 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
int j = blockposition.getY() >> 4;
if (this.isFullChunk() || (includedSectionsMask & 1 << j) != 0) {
+ // Paper start - improve oversized chunk data packet handling
+ if (++totalTileEntities > TE_LIMIT) {
+ ClientboundBlockEntityDataPacket updatePacket = tileentity.getUpdatePacket();
+ if (updatePacket != null) {
+ this.extraPackets.add(updatePacket);
+ continue;
+ }
+ }
+ // Paper end
CompoundTag nbttagcompound = tileentity.getUpdateTag();
if (tileentity instanceof SkullBlockEntity) { SkullBlockEntity.sanitizeTileEntityUUID(nbttagcompound); } // Paper

View file

@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: AgentTroll <woodyc40@gmail.com>
Date: Fri, 22 Mar 2019 22:24:03 -0700
Subject: [PATCH] Update entity Metadata for all tracked players
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 49c71b21b6b88bc41ca6ddf4c76186ce522ee456..1609ab94c86e964421f996d4d46aef30f8b8e696 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -420,6 +420,12 @@ public class ServerEntity {
return ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp);
}
+ // Paper start - Add broadcast method
+ void broadcast(Packet<?> packet) {
+ this.getPacketConsumer().accept(packet);
+ }
+ // Paper end
+
private void broadcastAndSend(Packet<?> packet) {
this.broadcast.accept(packet);
if (this.entity instanceof ServerPlayer) {
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index d6d8d83bc16572474d56a278dd119eacc2c52476..ed4129a51351aff16455960d71a0add1b8209c02 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2286,7 +2286,14 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
if (event.isCancelled() || this.player.inventory.getSelected() == null || this.player.inventory.getSelected().getItem() != origItem) {
// Refresh the current entity metadata
- this.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true));
+ // Paper start - update entity for all players
+ ClientboundSetEntityDataPacket packet1 = new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true);
+ if (entity.tracker != null) {
+ entity.tracker.broadcast(packet1);
+ } else {
+ this.send(packet1);
+ }
+ // Paper end
}
if (event.isCancelled()) {

View file

@ -1,265 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
Date: Sun, 17 Mar 2019 21:46:56 +0200
Subject: [PATCH] Fire event on GS4 query
diff --git a/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java b/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java
index d10de580430d754204b36de809376538a14591e6..f6f0539a8e6edbeb1c412cee753a282b24a38046 100644
--- a/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java
+++ b/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java
@@ -18,15 +18,27 @@ public class NetworkDataOutputStream {
this.dataOutputStream.write(abyte, 0, abyte.length);
}
+ public void writeString(String string) throws IOException { this.writeString(string); } // Paper - OBFHELPER
public void writeString(String s) throws IOException {
this.dataOutputStream.writeBytes(s);
this.dataOutputStream.write(0);
}
+ // Paper start - unchecked exception variant to use in Stream API
+ public void writeStringUnchecked(String string) {
+ try {
+ writeString(string);
+ } catch (IOException e) {
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(e);
+ }
+ }
+ // Paper end
+ public void writeInt(int i) throws IOException { this.write(i); } // Paper - OBFHELPER
public void write(int i) throws IOException {
this.dataOutputStream.write(i);
}
+ public void writeShort(short i) throws IOException { this.writeShort(i); } // Paper - OBFHELPER
public void writeShort(short short0) throws IOException {
this.dataOutputStream.writeShort(Short.reverseBytes(short0));
}
diff --git a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
index 170d047463154bd6851199f06fe343ccb1896213..5562a3caff328bb08857b4f06a79b1e52f390fdd 100644
--- a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
+++ b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
@@ -16,6 +16,7 @@ import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.Util;
import net.minecraft.server.ServerInterface;
+import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.rcon.NetworkDataOutputStream;
import net.minecraft.server.rcon.PktUtils;
import org.apache.logging.log4j.LogManager;
@@ -26,18 +27,18 @@ public class QueryThreadGs4 extends GenericThread {
private static final Logger LOGGER = LogManager.getLogger();
private long lastChallengeCheck;
private final int port;
- private final int serverPort;
- private final int maxPlayers;
- private final String serverName;
- private final String worldName;
+ private final int serverPort; private final int getServerPort() { return this.serverPort; } // Paper - OBFHELPER
+ private final int maxPlayers; private final int getMaxPlayers() { return this.maxPlayers; } // Paper - OBFHELPER
+ private final String serverName; private final String getMotd() { return this.serverName; } // Paper - OBFHELPER
+ private final String worldName; private final String getWorldName() { return this.worldName; } // Paper - OBFHELPER
private DatagramSocket socket;
private final byte[] buffer = new byte[1460];
- private String hostIp;
+ private String hostIp; public final String getServerHost() { return this.hostIp; } // Paper - OBFHELPER
private String serverIp;
private final Map<SocketAddress, QueryThreadGs4.RequestChallenge> validChallenges;
- private final NetworkDataOutputStream rulesResponse;
+ private final NetworkDataOutputStream rulesResponse; private final NetworkDataOutputStream getCachedFullResponse() { return this.rulesResponse; } // Paper - OBFHELPER
private long lastRulesResponse;
- private final ServerInterface serverInterface;
+ private final ServerInterface serverInterface; private final ServerInterface getServer() { return this.serverInterface; } // Paper - OBFHELPER
private QueryThreadGs4(ServerInterface server, int queryPort) {
super("Query Listener");
@@ -107,13 +108,39 @@ public class QueryThreadGs4 extends GenericThread {
remotestatusreply.write((int) 0);
remotestatusreply.writeBytes(this.getIdentBytes(packet.getSocketAddress()));
- remotestatusreply.writeString(this.serverName);
+ /* Paper start - GS4 Query event
+ remotestatusreply.a(this.i);
+ remotestatusreply.a("SMP");
+ remotestatusreply.a(this.j);
+ remotestatusreply.a(Integer.toString(this.r.getPlayerCount()));
+ remotestatusreply.a(Integer.toString(this.h));
+ remotestatusreply.a((short) this.g);
+ remotestatusreply.a(this.m);
+ */
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType =
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.BASIC;
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder()
+ .motd(this.getMotd())
+ .map(this.getWorldName())
+ .currentPlayers(this.getServer().getPlayerCount())
+ .maxPlayers(this.getMaxPlayers())
+ .port(this.getServerPort())
+ .hostname(this.getServerHost())
+ .gameVersion(this.getServer().getServerVersion())
+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion())
+ .build();
+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent =
+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, packet.getAddress(), queryResponse);
+ queryEvent.callEvent();
+ queryResponse = queryEvent.getResponse();
+ remotestatusreply.writeString(queryResponse.getMotd());
remotestatusreply.writeString("SMP");
- remotestatusreply.writeString(this.worldName);
- remotestatusreply.writeString(Integer.toString(this.serverInterface.getPlayerCount()));
- remotestatusreply.writeString(Integer.toString(this.maxPlayers));
- remotestatusreply.writeShort((short) this.serverPort);
- remotestatusreply.writeString(this.hostIp);
+ remotestatusreply.writeString(queryResponse.getMap());
+ remotestatusreply.writeString(Integer.toString(queryResponse.getCurrentPlayers()));
+ remotestatusreply.writeString(Integer.toString(queryResponse.getMaxPlayers()));
+ remotestatusreply.writeShort((short) queryResponse.getPort());
+ remotestatusreply.writeString(queryResponse.getHostname());
+ // Paper end
this.sendTo(remotestatusreply.toByteArray(), packet);
QueryThreadGs4.LOGGER.debug("Status [{}]", socketaddress);
}
@@ -150,41 +177,115 @@ public class QueryThreadGs4 extends GenericThread {
this.rulesResponse.writeString("splitnum");
this.rulesResponse.write((int) 128);
this.rulesResponse.write((int) 0);
- this.rulesResponse.writeString("hostname");
- this.rulesResponse.writeString(this.serverName);
- this.rulesResponse.writeString("gametype");
- this.rulesResponse.writeString("SMP");
- this.rulesResponse.writeString("game_id");
- this.rulesResponse.writeString("MINECRAFT");
- this.rulesResponse.writeString("version");
- this.rulesResponse.writeString(this.serverInterface.getServerVersion());
- this.rulesResponse.writeString("plugins");
- this.rulesResponse.writeString(this.serverInterface.getPluginNames());
- this.rulesResponse.writeString("map");
- this.rulesResponse.writeString(this.worldName);
- this.rulesResponse.writeString("numplayers");
- this.rulesResponse.writeString("" + this.serverInterface.getPlayerCount());
- this.rulesResponse.writeString("maxplayers");
- this.rulesResponse.writeString("" + this.maxPlayers);
- this.rulesResponse.writeString("hostport");
- this.rulesResponse.writeString("" + this.serverPort);
- this.rulesResponse.writeString("hostip");
- this.rulesResponse.writeString(this.hostIp);
- this.rulesResponse.write((int) 0);
- this.rulesResponse.write((int) 1);
- this.rulesResponse.writeString("player_");
- this.rulesResponse.write((int) 0);
- String[] astring = this.serverInterface.getPlayerNames();
+ /* Paper start - GS4 Query event
+ this.p.a("hostname");
+ this.p.a(this.i);
+ this.p.a("gametype");
+ this.p.a("SMP");
+ this.p.a("game_id");
+ this.p.a("MINECRAFT");
+ this.p.a("version");
+ this.p.a(this.r.getVersion());
+ this.p.a("plugins");
+ this.p.a(this.r.getPlugins());
+ this.p.a("map");
+ this.p.a(this.j);
+ this.p.a("numplayers");
+ this.p.a("" + this.r.getPlayerCount());
+ this.p.a("maxplayers");
+ this.p.a("" + this.h);
+ this.p.a("hostport");
+ this.p.a("" + this.g);
+ this.p.a("hostip");
+ this.p.a(this.m);
+ this.p.a((int) 0);
+ this.p.a((int) 1);
+ this.p.a("player_");
+ this.p.a((int) 0);
+ String[] astring = this.r.getPlayers();
String[] astring1 = astring;
int j = astring.length;
for (int k = 0; k < j; ++k) {
String s = astring1[k];
- this.rulesResponse.writeString(s);
+ this.p.a(s);
}
- this.rulesResponse.write((int) 0);
+ this.p.a((int) 0);
+ */
+ // Pack plugins
+ java.util.List<com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation> plugins = java.util.Collections.emptyList();
+ org.bukkit.plugin.Plugin[] bukkitPlugins;
+ if (((DedicatedServer) this.getServer()).server.getQueryPlugins() && (bukkitPlugins = org.bukkit.Bukkit.getPluginManager().getPlugins()).length > 0) {
+ plugins = java.util.stream.Stream.of(bukkitPlugins)
+ .map(plugin -> com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation.of(plugin.getName(), plugin.getDescription().getVersion()))
+ .collect(java.util.stream.Collectors.toList());
+ }
+
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder()
+ .motd(this.getMotd())
+ .map(this.getWorldName())
+ .currentPlayers(this.getServer().getPlayerCount())
+ .maxPlayers(this.getMaxPlayers())
+ .port(this.getServerPort())
+ .hostname(this.getServerHost())
+ .plugins(plugins)
+ .players(this.getServer().getPlayerNames())
+ .gameVersion(this.getServer().getServerVersion())
+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion())
+ .build();
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType =
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.FULL;
+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent =
+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, packet.getAddress(), queryResponse);
+ queryEvent.callEvent();
+ queryResponse = queryEvent.getResponse();
+ this.getCachedFullResponse().writeString("hostname");
+ this.getCachedFullResponse().writeString(queryResponse.getMotd());
+ this.getCachedFullResponse().writeString("gametype");
+ this.getCachedFullResponse().writeString("SMP");
+ this.getCachedFullResponse().writeString("game_id");
+ this.getCachedFullResponse().writeString("MINECRAFT");
+ this.getCachedFullResponse().writeString("version");
+ this.getCachedFullResponse().writeString(queryResponse.getGameVersion());
+ this.getCachedFullResponse().writeString("plugins");
+ java.lang.StringBuilder pluginsString = new java.lang.StringBuilder();
+ pluginsString.append(queryResponse.getServerVersion());
+ if (!queryResponse.getPlugins().isEmpty()) {
+ pluginsString.append(": ");
+ java.util.Iterator<com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation> iter = queryResponse.getPlugins().iterator();
+ while (iter.hasNext()) {
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation info = iter.next();
+ pluginsString.append(info.getName());
+ if (info.getVersion() != null) {
+ pluginsString.append(' ').append(info.getVersion().replace(";", ","));
+ }
+ if (iter.hasNext()) {
+ pluginsString.append(';').append(' ');
+ }
+ }
+ }
+ this.getCachedFullResponse().writeString(pluginsString.toString());
+ this.getCachedFullResponse().writeString("map");
+ this.getCachedFullResponse().writeString(queryResponse.getMap());
+ this.getCachedFullResponse().writeString("numplayers");
+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getCurrentPlayers()));
+ this.getCachedFullResponse().writeString("maxplayers");
+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getMaxPlayers()));
+ this.getCachedFullResponse().writeString("hostport");
+ this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getPort()));
+ this.getCachedFullResponse().writeString("hostip");
+ this.getCachedFullResponse().writeString(queryResponse.getHostname());
+ // The "meaningless data" start, copied from above
+ this.getCachedFullResponse().writeInt(0);
+ this.getCachedFullResponse().writeInt(1);
+ this.getCachedFullResponse().writeString("player_");
+ this.getCachedFullResponse().writeInt(0);
+ // "Meaningless data" end
+ queryResponse.getPlayers().forEach(this.getCachedFullResponse()::writeStringUnchecked);
+ this.getCachedFullResponse().writeInt(0);
+ // Paper end
return this.rulesResponse.toByteArray();
}
}

View file

@ -28,26 +28,10 @@ and then catch exceptions and close if they fire.
Part of this commit was authored by: Spottedleaf Part of this commit was authored by: Spottedleaf
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed0b562c1b 100644 index 9f0537799a3cae43fb120056b8fe805a4883cc4d..5897bdb4d1372fa3d7bdc482d02f0a54d8767bda 100644
--- a/src/main/java/net/minecraft/network/Connection.java --- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java
@@ -25,8 +25,15 @@ import net.minecraft.network.chat.Component; @@ -87,6 +87,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
+import net.minecraft.network.protocol.game.ClientboundBossEventPacket;
+import net.minecraft.network.protocol.game.ClientboundChatPacket;
+import net.minecraft.network.protocol.game.ClientboundCommandSuggestionsPacket;
import net.minecraft.network.protocol.game.ClientboundDisconnectPacket;
+import net.minecraft.network.protocol.game.ClientboundKeepAlivePacket;
+import net.minecraft.network.protocol.game.ClientboundSetTitlesPacket;
+import net.minecraft.server.MCUtil;
import net.minecraft.server.RunningOnDifferentThreadException;
+import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.ServerLoginPacketListenerImpl;
import net.minecraft.util.LazyLoadedValue;
@@ -75,6 +82,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
public int protocolVersion; public int protocolVersion;
public java.net.InetSocketAddress virtualHost; public java.net.InetSocketAddress virtualHost;
private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush"); private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush");
@ -58,7 +42,7 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
// Paper end // Paper end
public Connection(PacketFlow side) { public Connection(PacketFlow side) {
@@ -98,6 +109,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -110,6 +114,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
} }
public void setProtocol(ConnectionProtocol state) { public void setProtocol(ConnectionProtocol state) {
@ -66,12 +50,12 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
this.channel.attr(Connection.ATTRIBUTE_PROTOCOL).set(state); this.channel.attr(Connection.ATTRIBUTE_PROTOCOL).set(state);
this.channel.config().setAutoRead(true); this.channel.config().setAutoRead(true);
Connection.LOGGER.debug("Enabled auto read"); Connection.LOGGER.debug("Enabled auto read");
@@ -168,19 +180,84 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -186,19 +191,87 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
Validate.notNull(listener, "packetListener", new Object[0]); Validate.notNull(listener, "packetListener", new Object[0]);
this.packetListener = listener; this.packetListener = listener;
} }
+ // Paper start + // Paper start
+ public ServerPlayer getPlayer() { + public net.minecraft.server.level.ServerPlayer getPlayer() {
+ if (packetListener instanceof ServerGamePacketListenerImpl) { + if (packetListener instanceof ServerGamePacketListenerImpl) {
+ return ((ServerGamePacketListenerImpl) packetListener).player; + return ((ServerGamePacketListenerImpl) packetListener).player;
+ } else { + } else {
@ -101,11 +85,15 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
+ // Paper start + // Paper start
+ private static boolean canSendImmediate(Connection networkManager, Packet<?> packet) { + private static boolean canSendImmediate(Connection networkManager, Packet<?> packet) {
+ return networkManager.isPending || networkManager.protocol != ConnectionProtocol.PLAY || + return networkManager.isPending || networkManager.protocol != ConnectionProtocol.PLAY ||
+ packet instanceof ClientboundKeepAlivePacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundKeepAlivePacket ||
+ packet instanceof ClientboundChatPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundChatPacket ||
+ packet instanceof ClientboundCommandSuggestionsPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundCommandSuggestionsPacket ||
+ packet instanceof ClientboundSetTitlesPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket ||
+ packet instanceof ClientboundBossEventPacket; + packet instanceof net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket ||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket ||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket ||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundClearTitlesPacket ||
+ packet instanceof net.minecraft.network.protocol.game.ClientboundBossEventPacket;
+ } + }
+ // Paper end + // Paper end
+ } + }
@ -128,10 +116,10 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
+ } + }
+ packet.onPacketDispatch(getPlayer()); + packet.onPacketDispatch(getPlayer());
+ if (connected && (InnerUtil.canSendImmediate(this, packet) || ( + if (connected && (InnerUtil.canSendImmediate(this, packet) || (
+ MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() && + net.minecraft.server.MCUtil.isMainThread() && packet.isReady() && this.queue.isEmpty() &&
+ (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty()) + (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty())
+ ))) { + ))) {
+ this.dispatchPacket(packet, callback); + this.send(packet, callback);
+ return; + return;
} }
+ // write the packets to the queue, then flush - antixray hooks there already + // write the packets to the queue, then flush - antixray hooks there already
@ -142,106 +130,67 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
+ } else { + } else {
+ java.util.List<Connection.PacketHolder> packets = new java.util.ArrayList<>(1 + extraPackets.size()); + java.util.List<Connection.PacketHolder> packets = new java.util.ArrayList<>(1 + extraPackets.size());
+ packets.add(new Connection.PacketHolder(packet, null)); // delay the future listener until the end of the extra packets + packets.add(new Connection.PacketHolder(packet, null)); // delay the future listener until the end of the extra packets
+
+ for (int i = 0, len = extraPackets.size(); i < len;) { + for (int i = 0, len = extraPackets.size(); i < len;) {
+ Packet extra = extraPackets.get(i); + Packet extra = extraPackets.get(i);
+ boolean end = ++i == len; + boolean end = ++i == len;
+ packets.add(new Connection.PacketHolder(extra, end ? callback : null)); // append listener to the end + packets.add(new Connection.PacketHolder(extra, end ? callback : null)); // append listener to the end
+ } + }
+ this.queue.addAll(packets); // atomic + this.queue.addAll(packets); // atomic
+ } + }
+ this.sendPacketQueue(); + this.flushQueue();
+ // Paper end + // Paper end
} }
private void dispatchPacket(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> genericFutureListener) { this.sendPacket(packet, genericFutureListener); } // Paper - OBFHELPER private void sendPacket(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> callback) {
@@ -194,54 +271,119 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -226,33 +299,79 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
this.channel.config().setAutoRead(false); this.setProtocol(enumprotocol);
} }
+ ServerPlayer player = getPlayer(); // Paper + // Paper start
if (this.channel.eventLoop().inEventLoop()) { + net.minecraft.server.level.ServerPlayer player = getPlayer();
if (enumprotocol != enumprotocol1) { + if (!isConnected()) {
this.setProtocol(enumprotocol); + packet.onPacketDispatchFinish(player, null);
} + return;
+ // Paper start + }
+ if (!isConnected()) {
+ packet.onPacketDispatchFinish(player, null);
+ return;
+ }
+ try {
+ // Paper end
ChannelFuture channelfuture = this.channel.writeAndFlush(packet);
if (callback != null) {
channelfuture.addListener(callback);
}
+ // Paper start
+ if (packet.hasFinishListener()) {
+ channelfuture.addListener((ChannelFutureListener) channelFuture -> packet.onPacketDispatchFinish(player, channelFuture));
+ }
+ // Paper end
channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
+ // Paper start
+ } catch (Exception e) {
+ LOGGER.error("NetworkException: " + player, e);
+ disconnect(new TranslatableComponent("disconnect.genericReason", "Internal Exception: " + e.getMessage()));;
+ packet.onPacketDispatchFinish(player, null);
+ }
+ // Paper end
} else {
this.channel.eventLoop().execute(() -> {
if (enumprotocol != enumprotocol1) {
this.setProtocol(enumprotocol);
}
+ // Paper start
+ if (!isConnected()) {
+ packet.onPacketDispatchFinish(player, null);
+ return;
+ }
+ try {
+ // Paper end
ChannelFuture channelfuture1 = this.channel.writeAndFlush(packet);
+ +
if (callback != null) { + try {
channelfuture1.addListener(callback); + // Paper end
} ChannelFuture channelfuture = this.channel.writeAndFlush(packet);
+ // Paper start
+ if (packet.hasFinishListener()) {
+ channelfuture1.addListener((ChannelFutureListener) channelFuture -> packet.onPacketDispatchFinish(player, channelFuture));
+ }
+ // Paper end
channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); if (genericfuturelistener != null) {
+ // Paper start channelfuture.addListener(genericfuturelistener);
+ } catch (Exception e) {
+ LOGGER.error("NetworkException: " + player, e);
+ disconnect(new TranslatableComponent("disconnect.genericReason", "Internal Exception: " + e.getMessage()));;
+ packet.onPacketDispatchFinish(player, null);
+ }
+ // Paper end
});
} }
+ // Paper start
+ if (packet.hasFinishListener()) {
+ channelfuture.addListener((ChannelFutureListener) channelFuture -> packet.onPacketDispatchFinish(player, channelFuture));
+ }
+ // Paper end
channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
+ // Paper start
+ } catch (Exception e) {
+ LOGGER.error("NetworkException: " + player, e);
+ disconnect(new net.minecraft.network.chat.TranslatableComponent("disconnect.genericReason", "Internal Exception: " + e.getMessage()));
+ packet.onPacketDispatchFinish(player, null);
+ }
+ // Paper end
}
private ConnectionProtocol getCurrentProtocol() {
return (ConnectionProtocol) this.channel.attr(Connection.ATTRIBUTE_PROTOCOL).get();
} }
- private void sendPacketQueue() { this.flushQueue(); } // Paper - OBFHELPER
- private void flushQueue() { - private void flushQueue() {
- if (this.channel != null && this.channel.isOpen()) { - if (this.channel != null && this.channel.isOpen()) {
- Queue queue = this.queue; - Queue queue = this.queue;
- -
+ // Paper start - rewrite this to be safer if ran off main thread + // Paper start - rewrite this to be safer if ran off main thread
+ private boolean sendPacketQueue() { return this.p(); } // OBFHELPER // void -> boolean + private boolean flushQueue() { // void -> boolean
+ private boolean p() { // void -> boolean
+ if (!isConnected()) { + if (!isConnected()) {
+ return true; + return true;
+ } + }
+ if (MCUtil.isMainThread()) { + if (net.minecraft.server.MCUtil.isMainThread()) {
+ return processQueue(); + return processQueue();
+ } else if (isPending) { + } else if (isPending) {
+ // Should only happen during login/status stages + // Should only happen during login/status stages
@ -262,19 +211,19 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
+ // But if we are not on main due to login/status, the parent is synchronized on packetQueue + // But if we are not on main due to login/status, the parent is synchronized on packetQueue
+ java.util.Iterator<PacketHolder> iterator = this.queue.iterator(); + java.util.Iterator<PacketHolder> iterator = this.queue.iterator();
+ while (iterator.hasNext()) { + while (iterator.hasNext()) {
+ Connection.PacketHolder queued = iterator.next(); // poll -> peek + PacketHolder queued = iterator.next(); // poll -> peek
+ +
+ // Fix NPE (Spigot bug caused by handleDisconnection()) + // Fix NPE (Spigot bug caused by handleDisconnection())
+ if (queued == null) { + if (queued == null) {
+ return true; + return true;
+ } + }
+ Packet<?> packet = queued.getPacket(); + Packet<?> packet = queued.packet;
+ if (!packet.isReady()) { + if (!packet.isReady()) {
+ return false; + return false;
+ } else { + } else {
+ iterator.remove(); + iterator.remove();
+ this.dispatchPacket(packet, queued.getGenericFutureListener()); + this.sendPacket(packet, queued.listener);
} }
} }
+ return true; + return true;
@ -282,26 +231,23 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
+ // Paper end + // Paper end
public void tick() { public void tick() {
- this.flushQueue(); this.flushQueue();
+ this.p(); @@ -289,9 +408,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
if (this.packetListener instanceof ServerLoginPacketListenerImpl) {
((ServerLoginPacketListenerImpl) this.packetListener).tick();
}
@@ -271,9 +413,21 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
return this.address; return this.address;
} }
+ // Paper start + // Paper start
+ public void clearPacketQueue() { + public void clearPacketQueue() {
+ ServerPlayer player = getPlayer(); + net.minecraft.server.level.ServerPlayer player = getPlayer();
+ queue.forEach(queuedPacket -> { + queue.forEach(queuedPacket -> {
+ Packet<?> packet = queuedPacket.getPacket(); + Packet<?> packet = queuedPacket.packet;
+ if (packet.hasFinishListener()) { + if (packet.hasFinishListener()) {
+ packet.onPacketDispatchFinish(player, null); + packet.onPacketDispatchFinish(player, null);
+ } + }
+ }); + });
+ queue.clear(); + queue.clear();
+ } // Paper end + }
+ // Paper end
public void disconnect(Component disconnectReason) { public void disconnect(Component disconnectReason) {
// Spigot Start // Spigot Start
this.preparing = false; this.preparing = false;
@ -309,18 +255,18 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
// Spigot End // Spigot End
if (this.channel.isOpen()) { if (this.channel.isOpen()) {
this.channel.close(); // We can't wait as this may be called from an event loop. this.channel.close(); // We can't wait as this may be called from an event loop.
@@ -341,7 +495,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -409,7 +541,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
public void handleDisconnection() { public void handleDisconnection() {
if (this.channel != null && !this.channel.isOpen()) { if (this.channel != null && !this.channel.isOpen()) {
if (this.disconnectionHandled) { if (this.disconnectionHandled) {
- Connection.LOGGER.warn("handleDisconnection() called twice"); - Connection.LOGGER.warn("handleDisconnection() called twice");
+ //NetworkManager.LOGGER.warn("handleDisconnection() called twice"); // Paper - Do not log useless message + //Connection.LOGGER.warn("handleDisconnection() called twice"); // Paper - Do not log useless message
} else { } else {
this.disconnectionHandled = true; this.disconnectionHandled = true;
if (this.getDisconnectedReason() != null) { if (this.getDisconnectedReason() != null) {
@@ -349,7 +503,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -417,7 +549,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
} else if (this.getPacketListener() != null) { } else if (this.getPacketListener() != null) {
this.getPacketListener().a(new TranslatableComponent("multiplayer.disconnect.generic")); this.getPacketListener().onDisconnect(new TranslatableComponent("multiplayer.disconnect.generic"));
} }
- this.queue.clear(); // Free up packet queue. - this.queue.clear(); // Free up packet queue.
+ clearPacketQueue(); // Paper + clearPacketQueue(); // Paper
@ -328,67 +274,26 @@ index 3247ec5d6cf329ba0b7e6d5a6c3294dec2e34db4..fc63df21aecd4721efdb45d4744666ed
final PacketListener packetListener = this.getPacketListener(); final PacketListener packetListener = this.getPacketListener();
if (packetListener instanceof ServerGamePacketListenerImpl) { if (packetListener instanceof ServerGamePacketListenerImpl) {
diff --git a/src/main/java/net/minecraft/network/protocol/Packet.java b/src/main/java/net/minecraft/network/protocol/Packet.java diff --git a/src/main/java/net/minecraft/network/protocol/Packet.java b/src/main/java/net/minecraft/network/protocol/Packet.java
index 9914a82ba0ec146ab13fe94c4dbf0ebf64926536..22db5d0d2cc33498ca40162c66aa3b5fbf2f569f 100644 index 74bfe0d3942259c45702b099efdc4e101a4e3022..e8fcd56906d26f6dc87959e32c4c7c78cfea9658 100644
--- a/src/main/java/net/minecraft/network/protocol/Packet.java --- a/src/main/java/net/minecraft/network/protocol/Packet.java
+++ b/src/main/java/net/minecraft/network/protocol/Packet.java +++ b/src/main/java/net/minecraft/network/protocol/Packet.java
@@ -1,5 +1,6 @@ @@ -9,6 +9,19 @@ public interface Packet<T extends PacketListener> {
package net.minecraft.network.protocol;
+import io.netty.channel.ChannelFuture; // Paper
import java.io.IOException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.PacketListener;
@@ -13,6 +14,20 @@ public interface Packet<T extends PacketListener> {
void handle(T listener); void handle(T listener);
// Paper start // Paper start
+
+ /** + /**
+ * @param player Null if not at PLAY stage yet + * @param player Null if not at PLAY stage yet
+ */ + */
+ default void onPacketDispatch(@javax.annotation.Nullable EntityPlayer player) {} + default void onPacketDispatch(@javax.annotation.Nullable net.minecraft.server.level.ServerPlayer player) {}
+ +
+ /** + /**
+ * @param player Null if not at PLAY stage yet + * @param player Null if not at PLAY stage yet
+ * @param future Can be null if packet was cancelled + * @param future Can be null if packet was cancelled
+ */ + */
+ default void onPacketDispatchFinish(@javax.annotation.Nullable EntityPlayer player, @javax.annotation.Nullable ChannelFuture future) {} + default void onPacketDispatchFinish(@javax.annotation.Nullable net.minecraft.server.level.ServerPlayer player, @javax.annotation.Nullable io.netty.channel.ChannelFuture future) {}
+ default boolean hasFinishListener() { return false; } + default boolean hasFinishListener() { return false; }
+ default boolean isReady() { return true; } + default boolean isReady() { return true; }
+ default java.util.List<Packet> getExtraPackets() { return null; } + default java.util.List<Packet> getExtraPackets() { return null; }
default boolean packetTooLarge(NetworkManager manager) { default boolean packetTooLarge(net.minecraft.network.Connection manager) {
return false; return false;
} }
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
index 6cb51a4fe3c11f53fbb556ce6b0d64b735254d51..d46910cfdc0aef046a0c79731a85d381953c328a 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -16,6 +16,7 @@ import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.flush.FlushConsolidationHandler; // Paper
import io.netty.handler.timeout.ReadTimeoutHandler;
import java.io.IOException;
import java.net.InetAddress;
@@ -54,10 +55,12 @@ public class ServerConnectionListener {
private final List<Connection> connections = Collections.synchronizedList(Lists.newArrayList());
// Paper start - prevent blocking on adding a new network manager while the server is ticking
private final java.util.Queue<Connection> pending = new java.util.concurrent.ConcurrentLinkedQueue<>();
+ private static final boolean disableFlushConsolidation = Boolean.getBoolean("Paper.disableFlushConsolidate"); // Paper
private void addPending() {
Connection manager = null;
while ((manager = pending.poll()) != null) {
connections.add(manager);
+ manager.isPending = false;
}
}
// Paper end
@@ -92,6 +95,7 @@ public class ServerConnectionListener {
;
}
+ if (!disableFlushConsolidation) channel.pipeline().addFirst(new FlushConsolidationHandler()); // Paper
channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyQueryHandler(ServerConnectionListener.this)).addLast("splitter", new Varint21FrameDecoder()).addLast("decoder", new PacketDecoder(PacketFlow.SERVERBOUND)).addLast("prepender", new Varint21LengthFieldPrepender()).addLast("encoder", new PacketEncoder(PacketFlow.CLIENTBOUND));
int j = ServerConnectionListener.this.server.getRateLimitPacketsPerSecond();
Object object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND);

View file

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 6 May 2020 05:00:57 -0400
Subject: [PATCH] Handle Oversized Tile Entities in chunks
Splits out Extra Packets if too many TE's are encountered to prevent
creating too large of a packet to sed.
Co authored by Spottedleaf
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
index 96626835fee3c0fdb452acacdc9f737ad90c08de..c28879f32b004f36ff746ea2274f91ddd9501e71 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
@@ -27,6 +27,15 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
private final int[] biomes;
private final byte[] buffer;
private final List<CompoundTag> blockEntitiesTags;
+ // Paper start
+ private final java.util.List<Packet> extraPackets = new java.util.ArrayList<>();
+ private static final int TE_LIMIT = Integer.getInteger("Paper.excessiveTELimit", 750);
+
+ @Override
+ public java.util.List<Packet> getExtraPackets() {
+ return extraPackets;
+ }
+ // Paper end
public ClientboundLevelChunkPacket(LevelChunk chunk) {
ChunkPos chunkPos = chunk.getPos();
@@ -44,9 +53,19 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
this.buffer = new byte[this.calculateChunkSize(chunk)];
this.availableSections = this.extractChunkData(new FriendlyByteBuf(this.getWriteBuffer()), chunk);
this.blockEntitiesTags = Lists.newArrayList();
+ int totalTileEntities = 0; // Paper
for(Entry<BlockPos, BlockEntity> entry2 : chunk.getBlockEntities().entrySet()) {
BlockEntity blockEntity = entry2.getValue();
+ // Paper start - improve oversized chunk data packet handling
+ if (++totalTileEntities > TE_LIMIT) {
+ ClientboundBlockEntityDataPacket updatePacket = blockEntity.getUpdatePacket();
+ if (updatePacket != null) {
+ this.extraPackets.add(updatePacket);
+ continue;
+ }
+ }
+ // Paper end
CompoundTag compoundTag = blockEntity.getUpdateTag();
if (blockEntity instanceof net.minecraft.world.level.block.entity.SkullBlockEntity) { net.minecraft.world.level.block.entity.SkullBlockEntity.sanitizeTileEntityUUID(compoundTag); } // Paper
this.blockEntitiesTags.add(compoundTag);

View file

@ -11,10 +11,10 @@ everything to the Whitelist object.
https://github.com/PaperMC/Paper/issues/1880 https://github.com/PaperMC/Paper/issues/1880
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 5b71b487836cdd2ddc75b2039f4dc0177719d345..8d133d3c825f7747081de99ee67d4556e5c19cdd 100644 index 0df68991eb2ef3dabe779f42c2bf44846ac0d862..4ae234a107d16bc71425af5f2729c428f79e3db7 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -55,6 +55,7 @@ import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; @@ -62,6 +62,7 @@ import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket; import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateTagsPacket; import net.minecraft.network.protocol.game.ClientboundUpdateTagsPacket;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
@ -22,24 +22,15 @@ index 5b71b487836cdd2ddc75b2039f4dc0177719d345..8d133d3c825f7747081de99ee67d4556
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerAdvancements; import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.ServerScoreboard; import net.minecraft.server.ServerScoreboard;
@@ -1012,9 +1013,9 @@ public abstract class PlayerList { @@ -996,9 +997,9 @@ public abstract class PlayerList {
} }
public boolean isWhitelisted(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) { public boolean isWhitelisted(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) {
boolean isOp = this.ops.contains(gameprofile); boolean isOp = this.ops.contains(gameprofile);
- boolean isWhitelisted = !this.doWhiteList || isOp || this.whitelist.contains(gameprofile); - boolean isWhitelisted = !this.doWhiteList || isOp || this.whitelist.contains(gameprofile);
+ boolean isWhitelisted = !this.isUsingWhitelist() || isOp || this.whitelist.contains(gameprofile); + boolean isWhitelisted = !this.isUsingWhitelist() || isOp || this.whitelist.contains(gameprofile); // Paper - use isUsingWhitelist()
final com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent event; final com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent event;
- event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(MCUtil.toBukkit(gameprofile), this.doWhiteList, isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage); - event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(net.minecraft.server.MCUtil.toBukkit(gameprofile), this.doWhiteList, isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage);
+ event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(MCUtil.toBukkit(gameprofile), this.isUsingWhitelist(), isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage); + event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(net.minecraft.server.MCUtil.toBukkit(gameprofile), this.isUsingWhitelist(), isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage); // Paper - use isUsingWhitelist()
event.callEvent(); event.callEvent();
if (!event.isWhitelisted()) { if (!event.isWhitelisted()) {
if (loginEvent != null) { if (loginEvent != null) {
@@ -1062,7 +1063,7 @@ public abstract class PlayerList {
MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
MinecraftTimings.savePlayers.startTiming(); // Paper
for (int i = 0; i < this.players.size(); ++i) {
- this.savePlayerFile((EntityPlayer) this.players.get(i));
+ this.save((ServerPlayer) this.players.get(i));
}
MinecraftTimings.savePlayers.stopTiming(); // Paper
return null; }); // Paper - ensure main

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Set Zombie last tick at start of drowning process
Fixes GH-1887 Fixes GH-1887
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index ad4eeb15771750193a28116117992270c72a3644..6fecf4188fc0247143edc688c03e645376960687 100644 index c60d9775230b2ff554eeb38136f8e7c32c47d8cf..ee17cba501e0cc4822bd1278d18b561c77fe9674 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -220,6 +220,7 @@ public class Zombie extends Monster { @@ -225,6 +225,7 @@ public class Zombie extends Monster {
++this.inWaterTime; ++this.inWaterTime;
if (this.inWaterTime >= 600) { if (this.inWaterTime >= 600) {
this.startUnderWaterConversion(300); this.startUnderWaterConversion(300);

View file

@ -5,10 +5,10 @@ Subject: [PATCH] Call WhitelistToggleEvent when whitelist is toggled
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 8d133d3c825f7747081de99ee67d4556e5c19cdd..728eaadd3dc619e414ec30feb38c7d4a84b2e539 100644 index 4ae234a107d16bc71425af5f2729c428f79e3db7..ea336bdf2f15aabe74de82ef6c29b93573254e31 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1131,6 +1131,7 @@ public abstract class PlayerList { @@ -1115,6 +1115,7 @@ public abstract class PlayerList {
} }
public void setUsingWhiteList(boolean whitelistEnabled) { public void setUsingWhiteList(boolean whitelistEnabled) {

View file

@ -6,26 +6,26 @@ Subject: [PATCH] Use proper max length when serialising BungeeCord text
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java
index f13da9e7d014bc00fbabf0a495b548bba2f59468..002a6c7933f64405707d7d34d3e5c17584539623 100644 index a64780b4b49d01322d8f755ff540a9622c89e983..26a229f7aa3f4425ed572e2d50730b4e978bf33e 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundChatPacket.java
@@ -9,7 +9,7 @@ import net.minecraft.network.chat.Component; @@ -8,7 +8,7 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.Packet;
public class ClientboundChatPacket implements Packet<ClientGamePacketListener> { public class ClientboundChatPacket implements Packet<ClientGamePacketListener> {
- -
+ private static final int MAX_LENGTH = Short.MAX_VALUE * 8 + 8; // Paper + private static final int MAX_LENGTH = Short.MAX_VALUE * 8 + 8; // Paper
private Component message; private final Component message;
public net.kyori.adventure.text.Component adventure$message; // Paper public net.kyori.adventure.text.Component adventure$message; // Paper
public net.md_5.bungee.api.chat.BaseComponent[] components; // Spigot public net.md_5.bungee.api.chat.BaseComponent[] components; // Spigot
@@ -43,9 +43,9 @@ public class ClientboundChatPacket implements Packet<ClientGamePacketListener> { @@ -39,9 +39,9 @@ public class ClientboundChatPacket implements Packet<ClientGamePacketListener> {
//packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(components)); // Paper - comment, replaced with below // buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(components)); // Paper - comment, replaced with below
// Paper start - don't nest if we don't need to so that we can preserve formatting // Paper start - don't nest if we don't need to so that we can preserve formatting
if (this.components.length == 1) { if (this.components.length == 1) {
- buf.writeByteArray(net.md_5.bungee.chat.ComponentSerializer.toString(this.components[0])); - buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(this.components[0]));
+ buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(this.components[0]), MAX_LENGTH); // Paper - use proper max length + buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(this.components[0]), MAX_LENGTH); // Paper - use proper max length
} else { } else {
- buf.writeByteArray(net.md_5.bungee.chat.ComponentSerializer.toString(this.components)); - buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(this.components));
+ buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(this.components), MAX_LENGTH); // Paper - use proper max length + buf.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(this.components), MAX_LENGTH); // Paper - use proper max length
} }
// Paper end // Paper end

View file

@ -10,22 +10,22 @@ persistenting Living Entity, SPAWNER for spawners,
or DEFAULT since data was not stored. or DEFAULT since data was not stored.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 2ab221e5315dde4e556ee49a6962ae0091ccf616..d03b4f97102dfb88927a94ee5a5d397ac493eaa1 100644 index 731c8e38c8daf04fee40a5ccfb0715b20f4d890f..940e6587125df1f203cdeeefc31658635badea81 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1035,6 +1035,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl @@ -1093,6 +1093,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
// CraftBukkit start // CraftBukkit start
private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
+ if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper + if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper
// Paper start if (entity.isRemoved()) {
if (entity.valid) { // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.getEntityType())); // CraftBukkit
MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); return false;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 728eaadd3dc619e414ec30feb38c7d4a84b2e539..4d813b6556030354f51c1ee5f18eac2166b44576 100644 index ea336bdf2f15aabe74de82ef6c29b93573254e31..da3100d6577166e222164c174b28020541dd8e3a 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -331,7 +331,7 @@ public abstract class PlayerList { @@ -335,7 +335,7 @@ public abstract class PlayerList {
// CraftBukkit start // CraftBukkit start
ServerLevel finalWorldServer = worldserver1; ServerLevel finalWorldServer = worldserver1;
Entity entity = EntityType.loadEntityRecursive(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> { Entity entity = EntityType.loadEntityRecursive(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> {
@ -35,10 +35,10 @@ index 728eaadd3dc619e414ec30feb38c7d4a84b2e539..4d813b6556030354f51c1ee5f18eac21
}); });
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index d106118dbf4fb270f8526e40a767dd4c563a333f..6faac8773136412ca129dfa884178f311e197f6e 100644 index 8df9bd656374d0b43af378c61c1df7b951085b58..fcd3e6bfb4b1d0aefcb34eaec1212b08498dd5af 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -63,6 +63,8 @@ import net.minecraft.world.InteractionHand; @@ -67,6 +67,8 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.Nameable; import net.minecraft.world.Nameable;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
@ -47,30 +47,30 @@ index d106118dbf4fb270f8526e40a767dd4c563a333f..6faac8773136412ca129dfa884178f31
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.Boat; import net.minecraft.world.entity.vehicle.Boat;
@@ -157,6 +159,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -166,6 +168,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
} }
}; };
public List<Entity> entitySlice = null;
+ public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason;
// Paper end // Paper end
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
@@ -1673,6 +1676,9 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -1841,6 +1844,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
tag.setUUID("Paper.OriginWorld", origin.getWorld().getUID()); nbt.setUUID("Paper.OriginWorld", origin.getWorld().getUID());
tag.put("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ())); nbt.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ()));
} }
+ if (spawnReason != null) { + if (spawnReason != null) {
+ tag.putString("Paper.SpawnReason", spawnReason.name()); + nbt.putString("Paper.SpawnReason", spawnReason.name());
+ } + }
// Save entity's from mob spawner status // Save entity's from mob spawner status
if (spawnedViaMobSpawner) { if (spawnedViaMobSpawner) {
tag.putBoolean("Paper.FromMobSpawner", true); nbt.putBoolean("Paper.FromMobSpawner", true);
@@ -1811,6 +1817,26 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -1983,6 +1989,26 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
} }
spawnedViaMobSpawner = tag.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
+ if (tag.contains("Paper.SpawnReason")) { + if (nbt.contains("Paper.SpawnReason")) {
+ String spawnReasonName = tag.getString("Paper.SpawnReason"); + String spawnReasonName = nbt.getString("Paper.SpawnReason");
+ try { + try {
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName); + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName);
+ } catch (Exception ignored) { + } catch (Exception ignored) {
@ -81,7 +81,7 @@ index d106118dbf4fb270f8526e40a767dd4c563a333f..6faac8773136412ca129dfa884178f31
+ if (spawnedViaMobSpawner) { + if (spawnedViaMobSpawner) {
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER;
+ } else if (this instanceof Mob && (this instanceof Animal || this instanceof AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) { + } else if (this instanceof Mob && (this instanceof Animal || this instanceof AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) {
+ if (!tag.getBoolean("PersistenceRequired")) { + if (!nbt.getBoolean("PersistenceRequired")) {
+ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL;
+ } + }
+ } + }
@ -93,22 +93,22 @@ index d106118dbf4fb270f8526e40a767dd4c563a333f..6faac8773136412ca129dfa884178f31
} catch (Throwable throwable) { } catch (Throwable throwable) {
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index 1ce675d0d24ceb5724f5ac2d8f671e38f2735f74..3a7aec9bd2f3fd1b4a1981fb6a8c64b69e4875f8 100644 index 12a78685848b7fd945a472902d8200ea1d50b9ec..3aadcb472ab808ee981065ddfa86be6cbf38c8d9 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java --- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java +++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -183,6 +183,7 @@ public abstract class BaseSpawner { @@ -167,6 +167,7 @@ public abstract class BaseSpawner {
// Spigot End // Spigot End
} }
entity.spawnedViaMobSpawner = true; // Paper entity.spawnedViaMobSpawner = true; // Paper
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper + entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper
flag = true; // Paper flag = true; // Paper
// Spigot Start // Spigot Start
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, blockposition).isCancelled()) { if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index e1bbaf620f3ed2a6cb9ce8007a78c4cee47b653e..7ad4fb57af32cc1b8278688381e1b058ed8437db 100644 index c381ea321b0fb3498e3f101ee059ac7d42aa029a..33bc56eba4229d844e3af6ff4662d96450e929af 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1106,5 +1106,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @@ -1163,5 +1163,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public boolean fromMobSpawner() { public boolean fromMobSpawner() {
return getHandle().spawnedViaMobSpawner; return getHandle().spawnedViaMobSpawner;
} }

View file

@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: AgentTroll <woodyc40@gmail.com>
Date: Fri, 22 Mar 2019 22:24:03 -0700
Subject: [PATCH] Update entity Metadata for all tracked players
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 8311d921ded1c81a1f561dc13db2010d2b7ce5d6..95ac30f56a9268f14d2518974c5a52e08f40ea18 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1281,6 +1281,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else {
ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
playerchunkmap_entitytracker.updatePlayers(this.level.players());
if (entity instanceof ServerPlayer) {
@@ -1323,7 +1324,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (playerchunkmap_entitytracker1 != null) {
playerchunkmap_entitytracker1.broadcastRemoved();
}
-
+ entity.tracker = null; // Paper - We're no longer tracked
}
protected void tick() {
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index ad9bbda31a4cdb306ca40f2b99e4b815c4f136bd..28afe2f238ded241acf77c3272a44068646b9133 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -392,6 +392,12 @@ public class ServerEntity {
return ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp);
}
+ // Paper start - Add broadcast method
+ void broadcast(Packet<?> packet) {
+ this.broadcast.accept(packet);
+ }
+ // Paper end
+
private void broadcastAndSend(Packet<?> packet) {
this.broadcast.accept(packet);
if (this.entity instanceof ServerPlayer) {
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index defebf7b45e4f006fa7e575b5dbd01ac1e231d5a..6c4266d847b1181a055fa425d5734032dadabf93 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2289,7 +2289,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem) {
// Refresh the current entity metadata
- ServerGamePacketListenerImpl.this.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true));
+ // Paper start - update entity for all players
+ ClientboundSetEntityDataPacket packet1 = new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true);
+ if (entity.tracker != null) {
+ entity.tracker.broadcast(packet1);
+ } else {
+ ServerGamePacketListenerImpl.this.send(packet1);
+ }
+ // Paper end
}
if (event.isCancelled()) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index fcd3e6bfb4b1d0aefcb34eaec1212b08498dd5af..a5159198003e43ce272ae73941d2be47d50eedc9 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -300,6 +300,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
public boolean forceExplosionKnockback; // SPIGOT-949
public boolean persistentInvisibility = false;
public org.bukkit.Location origin; // Paper
+ public net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper - fast access to tracker
// Spigot start
public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;

View file

@ -0,0 +1,209 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
Date: Sun, 17 Mar 2019 21:46:56 +0200
Subject: [PATCH] Fire event on GS4 query
diff --git a/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java b/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java
index 51cb2644aa516a59e19fecb308d519dbc7e5fb11..e548aa0ca4e1e94ab628614b44fc11568ca3beff 100644
--- a/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java
+++ b/src/main/java/net/minecraft/server/rcon/NetworkDataOutputStream.java
@@ -22,6 +22,16 @@ public class NetworkDataOutputStream {
this.dataOutputStream.write(0);
}
+ // Paper start - unchecked exception variant to use in Stream API
+ public void writeStringUnchecked(String string) {
+ try {
+ writeString(string);
+ } catch (IOException e) {
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(e);
+ }
+ }
+ // Paper end
+
public void write(int value) throws IOException {
this.dataOutputStream.write(value);
}
diff --git a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
index 02bb0b2df37ead741adfef38d7479ba6f691dc2d..4632e8f0d27057bf3c47057124b347237ab58111 100644
--- a/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
+++ b/src/main/java/net/minecraft/server/rcon/thread/QueryThreadGs4.java
@@ -94,33 +94,52 @@ public class QueryThreadGs4 extends GenericThread {
if (3 <= i && -2 == bs[0] && -3 == bs[1]) {
LOGGER.debug("Packet '{}' [{}]", PktUtils.toHexString(bs[2]), socketAddress);
switch(bs[2]) {
- case 0:
- if (!this.validChallenge(packet)) {
- LOGGER.debug("Invalid challenge [{}]", (Object)socketAddress);
- return false;
- } else if (15 == i) {
- this.sendTo(this.buildRuleResponse(packet), packet);
- LOGGER.debug("Rules [{}]", (Object)socketAddress);
- } else {
- NetworkDataOutputStream networkDataOutputStream = new NetworkDataOutputStream(1460);
- networkDataOutputStream.write(0);
- networkDataOutputStream.writeBytes(this.getIdentBytes(packet.getSocketAddress()));
- networkDataOutputStream.writeString(this.serverName);
- networkDataOutputStream.writeString("SMP");
- networkDataOutputStream.writeString(this.worldName);
- networkDataOutputStream.writeString(Integer.toString(this.serverInterface.getPlayerCount()));
- networkDataOutputStream.writeString(Integer.toString(this.maxPlayers));
- networkDataOutputStream.writeShort((short)this.serverPort);
- networkDataOutputStream.writeString(this.hostIp);
- this.sendTo(networkDataOutputStream.toByteArray(), packet);
- LOGGER.debug("Status [{}]", (Object)socketAddress);
- }
- default:
- return true;
- case 9:
- this.sendChallenge(packet);
- LOGGER.debug("Challenge [{}]", (Object)socketAddress);
- return true;
+ case 0:
+ if (!this.validChallenge(packet)) {
+ LOGGER.debug("Invalid challenge [{}]", (Object)socketAddress);
+ return false;
+ } else if (15 == i) {
+ this.sendTo(this.buildRuleResponse(packet), packet);
+ LOGGER.debug("Rules [{}]", (Object)socketAddress);
+ } else {
+ NetworkDataOutputStream networkDataOutputStream = new NetworkDataOutputStream(1460);
+ networkDataOutputStream.write(0);
+ networkDataOutputStream.writeBytes(this.getIdentBytes(packet.getSocketAddress()));
+
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType =
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.BASIC;
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder()
+ .motd(this.serverName)
+ .map(this.worldName)
+ .currentPlayers(this.serverInterface.getPlayerCount())
+ .maxPlayers(this.maxPlayers)
+ .port(this.serverPort)
+ .hostname(this.hostIp)
+ .gameVersion(this.serverInterface.getServerVersion())
+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion())
+ .build();
+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent =
+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, packet.getAddress(), queryResponse);
+ queryEvent.callEvent();
+ queryResponse = queryEvent.getResponse();
+
+ networkDataOutputStream.writeString(queryResponse.getMotd());
+ networkDataOutputStream.writeString("SMP");
+ networkDataOutputStream.writeString(queryResponse.getMap());
+ networkDataOutputStream.writeString(Integer.toString(queryResponse.getCurrentPlayers()));
+ networkDataOutputStream.writeString(Integer.toString(queryResponse.getMaxPlayers()));
+ networkDataOutputStream.writeShort((short) queryResponse.getPort());
+ networkDataOutputStream.writeString(queryResponse.getHostname());
+ // Paper end
+ this.sendTo(networkDataOutputStream.toByteArray(), packet);
+ LOGGER.debug("Status [{}]", (Object)socketAddress);
+ }
+ default:
+ return true;
+ case 9:
+ this.sendChallenge(packet);
+ LOGGER.debug("Challenge [{}]", (Object)socketAddress);
+ return true;
}
} else {
LOGGER.debug("Invalid packet [{}]", (Object)socketAddress);
@@ -146,37 +165,79 @@ public class QueryThreadGs4 extends GenericThread {
this.rulesResponse.writeString("splitnum");
this.rulesResponse.write(128);
this.rulesResponse.write(0);
+ // Paper start
+ // Pack plugins
+ java.util.List<com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation> plugins = java.util.Collections.emptyList();
+ org.bukkit.plugin.Plugin[] bukkitPlugins;
+ if (((net.minecraft.server.dedicated.DedicatedServer) this.serverInterface).server.getQueryPlugins() && (bukkitPlugins = org.bukkit.Bukkit.getPluginManager().getPlugins()).length > 0) {
+ plugins = java.util.stream.Stream.of(bukkitPlugins)
+ .map(plugin -> com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation.of(plugin.getName(), plugin.getDescription().getVersion()))
+ .collect(java.util.stream.Collectors.toList());
+ }
+
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder()
+ .motd(this.serverName)
+ .map(this.worldName)
+ .currentPlayers(this.serverInterface.getPlayerCount())
+ .maxPlayers(this.maxPlayers)
+ .port(this.serverPort)
+ .hostname(this.hostIp)
+ .plugins(plugins)
+ .players(this.serverInterface.getPlayerNames())
+ .gameVersion(this.serverInterface.getServerVersion())
+ .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion())
+ .build();
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType =
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.FULL;
+ com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent =
+ new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, packet.getAddress(), queryResponse);
+ queryEvent.callEvent();
+ queryResponse = queryEvent.getResponse();
this.rulesResponse.writeString("hostname");
- this.rulesResponse.writeString(this.serverName);
+ this.rulesResponse.writeString(queryResponse.getMotd());
this.rulesResponse.writeString("gametype");
this.rulesResponse.writeString("SMP");
this.rulesResponse.writeString("game_id");
this.rulesResponse.writeString("MINECRAFT");
this.rulesResponse.writeString("version");
- this.rulesResponse.writeString(this.serverInterface.getServerVersion());
+ this.rulesResponse.writeString(queryResponse.getGameVersion());
this.rulesResponse.writeString("plugins");
- this.rulesResponse.writeString(this.serverInterface.getPluginNames());
+ java.lang.StringBuilder pluginsString = new java.lang.StringBuilder();
+ pluginsString.append(queryResponse.getServerVersion());
+ if (!queryResponse.getPlugins().isEmpty()) {
+ pluginsString.append(": ");
+ java.util.Iterator<com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation> iter = queryResponse.getPlugins().iterator();
+ while (iter.hasNext()) {
+ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation info = iter.next();
+ pluginsString.append(info.getName());
+ if (info.getVersion() != null) {
+ pluginsString.append(' ').append(info.getVersion().replace(";", ","));
+ }
+ if (iter.hasNext()) {
+ pluginsString.append(';').append(' ');
+ }
+ }
+ }
+ this.rulesResponse.writeString(pluginsString.toString());
this.rulesResponse.writeString("map");
- this.rulesResponse.writeString(this.worldName);
+ this.rulesResponse.writeString(queryResponse.getMap());
this.rulesResponse.writeString("numplayers");
- this.rulesResponse.writeString("" + this.serverInterface.getPlayerCount());
+ this.rulesResponse.writeString(Integer.toString(queryResponse.getCurrentPlayers()));
this.rulesResponse.writeString("maxplayers");
- this.rulesResponse.writeString("" + this.maxPlayers);
+ this.rulesResponse.writeString(Integer.toString(queryResponse.getMaxPlayers()));
this.rulesResponse.writeString("hostport");
- this.rulesResponse.writeString("" + this.serverPort);
+ this.rulesResponse.writeString(Integer.toString(queryResponse.getPort()));
this.rulesResponse.writeString("hostip");
- this.rulesResponse.writeString(this.hostIp);
- this.rulesResponse.write(0);
- this.rulesResponse.write(1);
+ this.rulesResponse.writeString(queryResponse.getHostname());
+ // The "meaningless data" start, copied from above
+ this.rulesResponse.writeInt(0);
+ this.rulesResponse.writeInt(1);
this.rulesResponse.writeString("player_");
- this.rulesResponse.write(0);
- String[] strings = this.serverInterface.getPlayerNames();
-
- for(String string : strings) {
- this.rulesResponse.writeString(string);
- }
-
- this.rulesResponse.write(0);
+ this.rulesResponse.writeInt(0);
+ // "Meaningless data" end
+ queryResponse.getPlayers().forEach(this.rulesResponse::writeStringUnchecked);
+ this.rulesResponse.writeInt(0);
+ // Paper end
return this.rulesResponse.toByteArray();
}
}

View file

@ -5,11 +5,11 @@ Subject: [PATCH] Implement PlayerPostRespawnEvent
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 4d813b6556030354f51c1ee5f18eac2166b44576..7412765020854caabd32fb6f4fffcf7f4bf6dba7 100644 index da3100d6577166e222164c174b28020541dd8e3a..c7956664427ca97544d1b47992a62c95d2fc9690 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -737,9 +737,14 @@ public abstract class PlayerList { @@ -715,9 +715,14 @@ public abstract class PlayerList {
// this.a(entityplayer1, entityplayer, worldserver1); // CraftBukkit - removed
boolean flag2 = false; boolean flag2 = false;
+ // Paper start + // Paper start
@ -24,7 +24,7 @@ index 4d813b6556030354f51c1ee5f18eac2166b44576..7412765020854caabd32fb6f4fffcf7f
ServerLevel worldserver1 = this.server.getLevel(entityplayer.getRespawnDimension()); ServerLevel worldserver1 = this.server.getLevel(entityplayer.getRespawnDimension());
if (worldserver1 != null) { if (worldserver1 != null) {
Optional optional; Optional optional;
@@ -790,6 +795,7 @@ public abstract class PlayerList { @@ -768,6 +773,7 @@ public abstract class PlayerList {
location = respawnEvent.getRespawnLocation(); location = respawnEvent.getRespawnLocation();
if (!flag) entityplayer.reset(); // SPIGOT-4785 if (!flag) entityplayer.reset(); // SPIGOT-4785
@ -32,7 +32,7 @@ index 4d813b6556030354f51c1ee5f18eac2166b44576..7412765020854caabd32fb6f4fffcf7f
} else { } else {
location.setWorld(worldserver.getWorld()); location.setWorld(worldserver.getWorld());
} }
@@ -847,6 +853,13 @@ public abstract class PlayerList { @@ -825,6 +831,13 @@ public abstract class PlayerList {
if (entityplayer.connection.isDisconnected()) { if (entityplayer.connection.isDisconnected()) {
this.save(entityplayer); this.save(entityplayer);
} }

View file

@ -1,5 +1,6 @@
pluginManagement { pluginManagement {
repositories { repositories {
mavenLocal()
gradlePluginPortal() gradlePluginPortal()
maven("https://wav.jfrog.io/artifactory/repo/") maven("https://wav.jfrog.io/artifactory/repo/")
} }