More work work work

This commit is contained in:
Bjarne Koll
2023-09-22 14:22:24 +02:00
parent 2578e385d9
commit b5c4a402ee
30 changed files with 22 additions and 23 deletions

View File

@@ -1,86 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 3 Jan 2021 17:58:11 -0800
Subject: [PATCH] Add BlockBreakBlockEvent
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -0,0 +0,0 @@ public class Block extends BlockBehaviour implements ItemLike {
}
}
+ // Paper start
+ public static boolean dropResources(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockEntity blockEntity, BlockPos source) {
+ if (world instanceof ServerLevel) {
+ List<org.bukkit.inventory.ItemStack> items = com.google.common.collect.Lists.newArrayList();
+ for (net.minecraft.world.item.ItemStack drop : net.minecraft.world.level.block.Block.getDrops(state, world.getMinecraftWorld(), pos, blockEntity)) {
+ items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
+ }
+ io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.block.CraftBlock.at(world, source), items);
+ event.callEvent();
+ for (var drop : event.getDrops()) {
+ popResource(world.getMinecraftWorld(), pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
+ }
+ state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, true);
+ }
+ return true;
+ }
+ // Paper end
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
if (world instanceof ServerLevel) {
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
@@ -0,0 +0,0 @@ public class PistonBaseBlock extends DirectionalBlock {
iblockdata1 = world.getBlockState(blockposition3);
BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
- dropResources(iblockdata1, world, blockposition3, tileentity);
+ dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper
world.setBlock(blockposition3, Blocks.AIR.defaultBlockState(), 18);
world.gameEvent(GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1));
if (!iblockdata1.is(BlockTags.FIRE)) {
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
((LiquidBlockContainer) state.getBlock()).placeLiquid(world, pos, state, fluidState);
} else {
if (!state.isAir()) {
- this.beforeDestroyingBlock(world, pos, state);
+ this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper
}
world.setBlock(pos, fluidState.createLegacyBlock(), 3);
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
}
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - add source parameter
protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state);
private static short getCacheKey(BlockPos from, BlockPos to) {
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
@@ -0,0 +0,0 @@ public abstract class WaterFluid extends FlowingFluid {
return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
}
+ // Paper start
+ @Override
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
+ BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
+ Block.dropResources(state, world, pos, tileentity, source);
+ }
+ // Paper end
@Override
protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state) {
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 14 Oct 2021 12:09:39 -0500
Subject: [PATCH] Add ItemFactory#getSpawnEgg API
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
@@ -0,0 +0,0 @@ public final class CraftItemFactory implements ItemFactory {
new net.md_5.bungee.api.chat.TextComponent(customName));
}
// Paper end - bungee hover events
+
+ // Paper start - old getSpawnEgg API
+ // @Override // used to override, upstream added conflicting method, is called via Commodore now
+ @Deprecated
+ public ItemStack getSpawnEgg0(org.bukkit.entity.EntityType type) {
+ if (type == null) {
+ return null;
+ }
+ String typeId = type.getKey().toString();
+ net.minecraft.resources.ResourceLocation typeKey = new net.minecraft.resources.ResourceLocation(typeId);
+ net.minecraft.world.entity.EntityType<?> nmsType = net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(typeKey);
+ net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType);
+ return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror();
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
@@ -0,0 +0,0 @@ public class Commodore
return;
}
// Paper end
+
+ // Paper start - ItemFactory#getSpawnEgg (paper had original method that returned ItemStack, upstream added identical but returned Material)
+ if (owner.equals("org/bukkit/inventory/ItemFactory") && name.equals("getSpawnEgg") && desc.equals("(Lorg/bukkit/entity/EntityType;)Lorg/bukkit/inventory/ItemStack;")) {
+ super.visitInsn(Opcodes.SWAP); // has 1 param, this moves the owner instance to the top for the checkcast
+ super.visitTypeInsn(Opcodes.CHECKCAST, CB_PACKAGE + "/inventory/CraftItemFactory");
+ super.visitInsn(Opcodes.SWAP); // moves param back to the the top of stack
+ super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CB_PACKAGE + "/inventory/CraftItemFactory", "getSpawnEgg0", desc, false);
+ return;
+ }
+ // Paper end - ItemFactory#getSpawnEgg
if ( modern )
{
if ( owner.equals( "org/bukkit/Material" ) )

View File

@@ -1,204 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 19 May 2021 18:59:10 -0700
Subject: [PATCH] Add PlayerSetSpawnEvent
diff --git a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
+++ b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
@@ -0,0 +0,0 @@ public class SetSpawnCommand {
ResourceKey<Level> resourcekey = source.getLevel().dimension();
Iterator iterator = targets.iterator();
+ final Collection<ServerPlayer> actualTargets = new java.util.ArrayList<>(); // Paper
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
- entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.COMMAND); // CraftBukkit
+ // Paper start - PlayerSetSpawnEvent
+ if (entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) {
+ actualTargets.add(entityplayer);
+ }
+ // Paper end
}
+ // Paper start
+ if (actualTargets.isEmpty()) {
+ return 0;
+ }
+ // Paper end
String s = resourcekey.location().toString();
- if (targets.size() == 1) {
+ if (actualTargets.size() == 1) { // Paper
source.sendSuccess(() -> {
- return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) targets.iterator().next()).getDisplayName());
+ return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) actualTargets.iterator().next()).getDisplayName()); // Paper
}, true);
} else {
source.sendSuccess(() -> {
- return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, targets.size());
+ return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, actualTargets.size()); // Paper
}, true);
}
- return targets.size();
+ return actualTargets.size(); // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
} else if (this.bedBlocked(blockposition, enumdirection)) {
return Either.left(Player.BedSleepingProblem.OBSTRUCTED);
} else {
- this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, PlayerSpawnChangeEvent.Cause.BED); // CraftBukkit
+ this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.BED); // Paper - PlayerSetSpawnEvent
if (this.level().isDay()) {
return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
} else {
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
return this.respawnForced;
}
+ @Deprecated // Paper
public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
- // CraftBukkit start
- this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, PlayerSpawnChangeEvent.Cause.UNKNOWN);
- }
-
- public void setRespawnPosition(ResourceKey<Level> resourcekey, @Nullable BlockPos blockposition, float f, boolean flag, boolean flag1, PlayerSpawnChangeEvent.Cause cause) {
- ServerLevel newWorld = this.server.getLevel(resourcekey);
- Location newSpawn = (blockposition != null) ? CraftLocation.toBukkit(blockposition, newWorld.getWorld(), f, 0) : null;
-
- PlayerSpawnChangeEvent event = new PlayerSpawnChangeEvent(this.getBukkitEntity(), newSpawn, flag, cause);
- Bukkit.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
- newSpawn = event.getNewSpawn();
- flag = event.isForced();
-
- if (newSpawn != null) {
- resourcekey = ((CraftWorld) newSpawn.getWorld()).getHandle().dimension();
- blockposition = BlockPos.containing(newSpawn.getX(), newSpawn.getY(), newSpawn.getZ());
- f = newSpawn.getYaw();
- } else {
- resourcekey = Level.OVERWORLD;
- blockposition = null;
- f = 0.0F;
+ // Paper start
+ this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.UNKNOWN);
+ }
+ @Deprecated
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, PlayerSpawnChangeEvent.Cause cause) {
+ return this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, cause == PlayerSpawnChangeEvent.Cause.RESET ?
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN : com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.valueOf(cause.name()));
+ }
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause cause) {
+ Location spawnLoc = null;
+ boolean willNotify = false;
+ if (pos != null) {
+ boolean flag2 = pos.equals(this.respawnPosition) && dimension.equals(this.respawnDimension);
+ spawnLoc = io.papermc.paper.util.MCUtil.toLocation(this.getServer().getLevel(dimension), pos);
+ spawnLoc.setYaw(angle);
+ willNotify = sendMessage && !flag2;
+ }
+
+ PlayerSpawnChangeEvent dumbEvent = new PlayerSpawnChangeEvent(this.getBukkitEntity(), spawnLoc, forced,
+ cause == com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN ? PlayerSpawnChangeEvent.Cause.RESET : PlayerSpawnChangeEvent.Cause.valueOf(cause.name()));
+ dumbEvent.callEvent();
+
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent event = new com.destroystokyo.paper.event.player.PlayerSetSpawnEvent(this.getBukkitEntity(), cause, dumbEvent.getNewSpawn(), dumbEvent.isForced(), willNotify, willNotify ? net.kyori.adventure.text.Component.translatable("block.minecraft.set_spawn") : null);
+ event.setCancelled(dumbEvent.isCancelled());
+ if (!event.callEvent()) {
+ return false;
}
- // CraftBukkit end
- if (blockposition != null) {
- boolean flag2 = blockposition.equals(this.respawnPosition) && resourcekey.equals(this.respawnDimension);
+ if (event.getLocation() != null) {
+ dimension = event.getLocation().getWorld() != null ? ((CraftWorld) event.getLocation().getWorld()).getHandle().dimension() : dimension;
+ pos = io.papermc.paper.util.MCUtil.toBlockPosition(event.getLocation());
+ angle = event.getLocation().getYaw();
+ forced = event.isForced();
+ // Paper end
- if (flag1 && !flag2) {
- this.sendSystemMessage(Component.translatable("block.minecraft.set_spawn"));
+ if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper
+ this.sendSystemMessage(PaperAdventure.asVanilla(event.getNotification())); // Paper
}
- this.respawnPosition = blockposition;
- this.respawnDimension = resourcekey;
- this.respawnAngle = f;
- this.respawnForced = flag;
+ this.respawnPosition = pos;
+ this.respawnDimension = dimension;
+ this.respawnAngle = angle;
+ this.respawnForced = forced;
} else {
this.respawnPosition = null;
this.respawnDimension = Level.OVERWORLD;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
this.respawnForced = false;
}
+ return true; // Paper
}
public void trackChunk(ChunkPos chunkPos, Packet<?> chunkDataPacket) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
location = CraftLocation.toBukkit(vec3d, worldserver1.getWorld(), f1, 0.0F);
} else if (blockposition != null) {
entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
- entityplayer1.setRespawnPosition(null, null, 0f, false, false, PlayerSpawnChangeEvent.Cause.RESET); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed
+ entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - PlayerSetSpawnEvent
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -0,0 +0,0 @@ public class RespawnAnchorBlock extends Block {
ServerPlayer entityplayer = (ServerPlayer) player;
if (entityplayer.getRespawnDimension() != world.dimension() || !pos.equals(entityplayer.getRespawnPosition())) {
- entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR); // CraftBukkit
+ if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - PlayerSetSpawnEvent
world.playSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
return InteractionResult.SUCCESS;
+ // Paper start - handle failed set spawn
+ } else {
+ return InteractionResult.FAIL;
+ }
+ // Paper end
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setBedSpawnLocation(Location location, boolean override) {
if (location == null) {
- this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
+ this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent
} else {
- this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
+ this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent
}
}

View File

@@ -1,118 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: underscore11code <minecrafter11mrt@gmail.com>
Date: Fri, 23 Jul 2021 23:01:42 -0700
Subject: [PATCH] Add System.out/err catcher
diff --git a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.logging;
+
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+
+public final class SysoutCatcher {
+ private static final boolean SUPPRESS_NAGS = Boolean.getBoolean("io.papermc.paper.suppress.sout.nags");
+ // Nanoseconds between nag at most; if interval is caught first, this is reset.
+ // <= 0 for disabling.
+ private static final long NAG_TIMEOUT = TimeUnit.MILLISECONDS.toNanos(
+ Long.getLong("io.papermc.paper.sout.nags.timeout", TimeUnit.MINUTES.toMillis(5L)));
+ // Count since last nag; if timeout is first, this is reset.
+ // <= 0 for disabling.
+ private static final long NAG_INTERVAL = Long.getLong("io.papermc.paper.sout.nags.interval", 200L);
+
+ // We don't particularly care about how correct this is at any given moment; let's do it on a best attempt basis.
+ // The records are also pretty small, so let's just go for a size of 64 to start...
+ //
+ // Content: Plugin name => nag object
+ // Why plugin name?: This doesn't store a reference to the plugin; keeps the reload ability.
+ // Why not clean on reload?: Effort.
+ private final ConcurrentMap<String, PluginNag> nagRecords = new ConcurrentHashMap<>(64);
+
+ public SysoutCatcher() {
+ System.setOut(new WrappedOutStream(System.out, Level.INFO, "[STDOUT] "));
+ System.setErr(new WrappedOutStream(System.err, Level.SEVERE, "[STDERR] "));
+ }
+
+ private final class WrappedOutStream extends PrintStream {
+ private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ private final Level level;
+ private final String prefix;
+
+ public WrappedOutStream(@NotNull final OutputStream out, final Level level, final String prefix) {
+ super(out);
+ this.level = level;
+ this.prefix = prefix;
+ }
+
+ @Override
+ public void println(@Nullable final String line) {
+ final Class<?> clazz = STACK_WALKER.getCallerClass();
+ try {
+ final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(clazz);
+
+ // Instead of just printing the message, send it to the plugin's logger
+ plugin.getLogger().log(this.level, this.prefix + line);
+
+ if (SysoutCatcher.SUPPRESS_NAGS) {
+ return;
+ }
+ if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) {
+ final PluginNag nagRecord = SysoutCatcher.this.nagRecords.computeIfAbsent(plugin.getName(), k -> new PluginNag());
+ final boolean hasTimePassed = SysoutCatcher.NAG_TIMEOUT > 0
+ && (nagRecord.lastNagTimestamp == Long.MIN_VALUE
+ || nagRecord.lastNagTimestamp + SysoutCatcher.NAG_TIMEOUT <= System.nanoTime());
+ final boolean hasMessagesPassed = SysoutCatcher.NAG_INTERVAL > 0
+ && (nagRecord.messagesSinceNag == Long.MIN_VALUE
+ || ++nagRecord.messagesSinceNag >= SysoutCatcher.NAG_INTERVAL);
+ if (!hasMessagesPassed && !hasTimePassed) {
+ return;
+ }
+ nagRecord.lastNagTimestamp = System.nanoTime();
+ nagRecord.messagesSinceNag = 0;
+ }
+ Bukkit.getLogger().warning(
+ String.format("Nag author(s): '%s' of '%s' about their usage of System.out/err.print. "
+ + "Please use your plugin's logger instead (JavaPlugin#getLogger).",
+ plugin.getPluginMeta().getAuthors(),
+ plugin.getPluginMeta().getDisplayName())
+ );
+ } catch (final IllegalArgumentException | IllegalStateException e) {
+ // If anything happens, the calling class doesn't exist, there is no JavaPlugin that "owns" the calling class, etc
+ // Just print out normally, with some added information
+ Bukkit.getLogger().log(this.level, String.format("%s[%s] %s", this.prefix, clazz.getName(), line));
+ }
+ }
+ }
+
+ private static class PluginNag {
+ private long lastNagTimestamp = Long.MIN_VALUE;
+ private long messagesSinceNag = Long.MIN_VALUE;
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
public int reloadCount;
private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
public static Exception excessiveVelEx; // Paper - Velocity warnings
+ private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
static {
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);

View File

@@ -1,106 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 20 Jul 2021 21:25:35 -0700
Subject: [PATCH] Add a bunch of missing forceDrop toggles
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
@@ -0,0 +0,0 @@ public class WorkAtComposter extends WorkAtPoi {
simpleContainer.removeItemType(Items.WHEAT, m);
ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l));
if (!itemStack.isEmpty()) {
+ entity.forceDrops = true; // Paper
entity.spawnAtLocation(itemStack, 0.5F);
+ entity.forceDrops = false; // Paper
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
@@ -0,0 +0,0 @@ public class Panda extends Animal {
}
if (!this.level().isClientSide() && this.random.nextInt(700) == 0 && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
+ this.forceDrops = true; // Paper
this.spawnAtLocation((ItemLike) Items.SLIME_BALL);
+ this.forceDrops = false; // Paper
}
}
@@ -0,0 +0,0 @@ public class Panda extends Animal {
ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemstack1.isEmpty() && !player.getAbilities().instabuild) {
+ this.forceDrops = true; // Paper
this.spawnAtLocation(itemstack1);
+ this.forceDrops = false; // Paper
}
this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1));
@@ -0,0 +0,0 @@ public class Panda extends Animal {
ItemStack itemstack = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemstack.isEmpty()) {
+ Panda.this.forceDrops = true; // Paper
Panda.this.spawnAtLocation(itemstack);
+ Panda.this.forceDrops = false; // Paper
Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10;
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -0,0 +0,0 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@Override
protected void finishConversion(ServerLevel world) {
PiglinAi.cancelAdmiring(this);
+ this.forceDrops = true; // Paper
this.inventory.removeAllItems().forEach(this::spawnAtLocation);
+ this.forceDrops = false; // Paper
super.finishConversion(world);
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -0,0 +0,0 @@ public class PiglinAi {
private static void holdInOffhand(Piglin piglin, ItemStack stack) {
if (PiglinAi.isHoldingItemInOffHand(piglin)) {
+ piglin.forceDrops = true; // Paper
piglin.spawnAtLocation(piglin.getItemInHand(InteractionHand.OFF_HAND));
+ piglin.forceDrops = false; // Paper
}
piglin.holdInOffHand(stack);
@@ -0,0 +0,0 @@ public class PiglinAi {
protected static void cancelAdmiring(Piglin piglin) {
if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+ piglin.forceDrops = true; // Paper
piglin.spawnAtLocation(piglin.getOffhandItem());
+ piglin.forceDrops = false; // Paper
piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
}
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java
@@ -0,0 +0,0 @@ public abstract class Raider extends PatrollingMonster {
double d0 = (double) this.getEquipmentDropChance(enumitemslot);
if (!itemstack1.isEmpty() && (double) Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d0) {
+ this.forceDrops = true; // Paper
this.spawnAtLocation(itemstack1);
+ this.forceDrops = false; // Paper
}
this.onItemPickup(item);

View File

@@ -1,50 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 16 May 2021 09:39:46 -0700
Subject: [PATCH] Add back EntityPortalExitEvent
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
} else {
// CraftBukkit start
worldserver = shapedetectorshape.world;
+ // Paper start - Call EntityPortalExitEvent
+ CraftEntity bukkitEntity = this.getBukkitEntity();
+ Vec3 position = shapedetectorshape.pos;
+ float yaw = shapedetectorshape.yRot;
+ float pitch = bukkitEntity.getLocation().getPitch(); // Keep entity pitch as per moveTo line below
+ Vec3 velocity = shapedetectorshape.speed;
+ org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent(bukkitEntity,
+ bukkitEntity.getLocation(), new Location(worldserver.getWorld(), position.x, position.y, position.z, yaw, pitch),
+ bukkitEntity.getVelocity(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(shapedetectorshape.speed));
+ event.callEvent();
+ if (this.isRemoved()) {
+ return null;
+ }
+
+ if (!event.isCancelled() && event.getTo() != null) {
+ worldserver = ((CraftWorld) event.getTo().getWorld()).getHandle();
+ position = new Vec3(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
+ yaw = event.getTo().getYaw();
+ pitch = event.getTo().getPitch();
+ velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter());
+ }
+ // Paper end
if (worldserver == this.level) {
// SPIGOT-6782: Just move the entity if a plugin changed the world to the one the entity is already in
this.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, shapedetectorshape.xRot);
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (entity != null) {
entity.restoreFrom(this);
- entity.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, entity.getXRot());
- entity.setDeltaMovement(shapedetectorshape.speed);
+ entity.moveTo(position.x, position.y, position.z, yaw, pitch); // Paper - use EntityPortalExitEvent values
+ entity.setDeltaMovement(velocity); // Paper - use EntityPortalExitEvent values
worldserver.addDuringTeleport(entity);
if (worldserver.getTypeKey() == LevelStem.END) { // CraftBukkit
ServerLevel.makeObsidianPlatform(worldserver, this); // CraftBukkit

View File

@@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakub Zacek <dawon@dawon.eu>
Date: Mon, 4 Oct 2021 10:16:44 +0200
Subject: [PATCH] Add methods to find targets for lightning strikes
== AT ==
public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
protected BlockPos findLightningTargetAround(BlockPos pos) {
+ // Paper start
+ return this.findLightningTargetAround(pos, false);
+ }
+ public BlockPos findLightningTargetAround(BlockPos pos, boolean returnNullWhenNoTarget) {
+ // Paper end
BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
Optional<BlockPos> optional = this.findLightningRod(blockposition1);
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (!list.isEmpty()) {
return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition();
} else {
+ if (returnNullWhenNoTarget) return null; // Paper
if (blockposition1.getY() == this.getMinBuildHeight() - 1) {
blockposition1 = blockposition1.above(2);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return (LightningStrike) lightning.getBukkitEntity();
}
+ // Paper start
+ @Override
+ public Location findLightningRod(Location location) {
+ return this.world.findLightningRod(io.papermc.paper.util.MCUtil.toBlockPosition(location))
+ .map(blockPos -> io.papermc.paper.util.MCUtil.toLocation(this.world, blockPos)
+ // get the actual rod pos
+ .subtract(0, 1, 0))
+ .orElse(null);
+ }
+
+ @Override
+ public Location findLightningTarget(Location location) {
+ final BlockPos pos = this.world.findLightningTargetAround(io.papermc.paper.util.MCUtil.toBlockPosition(location), true);
+ return pos == null ? null : io.papermc.paper.util.MCUtil.toLocation(this.world, pos);
+ }
+ // Paper end
+
@Override
public boolean generateTree(Location loc, TreeType type) {
return generateTree(loc, CraftWorld.rand, type);

View File

@@ -1,106 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 1 Oct 2021 08:04:39 -0700
Subject: [PATCH] Add missing team sidebar display slots
== AT ==
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations toBukkitSlot(I)Lorg/bukkit/scoreboard/DisplaySlot;
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations fromBukkitSlot(Lorg/bukkit/scoreboard/DisplaySlot;)I
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
@@ -0,0 +0,0 @@ import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.RenderType;
public final class CraftScoreboardTranslations {
- static final int MAX_DISPLAY_SLOT = 19;
+ static final int MAX_DISPLAY_SLOT = Scoreboard.getDisplaySlotNames().length; // Paper
+ @Deprecated // Paper
static final ImmutableBiMap<DisplaySlot, String> SLOTS = ImmutableBiMap.<DisplaySlot, String>builder()
.put(DisplaySlot.BELOW_NAME, "belowName")
.put(DisplaySlot.PLAYER_LIST, "list")
.put(DisplaySlot.SIDEBAR, "sidebar")
- .put(DisplaySlot.SIDEBAR_BLACK, "sidebar.team.black")
- .put(DisplaySlot.SIDEBAR_DARK_BLUE, "sidebar.team.dark_blue")
- .put(DisplaySlot.SIDEBAR_DARK_GREEN, "sidebar.team.dark_green")
- .put(DisplaySlot.SIDEBAR_DARK_AQUA, "sidebar.team.dark_aqua")
- .put(DisplaySlot.SIDEBAR_DARK_RED, "sidebar.team.dark_red")
- .put(DisplaySlot.SIDEBAR_DARK_PURPLE, "sidebar.team.dark_purple")
- .put(DisplaySlot.SIDEBAR_GOLD, "sidebar.team.gold")
- .put(DisplaySlot.SIDEBAR_GRAY, "sidebar.team.gray")
- .put(DisplaySlot.SIDEBAR_DARK_GRAY, "sidebar.team.dark_gray")
- .put(DisplaySlot.SIDEBAR_BLUE, "sidebar.team.blue")
- .put(DisplaySlot.SIDEBAR_GREEN, "sidebar.team.green")
- .put(DisplaySlot.SIDEBAR_AQUA, "sidebar.team.aqua")
- .put(DisplaySlot.SIDEBAR_RED, "sidebar.team.red")
- .put(DisplaySlot.SIDEBAR_LIGHT_PURPLE, "sidebar.team.light_purple")
- .put(DisplaySlot.SIDEBAR_YELLOW, "sidebar.team.yellow")
- .put(DisplaySlot.SIDEBAR_WHITE, "sidebar.team.white")
.buildOrThrow();
private CraftScoreboardTranslations() {}
public static DisplaySlot toBukkitSlot(int i) {
+ if (true) return org.bukkit.scoreboard.DisplaySlot.NAMES.value(Scoreboard.getDisplaySlotName(i)); // Paper
return CraftScoreboardTranslations.SLOTS.inverse().get(Scoreboard.getDisplaySlotName(i));
}
public static int fromBukkitSlot(DisplaySlot slot) {
+ if (true) return Scoreboard.getDisplaySlotByName(slot.getId()); // Paper
return Scoreboard.getDisplaySlotByName(CraftScoreboardTranslations.SLOTS.get(slot));
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
@@ -0,0 +0,0 @@ public class Commodore
desc = getOriginalOrRewrite( desc );
}
// Paper end
+ // Paper start - DisplaySlot
+ if (owner.equals("org/bukkit/scoreboard/DisplaySlot")) {
+ if (name.startsWith("SIDEBAR_") && !name.startsWith("SIDEBAR_TEAM_")) {
+ super.visitFieldInsn(opcode, owner, name.replace("SIDEBAR_", "SIDEBAR_TEAM_"), desc);
+ return;
+ }
+ }
+ // Paper end - DisplaySlot
if ( owner.equals( "org/bukkit/block/Biome" ) )
{
diff --git a/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.scoreboard;
+
+import net.minecraft.world.scores.Scoreboard;
+import org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class DisplaySlotTest {
+
+ @Test
+ public void testBukkitToMinecraftDisplaySlots() {
+ for (DisplaySlot value : DisplaySlot.values()) {
+ assertNotEquals(-1, CraftScoreboardTranslations.fromBukkitSlot(value));
+ }
+ }
+
+ @Test
+ public void testMinecraftToBukkitDisplaySlots() {
+ for (String name : Scoreboard.getDisplaySlotNames()) {
+ assertNotNull(CraftScoreboardTranslations.toBukkitSlot(Scoreboard.getDisplaySlotByName(name)));
+ }
+ }
+}

View File

@@ -1,244 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: syldium <syldium@mailo.com>
Date: Fri, 9 Jul 2021 18:50:40 +0200
Subject: [PATCH] Add more advancement API
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.advancement;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import net.kyori.adventure.text.Component;
+import net.minecraft.advancements.Advancement;
+import net.minecraft.advancements.DisplayInfo;
+import net.minecraft.advancements.FrameType;
+import org.bukkit.NamespacedKey;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public record PaperAdvancementDisplay(DisplayInfo handle) implements AdvancementDisplay {
+
+ @Override
+ public @NotNull Frame frame() {
+ return asPaperFrame(this.handle.getFrame());
+ }
+
+ @Override
+ public @NotNull Component title() {
+ return PaperAdventure.asAdventure(this.handle.getTitle());
+ }
+
+ @Override
+ public @NotNull Component description() {
+ return PaperAdventure.asAdventure(this.handle.getDescription());
+ }
+
+ @Override
+ public @NotNull ItemStack icon() {
+ return CraftItemStack.asBukkitCopy(this.handle.getIcon());
+ }
+
+ @Override
+ public boolean doesShowToast() {
+ return this.handle.shouldShowToast();
+ }
+
+ @Override
+ public boolean doesAnnounceToChat() {
+ return this.handle.shouldAnnounceChat();
+ }
+
+ @Override
+ public boolean isHidden() {
+ return this.handle.isHidden();
+ }
+
+ @Override
+ public @Nullable NamespacedKey backgroundPath() {
+ return this.handle.getBackground() == null ? null : CraftNamespacedKey.fromMinecraft(this.handle.getBackground());
+ }
+
+ @Override
+ public @NotNull Component displayName() {
+ return PaperAdventure.asAdventure(Advancement.constructDisplayComponent(null, this.handle));
+ }
+
+ public static @NotNull Frame asPaperFrame(@NotNull FrameType frameType) {
+ return switch (frameType) {
+ case TASK -> Frame.TASK;
+ case CHALLENGE -> Frame.CHALLENGE;
+ case GOAL -> Frame.GOAL;
+ };
+ }
+}
diff --git a/src/main/java/net/minecraft/advancements/Advancement.java b/src/main/java/net/minecraft/advancements/Advancement.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/advancements/Advancement.java
+++ b/src/main/java/net/minecraft/advancements/Advancement.java
@@ -0,0 +0,0 @@ public class Advancement {
parent.addChild(this);
}
- if (display == null) {
- this.chatComponent = Component.literal(id.toString());
+ // Paper start - moved to static method
+ this.chatComponent = constructDisplayComponent(this.id, this.display);
+ }
+
+ public static Component constructDisplayComponent(final @Nullable ResourceLocation id, final @Nullable DisplayInfo display) {
+ if (id == null && display == null) {
+ throw new IllegalArgumentException("can't both be null");
+ } else if (display == null) {
+ return Component.literal(id.toString());
+ // Paper end
} else {
Component ichatbasecomponent = display.getTitle();
ChatFormatting enumchatformat = display.getFrame().getChatColor();
@@ -0,0 +0,0 @@ public class Advancement {
return chatmodifier.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, ichatmutablecomponent));
});
- this.chatComponent = ComponentUtils.wrapInSquareBrackets(ichatmutablecomponent1).withStyle(enumchatformat);
+ return ComponentUtils.wrapInSquareBrackets(ichatmutablecomponent1).withStyle(enumchatformat); // Paper
}
}
diff --git a/src/main/java/net/minecraft/advancements/DisplayInfo.java b/src/main/java/net/minecraft/advancements/DisplayInfo.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/advancements/DisplayInfo.java
+++ b/src/main/java/net/minecraft/advancements/DisplayInfo.java
@@ -0,0 +0,0 @@ public class DisplayInfo {
private final boolean hidden;
private float x;
private float y;
+ public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper
public DisplayInfo(ItemStack icon, Component title, Component description, @Nullable ResourceLocation background, FrameType frame, boolean showToast, boolean announceToChat, boolean hidden) {
this.title = title;
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
@@ -0,0 +0,0 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement {
return Collections.unmodifiableCollection(this.handle.getCriteria().keySet());
}
+ // Paper start
@Override
- public AdvancementDisplay getDisplay() {
- if (this.handle.getDisplay() == null) {
- return null;
+ public io.papermc.paper.advancement.AdvancementDisplay getDisplay() {
+ return this.handle.getDisplay() == null ? null : this.handle.getDisplay().paper;
+ }
+
+ @Deprecated @io.papermc.paper.annotation.DoNotUse
+ public AdvancementDisplay getDisplay0() { // May be called by plugins via Commodore
+ return this.handle.getDisplay() == null ? null : new CraftAdvancementDisplay(this.handle.getDisplay());
+ }
+
+ @Override
+ public net.kyori.adventure.text.Component displayName() {
+ return io.papermc.paper.adventure.PaperAdventure.asAdventure(Advancement.constructDisplayComponent(this.handle.getId(), this.handle.getDisplay()));
+ }
+
+ @Override
+ public org.bukkit.advancement.Advancement getParent() {
+ return this.handle.getParent() == null ? null : this.handle.getParent().bukkit;
+ }
+
+ @Override
+ public Collection<org.bukkit.advancement.Advancement> getChildren() {
+ final var children = com.google.common.collect.ImmutableList.<org.bukkit.advancement.Advancement>builder();
+ for (Advancement advancement : this.handle.getChildren()) {
+ children.add(advancement.bukkit);
}
+ return children.build();
+ }
- return new CraftAdvancementDisplay(this.handle.getDisplay());
+ @Override
+ public org.bukkit.advancement.Advancement getRoot() {
+ Advancement advancement = this.handle;
+ while (advancement.getParent() != null) {
+ advancement = advancement.getParent();
+ }
+ return advancement.bukkit;
}
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.inventory.ItemStack;
+@Deprecated // Paper
public class CraftAdvancementDisplay implements org.bukkit.advancement.AdvancementDisplay {
private final DisplayInfo handle;
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
@@ -0,0 +0,0 @@ public class Commodore
) );
// Paper start - Plugin rewrites
+ private static final String CB_PACKAGE = org.bukkit.Bukkit.getServer().getClass().getPackageName().replace('.', '/');
private static final Map<String, String> SEARCH_AND_REMOVE = initReplacementsMap();
private static Map<String, String> initReplacementsMap()
{
@@ -0,0 +0,0 @@ public class Commodore
super.visitMethodInsn(opcode, owner, name, "()Lcom/destroystokyo/paper/profile/PlayerProfile;", itf);
return;
}
+ if (owner.equals("org/bukkit/advancement/Advancement") && name.equals("getDisplay") && desc.endsWith(")Lorg/bukkit/advancement/AdvancementDisplay;")) {
+ super.visitTypeInsn(Opcodes.CHECKCAST, CB_PACKAGE + "/advancement/CraftAdvancement");
+ super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CB_PACKAGE + "/advancement/CraftAdvancement", "getDisplay0", desc, false);
+ return;
+ }
// Paper end
if ( modern )
{
diff --git a/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.advancement;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import net.kyori.adventure.text.format.TextColor;
+import net.minecraft.advancements.FrameType;
+import net.minecraft.network.chat.contents.TranslatableContents;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class AdvancementFrameTest {
+
+ @Test
+ public void test() {
+ for (FrameType nmsFrameType : FrameType.values()) {
+ final TextColor expectedColor = PaperAdventure.asAdventure(nmsFrameType.getChatColor());
+ final String expectedTranslationKey = ((TranslatableContents) nmsFrameType.getDisplayName().getContents()).getKey();
+ final var frame = PaperAdvancementDisplay.asPaperFrame(nmsFrameType);
+ assertEquals("The translation keys should be the same", expectedTranslationKey, frame.translationKey());
+ assertEquals("The frame colors should be the same", expectedColor, frame.color());
+ assertEquals(nmsFrameType.getName(), AdvancementDisplay.Frame.NAMES.key(frame));
+ }
+ }
+}

View File

@@ -1,65 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 22 Dec 2020 13:52:48 -0800
Subject: [PATCH] Added EntityDamageItemEvent
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -0,0 +0,0 @@ public final class ItemStack {
return this.getItem().getMaxDamage();
}
- public boolean hurt(int amount, RandomSource random, @Nullable ServerPlayer player) {
+ public boolean hurt(int amount, RandomSource random, @Nullable LivingEntity player) { // Paper - allow any living entity instead of only ServerPlayers
if (!this.isDamageableItem()) {
return false;
} else {
@@ -0,0 +0,0 @@ public final class ItemStack {
amount -= k;
// CraftBukkit start
- if (player != null) {
- PlayerItemDamageEvent event = new PlayerItemDamageEvent(player.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount);
+ if (player instanceof ServerPlayer serverPlayer) { // Paper
+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper
event.getPlayer().getServer().getPluginManager().callEvent(event);
if (amount != event.getDamage() || event.isCancelled()) {
@@ -0,0 +0,0 @@ public final class ItemStack {
}
amount = event.getDamage();
+ // Paper start - EntityDamageItemEvent
+ } else if (player != null) {
+ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount);
+ if (!event.callEvent()) {
+ return false;
+ }
+ amount = event.getDamage();
+ // Paper end
}
// CraftBukkit end
if (amount <= 0) {
@@ -0,0 +0,0 @@ public final class ItemStack {
}
}
- if (player != null && amount != 0) {
- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, this.getDamageValue() + amount);
+ if (player instanceof ServerPlayer serverPlayer && amount != 0) { // Paper
+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, this.getDamageValue() + amount); // Paper
}
j = this.getDamageValue() + amount;
@@ -0,0 +0,0 @@ public final class ItemStack {
public <T extends LivingEntity> void hurtAndBreak(int amount, T entity, Consumer<T> breakCallback) {
if (!entity.level().isClientSide && (!(entity instanceof net.minecraft.world.entity.player.Player) || !((net.minecraft.world.entity.player.Player) entity).getAbilities().instabuild)) {
if (this.isDamageableItem()) {
- if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer) entity : null)) {
+ if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - pass LivingEntity for EntityItemDamageEvent
breakCallback.accept(entity);
Item item = this.getItem();
// CraftBukkit start - Check for item breaking

View File

@@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Professor Bloodstone <git@bloodstone.dev>
Date: Fri, 23 Jul 2021 02:32:04 +0200
Subject: [PATCH] Allow skipping writing of comments to server.properties
Makes less git noise, as it won't update the date every single time
Use -DPaper.skipServerPropertiesComments=true flag to disable writing it
diff --git a/src/main/java/net/minecraft/server/dedicated/Settings.java b/src/main/java/net/minecraft/server/dedicated/Settings.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/dedicated/Settings.java
+++ b/src/main/java/net/minecraft/server/dedicated/Settings.java
@@ -0,0 +0,0 @@ public abstract class Settings<T extends Settings<T>> {
private static final Logger LOGGER = LogUtils.getLogger();
public final Properties properties;
+ private static final boolean skipComments = Boolean.getBoolean("Paper.skipServerPropertiesComments"); // Paper - allow skipping server.properties comments
// CraftBukkit start
private OptionSet options = null;
@@ -0,0 +0,0 @@ public abstract class Settings<T extends Settings<T>> {
return;
}
// CraftBukkit end
- BufferedWriter bufferedwriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8);
+ // Paper start - disable writing comments to properties file
+ java.io.OutputStream outputstream = Files.newOutputStream(path);
+ java.io.BufferedOutputStream bufferedOutputStream = !skipComments ? new java.io.BufferedOutputStream(outputstream) : new java.io.BufferedOutputStream(outputstream) {
+ private boolean isRightAfterNewline = true; // If last written char was newline
+ private boolean isComment = false; // Are we writing comment currently?
+
+ @Override
+ public void write(@org.jetbrains.annotations.NotNull byte[] b) throws IOException {
+ this.write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(@org.jetbrains.annotations.NotNull byte[] bbuf, int off, int len) throws IOException {
+ int latest_offset = off; // The latest offset, updated when comment ends
+ for (int index = off; index < off + len; ++index ) {
+ byte c = bbuf[index];
+ boolean isNewline = (c == '\n' || c == '\r');
+ if (isNewline && this.isComment) {
+ // Comment has ended
+ this.isComment = false;
+ latest_offset = index+1;
+ }
+ if (c == '#' && this.isRightAfterNewline) {
+ this.isComment = true;
+ if (index != latest_offset) {
+ // We got some non-comment data earlier
+ super.write(bbuf, latest_offset, index-latest_offset);
+ }
+ }
+ this.isRightAfterNewline = isNewline; // Store for next iteration
+
+ }
+ if (latest_offset < off+len && !this.isComment) {
+ // We have some unwritten data, that isn't part of a comment
+ super.write(bbuf, latest_offset, (off + len) - latest_offset);
+ }
+ }
+ };
+ BufferedWriter bufferedwriter = new BufferedWriter(new java.io.OutputStreamWriter(bufferedOutputStream, java.nio.charset.StandardCharsets.UTF_8.newEncoder()));
+ // Paper end
try {
this.properties.store(bufferedwriter, "Minecraft server properties");

View File

@@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 21 Aug 2021 12:13:53 -0700
Subject: [PATCH] Change EnderEye target without changing other things
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -0,0 +0,0 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
}
public void signalTo(BlockPos pos) {
+ // Paper start
+ this.signalTo(pos, true);
+ }
+ public void signalTo(BlockPos pos, boolean update) {
+ // Paper end
double d0 = (double) pos.getX();
int i = pos.getY();
double d1 = (double) pos.getZ();
@@ -0,0 +0,0 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
this.tz = d1;
}
+ if (update) { // Paper
this.life = 0;
this.surviveAfterDeath = this.random.nextInt(5) > 0;
+ } // Paper
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
@@ -0,0 +0,0 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
@Override
public void setTargetLocation(Location location) {
+ // Paper start
+ this.setTargetLocation(location, true);
+ }
+
+ @Override
+ public void setTargetLocation(Location location, boolean update) {
+ // Paper end
Preconditions.checkArgument(getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
- this.getHandle().signalTo(CraftLocation.toBlockPosition(location));
+ this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper
}
@Override

View File

@@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 13 Aug 2021 15:00:06 -0700
Subject: [PATCH] Clear bucket NBT after dispense
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
Item item = Items.BUCKET;
stack.shrink(1);
if (stack.isEmpty()) {
- stack.setItem(Items.BUCKET);
- stack.setCount(1);
+ stack = new ItemStack(item); // Paper - clear tag
} else if (((DispenserBlockEntity) pointer.getEntity()).addItem(new ItemStack(item)) < 0) {
this.defaultDispenseItemBehavior.dispense(pointer, new ItemStack(item));
}

View File

@@ -1,18 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 2 Dec 2020 03:07:58 -0800
Subject: [PATCH] Config option for Piglins guarding chests
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -0,0 +0,0 @@ public class PiglinAi {
}
public static void angerNearbyPiglins(Player player, boolean blockOpen) {
+ if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper
List<Piglin> list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D));
list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> {

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
Date: Fri, 13 Aug 2021 01:14:38 +0200
Subject: [PATCH] Configurable item frame map cursor update interval
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -0,0 +0,0 @@ public class ServerEntity {
if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block
ItemStack itemstack = entityitemframe.getItem();
- if (this.tickCount % 10 == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks
+ if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable
Integer integer = MapItem.getMapId(itemstack);
MapItemSavedData worldmap = MapItem.getSavedData(integer, this.level);

View File

@@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Sun, 20 Jun 2021 16:35:42 +0100
Subject: [PATCH] Don't apply cramming damage to players
It does not make a lot of sense to damage players if they get crammed,
especially as the usecase of teleporting lots of players to the same
location isn't too uncommon and killing all those players isn't
really what one would expect to happen.
For those who really want it a config option is provided.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.util.Unit;
import net.minecraft.world.damagesource.DamageSource;
+import net.minecraft.world.damagesource.DamageSources;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
@Override
public boolean isInvulnerableTo(DamageSource damageSource) {
- return super.isInvulnerableTo(damageSource) || this.isChangingDimension();
+ return super.isInvulnerableTo(damageSource) || this.isChangingDimension() || !this.level().paperConfig().collisions.allowPlayerCrammingDamage && damageSource == damageSources().cramming(); // Paper - disable player cramming
}
@Override

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 1 Aug 2021 09:49:06 +0100
Subject: [PATCH] Fix incosistency issue with empty map items in CB
diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/MapItem.java
+++ b/src/main/java/net/minecraft/world/item/MapItem.java
@@ -0,0 +0,0 @@ public class MapItem extends ComplexItem {
public static Integer getMapId(ItemStack stack) {
CompoundTag nbttagcompound = stack.getTag();
- return nbttagcompound != null && nbttagcompound.contains("map", 99) ? nbttagcompound.getInt("map") : -1; // CraftBukkit - make new maps for no tag
+ return nbttagcompound != null && nbttagcompound.contains("map", 99) ? nbttagcompound.getInt("map") : null; // CraftBukkit - make new maps for no tag // Paper - don't return invalid ID
}
public static int createNewSavedData(Level world, int x, int z, int scale, boolean showIcons, boolean unlimitedTracking, ResourceKey<Level> dimension) {
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
@@ -0,0 +0,0 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta {
@Override
public int getMapId() {
+ Preconditions.checkState(this.hasMapView(), "Item does not have map associated - check hasMapView() first!"); // Paper - more friendly message
return this.mapId;
}

View File

@@ -1,150 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 20 Aug 2021 13:03:21 -0700
Subject: [PATCH] Get entity default attributes
== AT ==
public net.minecraft.world.entity.ai.attributes.AttributeSupplier getAttributeInstance(Lnet/minecraft/world/entity/ai/attributes/Attribute;)Lnet/minecraft/world/entity/ai/attributes/AttributeInstance;
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.attribute;
+
+import net.minecraft.world.entity.ai.attributes.AttributeInstance;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
+
+import java.util.Collection;
+
+public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
+
+ public UnmodifiableAttributeInstance(AttributeInstance handle, Attribute attribute) {
+ super(handle, attribute);
+ }
+
+ @Override
+ public void setBaseValue(double d) {
+ throw new UnsupportedOperationException("Cannot modify default attributes");
+ }
+
+ @Override
+ public void addModifier(AttributeModifier modifier) {
+ throw new UnsupportedOperationException("Cannot modify default attributes");
+ }
+
+ @Override
+ public void removeModifier(AttributeModifier modifier) {
+ throw new UnsupportedOperationException("Cannot modify default attributes");
+ }
+}
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.attribute;
+
+import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
+import org.bukkit.attribute.Attributable;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeInstance;
+import org.bukkit.craftbukkit.attribute.CraftAttributeMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class UnmodifiableAttributeMap implements Attributable {
+
+ private final AttributeSupplier handle;
+
+ public UnmodifiableAttributeMap(@NotNull AttributeSupplier handle) {
+ this.handle = handle;
+ }
+
+ @Override
+ public @Nullable AttributeInstance getAttribute(@NotNull Attribute attribute) {
+ net.minecraft.world.entity.ai.attributes.Attribute nmsAttribute = CraftAttributeMap.toMinecraft(attribute);
+ if (!this.handle.hasAttribute(nmsAttribute)) {
+ return null;
+ }
+ return new UnmodifiableAttributeInstance(this.handle.getAttributeInstance(nmsAttribute), attribute);
+ }
+
+ @Override
+ public void registerAttribute(@NotNull Attribute attribute) {
+ throw new UnsupportedOperationException("Cannot register new attributes here");
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
public int getProtocolVersion() {
return net.minecraft.SharedConstants.getCurrentVersion().getProtocolVersion();
}
+
+ @Override
+ public boolean hasDefaultEntityAttributes(NamespacedKey bukkitEntityKey) {
+ return net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
+ }
+
+ @Override
+ public org.bukkit.attribute.Attributable getDefaultEntityAttributes(NamespacedKey bukkitEntityKey) {
+ Preconditions.checkArgument(hasDefaultEntityAttributes(bukkitEntityKey), bukkitEntityKey + " doesn't have default attributes");
+ var supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier((net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.LivingEntity>) net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
+ return new io.papermc.paper.attribute.UnmodifiableAttributeMap(supplier);
+ }
// Paper end
/**
diff --git a/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.attribute;
+
+import org.bukkit.attribute.Attributable;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeInstance;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.entity.EntityType;
+import org.bukkit.support.AbstractTestingBase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+public class EntityTypeAttributesTest extends AbstractTestingBase {
+
+ @Test
+ public void testIllegalEntity() {
+ assertFalse(EntityType.EGG.hasDefaultAttributes());
+ assertThrows(IllegalArgumentException.class, () -> EntityType.EGG.getDefaultAttributes());
+ }
+
+ @Test
+ public void testLegalEntity() {
+ assertTrue(EntityType.ZOMBIE.hasDefaultAttributes());
+ EntityType.ZOMBIE.getDefaultAttributes();
+ }
+
+ @Test
+ public void testUnmodifiabilityOfAttributable() {
+ Attributable attributable = EntityType.ZOMBIE.getDefaultAttributes();
+ assertThrows(UnsupportedOperationException.class, () -> attributable.registerAttribute(Attribute.GENERIC_ATTACK_DAMAGE));
+ AttributeInstance instance = attributable.getAttribute(Attribute.GENERIC_FOLLOW_RANGE);
+ assertNotNull(instance);
+ assertThrows(UnsupportedOperationException.class, () -> instance.addModifier(new AttributeModifier("test", 3, AttributeModifier.Operation.ADD_NUMBER)));
+ assertThrows(UnsupportedOperationException.class, () -> instance.setBaseValue(3.2));
+ }
+}

View File

@@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 2 Aug 2021 10:10:40 +0200
Subject: [PATCH] Improve boat collision performance
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -0,0 +0,0 @@ public class Util {
}).findFirst().orElseThrow(() -> {
return new IllegalStateException("No jar file system provider found");
});
+ public static final double COLLISION_EPSILON = 1.0E-7; // Paper
private static Consumer<String> thePauser = (message) -> {
};
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (!source.is(DamageTypeTags.IS_PROJECTILE)) {
Entity entity = source.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper
LivingEntity entityliving = (LivingEntity) entity;
this.blockUsingShield(entityliving);
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
if (entity1 != null && !source.is(DamageTypeTags.IS_EXPLOSION)) {
- double d0 = entity1.getX() - this.getX();
+ final boolean far = entity1.distanceToSqr(this) > (200.0 * 200.0); // Paper
+ double d0 = far ? (Math.random() - Math.random()) : entity1.getX() - this.getX(); // Paper
double d1;
- for (d1 = entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) {
+ for (d1 = far ? Math.random() - Math.random() : entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { // Paper
d0 = (Math.random() - Math.random()) * 0.01D;
}
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
Entity entity = damagesource.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper
this.blockUsingShield((LivingEntity) entity);
}
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
@@ -0,0 +0,0 @@ public class Boat extends Entity implements VariantHolder<Boat.Type> {
this.invFriction = 0.05F;
if (this.oldStatus == Boat.Status.IN_AIR && this.status != Boat.Status.IN_AIR && this.status != Boat.Status.ON_LAND) {
this.waterLevel = this.getY(1.0D);
- this.setPos(this.getX(), (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D, this.getZ());
- this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
+ this.move(MoverType.SELF, new Vec3(0.0, ((double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D) - this.getY(), 0.0)); // Paper
+ this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); // Paper
this.lastYd = 0.0D;
this.status = Boat.Status.IN_WATER;
} else {

View File

@@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 14 Oct 2021 12:36:58 -0500
Subject: [PATCH] Left handed API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
public int getMaxHeadPitch() {
return getHandle().getMaxHeadXRot();
}
+
+ @Override
+ public boolean isLeftHanded() {
+ return getHandle().isLeftHanded();
+ }
+
+ @Override
+ public void setLeftHanded(boolean leftHanded) {
+ getHandle().setLeftHanded(leftHanded);
+ }
// Paper end
}

View File

@@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 3 Jan 2021 21:25:31 -0800
Subject: [PATCH] Make EntityUnleashEvent cancellable
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting {
if (flag1 && this.isLeashed()) {
// Paper start - drop leash variable
EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN, true);
- this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ if (!event.callEvent()) { return flag1; }
this.dropLeash(true, event.isDropLeash());
// Paper end
}
diff --git a/src/main/java/net/minecraft/world/entity/PathfinderMob.java b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/PathfinderMob.java
+++ b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
@@ -0,0 +0,0 @@ public abstract class PathfinderMob extends Mob {
if (f > entity.level().paperConfig().misc.maxLeashDistance) { // Paper
// Paper start - drop leash variable
EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
- this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ if (!event.callEvent()) { return; }
this.dropLeash(true, event.isDropLeash());
// Paper end
}
@@ -0,0 +0,0 @@ public abstract class PathfinderMob extends Mob {
if (f > entity.level().paperConfig().misc.maxLeashDistance) { // Paper
// Paper start - drop leash variable
EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
- this.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ if (!event.callEvent()) { return; }
this.dropLeash(true, event.isDropLeash());
// Paper end
this.goalSelector.disableControlFlag(Goal.Flag.MOVE);

View File

@@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 7 Jul 2021 16:30:17 -0700
Subject: [PATCH] Make hoppers respect inventory max stack size
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -0,0 +0,0 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (itemstack1.isEmpty()) {
// Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
+ ItemStack leftover = ItemStack.EMPTY; // Paper
if (!stack.isEmpty() && stack.getCount() > to.getMaxStackSize()) {
+ leftover = stack; // Paper
stack = stack.split(to.getMaxStackSize());
}
// Spigot end
to.setItem(slot, stack);
- stack = ItemStack.EMPTY;
+ stack = leftover; // Paper
flag = true;
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
- int j = stack.getMaxStackSize() - itemstack1.getCount();
+ int j = Math.min(stack.getMaxStackSize(), to.getMaxStackSize()) - itemstack1.getCount(); // Paper
int k = Math.min(stack.getCount(), j);
stack.shrink(k);

View File

@@ -1,100 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 23 Sep 2021 10:40:09 -0700
Subject: [PATCH] More CommandBlock API
diff --git a/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.commands;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import io.papermc.paper.command.CommandBlockHolder;
+import net.kyori.adventure.text.Component;
+import net.minecraft.world.level.BaseCommandBlock;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface PaperCommandBlockHolder extends CommandBlockHolder {
+
+ BaseCommandBlock getCommandBlockHandle();
+
+ @Override
+ default @NotNull Component lastOutput() {
+ return PaperAdventure.asAdventure(getCommandBlockHandle().getLastOutput());
+ }
+
+ @Override
+ default void lastOutput(@Nullable Component lastOutput) {
+ getCommandBlockHandle().setLastOutput(PaperAdventure.asVanilla(lastOutput));
+ }
+
+ @Override
+ default int getSuccessCount() {
+ return getCommandBlockHandle().getSuccessCount();
+ }
+
+ @Override
+ default void setSuccessCount(int successCount) {
+ getCommandBlockHandle().setSuccessCount(successCount);
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
@@ -0,0 +0,0 @@ import org.bukkit.World;
import org.bukkit.block.CommandBlock;
import org.bukkit.craftbukkit.util.CraftChatMessage;
-public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock {
+public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock, io.papermc.paper.commands.PaperCommandBlockHolder {
public CraftCommandBlock(World world, CommandBlockEntity tileEntity) {
super(world, tileEntity);
@@ -0,0 +0,0 @@ public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity>
public void name(net.kyori.adventure.text.Component name) {
getSnapshot().getCommandBlock().setName(name == null ? net.minecraft.network.chat.Component.literal("@") : io.papermc.paper.adventure.PaperAdventure.asVanilla(name));
}
+
+ @Override
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
+ return getSnapshot().getCommandBlock();
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
@@ -0,0 +0,0 @@ import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
-public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart {
+public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart, io.papermc.paper.commands.PaperCommandBlockHolder {
private final PermissibleBase perm = new PermissibleBase(this);
public CraftMinecartCommand(CraftServer server, MinecartCommandBlock entity) {
@@ -0,0 +0,0 @@ public class CraftMinecartCommand extends CraftMinecart implements CommandMineca
public net.kyori.adventure.text.@org.jetbrains.annotations.NotNull Component name() {
return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getHandle().getCommandBlock().getName());
}
+
+ @Override
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
+ return getHandle().getCommandBlock();
+ }
+
+ @Override
+ public void lastOutput(net.kyori.adventure.text.Component lastOutput) {
+ io.papermc.paper.commands.PaperCommandBlockHolder.super.lastOutput(lastOutput);
+ getCommandBlockHandle().onUpdated();
+ }
// Paper end
@Override

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Sun, 8 Aug 2021 00:52:54 -0400
Subject: [PATCH] Optimize entity tracker passenger checks
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -0,0 +0,0 @@ public class ServerEntity {
this.trackedPlayers = trackedPlayers;
// CraftBukkit end
this.ap = Vec3.ZERO;
- this.lastPassengers = Collections.emptyList();
+ this.lastPassengers = com.google.common.collect.ImmutableList.of(); // Paper - optimize passenger checks
this.level = worldserver;
this.broadcast = consumer;
this.entity = entity;

View File

@@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Mon, 9 Aug 2021 00:38:37 -0400
Subject: [PATCH] Optimize indirect passenger iteration
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
private Stream<Entity> getIndirectPassengersStream() {
+ if (this.passengers.isEmpty()) { return Stream.of(); } // Paper
return this.passengers.stream().flatMap(Entity::getSelfAndPassengers);
}
@Override
public Stream<Entity> getSelfAndPassengers() {
+ if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper
return Stream.concat(Stream.of(this), this.getIndirectPassengersStream());
}
@Override
public Stream<Entity> getPassengersAndSelf() {
+ if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper
return Stream.concat(this.passengers.stream().flatMap(Entity::getPassengersAndSelf), Stream.of(this));
}
public Iterable<Entity> getIndirectPassengers() {
+ // Paper start - rewrite this method
+ if (this.passengers.isEmpty()) { return ImmutableList.of(); }
+ ImmutableList.Builder<Entity> indirectPassengers = ImmutableList.builder();
+ for (Entity passenger : this.passengers) {
+ indirectPassengers.add(passenger);
+ indirectPassengers.addAll(passenger.getIndirectPassengers());
+ }
+ return indirectPassengers.build();
+ }
+ private Iterable<Entity> getIndirectPassengers_old() {
+ // Paper end
return () -> {
return this.getIndirectPassengersStream().iterator();
};
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
// Paper end - rewrite chunk system
public boolean hasExactlyOnePlayerPassenger() {
+ if (this.passengers.isEmpty()) { return false; } // Paper
return this.getIndirectPassengersStream().filter((entity) -> {
return entity instanceof Player;
}).count() == 1L;

View File

@@ -1,147 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 26 Sep 2021 12:57:28 -0700
Subject: [PATCH] Option to prevent NBT copy in smithing recipes
diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
@@ -0,0 +0,0 @@ public class SmithingTransformRecipe implements SmithingRecipe {
final Ingredient base;
final Ingredient addition;
final ItemStack result;
+ final boolean copyNBT; // Paper
public SmithingTransformRecipe(ResourceLocation id, Ingredient template, Ingredient base, Ingredient addition, ItemStack result) {
+ // Paper start
+ this(id, template, base, addition, result, true);
+ }
+ public SmithingTransformRecipe(ResourceLocation id, Ingredient template, Ingredient base, Ingredient addition, ItemStack result, boolean copyNBT) {
+ this.copyNBT = copyNBT;
+ // Paper end
this.id = id;
this.template = template;
this.base = base;
@@ -0,0 +0,0 @@ public class SmithingTransformRecipe implements SmithingRecipe {
@Override
public ItemStack assemble(Container inventory, RegistryAccess registryManager) {
ItemStack itemstack = this.result.copy();
+ if (this.copyNBT) { // Paper - copy nbt conditionally
CompoundTag nbttagcompound = inventory.getItem(1).getTag();
if (nbttagcompound != null) {
itemstack.setTag(nbttagcompound.copy());
}
+ } // Paper
return itemstack;
}
@@ -0,0 +0,0 @@ public class SmithingTransformRecipe implements SmithingRecipe {
public Recipe toBukkitRecipe() {
CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
- CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(CraftNamespacedKey.fromMinecraft(this.id), result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
+ CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(CraftNamespacedKey.fromMinecraft(this.id), result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNBT); // Paper
return recipe;
}
diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
@@ -0,0 +0,0 @@ public class SmithingTrimRecipe implements SmithingRecipe {
final Ingredient template;
final Ingredient base;
final Ingredient addition;
+ final boolean copyNbt; // Paper
public SmithingTrimRecipe(ResourceLocation id, Ingredient template, Ingredient base, Ingredient addition) {
+ // Paper start
+ this(id, template, base, addition, true);
+ }
+ public SmithingTrimRecipe(ResourceLocation id, Ingredient template, Ingredient base, Ingredient addition, boolean copyNbt) {
+ this.copyNbt = copyNbt;
+ // Paper end
this.id = id;
this.template = template;
this.base = base;
@@ -0,0 +0,0 @@ public class SmithingTrimRecipe implements SmithingRecipe {
return ItemStack.EMPTY;
}
- ItemStack itemstack1 = itemstack.copy();
+ ItemStack itemstack1 = this.copyNbt ? itemstack.copy() : new ItemStack(itemstack.getItem(), itemstack.getCount()); // Paper
itemstack1.setCount(1);
ArmorTrim armortrim = new ArmorTrim((Holder) optional.get(), (Holder) optional1.get());
@@ -0,0 +0,0 @@ public class SmithingTrimRecipe implements SmithingRecipe {
// CraftBukkit start
@Override
public Recipe toBukkitRecipe() {
- return new CraftSmithingTrimRecipe(CraftNamespacedKey.fromMinecraft(this.id), CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
+ return new CraftSmithingTrimRecipe(CraftNamespacedKey.fromMinecraft(this.id), CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNbt); // Paper
}
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
@@ -0,0 +0,0 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
super(key, result, template, base, addition);
}
+ // Paper start
+ public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyNbt) {
+ super(key, result, template, base, addition, copyNbt);
+ }
+ // Paper end
public static CraftSmithingTransformRecipe fromBukkitRecipe(SmithingTransformRecipe recipe) {
if (recipe instanceof CraftSmithingTransformRecipe) {
return (CraftSmithingTransformRecipe) recipe;
}
- CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
+ CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper
return ret;
}
@@ -0,0 +0,0 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
public void addToCraftingManager() {
ItemStack result = this.getResult();
- MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.SmithingTransformRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), toNMS(this.getTemplate(), true), toNMS(this.getBase(), true), toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result)));
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.SmithingTransformRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), toNMS(this.getTemplate(), true), toNMS(this.getBase(), true), toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result), this.willCopyNbt())); // Paper
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
@@ -0,0 +0,0 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft
public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
super(key, template, base, addition);
}
+ // Paper start
+ public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyNbt) {
+ super(key, template, base, addition, copyNbt);
+ }
+ // Paper end
public static CraftSmithingTrimRecipe fromBukkitRecipe(SmithingTrimRecipe recipe) {
if (recipe instanceof CraftSmithingTrimRecipe) {
return (CraftSmithingTrimRecipe) recipe;
}
- CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
+ CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper
return ret;
}
@Override
public void addToCraftingManager() {
- MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.SmithingTrimRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), toNMS(this.getTemplate(), true), toNMS(this.getBase(), true), toNMS(this.getAddition(), true)));
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.SmithingTrimRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), toNMS(this.getTemplate(), true), toNMS(this.getBase(), true), toNMS(this.getAddition(), true), this.willCopyNbt())); // Paper
}
}

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Noah van der Aa <ndvdaa@gmail.com>
Date: Sat, 24 Jul 2021 16:54:11 +0200
Subject: [PATCH] Prevent AFK kick while watching end credits.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
--this.dropSpamTickCount;
}
- if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) {
+ if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits.
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}

View File

@@ -1,134 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Mon, 28 Jun 2021 22:38:29 +0100
Subject: [PATCH] Rate options and timings for sensors and behaviors
This adds config options to specify the tick rate for sensors
and behaviors of different entity types as well as timings
for those in order to be able to have some metrics as to which
ones might need tweaking.
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -0,0 +0,0 @@ public final class MinecraftTimings {
return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer);
}
+ public static Timing getBehaviorTimings(String type) {
+ return Timings.ofSafe("## Behavior - " + type);
+ }
+
+ public static Timing getSensorTimings(String type, int rate) {
+ return Timings.ofSafe("## Sensor - " + type + " (Default rate: " + rate + ")");
+ }
+
/**
* Get a named timer for the specified tile entity type to track type specific timings.
* @param entity
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
@@ -0,0 +0,0 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
private long endTimestamp;
private final int minDuration;
private final int maxDuration;
+ // Paper start - configurable behavior tick rate and timings
+ private final String configKey;
+ private final co.aikar.timings.Timing timing;
+ // Paper end
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState) {
this(requiredMemoryState, 60);
@@ -0,0 +0,0 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
this.minDuration = minRunTime;
this.maxDuration = maxRunTime;
this.entryCondition = requiredMemoryState;
+ // Paper start - configurable behavior tick rate and timings
+ String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName());
+ int lastSeparator = key.lastIndexOf('.');
+ if (lastSeparator != -1) {
+ key = key.substring(lastSeparator + 1);
+ }
+ this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+ this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey);
+ // Paper end
}
@Override
@@ -0,0 +0,0 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
@Override
public final boolean tryStart(ServerLevel world, E entity, long time) {
+ // Paper start - behavior tick rate
+ int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1);
+ if (tickRate > -1 && time < this.endTimestamp + tickRate) {
+ return false;
+ }
+ // Paper end
if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) {
this.status = Behavior.Status.RUNNING;
int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration);
this.endTimestamp = time + (long)i;
+ this.timing.startTiming(); // Paper - behavior timings
this.start(world, entity, time);
+ this.timing.stopTiming(); // Paper - behavior timings
return true;
} else {
return false;
@@ -0,0 +0,0 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
@Override
public final void tickOrStop(ServerLevel world, E entity, long time) {
+ this.timing.startTiming(); // Paper - behavior timings
if (!this.timedOut(time) && this.canStillUse(world, entity, time)) {
this.tick(world, entity, time);
} else {
this.doStop(world, entity, time);
}
+ this.timing.stopTiming(); // Paper - behavior timings
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
@@ -0,0 +0,0 @@ public abstract class Sensor<E extends LivingEntity> {
private static final TargetingConditions ATTACK_TARGET_CONDITIONS_IGNORE_INVISIBILITY_AND_LINE_OF_SIGHT = TargetingConditions.forCombat().range(16.0D).ignoreLineOfSight().ignoreInvisibilityTesting();
private final int scanRate;
private long timeToTick;
+ // Paper start - configurable sensor tick rate and timings
+ private final String configKey;
+ private final co.aikar.timings.Timing timing;
+ // Paper end
public Sensor(int senseInterval) {
+ // Paper start - configurable sensor tick rate and timings
+ String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName());
+ int lastSeparator = key.lastIndexOf('.');
+ if (lastSeparator != -1) {
+ key = key.substring(lastSeparator + 1);
+ }
+ this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+ this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval);
+ // Paper end
this.scanRate = senseInterval;
this.timeToTick = (long)RANDOM.nextInt(senseInterval);
}
@@ -0,0 +0,0 @@ public abstract class Sensor<E extends LivingEntity> {
public final void tick(ServerLevel world, E entity) {
if (--this.timeToTick <= 0L) {
- this.timeToTick = (long)this.scanRate;
+ // Paper start - configurable sensor tick rate and timings
+ this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate);
+ this.timing.startTiming();
+ // Paper end
this.doTick(world, entity);
+ this.timing.stopTiming(); // Paper - sensor timings
}
}

View File

@@ -1,246 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SirYwell <hannesgreule@outlook.de>
Date: Sat, 10 Jul 2021 11:12:30 +0200
Subject: [PATCH] Rewrite LogEvents to contain the source jars in stack traces
diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/DelegateLogEvent.java b/src/log4jPlugins/java/io/papermc/paper/logging/DelegateLogEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/log4jPlugins/java/io/papermc/paper/logging/DelegateLogEvent.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.logging;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+import java.util.Map;
+
+public class DelegateLogEvent implements LogEvent {
+ private final LogEvent original;
+
+ protected DelegateLogEvent(LogEvent original) {
+ this.original = original;
+ }
+
+ @Override
+ public LogEvent toImmutable() {
+ return this.original.toImmutable();
+ }
+
+ @Override
+ public Map<String, String> getContextMap() {
+ return this.original.getContextMap();
+ }
+
+ @Override
+ public ReadOnlyStringMap getContextData() {
+ return this.original.getContextData();
+ }
+
+ @Override
+ public ThreadContext.ContextStack getContextStack() {
+ return this.original.getContextStack();
+ }
+
+ @Override
+ public String getLoggerFqcn() {
+ return this.original.getLoggerFqcn();
+ }
+
+ @Override
+ public Level getLevel() {
+ return this.original.getLevel();
+ }
+
+ @Override
+ public String getLoggerName() {
+ return this.original.getLoggerName();
+ }
+
+ @Override
+ public Marker getMarker() {
+ return this.original.getMarker();
+ }
+
+ @Override
+ public Message getMessage() {
+ return this.original.getMessage();
+ }
+
+ @Override
+ public long getTimeMillis() {
+ return this.original.getTimeMillis();
+ }
+
+ @Override
+ public Instant getInstant() {
+ return this.original.getInstant();
+ }
+
+ @Override
+ public StackTraceElement getSource() {
+ return this.original.getSource();
+ }
+
+ @Override
+ public String getThreadName() {
+ return this.original.getThreadName();
+ }
+
+ @Override
+ public long getThreadId() {
+ return this.original.getThreadId();
+ }
+
+ @Override
+ public int getThreadPriority() {
+ return this.original.getThreadPriority();
+ }
+
+ @Override
+ public Throwable getThrown() {
+ return this.original.getThrown();
+ }
+
+ @Override
+ public ThrowableProxy getThrownProxy() {
+ return this.original.getThrownProxy();
+ }
+
+ @Override
+ public boolean isEndOfBatch() {
+ return this.original.isEndOfBatch();
+ }
+
+ @Override
+ public boolean isIncludeLocation() {
+ return this.original.isIncludeLocation();
+ }
+
+ @Override
+ public void setEndOfBatch(boolean endOfBatch) {
+ this.original.setEndOfBatch(endOfBatch);
+ }
+
+ @Override
+ public void setIncludeLocation(boolean locationRequired) {
+ this.original.setIncludeLocation(locationRequired);
+ }
+
+ @Override
+ public long getNanoTime() {
+ return this.original.getNanoTime();
+ }
+}
diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.logging;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ExtendedClassInfo;
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+
+public class ExtraClassInfoLogEvent extends DelegateLogEvent {
+
+ private boolean fixed;
+
+ public ExtraClassInfoLogEvent(LogEvent original) {
+ super(original);
+ }
+
+ @Override
+ public ThrowableProxy getThrownProxy() {
+ if (fixed) {
+ return super.getThrownProxy();
+ }
+ rewriteStackTrace(super.getThrownProxy());
+ fixed = true;
+ return super.getThrownProxy();
+ }
+
+ private void rewriteStackTrace(ThrowableProxy throwable) {
+ ExtendedStackTraceElement[] stackTrace = throwable.getExtendedStackTrace();
+ for (int i = 0; i < stackTrace.length; i++) {
+ ExtendedClassInfo classInfo = stackTrace[i].getExtraClassInfo();
+ if (classInfo.getLocation().equals("?")) {
+ StackTraceElement element = stackTrace[i].getStackTraceElement();
+ String classLoaderName = element.getClassLoaderName();
+ if (classLoaderName != null) {
+ stackTrace[i] = new ExtendedStackTraceElement(element,
+ new ExtendedClassInfo(classInfo.getExact(), classLoaderName, "?"));
+ }
+ }
+ }
+ if (throwable.getCauseProxy() != null) {
+ rewriteStackTrace(throwable.getCauseProxy());
+ }
+ if (throwable.getSuppressedProxies() != null) {
+ for (ThrowableProxy proxy : throwable.getSuppressedProxies()) {
+ rewriteStackTrace(proxy);
+ }
+ }
+ }
+}
diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
@@ -0,0 +0,0 @@
+package io.papermc.paper.logging;
+
+import org.apache.logging.log4j.core.Core;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.jetbrains.annotations.NotNull;
+
+@Plugin(
+ name = "ExtraClassInfoRewritePolicy",
+ category = Core.CATEGORY_NAME,
+ elementType = "rewritePolicy",
+ printObject = true
+)
+public final class ExtraClassInfoRewritePolicy implements RewritePolicy {
+ @Override
+ public LogEvent rewrite(LogEvent source) {
+ if (source.getThrown() != null) {
+ return new ExtraClassInfoLogEvent(source);
+ }
+ return source;
+ }
+
+ @PluginFactory
+ public static @NotNull ExtraClassInfoRewritePolicy createPolicy() {
+ return new ExtraClassInfoRewritePolicy();
+ }
+}
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +0,0 @@
</Async>
<Rewrite name="rewrite">
<StacktraceDeobfuscatingRewritePolicy />
+ <AppenderRef ref="rewrite2"/>
+ </Rewrite>
+ <Rewrite name="rewrite2">
+ <ExtraClassInfoRewritePolicy />
<AppenderRef ref="File"/>
<AppenderRef ref="TerminalConsole" level="info"/>
<AppenderRef ref="ServerGuiConsole" level="info"/>

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Tue, 22 Jun 2021 23:15:44 -0400
Subject: [PATCH] Stinger API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
}
// Paper end
}
+ // Paper Start - Bee Stinger API
+ @Override
+ public int getBeeStingerCooldown() {
+ return getHandle().removeStingerTime;
+ }
+
+ @Override
+ public void setBeeStingerCooldown(int ticks) {
+ getHandle().removeStingerTime = ticks;
+ }
+ @Override
+ public int getBeeStingersInBody() {
+ return getHandle().getStingerCount();
+ }
+
+ @Override
+ public void setBeeStingersInBody(int count) {
+ Preconditions.checkArgument(count >= 0, "New bee stinger amount must be >= 0");
+ getHandle().setStingerCount(count);
+ }
+ // Paper End - Bee Stinger API
@Override
public void damage(double amount) {
this.damage(amount, null);