more patches (#5808)

This commit is contained in:
Jake Potrebic 2021-06-12 12:30:37 -07:00 committed by GitHub
parent d7e184d055
commit 716a3139b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 515 additions and 605 deletions

View file

@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 21 Mar 2018 20:52:07 -0400
Subject: [PATCH] Fix Dragon Server Crashes
If the dragon tries to find "ground" and hits a hole, or off edge,
it will infinitely keep looking for non air and eventually crash.
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
index 5e701b02e464889fe433b08018d13e63b24506eb..0c2a5f5c4d7d7516793eba20205b5703fe1450d5 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
@@ -63,7 +63,7 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase {
double d3 = d2;
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(d0, d2, d1);
- while (this.dragon.level.isEmptyBlock(blockposition_mutableblockposition)) {
+ while (this.dragon.level.isEmptyBlock(blockposition_mutableblockposition ) && d2 > 0) { // Paper
--d3;
if (d3 < 0.0D) {
d3 = d2;

View file

@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 22 Mar 2018 01:40:24 -0400
Subject: [PATCH] getPlayerUniqueId API
Gets the unique ID of the player currently known as the specified player name
In Offline Mode, will return an Offline UUID
This is a more performant way to obtain a UUID for a name than loading an OfflinePlayer
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 10addb128a357e7719854bf4f9d75f5def32b27d..20915e40fbcf28faed603d449a99bf2157fcf972 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1517,6 +1517,25 @@ public final class CraftServer implements Server {
return recipients.size();
}
+ // Paper start
+ @Nullable
+ public UUID getPlayerUniqueId(String name) {
+ Player player = Bukkit.getPlayerExact(name);
+ if (player != null) {
+ return player.getUniqueId();
+ }
+ GameProfile profile;
+ // Only fetch an online UUID in online mode
+ if (com.destroystokyo.paper.PaperConfig.isProxyOnlineMode()) {
+ profile = console.getProfileCache().get( name );
+ } else {
+ // Make an OfflinePlayer using an offline mode UUID since the name has no profile
+ profile = new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name);
+ }
+ return profile != null ? profile.getId() : null;
+ }
+ // Paper end
+
@Override
@Deprecated
public OfflinePlayer getOfflinePlayer(String name) {

View file

@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
Date: Mon, 26 Mar 2018 18:30:53 +0300
Subject: [PATCH] Make player data saving configurable
Upstream has added a patch which negates the need for this patch,
however, we should still migrate our configuration back upstream,
to prevent unexpected situations
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 52954fc3bf932cfc9d5ce63e3d3cace351305790..05a5abb951abe37f30a719cb75376d2d43c0d252 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -279,4 +279,13 @@ public class PaperConfig {
private static void authenticationServersDownKickMessage() {
authenticationServersDownKickMessage = Strings.emptyToNull(getString("messages.kick.authentication-servers-down", authenticationServersDownKickMessage));
}
+
+ private static void savePlayerData() {
+ Object val = config.get("settings.save-player-data");
+ if (val instanceof Boolean) {
+ SpigotConfig.disablePlayerDataSaving = !(Boolean) val;
+ SpigotConfig.config.set("players.disable-saving", SpigotConfig.disableAdvancementSaving);
+ SpigotConfig.save();
+ }
+ }
}

View file

@ -1,181 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Minecrell <minecrell@minecrell.net>
Date: Wed, 11 Oct 2017 18:22:50 +0200
Subject: [PATCH] Make legacy ping handler more reliable
The Minecraft server often fails to respond to old ("legacy") pings
from old Minecraft versions using the protocol used before the switch
to Netty in Minecraft 1.7.
Due to packet fragmentation[1], we might not have all needed bytes
available when the LegacyPingHandler is called. In this case, it will
run into an error, remove the handler and continue using the modern
protocol.
This is unlikely to happen for the first two revisions of the legacy
ping protocol (used in Minecraft 1.5.x and older) since the request
consists of only one or two bytes, but happens frequently for the
last/third revision introduced in Minecraft 1.6.
It has much larger, variable packet sizes due to the inclusion of
the virtual host (the hostname/port used to connect to the server).
The solution[2] is simple: If we find more than two matching bytes,
we buffer the remaining bytes until we have enough to fully read and
respond to the request.
[1]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-11
[2]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h4-13
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
index e2867a3de87a778a897b4963212fa4aab566a643..1d11802876c1a94ecf991cd8249bd6a911c0ac20 100644
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
@@ -15,6 +15,7 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOGGER = LogManager.getLogger();
private final ServerConnectionListener serverConnectionListener;
+ private ByteBuf buf; // Paper
public LegacyQueryHandler(ServerConnectionListener networkIo) {
this.serverConnectionListener = networkIo;
@@ -23,6 +24,16 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
public void channelRead(ChannelHandlerContext channelhandlercontext, Object object) throws Exception {
ByteBuf bytebuf = (ByteBuf) object;
+ // Paper start - Make legacy ping handler more reliable
+ if (this.buf != null) {
+ try {
+ readLegacy1_6(channelhandlercontext, bytebuf);
+ } finally {
+ bytebuf.release();
+ }
+ return;
+ }
+ // Paper end
bytebuf.markReaderIndex();
boolean flag = true;
@@ -53,6 +64,10 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
this.sendFlushAndClose(channelhandlercontext, this.createReply(s));
break;
default:
+ // Paper start - Replace with improved version below
+ if (bytebuf.readUnsignedByte() != 0x01 || bytebuf.readUnsignedByte() != 0xFA) return;
+ readLegacy1_6(channelhandlercontext, bytebuf);
+ /*
boolean flag1 = bytebuf.readUnsignedByte() == 1;
flag1 &= bytebuf.readUnsignedByte() == 250;
@@ -67,15 +82,16 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
return;
}
- LegacyQueryHandler.LOGGER.debug("Ping: (1.6) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort());
- String s1 = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", 127, minecraftserver.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
- ByteBuf bytebuf1 = this.createReply(s1);
+ LegacyPingHandler.LOGGER.debug("Ping: (1.6) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort());
+ String s1 = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", 127, minecraftserver.getVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
+ ByteBuf bytebuf1 = this.a(s1);
try {
- this.sendFlushAndClose(channelhandlercontext, bytebuf1);
+ this.a(channelhandlercontext, bytebuf1);
} finally {
bytebuf1.release();
}
+ */ // Paper end - Replace with improved version below
}
bytebuf.release();
@@ -93,6 +109,90 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
}
+ // Paper start
+ private static String readLegacyString(ByteBuf buf) {
+ int size = buf.readShort() * Character.BYTES;
+ if (!buf.isReadable(size)) {
+ return null;
+ }
+
+ String result = buf.toString(buf.readerIndex(), size, StandardCharsets.UTF_16BE);
+ buf.skipBytes(size); // toString doesn't increase readerIndex automatically
+ return result;
+ }
+
+ private void readLegacy1_6(ChannelHandlerContext ctx, ByteBuf part) {
+ ByteBuf buf = this.buf;
+
+ if (buf == null) {
+ this.buf = buf = ctx.alloc().buffer();
+ buf.markReaderIndex();
+ } else {
+ buf.resetReaderIndex();
+ }
+
+ buf.writeBytes(part);
+
+ if (!buf.isReadable(Short.BYTES + Short.BYTES + Byte.BYTES + Short.BYTES + Integer.BYTES)) {
+ return;
+ }
+
+ String s = readLegacyString(buf);
+ if (s == null) {
+ return;
+ }
+
+ if (!s.equals("MC|PingHost")) {
+ removeHandler(ctx);
+ return;
+ }
+
+ if (!buf.isReadable(Short.BYTES) || !buf.isReadable(buf.readShort())) {
+ return;
+ }
+
+ MinecraftServer server = this.serverConnectionListener.getServer();
+ int protocolVersion = buf.readByte();
+ String host = readLegacyString(buf);
+ if (host == null) {
+ removeHandler(ctx);
+ return;
+ }
+ int port = buf.readInt();
+
+ if (buf.isReadable()) {
+ removeHandler(ctx);
+ return;
+ }
+
+ buf.release();
+ this.buf = null;
+
+ LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
+
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
+ Byte.MAX_VALUE, server.getServerVersion(), server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
+ this.sendFlushAndClose(ctx, this.createReply(response));
+ }
+
+ private void removeHandler(ChannelHandlerContext ctx) {
+ ByteBuf buf = this.buf;
+ this.buf = null;
+
+ buf.resetReaderIndex();
+ ctx.pipeline().remove(this);
+ ctx.fireChannelRead(buf);
+ }
+
+ @Override
+ public void handlerRemoved(ChannelHandlerContext ctx) {
+ if (this.buf != null) {
+ this.buf.release();
+ this.buf = null;
+ }
+ }
+ // Paper end
+
private void sendFlushAndClose(ChannelHandlerContext ctx, ByteBuf buf) {
ctx.pipeline().firstContext().writeAndFlush(buf).addListener(ChannelFutureListener.CLOSE);
}

View file

@ -1,154 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Minecrell <minecrell@minecrell.net>
Date: Wed, 11 Oct 2017 19:30:51 +0200
Subject: [PATCH] Call PaperServerListPingEvent for legacy pings
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..74c012fd40491f1d870fbc1aa8c318a2197eb106
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
@@ -0,0 +1,73 @@
+package com.destroystokyo.paper.network;
+
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
+import net.minecraft.server.MinecraftServer;
+import org.apache.commons.lang3.StringUtils;
+import org.bukkit.ChatColor;
+
+import java.net.InetSocketAddress;
+
+import javax.annotation.Nullable;
+
+public final class PaperLegacyStatusClient implements StatusClient {
+
+ private final InetSocketAddress address;
+ private final int protocolVersion;
+ @Nullable private final InetSocketAddress virtualHost;
+
+ private PaperLegacyStatusClient(InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
+ this.address = address;
+ this.protocolVersion = protocolVersion;
+ this.virtualHost = virtualHost;
+ }
+
+ @Override
+ public InetSocketAddress getAddress() {
+ return this.address;
+ }
+
+ @Override
+ public int getProtocolVersion() {
+ return this.protocolVersion;
+ }
+
+ @Nullable
+ @Override
+ public InetSocketAddress getVirtualHost() {
+ return this.virtualHost;
+ }
+
+ @Override
+ public boolean isLegacy() {
+ return true;
+ }
+
+ public static PaperServerListPingEvent processRequest(MinecraftServer server,
+ InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
+
+ PaperServerListPingEvent event = new PaperServerListPingEventImpl(server,
+ new PaperLegacyStatusClient(address, protocolVersion, virtualHost), Byte.MAX_VALUE, null);
+ server.server.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return null;
+ }
+
+ return event;
+ }
+
+ public static String getMotd(PaperServerListPingEvent event) {
+ return getFirstLine(event.getMotd());
+ }
+
+ public static String getUnformattedMotd(PaperServerListPingEvent event) {
+ // Strip color codes and all other occurrences of the color char (because it's used as delimiter)
+ return getFirstLine(StringUtils.remove(ChatColor.stripColor(event.getMotd()), ChatColor.COLOR_CHAR));
+ }
+
+ private static String getFirstLine(String s) {
+ int pos = s.indexOf('\n');
+ return pos >= 0 ? s.substring(0, pos) : s;
+ }
+
+}
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
index 1d11802876c1a94ecf991cd8249bd6a911c0ac20..dfe2cd46f2432dca2028b7436c4108e3f190787f 100644
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
@@ -1,5 +1,7 @@
package net.minecraft.server.network;
+import com.destroystokyo.paper.network.PaperLegacyStatusClient;
+
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
@@ -46,12 +48,19 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
MinecraftServer minecraftserver = this.serverConnectionListener.getServer();
int i = bytebuf.readableBytes();
String s;
- org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(minecraftserver.server, inetsocketaddress.getAddress(), minecraftserver.getMotd(), minecraftserver.getPlayerCount(), minecraftserver.getMaxPlayers()); // CraftBukkit
+ //org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(minecraftserver.server, inetsocketaddress.getAddress(), minecraftserver.getMotd(), minecraftserver.getPlayerCount(), minecraftserver.getMaxPlayers()); // CraftBukkit // Paper
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper
switch (i) {
case 0:
LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort());
- s = String.format("%s\u00a7%d\u00a7%d", event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
+ // Paper start - Call PaperServerListPingEvent and use results
+ event = PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 39, null);
+ if (event == null) {
+ channelhandlercontext.close();
+ break;
+ }
+ s = String.format("%s\u00a7%d\u00a7%d", PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers());
this.sendFlushAndClose(channelhandlercontext, this.createReply(s));
break;
case 1:
@@ -60,7 +69,14 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
}
LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort());
- s = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", 127, minecraftserver.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
+ // Paper start - Call PaperServerListPingEvent and use results
+ event = PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 127, null); // Paper
+ if (event == null) {
+ channelhandlercontext.close();
+ break;
+ }
+ s = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", new Object[] { event.getProtocolVersion(), minecraftserver.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()}); // CraftBukkit
+ // Paper end
this.sendFlushAndClose(channelhandlercontext, this.createReply(s));
break;
default:
@@ -170,8 +186,16 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
- String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
- Byte.MAX_VALUE, server.getServerVersion(), server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
+ InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = PaperLegacyStatusClient.processRequest(
+ server, (InetSocketAddress) ctx.channel().remoteAddress(), protocolVersion, virtualHost);
+ if (event == null) {
+ ctx.close();
+ return;
+ }
+
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), event.getVersion(),
+ PaperLegacyStatusClient.getMotd(event), event.getNumPlayers(), event.getMaxPlayers());
this.sendFlushAndClose(ctx, this.createReply(response));
}

View file

@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sat, 31 Mar 2018 17:04:26 +0100
Subject: [PATCH] Flag to disable the channel limit
In some enviroments, the channel limit set by spigot can cause issues,
e.g. servers which allow and support the usage of mod packs.
provide an optional flag to disable this check, at your own risk.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 9d853733ff9054cc48925e22c8bb3c8d9b898808..46338fe5693003698de9c7b37a860c3481e06233 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -143,6 +143,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Paper start
private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus;
private String resourcePackHash;
+ private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
// Paper end
public CraftPlayer(CraftServer server, ServerPlayer entity) {
@@ -1576,7 +1577,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
public void addChannel(String channel) {
- Preconditions.checkState(channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel);
+ Preconditions.checkState(DISABLE_CHANNEL_LIMIT || channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel); // Paper - flag to disable channel limit
channel = StandardMessenger.validateAndCorrectChannel(channel);
if (channels.add(channel)) {
server.getPluginManager().callEvent(new PlayerRegisterChannelEvent(this, channel));

View file

@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
Date: Sun, 1 Apr 2018 02:29:37 +0300
Subject: [PATCH] Add method to open already placed sign
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index c62d01719f21762aa10294815ab88e450e4dce3f..4aec1c2b26d48cb5bea3dfb9e183526763bdb98f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -28,6 +28,7 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CraftingTableBlock;
import net.minecraft.world.level.block.EnchantmentTableBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.SignBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.GameMode;
import org.bukkit.Location;
@@ -604,6 +605,17 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
}
}
+ // Paper start - Add method to open already placed sign
+ @Override
+ public void openSign(org.bukkit.block.Sign sign) {
+ org.apache.commons.lang.Validate.isTrue(sign.getWorld().equals(this.getWorld()), "Sign must be in the same world as player is in");
+ org.bukkit.craftbukkit.block.CraftSign craftSign = (org.bukkit.craftbukkit.block.CraftSign) sign;
+ SignBlockEntity teSign = craftSign.getTileEntity();
+ // Make sign editable temporarily, will be set back to false in PlayerConnection later
+ teSign.isEditable = true;
+ getHandle().openTextEdit(teSign);
+ }
+ // Paper end
@Override
public boolean dropItem(boolean dropAll) {
return getHandle().drop(dropAll);

View file

@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brokkonaut <hannos17@gmx.de>
Date: Sat, 14 Apr 2018 20:20:46 +0200
Subject: [PATCH] Configurable sprint interruption on attack
If the sprint interruption is disabled players continue sprinting when they attack entities.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 48f0385c7203c7955de5a015f3dc42be2ab7b681..cebf1a623a9bec72d60fdd23dda01868ef6431d4 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -358,4 +358,9 @@ public class PaperWorldConfig {
private void squidMaxSpawnHeight() {
squidMaxSpawnHeight = getDouble("squid-spawn-height.maximum", 0.0D);
}
+
+ public boolean disableSprintInterruptionOnAttack;
+ private void disableSprintInterruptionOnAttack() {
+ disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
+ }
}
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index c4aa824d03de952fe6b306e539baa47af979add1..552920f59aae9de2cad3edcdc8c48a91dff49093 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1180,7 +1180,11 @@ public abstract class Player extends LivingEntity {
}
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
- this.setSprinting(false);
+ // Paper start - Configuration option to disable automatic sprint interruption
+ if (!level.paperConfig.disableSprintInterruptionOnAttack) {
+ this.setSprinting(false);
+ }
+ // Paper end
}
if (flag3) {

View file

@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 0x22 <0x22@futureclient.net>
Date: Thu, 26 Apr 2018 04:41:11 -0400
Subject: [PATCH] Fix exploit that allowed colored signs to be created
diff --git a/src/main/java/net/minecraft/SharedConstants.java b/src/main/java/net/minecraft/SharedConstants.java
index a70c3d25930e7414fc9e897de8d2e0c12f11c0e4..04b8783417bbcd826d6d1c302551fbad9c48bd01 100644
--- a/src/main/java/net/minecraft/SharedConstants.java
+++ b/src/main/java/net/minecraft/SharedConstants.java
@@ -20,6 +20,7 @@ public class SharedConstants {
return chr != 167 && chr >= ' ' && chr != 127;
}
+ public static String filterAllowedChatCharacters(String input) { return filterText(input); } // Paper - OBFHELPER
public static String filterText(String s) {
StringBuilder stringbuilder = new StringBuilder();
char[] achar = s.toCharArray();
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 8d0c44b6c2c99d5161c5d4b79209b79ff6db75e4..fb36aa08cd2fbe3f7262dccb8cf0f7cae55aea9c 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2786,7 +2786,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
List<net.kyori.adventure.text.Component> lines = new java.util.ArrayList<>();
for (int i = 0; i < list.size(); ++i) {
- lines.add(net.kyori.adventure.text.Component.text(list.get(i)));
+ lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterAllowedChatCharacters(list.get(i)))); // Paper - Replaced with anvil color stripping method to stop exploits that allow colored signs to be created.
}
SignChangeEvent event = new SignChangeEvent(org.bukkit.craftbukkit.block.CraftBlock.at(worldserver, blockposition), this.getPlayer(), lines);
this.craftServer.getPluginManager().callEvent(event);

View file

@ -1,82 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 13:15:55 -0400
Subject: [PATCH] EndermanEscapeEvent
Fires an event anytime an enderman intends to teleport away from the player
You may cancel this, enabling ranged attacks to damage the enderman for example.
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index 1c2998c89fd660d6b26b7ff48cddd1862b9b1828..1b9c77666204765a3ed5648b0f8eaa820f578e58 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -2,6 +2,7 @@ package net.minecraft.world.entity.monster;
import java.util.EnumSet;
import java.util.Optional;
+import com.destroystokyo.paper.event.entity.EndermanEscapeEvent; // Paper
import java.util.Random;
import java.util.UUID;
import java.util.function.Predicate;
@@ -109,6 +110,12 @@ public class EnderMan extends Monster implements NeutralMob {
setGoalTarget(target, org.bukkit.event.entity.EntityTargetEvent.TargetReason.UNKNOWN, true);
}
+ // Paper start
+ private boolean tryEscape(EndermanEscapeEvent.Reason reason) {
+ return new EndermanEscapeEvent((org.bukkit.craftbukkit.entity.CraftEnderman) this.getBukkitEntity(), reason).callEvent();
+ }
+ // Paper end
+
@Override
public boolean setGoalTarget(LivingEntity entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fireEvent) {
if (!super.setGoalTarget(entityliving, reason, fireEvent)) {
@@ -262,7 +269,7 @@ public class EnderMan extends Monster implements NeutralMob {
if (this.level.isDay() && this.tickCount >= this.targetChangeTime + 600) {
float f = this.getBrightness();
- if (f > 0.5F && this.level.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
+ if (f > 0.5F && this.level.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper
this.setTarget((LivingEntity) null);
this.teleport();
}
@@ -360,17 +367,19 @@ public class EnderMan extends Monster implements NeutralMob {
if (this.isInvulnerableTo(source)) {
return false;
} else if (source instanceof IndirectEntityDamageSource) {
+ if (this.tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start
for (int i = 0; i < 64; ++i) {
if (this.teleport()) {
return true;
}
}
+ } // Paper end
return false;
} else {
boolean flag = super.hurt(source, amount);
- if (!this.level.isClientSide() && !(source.getEntity() instanceof LivingEntity) && this.random.nextInt(10) != 0) {
+ if (!this.level.isClientSide() && !(source.getEntity() instanceof LivingEntity) && this.random.nextInt(10) != 0 && this.tryEscape(source == DamageSource.DROWN ? EndermanEscapeEvent.Reason.DROWN : EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - use to be critical hits as else, but mojang removed critical hits in 1.16.2 due to MC-185684
this.teleport();
}
@@ -515,7 +524,7 @@ public class EnderMan extends Monster implements NeutralMob {
static class EndermanLookForPlayerGoal extends NearestAttackableTargetGoal<Player> {
- private final EnderMan enderman;
+ private final EnderMan enderman; public final EnderMan getEnderman() { return this.enderman; } // Paper - OBFHELPER
private Player pendingTarget;
private int aggroTime;
private int teleportTime;
@@ -578,7 +587,7 @@ public class EnderMan extends Monster implements NeutralMob {
} else {
if (this.target != null && !this.enderman.isPassenger()) {
if (this.enderman.isLookingAtMe((Player) this.target)) {
- if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D) {
+ if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D && this.getEnderman().tryEscape(EndermanEscapeEvent.Reason.STARE)) { // Paper
this.enderman.teleport();
}

View file

@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 13:29:44 -0400
Subject: [PATCH] Enderman.teleportRandomly()
Ability to trigger the vanilla "teleport randomly" mechanic of an enderman.
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index 1b9c77666204765a3ed5648b0f8eaa820f578e58..1981c08af85b16d45531ffae4fe790bb31edec04 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -278,6 +278,7 @@ public class EnderMan extends Monster implements NeutralMob {
super.customServerAiStep();
}
+ public final boolean teleportRandomly() { return this.teleport(); } // Paper - OBFHELPER
protected boolean teleport() {
if (!this.level.isClientSide() && this.isAlive()) {
double d0 = this.getX() + (this.random.nextDouble() - 0.5D) * 64.0D;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
index d17ed71e800ebcd12b69745f239fa7dbc8a0c808..1edb45490b35b6517201acc8551da8d3c5a489de 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
@@ -16,6 +16,7 @@ public class CraftEnderman extends CraftMonster implements Enderman {
super(server, entity);
}
+ @Override public boolean teleportRandomly() { return getHandle().teleportRandomly(); } // Paper
@Override
public MaterialData getCarriedMaterial() {
BlockState blockData = getHandle().getCarriedBlock();

View file

@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 17:15:26 -0400
Subject: [PATCH] Block Enderpearl Travel Exploit
Players are able to use alt accounts and enderpearls to travel
long distances utilizing the pearls in unloaded chunks and loading
the chunk later when convenient.
This disables that by not saving the thrower when the chunk is unloaded.
This is mainly useful for survival servers that do not allow freeform teleporting.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index cebf1a623a9bec72d60fdd23dda01868ef6431d4..e8e1e7dafaf1c105b2f58cf3e118e3d665dc50ec 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -363,4 +363,10 @@ public class PaperWorldConfig {
private void disableSprintInterruptionOnAttack() {
disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
}
+
+ public boolean disableEnderpearlExploit = true;
+ private void disableEnderpearlExploit() {
+ disableEnderpearlExploit = getBoolean("game-mechanics.disable-unloaded-chunk-enderpearl-exploit", disableEnderpearlExploit);
+ log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled"));
+ }
}
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
index 14ed4f212a9c9c3128c4ddbef7b2e243c925b509..16b554675a276471851846d4f2bea06fdcc166d9 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -62,6 +62,7 @@ public abstract class Projectile extends Entity {
protected void readAdditionalSaveData(CompoundTag tag) {
if (tag.hasUUID("Owner")) {
this.ownerUUID = tag.getUUID("Owner");
+ if (this instanceof ThrownEnderpearl && this.level != null && this.level.paperConfig.disableEnderpearlExploit) { this.ownerUUID = null; } // Paper - Don't store shooter name for pearls to block enderpearl travel exploit
}
this.leftOwner = tag.getBoolean("LeftOwner");

View file

@ -1,67 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 15 Aug 2017 22:29:12 -0400
Subject: [PATCH] Expand World.spawnParticle API and add Builder
Adds ability to control who receives it and who is the source/sender (vanish API)
the standard API is to send the packet to everyone in the world, which is ineffecient.
Adds an option to control the force mode of the particle.
This adds a new Builder API which is much friendlier to use.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 20650bfd10abfa010e71cfeede06c461d50d19a3..5110f2c70d96284e8e7592b3d89266b867b9a466 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -164,7 +164,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
public final Int2ObjectMap<Entity> entitiesById = new Int2ObjectLinkedOpenHashMap();
private final Map<UUID, Entity> entitiesByUuid = Maps.newHashMap();
private final Queue<Entity> toAddAfterTick = Queues.newArrayDeque();
- private final List<ServerPlayer> players = Lists.newArrayList();
+ public final List<ServerPlayer> players = Lists.newArrayList(); // Paper - private -> public
public final ServerChunkCache chunkSource; // Paper - public
boolean tickingEntities;
private final MinecraftServer server;
@@ -1472,12 +1472,17 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
}
public <T extends ParticleOptions> int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
+ // Paper start - Particle API Expansion
+ return sendParticles(players, sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force);
+ }
+ public <T extends ParticleOptions> int sendParticles(List<ServerPlayer> receivers, ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
+ // Paper end
ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(t0, force, d0, d1, d2, (float) d3, (float) d4, (float) d5, (float) d6, i);
// CraftBukkit end
int j = 0;
- for (int k = 0; k < this.players.size(); ++k) {
- ServerPlayer entityplayer = (ServerPlayer) this.players.get(k);
+ for (Player entityhuman : receivers) { // Paper - Particle API Expansion
+ ServerPlayer entityplayer = (ServerPlayer) entityhuman; // Paper - Particle API Expansion
if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit
if (this.sendParticles(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 88658d4deacc29128c537e2e02fdc8f684090a2c..beb7219312be5143a50b0841c25efea5dbcc1267 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2334,11 +2334,17 @@ public class CraftWorld implements World {
@Override
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
+ // Paper start - Particle API Expansion
+ spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, force);
+ }
+ public <T> void spawnParticle(Particle particle, List<Player> receivers, Player sender, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
+ // Paper end
if (data != null && !particle.getDataType().isInstance(data)) {
throw new IllegalArgumentException("data should be " + particle.getDataType() + " got " + data.getClass());
}
getHandle().sendParticles(
- null, // Sender
+ receivers == null ? getHandle().players : receivers.stream().map(player -> ((CraftPlayer) player).getHandle()).collect(java.util.stream.Collectors.toList()), // Paper - Particle API Expansion
+ sender != null ? ((CraftPlayer) sender).getHandle() : null, // Sender // Paper - Particle API Expansion
CraftParticle.toNMS(particle, data), // Particle
x, y, z, // Position
count, // Count

View file

@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 1 May 2018 20:18:54 -0400
Subject: [PATCH] EndermanAttackPlayerEvent
Allow control over whether or not an enderman aggros a player.
This allows you to override/extend the pumpkin/stare logic.
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index 1981c08af85b16d45531ffae4fe790bb31edec04..d190b58bea310f4006ea3deaf0d42c502d441284 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -221,20 +221,28 @@ public class EnderMan extends Monster implements NeutralMob {
this.readPersistentAngerSaveData((ServerLevel) this.level, tag);
}
+ // Paper start - OBFHELPER - ok not really, but verify this on updates
private boolean isLookingAtMe(Player player) {
- ItemStack itemstack = (ItemStack) player.inventory.armor.get(3);
+ boolean shouldAttack = g_real(player);
+ com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event = new com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent((org.bukkit.entity.Enderman) getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity());
+ event.setCancelled(!shouldAttack);
+ return event.callEvent();
+ }
+ private boolean g_real(Player entityhuman) {
+ // Paper end
+ ItemStack itemstack = (ItemStack) entityhuman.inventory.armor.get(3);
if (itemstack.getItem() == Blocks.CARVED_PUMPKIN.asItem()) {
return false;
} else {
- Vec3 vec3d = player.getViewVector(1.0F).normalize();
- Vec3 vec3d1 = new Vec3(this.getX() - player.getX(), this.getEyeY() - player.getEyeY(), this.getZ() - player.getZ());
+ Vec3 vec3d = entityhuman.getViewVector(1.0F).normalize();
+ Vec3 vec3d1 = new Vec3(this.getX() - entityhuman.getX(), this.getEyeY() - entityhuman.getEyeY(), this.getZ() - entityhuman.getZ());
double d0 = vec3d1.length();
vec3d1 = vec3d1.normalize();
double d1 = vec3d.dot(vec3d1);
- return d1 > 1.0D - 0.025D / d0 ? player.canSee(this) : false;
+ return d1 > 1.0D - 0.025D / d0 ? entityhuman.canSee(this) : false;
}
}

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 16 May 2018 20:35:16 -0400
Subject: [PATCH] WitchConsumePotionEvent
Fires when a witch consumes the potion in their hand
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
index 9b0269bdd25123f5c0662187de49a869ead3ee81..dd5976d81ff57e8691ba60f425af37572edd26e7 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
@@ -124,7 +124,11 @@ public class Witch extends Raider implements RangedAttackMob {
this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
if (itemstack.getItem() == Items.POTION) {
- List<MobEffectInstance> list = PotionUtils.getMobEffects(itemstack);
+ // Paper start
+ com.destroystokyo.paper.event.entity.WitchConsumePotionEvent event = new com.destroystokyo.paper.event.entity.WitchConsumePotionEvent((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack));
+
+ List<MobEffectInstance> list = event.callEvent() ? PotionUtils.getMobEffects(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion())) : null;
+ // Paper end
if (list != null) {
Iterator iterator = list.iterator();

View file

@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 16 May 2018 20:44:58 -0400
Subject: [PATCH] WitchThrowPotionEvent
Fired when a witch throws a potion at a player
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
index dd5976d81ff57e8691ba60f425af37572edd26e7..7cefabfb0d8a264cae24f23c06f1c5f552ff0158 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
@@ -224,9 +224,16 @@ public class Witch extends Raider implements RangedAttackMob {
potionregistry = Potions.WEAKNESS;
}
+ // Paper start
+ ItemStack potion = PotionUtils.setPotion(new ItemStack(Items.SPLASH_POTION), potionregistry);
+ com.destroystokyo.paper.event.entity.WitchThrowPotionEvent event = new com.destroystokyo.paper.event.entity.WitchThrowPotionEvent((org.bukkit.entity.Witch) this.getBukkitEntity(), (org.bukkit.entity.LivingEntity) target.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion));
+ if (!event.callEvent()) {
+ return;
+ }
+ potion = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion());
ThrownPotion entitypotion = new ThrownPotion(this.level, this);
-
- entitypotion.setItem(PotionUtils.setPotion(new ItemStack(Items.SPLASH_POTION), potionregistry));
+ entitypotion.setItem(potion);
+ // Paper end
entitypotion.xRot -= -20.0F;
entitypotion.shoot(d0, d1 + (double) (f1 * 0.2F), d2, 0.75F, 8.0F);
if (!this.isSilent()) {

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 4 Jun 2018 20:39:20 -0400
Subject: [PATCH] Allow spawning Item entities with World.spawnEntity
This API has more capabilities than .dropItem with the Consumer function
Item can be set inside of the Consumer pre spawn function.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index beb7219312be5143a50b0841c25efea5dbcc1267..2dc9daaeea600fff1f2efddf74b6849fd745a28c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1497,6 +1497,10 @@ public class CraftWorld implements World {
if (Boat.class.isAssignableFrom(clazz)) {
entity = new net.minecraft.world.entity.vehicle.Boat(world, x, y, z);
entity.moveTo(x, y, z, yaw, pitch);
+ // Paper start
+ } else if (org.bukkit.entity.Item.class.isAssignableFrom(clazz)) {
+ entity = new ItemEntity(world, x, y, z, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Item.byBlock(net.minecraft.world.level.block.Blocks.DIRT)));
+ // Paper end
} else if (FallingBlock.class.isAssignableFrom(clazz)) {
entity = new FallingBlockEntity(world, x, y, z, world.getBlockState(new BlockPos(x, y, z)));
} else if (Projectile.class.isAssignableFrom(clazz)) {

View file

@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 5 Jun 2018 22:47:26 -0400
Subject: [PATCH] WitchReadyPotionEvent
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
index 7cefabfb0d8a264cae24f23c06f1c5f552ff0158..a37ee32b46aa87be6e3eeca2892b4e7294fd1aef 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
@@ -157,7 +157,11 @@ public class Witch extends Raider implements RangedAttackMob {
}
if (potionregistry != null) {
- this.setItemSlot(EquipmentSlot.MAINHAND, PotionUtils.setPotion(new ItemStack(Items.POTION), potionregistry));
+ // Paper start
+ ItemStack potion = PotionUtils.setPotion(new ItemStack(Items.POTION), potionregistry);
+ org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion));
+ this.setItemSlot(EquipmentSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack));
+ // Paper end
this.usingTime = this.getMainHandItem().getUseDuration();
this.setUsingItem(true);
if (!this.isSilent()) {

View file

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 5 Jun 2018 23:00:29 -0400
Subject: [PATCH] ItemStack#getMaxItemUseDuration
Allows you to determine how long it takes to use a usable/consumable item
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index a0815c0d7f68f345dc48c73b8253de637c7a3e0f..34187197efd5ceff0503682dc6ce313220ca916f 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -604,6 +604,7 @@ public final class ItemStack {
this.getItem().onCraftedBy(this, world, player);
}
+ public int getItemUseMaxDuration() { return getUseDuration(); } // Paper - OBFHELPER
public int getUseDuration() {
return this.getItem().getUseDuration(this);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index 5f0ccdeb8565505278caa591f7390047eab49cf4..44caf00330e4f4f74745973dbe709980f0b61269 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
@@ -173,6 +173,13 @@ public final class CraftItemStack extends ItemStack {
return (handle == null) ? Material.AIR.getMaxStackSize() : handle.getItem().getMaxStackSize();
}
+ // Paper start
+ @Override
+ public int getMaxItemUseDuration() {
+ return handle == null ? 0 : handle.getItemUseMaxDuration();
+ }
+ // Paper end
+
@Override
public void addUnsafeEnchantment(Enchantment ench, int level) {
Validate.notNull(ench, "Cannot add null enchantment");

View file

@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sat, 9 Jun 2018 14:08:39 +0200
Subject: [PATCH] Implement EntityTeleportEndGatewayEvent
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
index 2c974f9801d209907733bed8e6c4c9ef46e2b610..b70e0633435a272ae1e9fbd12d7f18862de0b951 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -191,9 +191,20 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity implements
}
// CraftBukkit end
+ // Paper start - EntityTeleportEndGatewayEvent - replicated from above
+ org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity = entity.getBukkitEntity();
+ org.bukkit.Location location = new Location(level.getWorld(), (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D);
+ location.setPitch(bukkitEntity.getLocation().getPitch());
+ location.setYaw(bukkitEntity.getLocation().getYaw());
+
+ com.destroystokyo.paper.event.entity.EntityTeleportEndGatewayEvent event = new com.destroystokyo.paper.event.entity.EntityTeleportEndGatewayEvent(bukkitEntity, bukkitEntity.getLocation(), location, new org.bukkit.craftbukkit.block.CraftEndGateway(MCUtil.toLocation(level, this.getBlockPos()).getBlock()));
+ if (!event.callEvent()) {
+ return;
+ }
+ // Paper end
entity1.setPortalCooldown();
- entity1.teleportToWithTicket((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D);
+ entity1.teleportToWithTicket(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); // Paper
}
this.triggerCooldown();

View file

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 10 Jun 2018 01:18:49 -0400
Subject: [PATCH] Unset Ignited flag on cancel of Explosion Event
Otherwise the creeper infinite explodes
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
index 8f8d0a23d011936150854a0606be3d63b18c57af..d9b5cf8ac01289801ded01d928fa7ead96551be5 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
@@ -47,7 +47,7 @@ public class Creeper extends Monster {
private static final EntityDataAccessor<Integer> DATA_SWELL_DIR = SynchedEntityData.defineId(Creeper.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> DATA_IS_POWERED = SynchedEntityData.defineId(Creeper.class, EntityDataSerializers.BOOLEAN);
- private static final EntityDataAccessor<Boolean> DATA_IS_IGNITED = SynchedEntityData.defineId(Creeper.class, EntityDataSerializers.BOOLEAN);
+ private static final EntityDataAccessor<Boolean> DATA_IS_IGNITED = SynchedEntityData.defineId(Creeper.class, EntityDataSerializers.BOOLEAN); private static final EntityDataAccessor<Boolean> isIgnitedDW = DATA_IS_IGNITED; // Paper OBFHELPER
private int oldSwell;
public int swell; // PAIL
public int maxSwell = 30;
@@ -252,6 +252,7 @@ public class Creeper extends Monster {
this.spawnLingeringCloud();
} else {
swell = 0;
+ this.entityData.set(isIgnitedDW, Boolean.valueOf(false)); // Paper
}
// CraftBukkit end
}

View file

@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 10 Jun 2018 20:20:15 -0400
Subject: [PATCH] Fix CraftEntity hashCode
hashCodes are not allowed to change, however bukkit used a value
that does change, the entityId.
When an entity is teleported dimensions, the entity reference is
replaced with a new one with a new entity ID.
For hashCode, we can simply use the UUID's hashCode to keep
the hashCode from changing.
equals() is ok to use getEntityId() because equals() should only
be true if both the left and right are the same reference.
Since entity ids can not duplicate during runtime, this
check is essentially the same as this.getHandle() == other.getHandle()
However, replaced it too to make it clearer of intent.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index ecb5f5ca547930f91602d539e541964cd9f10287..e1bbaf620f3ed2a6cb9ce8007a78c4cee47b653e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -745,14 +745,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return false;
}
final CraftEntity other = (CraftEntity) obj;
- return (this.getEntityId() == other.getEntityId());
+ return (this.getHandle() == other.getHandle()); // Paper - while logically the same, this is clearer
}
+ // Paper - Fix hashCode. entity ID's are not static.
+ // A CraftEntity can change reference to a new entity with a new ID, and hash codes should never change
@Override
public int hashCode() {
- int hash = 7;
- hash = 29 * hash + this.getEntityId();
- return hash;
+ return getUniqueId().hashCode();
+ // Paper end
}
@Override

View file

@ -1,118 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 15 Jun 2018 00:30:32 -0400
Subject: [PATCH] Configurable Alternative LootPool Luck Formula
Rewrites the Vanilla luck application formula so that luck can be
applied to items that do not have any quality defined.
See: https://luckformula.emc.gs for data and details
-----------
The rough summary is:
My goal was that in a pool, when luck was applied, the pool
rebalances so the percentages for bigger items is
lowered and smaller items is boosted.
Do this by boosting and then reducing the weight value,
so that larger numbers are penalized more than smaller numbers.
resulting in a larger reduction of entries for more common
items than the reduction on small weights,
giving smaller weights more of a chance
-----------
This work kind of obsoletes quality, but quality would be useful
for 2 items with same weight that you want luck to impact
in varying directions.
Fishing still falls into that as the weights are closer, so luck
will invalidate junk more.
This change will result in some major changes to fishing formulas.
-----------
I would love to see this change in Vanilla, so Mojang please pull :)
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 05a5abb951abe37f30a719cb75376d2d43c0d252..77a03abd59db4a43f6f2d59d4c7ef176e782f205 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -288,4 +288,12 @@ public class PaperConfig {
SpigotConfig.save();
}
}
+
+ public static boolean useAlternativeLuckFormula = false;
+ private static void useAlternativeLuckFormula() {
+ useAlternativeLuckFormula = getBoolean("settings.use-alternative-luck-formula", false);
+ if (useAlternativeLuckFormula) {
+ Bukkit.getLogger().log(Level.INFO, "Using Aikar's Alternative Luck Formula to apply Luck attribute to all loot pool calculations. See https://luckformula.emc.gs");
+ }
+ }
}
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
index ceb5e5405ed20c8de954847bbb269109107a43fc..d99bc0b8a1e9c4749b176a823b879ced9efdd7d6 100644
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
@@ -8,7 +8,6 @@ import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import net.minecraft.util.GsonHelper;
-import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.ValidationContext;
@@ -20,8 +19,8 @@ import org.apache.commons.lang3.ArrayUtils;
public abstract class LootPoolSingletonContainer extends LootPoolEntryContainer {
- protected final int weight;
- protected final int quality;
+ protected final int weight; public int getWeight() { return weight; } // Paper - OBFHELPER
+ protected final int quality; public int getQuality() { return quality; } // Paper - OBFHELPER
protected final LootItemFunction[] functions;
private final BiFunction<ItemStack, LootContext, ItemStack> compositeFunction;
private final LootPoolEntry entry = new LootPoolSingletonContainer.EntryBase() {
@@ -152,11 +151,38 @@ public abstract class LootPoolSingletonContainer extends LootPoolEntryContainer
public abstract class EntryBase implements LootPoolEntry {
- protected EntryBase() {}
+ protected EntryBase() {
+ }
@Override
public int getWeight(float luck) {
- return Math.max(Mth.floor((float) LootPoolSingletonContainer.this.weight + (float) LootPoolSingletonContainer.this.quality * luck), 0);
+ // Paper start - Offer an alternative loot formula to refactor how luck bonus applies
+ // SEE: https://luckformula.emc.gs for details and data
+ if (lastLuck != null && lastLuck == luck) {
+ return lastWeight;
+ }
+ // This is vanilla
+ float qualityModifer = (float) getQuality() * luck;
+ double baseWeight = (getWeight() + qualityModifer);
+ if (com.destroystokyo.paper.PaperConfig.useAlternativeLuckFormula) {
+ // Random boost to avoid losing precision in the final int cast on return
+ final int weightBoost = 100;
+ baseWeight *= weightBoost;
+ // If we have vanilla 1, bump that down to 0 so nothing is is impacted
+ // vanilla 3 = 300, 200 basis = impact 2%
+ // =($B2*(($B2-100)/100/100))
+ double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100);
+ // =($B$7/100)
+ float luckModifier = Math.min(100, luck * 10) / 100;
+ // =B2 - (C2 *($B$7/100))
+ baseWeight = Math.ceil(baseWeight - (impacted * luckModifier));
+ }
+ lastLuck = luck;
+ lastWeight = (int) Math.max(0, Math.floor(baseWeight));
+ return lastWeight;
}
}
+ private Float lastLuck = null;
+ private int lastWeight = 0;
+ // Paper end
}

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 15 Jun 2018 20:37:03 -0400
Subject: [PATCH] Print Error details when failing to save player data
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
index 60fe01e824e4657d2601797d7858d5de339ab255..5b2a558d4d357d0de033ec2d7a9b4686f202c903 100644
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
@@ -43,7 +43,7 @@ public class PlayerDataStorage {
Util.safeReplaceFile(file1, file, file2);
} catch (Exception exception) {
- PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", entityhuman.getName().getString());
+ PlayerDataStorage.LOGGER.error("Failed to save player data for {}", entityhuman.getScoreboardName(), exception); // Paper
}
}

View file

@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Sat, 16 Jun 2018 01:18:16 -0500
Subject: [PATCH] Make shield blocking delay configurable
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index e8e1e7dafaf1c105b2f58cf3e118e3d665dc50ec..3e4bd1d6718d3ad2498fe9bd72eaac45044ecb77 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -369,4 +369,9 @@ public class PaperWorldConfig {
disableEnderpearlExploit = getBoolean("game-mechanics.disable-unloaded-chunk-enderpearl-exploit", disableEnderpearlExploit);
log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled"));
}
+
+ public int shieldBlockingDelay = 5;
+ private void shieldBlockingDelay() {
+ shieldBlockingDelay = getInt("game-mechanics.shield-blocking-delay", 5);
+ }
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 8b0d1f4fbc43a6f37a5f9c453b5dd142a4f69745..af2e81137d9c686f8d94a1d0d7241619fa1f352c 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3308,7 +3308,7 @@ public abstract class LivingEntity extends Entity {
if (this.isUsingItem() && !this.useItem.isEmpty()) {
Item item = this.useItem.getItem();
- return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= 5;
+ return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay
} else {
return false;
}
@@ -3587,4 +3587,15 @@ public abstract class LivingEntity extends Entity {
public void broadcastBreakEvent(InteractionHand hand) {
this.broadcastBreakEvent(hand == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND);
}
+ // Paper start
+ public int shieldBlockingDelay = level.paperConfig.shieldBlockingDelay;
+
+ public int getShieldBlockingDelay() {
+ return shieldBlockingDelay;
+ }
+
+ public void setShieldBlockingDelay(int shieldBlockingDelay) {
+ this.shieldBlockingDelay = shieldBlockingDelay;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 006f4c71bbcda61b55815e7ceab91731ab062da0..663887d9aecc2823fe7d02a9b108a291cd27102c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -699,5 +699,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
public void setArrowsStuck(int arrows) {
getHandle().setArrowCount(arrows);
}
+
+ @Override
+ public int getShieldBlockingDelay() {
+ return getHandle().getShieldBlockingDelay();
+ }
+
+ @Override
+ public void setShieldBlockingDelay(int delay) {
+ getHandle().setShieldBlockingDelay(delay);
+ }
// Paper end
}

View file

@ -1,44 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 15 Jun 2013 19:51:17 -0400
Subject: [PATCH] Improve EntityShootBowEvent
Adds missing call to Illagers and also adds Arrow ItemStack to skeltons
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
index e8ad820b11dd1b89e442bb057d5761c90c4b1923..76027a7c9615495af64102744e264d7ba7c9b87e 100644
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
@@ -197,7 +197,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level.getDifficulty().getId() * 4));
// CraftBukkit start
- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), null, entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true);
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getOriginalItemStack(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper
if (event.isCancelled()) {
event.getProjectile().remove();
return;
diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
index ab8c41e72c15ee9e5256eba2ba2681a33ce8a8d9..2d07e9cf4c84bc32a7624f65173c4e8a6dc07165 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
@@ -171,8 +171,18 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
double d3 = (double) Mth.sqrt(d0 * d0 + d2 * d2);
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level.getDifficulty().getId() * 4));
+ // Paper start
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getOriginalItemStack(), entityarrow, target.getUsedItemHand(), 0.8F, true);
+ if (event.isCancelled()) {
+ event.getProjectile().remove();
+ return;
+ }
+
+ if (event.getProjectile() == entityarrow.getBukkitEntity()) {
+ this.level.addFreshEntity(entityarrow);
+ }
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
- this.level.addFreshEntity(entityarrow);
+ // Paper end
}
class IllusionerBlindnessSpellGoal extends SpellcasterIllager.SpellcasterUseSpellGoal {

View file

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 18 Jun 2018 01:12:53 -0400
Subject: [PATCH] PlayerReadyArrowEvent
Called when a player is firing a bow and the server is choosing an arrow to use.
Plugins can skip selection of certain arrows and control which is used.
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 552920f59aae9de2cad3edcdc8c48a91dff49093..b88d8f2c377322290002e84e217f3f2f6e4e71e8 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -2139,6 +2139,17 @@ public abstract class Player extends LivingEntity {
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
}
+ // Paper start
+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) {
+ return !(this instanceof ServerPlayer) ||
+ new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent(
+ ((ServerPlayer) this).getBukkitEntity(),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)
+ ).callEvent();
+ // Paper end
+ }
+
@Override
public ItemStack getProjectile(ItemStack stack) {
if (!(stack.getItem() instanceof ProjectileWeaponItem)) {
@@ -2155,7 +2166,7 @@ public abstract class Player extends LivingEntity {
for (int i = 0; i < this.inventory.getContainerSize(); ++i) {
ItemStack itemstack2 = this.inventory.getItem(i);
- if (predicate.test(itemstack2)) {
+ if (predicate.test(itemstack2) && tryReadyArrow(stack, itemstack2)) { // Paper
return itemstack2;
}
}

View file

@ -1,93 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brokkonaut <hannos17@gmx.de>
Date: Mon, 18 Jun 2018 15:46:23 +0200
Subject: [PATCH] Implement EntityKnockbackByEntityEvent
This event is called when an entity receives knockback by another entity.
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index af2e81137d9c686f8d94a1d0d7241619fa1f352c..04489a915d11ba970a5188a5a913432ab4ef9faa 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1336,7 +1336,7 @@ public abstract class LivingEntity extends Entity {
}
this.hurtDir = (float) (Mth.atan2(d1, d0) * 57.2957763671875D - (double) this.yRot);
- this.knockback(0.4F, d0, d1);
+ this.doKnockback(0.4F, d0, d1, entity1); // Paper
} else {
this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180);
}
@@ -1384,7 +1384,7 @@ public abstract class LivingEntity extends Entity {
}
protected void blockedByShield(LivingEntity target) {
- target.knockback(0.5F, target.getX() - this.getX(), target.getZ() - this.getZ());
+ target.doKnockback(0.5F, target.getX() - this.getX(), target.getZ() - this.getZ(), this); // Paper
}
private boolean checkTotemDeathProtection(DamageSource source) {
@@ -1627,6 +1627,11 @@ public abstract class LivingEntity extends Entity {
}
public void knockback(float f, double d0, double d1) {
+ // Paper start - add knockbacking entity parameter
+ this.doKnockback(f, d0, d1, null);
+ }
+ public void doKnockback(float f, double d0, double d1, Entity knockingBackEntity) {
+ // Paper end - add knockbacking entity parameter
f = (float) ((double) f * (1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)));
if (f > 0.0F) {
this.hasImpulse = true;
@@ -1634,6 +1639,16 @@ public abstract class LivingEntity extends Entity {
Vec3 vec3d1 = (new Vec3(d0, 0.0D, d1)).normalize().scale((double) f);
this.setDeltaMovement(vec3d.x / 2.0D - vec3d1.x, this.onGround ? Math.min(0.4D, vec3d.y / 2.0D + (double) f) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
+
+ // Paper start - call EntityKnockbackByEntityEvent
+ Vec3 currentMot = this.getDeltaMovement();
+ org.bukkit.util.Vector delta = new org.bukkit.util.Vector(currentMot.x - vec3d.x, currentMot.y - vec3d.y, currentMot.z - vec3d.z);
+ // Restore old velocity to be able to access it in the event
+ this.setDeltaMovement(vec3d);
+ if (knockingBackEntity == null || new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((org.bukkit.entity.LivingEntity) getBukkitEntity(), knockingBackEntity.getBukkitEntity(), f, delta).callEvent()) {
+ this.setDeltaMovement(vec3d.x + delta.getX(), vec3d.y + delta.getY(), vec3d.z + delta.getZ());
+ }
+ // Paper end
}
}
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index eb35c69bb777ba8d83b2304ff9f862512643e745..f3690ea49cf90c816b8b3554b47d6f2d9dfbe016 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1566,7 +1566,7 @@ public abstract class Mob extends LivingEntity {
if (flag) {
if (f1 > 0.0F && target instanceof LivingEntity) {
- ((LivingEntity) target).knockback(f1 * 0.5F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)));
+ ((LivingEntity) target).doKnockback(f1 * 0.5F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)), this); // Paper
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
}
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index b88d8f2c377322290002e84e217f3f2f6e4e71e8..5e6a86b0b8999a5c47d2f9bdd9857ab5f0772033 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1174,7 +1174,7 @@ public abstract class Player extends LivingEntity {
if (flag5) {
if (i > 0) {
if (target instanceof LivingEntity) {
- ((LivingEntity) target).knockback((float) i * 0.5F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)));
+ ((LivingEntity) target).doKnockback((float) i * 0.5F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)), this); // Paper
} else {
target.push((double) (-Mth.sin(this.yRot * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.yRot * 0.017453292F) * (float) i * 0.5F));
}
@@ -1198,7 +1198,7 @@ public abstract class Player extends LivingEntity {
if (entityliving != this && entityliving != target && !this.isAlliedTo(entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr((Entity) entityliving) < 9.0D) {
// CraftBukkit start - Only apply knockback if the damage hits
if (entityliving.hurt(DamageSource.playerAttack(this).sweep(), f4)) {
- entityliving.knockback(0.4F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)));
+ entityliving.doKnockback(0.4F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)), this); // Paper
}
// CraftBukkit end
}

View file

@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 20 Jun 2018 23:17:24 -0400
Subject: [PATCH] Expand Explosions API
Add Entity as a Source capability, and add more API choices, and on Location.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 2dc9daaeea600fff1f2efddf74b6849fd745a28c..9b5a1c3ab8ffde524e194fdeaa8eaef6b286b57b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -871,6 +871,11 @@ public class CraftWorld implements World {
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) {
return !world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled;
}
+ // Paper start
+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) {
+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled;
+ }
+ // Paper end
@Override
public boolean createExplosion(Location loc, float power) {

View file

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 29 Jun 2018 00:21:28 -0400
Subject: [PATCH] LivingEntity Hand Raised/Item Use API
How long an entity has raised hands to charge an attack or use an item
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 04489a915d11ba970a5188a5a913432ab4ef9faa..205c639d26652befebae925fc6e40976c370710f 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -209,7 +209,7 @@ public abstract class LivingEntity extends Entity {
private float speed;
private int noJumpDelay;
private float absorptionAmount;
- protected ItemStack useItem;
+ public ItemStack useItem; // Paper - public
protected int useItemRemaining;
protected int fallFlyTicks;
private BlockPos lastPos;
@@ -3291,10 +3291,12 @@ public abstract class LivingEntity extends Entity {
return this.useItem;
}
+ public int getItemUseRemainingTime() { return this.getUseItemRemainingTicks(); } // Paper - OBFHELPER
public int getUseItemRemainingTicks() {
return this.useItemRemaining;
}
+ public int getHandRaisedTime() { return this.getTicksUsingItem(); } // Paper - OBFHELPER
public int getTicksUsingItem() {
return this.isUsingItem() ? this.useItem.getUseDuration() - this.getUseItemRemainingTicks() : 0;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 663887d9aecc2823fe7d02a9b108a291cd27102c..6dd7a722e10a2727f68318b880f2726bb816f198 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -709,5 +709,30 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
public void setShieldBlockingDelay(int delay) {
getHandle().setShieldBlockingDelay(delay);
}
+
+ @Override
+ public ItemStack getActiveItem() {
+ return getHandle().useItem.asBukkitMirror();
+ }
+
+ @Override
+ public int getItemUseRemainingTime() {
+ return getHandle().getItemUseRemainingTime();
+ }
+
+ @Override
+ public int getHandRaisedTime() {
+ return getHandle().getHandRaisedTime();
+ }
+
+ @Override
+ public boolean isHandRaised() {
+ return getHandle().isUsingItem();
+ }
+
+ @Override
+ public org.bukkit.inventory.EquipmentSlot getHandRaised() {
+ return getHandle().getUsedItemHand() == net.minecraft.world.InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND;
+ }
// Paper end
}

View file

@ -1,171 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 26 Jun 2018 22:00:49 -0400
Subject: [PATCH] RangedEntity API
Allows you to determine if an entity is capable of ranged attacks,
and to perform an attack.
diff --git a/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..e75e1d0d833c96af139fd955b2585ec24281b294
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
@@ -0,0 +1,19 @@
+package com.destroystokyo.paper.entity;
+
+import net.minecraft.world.entity.monster.RangedAttackMob;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.entity.LivingEntity;
+
+public interface CraftRangedEntity<T extends RangedAttackMob> extends RangedEntity {
+ T getHandle();
+
+ @Override
+ default void rangedAttack(LivingEntity target, float charge) {
+ getHandle().rangedAttack(((CraftLivingEntity) target).getHandle(), charge);
+ }
+
+ @Override
+ default void setChargingAttack(boolean raiseHands) {
+ getHandle().setChargingAttack(raiseHands);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java b/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
index b3ad4d54eeb1b894c24a5a76e8b12b8d9568cd56..ae10f3933fe78f74995952a6a8acf09ef4e99823 100644
--- a/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
+++ b/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
@@ -4,5 +4,8 @@ import net.minecraft.world.entity.LivingEntity;
public interface RangedAttackMob {
- void performRangedAttack(LivingEntity target, float pullProgress);
+ void performRangedAttack(LivingEntity target, float pullProgress); default void rangedAttack(LivingEntity entityliving, float f) { performRangedAttack(entityliving, f); } // Paper - OBFHELPER
+
+ // - see EntitySkeletonAbstract melee goal
+ void setAggressive(boolean flag); default void setChargingAttack(boolean charging) { setAggressive(charging); }; // Paper
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
index 34cb8062168258bfd168826ceeb2fde669f6d1a8..03e2acd4829da449a471b0fa1a311e74aee114d3 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.Drowned;
import org.bukkit.entity.EntityType;
-public class CraftDrowned extends CraftZombie implements Drowned {
+public class CraftDrowned extends CraftZombie implements Drowned, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Drowned> { // Paper
public CraftDrowned(CraftServer server, net.minecraft.world.entity.monster.Drowned entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
index 59b866e54e0d7e1dd8815ffa85275e36271113da..bbf7189a0fc9921e7a6007494f91229d9fba0846 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Illusioner;
-public class CraftIllusioner extends CraftSpellcaster implements Illusioner {
+public class CraftIllusioner extends CraftSpellcaster implements Illusioner, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Illusioner> { // Paper
public CraftIllusioner(CraftServer server, net.minecraft.world.entity.monster.Illusioner entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
index 04f716af67939b2dc34875f722816dd1ffdc4966..ed3b8fcc221d6c0789eb92eb4716d640ba0fec9f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
@@ -1,5 +1,6 @@
package org.bukkit.craftbukkit.entity;
+import com.destroystokyo.paper.entity.CraftRangedEntity;
import com.google.common.base.Preconditions;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.inventory.CraftInventoryLlama;
@@ -9,7 +10,7 @@ import org.bukkit.entity.Llama;
import org.bukkit.entity.Llama.Color;
import org.bukkit.inventory.LlamaInventory;
-public class CraftLlama extends CraftChestedHorse implements Llama {
+public class CraftLlama extends CraftChestedHorse implements Llama, CraftRangedEntity<net.minecraft.world.entity.animal.horse.Llama> { // Paper
public CraftLlama(CraftServer server, net.minecraft.world.entity.animal.horse.Llama entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
index 12bce49fcb164b6311a81024d1749a582ab1be25..c06fea6e0eaf58b8e7441ccf8595d6ca8417526a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
@@ -13,7 +13,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Piglin;
import org.bukkit.inventory.Inventory;
-public class CraftPiglin extends CraftPiglinAbstract implements Piglin {
+public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.piglin.Piglin> { // Paper
public CraftPiglin(CraftServer server, net.minecraft.world.entity.monster.piglin.Piglin entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
index fc86b8ecc349ed59c9eb6de03086d4027cb4e08d..949260d6750e71f148229955c94bcbaad9d54a2d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
@@ -6,7 +6,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Pillager;
import org.bukkit.inventory.Inventory;
-public class CraftPillager extends CraftIllager implements Pillager {
+public class CraftPillager extends CraftIllager implements Pillager, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Pillager> { // Paper
public CraftPillager(CraftServer server, net.minecraft.world.entity.monster.Pillager entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
index 4cd3dfd3466f384aab06dacd388e8053b045b046..b2d3244cca4d9d108159f3537d8a9aace3f8e77f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
@@ -6,7 +6,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
-public class CraftSkeleton extends CraftMonster implements Skeleton {
+public class CraftSkeleton extends CraftMonster implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity<AbstractSkeleton> { // Paper
public CraftSkeleton(CraftServer server, AbstractSkeleton entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
index fcce4aa391d0c448531815e99e0e32c84203c1b8..a7164a921f479c928049d4e812eab50567e96fc2 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
@@ -5,7 +5,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Snowman;
-public class CraftSnowman extends CraftGolem implements Snowman {
+public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem> { // Paper
public CraftSnowman(CraftServer server, SnowGolem entity) {
super(server, entity);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
index 60e00e539d214eb8854a53364c92c3cf55ca1062..d4eeb071dbbfca3ecea256228853bcb5c11f49ee 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Witch;
-public class CraftWitch extends CraftRaider implements Witch {
+public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Witch> { // Paper
public CraftWitch(CraftServer server, net.minecraft.world.entity.monster.Witch entity) {
super(server, entity);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
index 728a8c0f5781f33bdb096aefb569e9509dda8c89..fdcd680b972da54f9cdb41dff5563e42bd12d8e3 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.boss.CraftBossBar;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Wither;
-public class CraftWither extends CraftMonster implements Wither {
+public class CraftWither extends CraftMonster implements Wither, com.destroystokyo.paper.entity.CraftRangedEntity<WitherBoss> { // Paper
private BossBar bossBar;

View file

@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Fri, 22 Jun 2018 10:38:31 -0500
Subject: [PATCH] Add config to disable ender dragon legacy check
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 3e4bd1d6718d3ad2498fe9bd72eaac45044ecb77..4813f62d1e382d5ac6971b2244df3f13c80d1950 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -374,4 +374,9 @@ public class PaperWorldConfig {
private void shieldBlockingDelay() {
shieldBlockingDelay = getInt("game-mechanics.shield-blocking-delay", 5);
}
+
+ public boolean scanForLegacyEnderDragon = true;
+ private void scanForLegacyEnderDragon() {
+ scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true);
+ }
}
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
index 2386ffeec60851ba192b89bc6fd7ffff9c56aff5..4b18931225ef60dbcffd7fcc20d0e9ce62348a07 100644
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
@@ -73,7 +73,7 @@ public class EndDragonFight {
private boolean dragonKilled;
private boolean previouslyKilled;
public UUID dragonUUID;
- private boolean needsStateScanning;
+ private boolean needsStateScanning; private void setScanForLegacyFight(boolean scanForLegacyFight) { this.needsStateScanning = scanForLegacyFight; } private boolean scanForLegacyFight() { return this.needsStateScanning; } // Paper - OBFHELPER
public BlockPos portalLocation;
public DragonRespawnAnimation respawnStage;
private int respawnTime;

View file

@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brokkonaut <hannos17@gmx.de>
Date: Tue, 3 Jul 2018 16:08:14 +0200
Subject: [PATCH] Implement World.getEntity(UUID) API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 9b5a1c3ab8ffde524e194fdeaa8eaef6b286b57b..3a3466cd9bbd34dbc0b79567f5579e84a81d6009 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1286,6 +1286,15 @@ public class CraftWorld implements World {
return list;
}
+ // Paper start - getEntity by UUID API
+ @Override
+ public Entity getEntity(UUID uuid) {
+ Validate.notNull(uuid, "UUID cannot be null");
+ net.minecraft.world.entity.Entity entity = world.getEntity(uuid);
+ return entity == null ? null : entity.getBukkitEntity();
+ }
+ // Paper end
+
@Override
public void save() {
org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot

View file

@ -1,228 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 3 Jul 2018 21:56:23 -0400
Subject: [PATCH] InventoryCloseEvent Reason API
Allows you to determine why an inventory was closed, enabling plugin developers
to "confirm" things based on if it was player triggered close or not.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 5110f2c70d96284e8e7592b3d89266b867b9a466..ea1b15495481157912140bf5de9bf4a949c16910 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1119,7 +1119,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
for (BlockEntity tileentity : chunk.getBlockEntities().values()) {
if (tileentity instanceof net.minecraft.world.Container) {
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
- h.closeInventory();
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
}
}
}
@@ -1177,7 +1177,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder) {
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
- h.closeInventory();
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
}
}
// Spigot End
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0fa977a31cf945b74f3a046b6be302b10f494ad1..1441a461e749dbfa303095f6b51d655c45f68ce0 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -544,7 +544,7 @@ public class ServerPlayer extends Player implements ContainerListener {
}
// Paper end
if (!this.level.isClientSide && !this.containerMenu.stillValid(this)) {
- this.closeContainer();
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
this.containerMenu = this.inventoryMenu;
}
@@ -717,7 +717,7 @@ public class ServerPlayer extends Player implements ContainerListener {
// SPIGOT-943 - only call if they have an inventory open
if (this.containerMenu != this.inventoryMenu) {
- this.closeContainer();
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper
}
net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
@@ -1290,7 +1290,7 @@ public class ServerPlayer extends Player implements ContainerListener {
return OptionalInt.empty();
} else {
if (this.containerMenu != this.inventoryMenu) {
- this.closeContainer();
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
}
this.nextContainerCounter();
@@ -1350,7 +1350,7 @@ public class ServerPlayer extends Player implements ContainerListener {
}
// CraftBukkit end
if (this.containerMenu != this.inventoryMenu) {
- this.closeContainer();
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
}
// this.nextContainerCounter(); // CraftBukkit - moved up
@@ -1414,7 +1414,12 @@ public class ServerPlayer extends Player implements ContainerListener {
@Override
public void closeContainer() {
- CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit
+ // Paper start
+ closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
+ }
+ public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
+ // Paper end
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
this.doCloseContainer();
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index fb36aa08cd2fbe3f7262dccb8cf0f7cae55aea9c..d322e99170b3cb6594efc824a879ab9a538ea1eb 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -188,6 +188,7 @@ import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent; // Paper
import org.bukkit.event.inventory.InventoryCreativeEvent;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.inventory.SmithItemEvent;
@@ -2309,10 +2310,15 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@Override
public void handleContainerClose(ServerboundContainerClosePacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
+ // Paper start
+ handleContainerClose(packet, InventoryCloseEvent.Reason.PLAYER);
+ }
+ public void handleContainerClose(ServerboundContainerClosePacket packetplayinclosewindow, InventoryCloseEvent.Reason reason) {
+ // Paper end
+ PacketUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.getLevel());
if (this.player.isImmobile()) return; // CraftBukkit
- CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
+ CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper
this.player.doCloseContainer();
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index ae60b233c4d56a4964b388f96e9cc66410774e8d..51b1ce465d23b971f7e08a3175319a33183d0398 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -490,7 +490,7 @@ public abstract class PlayerList {
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
// See SPIGOT-5799, SPIGOT-6145
if (entityplayer.containerMenu != entityplayer.inventoryMenu) {
- entityplayer.closeContainer();
+ entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
}
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())));
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 5e6a86b0b8999a5c47d2f9bdd9857ab5f0772033..709e930eef7bae5694238ed8c4d0ef59316bb715 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -249,7 +249,7 @@ public abstract class Player extends LivingEntity {
this.updateIsUnderwater();
super.tick();
if (!this.level.isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) {
- this.closeContainer();
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
this.containerMenu = this.inventoryMenu;
}
@@ -444,6 +444,13 @@ public abstract class Player extends LivingEntity {
return 20;
}
+ // Paper start - unused code, but to keep signatures aligned
+ public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ closeContainer();
+ this.containerMenu = this.inventoryMenu;
+ }
+ // Paper end
+
public void closeContainer() {
this.containerMenu = this.inventoryMenu;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index 4aec1c2b26d48cb5bea3dfb9e183526763bdb98f..a73c6ddd6bf66cc21ae5b25daacdece8cbfeeeac 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -374,7 +374,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
if (((ServerPlayer) getHandle()).connection == null) return;
if (getHandle().containerMenu != getHandle().inventoryMenu) {
// fire INVENTORY_CLOSE if one already open
- ((ServerPlayer) getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(getHandle().containerMenu.containerId));
+ ((ServerPlayer) getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(getHandle().containerMenu.containerId), org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
}
ServerPlayer player = (ServerPlayer) getHandle();
AbstractContainerMenu container;
@@ -444,8 +444,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
@Override
public void closeInventory() {
- getHandle().closeContainer();
+ // Paper start
+ getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLUGIN);
}
+ public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ getHandle().closeContainer(reason);
+ }
+ // Paper end
@Override
public boolean isBlocking() {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 46338fe5693003698de9c7b37a860c3481e06233..c7f66dddf0a0850ca4048dd47cd2ded114caa07e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -895,7 +895,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Close any foreign inventory
if (getHandle().containerMenu != getHandle().inventoryMenu) {
- getHandle().closeContainer();
+ getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper
}
// Check if the fromWorld and toWorld are the same.
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 5e8ff18f98b03741ccbb927f87499ae36d775a86..c2f58b95db41b2205fbf2728c6a99419c6a63dfa 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1175,7 +1175,7 @@ public class CraftEventFactory {
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open
- player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId));
+ player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper
}
CraftServer server = player.level.getCraftServer();
@@ -1341,8 +1341,18 @@ public class CraftEventFactory {
return event;
}
+ // Paper start
+ /**
+ * Incase plugins hooked into this or Spigot adds a new inventory close event. Prefer to pass a reason
+ * @param human
+ */
+ @Deprecated
public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human) {
- InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView());
+ handleInventoryCloseEvent(human, org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
+ }
+ public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ // Paper end
+ InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView(), reason); // Paper
human.level.getCraftServer().getPluginManager().callEvent(event);
human.containerMenu.transferTo(human.inventoryMenu, human.getBukkitEntity());
}