1.21.6 dev

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Bjarne Koll
2025-05-28 13:23:32 +02:00
committed by Nassim Jahnke
parent 39203a65e0
commit a24f9b204c
788 changed files with 41006 additions and 6324 deletions

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/BaseCommandBlock.java
+++ b/net/minecraft/world/level/BaseCommandBlock.java
@@ -37,6 +_,11 @@
@@ -34,6 +_,11 @@
private String command = "";
@Nullable
private Component customName;
@@ -12,7 +12,7 @@
public int getSuccessCount() {
return this.successCount;
@@ -114,7 +_,7 @@
@@ -108,7 +_,7 @@
this.successCount++;
}
});
@@ -21,7 +21,7 @@
} catch (Throwable var6) {
CrashReport crashReport = CrashReport.forThrowable(var6, "Executing command block");
CrashReportCategory crashReportCategory = crashReport.addCategory("Command to be executed");
@@ -150,6 +_,7 @@
@@ -144,6 +_,7 @@
@Override
public void sendSystemMessage(Component component) {
if (this.trackOutput) {
@@ -29,7 +29,7 @@
this.lastOutput = Component.literal("[" + TIME_FORMAT.format(new Date()) + "] ").append(component);
this.onUpdated();
}
@@ -172,7 +_,7 @@
@@ -166,7 +_,7 @@
}
public InteractionResult usedBy(Player player) {
@@ -37,4 +37,4 @@
+ if (!player.canUseGameMasterBlocks() && (!player.isCreative() || !player.getBukkitEntity().hasPermission("minecraft.commandblock"))) { // Paper - command block permission
return InteractionResult.PASS;
} else {
if (player.getCommandSenderWorld().isClientSide) {
if (player.level().isClientSide) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/BaseSpawner.java
+++ b/net/minecraft/world/level/BaseSpawner.java
@@ -46,13 +_,15 @@
@@ -53,13 +_,15 @@
public int maxNearbyEntities = 6;
public int requiredPlayerRange = 16;
public int spawnRange = 4;
@@ -17,7 +17,7 @@
}
public void clientTick(Level level, BlockPos pos) {
@@ -75,13 +_,19 @@
@@ -82,13 +_,19 @@
}
public void serverTick(ServerLevel serverLevel, BlockPos pos) {
@@ -39,108 +39,107 @@
} else {
boolean flag = false;
RandomSource random = serverLevel.getRandom();
@@ -118,6 +_,21 @@
continue;
}
+ // Paper start - PreCreatureSpawnEvent
+ com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent(
+ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(vec3, serverLevel.getWorld()),
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()),
+ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, serverLevel)
+ );
+ if (!event.callEvent()) {
+ flag = true;
+ if (event.shouldAbortSpawn()) {
+ break;
+ }
+ continue;
+ }
+ // Paper end - PreCreatureSpawnEvent
+
Entity entity = EntityType.loadEntityRecursive(entityToSpawn, serverLevel, EntitySpawnReason.SPAWNER, entity1 -> {
entity1.snapTo(vec3.x, vec3.y, vec3.z, entity1.getYRot(), entity1.getXRot());
return entity1;
@@ -138,6 +_,7 @@
return;
}
+ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag
entity.snapTo(entity.getX(), entity.getY(), entity.getZ(), random.nextFloat() * 360.0F, 0.0F);
if (entity instanceof Mob mob) {
if (nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(serverLevel, EntitySpawnReason.SPAWNER)
@@ -152,9 +_,22 @@
@@ -128,6 +_,21 @@
continue;
}
nextSpawnData.getEquipment().ifPresent(mob::equip);
+ // Spigot start
+ if (mob.level().spigotConfig.nerfSpawnerMobs) {
+ mob.aware = false;
+ // Paper start - PreCreatureSpawnEvent
+ com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent(
+ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(vec3, serverLevel.getWorld()),
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()),
+ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, serverLevel)
+ );
+ if (!event.callEvent()) {
+ flag = true;
+ if (event.shouldAbortSpawn()) {
+ break;
+ }
+ continue;
+ }
+ // Spigot end
}
+ // Paper end - PreCreatureSpawnEvent
+
Entity entity = EntityType.loadEntityRecursive(valueInput, serverLevel, EntitySpawnReason.SPAWNER, entity1 -> {
entity1.snapTo(vec3.x, vec3.y, vec3.z, entity1.getYRot(), entity1.getXRot());
return entity1;
@@ -148,6 +_,7 @@
return;
}
- if (!serverLevel.tryAddFreshEntityWithPassengers(entity)) {
+ entity.spawnedViaMobSpawner = true; // Paper
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper - Entity#getEntitySpawnReason
+ flag = true; // Paper
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ continue;
+ }
+ if (!serverLevel.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER)) {
+ // CraftBukkit end
this.delay(serverLevel, pos);
return;
}
@@ -165,7 +_,7 @@
((Mob)entity).spawnAnim();
}
+ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag
entity.snapTo(entity.getX(), entity.getY(), entity.getZ(), random.nextFloat() * 360.0F, 0.0F);
if (entity instanceof Mob mob) {
if (nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(serverLevel, EntitySpawnReason.SPAWNER)
@@ -162,9 +_,22 @@
}
- flag = true;
+ //flag = true; // Paper - moved up above cancellable event
nextSpawnData.getEquipment().ifPresent(mob::equip);
+ // Spigot start
+ if (mob.level().spigotConfig.nerfSpawnerMobs) {
+ mob.aware = false;
+ }
+ // Spigot end
}
- if (!serverLevel.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start
+ entity.spawnedViaMobSpawner = true;
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER;
+ flag = true;
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ continue;
+ }
+ if (!serverLevel.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER)) {
+ // Paper end
this.delay(serverLevel, pos);
return;
}
@@ -175,7 +_,7 @@
((Mob)entity).spawnAnim();
}
- flag = true;
+ //flag = true; // Paper - moved up above cancellable event
}
}
}
@@ -189,12 +_,14 @@
@@ -202,12 +_,14 @@
}
public void load(@Nullable Level level, BlockPos pos, CompoundTag tag) {
- this.spawnDelay = tag.getShortOr("Delay", (short)20);
+ this.spawnDelay = tag.getIntOr("Paper.Delay", tag.getShortOr("Delay", (short) 20)); // Paper - use int if set
tag.read("SpawnData", SpawnData.CODEC).ifPresent(spawnData -> this.setNextSpawnData(level, pos, spawnData));
this.spawnPotentials = tag.read("SpawnPotentials", SpawnData.LIST_CODEC)
- .orElseGet(() -> WeightedList.of(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData()));
- this.minSpawnDelay = tag.getIntOr("MinSpawnDelay", 200);
- this.maxSpawnDelay = tag.getIntOr("MaxSpawnDelay", 800);
+ .orElseGet(() -> WeightedList.of(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData()));
public void load(@Nullable Level level, BlockPos pos, ValueInput input) {
- this.spawnDelay = input.getShortOr("Delay", (short)20);
+ this.spawnDelay = input.getIntOr("Paper.Delay", input.getShortOr("Delay", (short) 20)); // Paper - use int if set
input.read("SpawnData", SpawnData.CODEC).ifPresent(spawnData -> this.setNextSpawnData(level, pos, spawnData));
this.spawnPotentials = input.read("SpawnPotentials", SpawnData.LIST_CODEC)
.orElseGet(() -> WeightedList.of(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData()));
- this.minSpawnDelay = input.getIntOr("MinSpawnDelay", 200);
- this.maxSpawnDelay = input.getIntOr("MaxSpawnDelay", 800);
+ // Paper start - use int if set
+ this.minSpawnDelay = tag.getIntOr("Paper.MinSpawnDelay", tag.getIntOr("MinSpawnDelay", 200));
+ this.maxSpawnDelay = tag.getIntOr("Paper.MaxSpawnDelay", tag.getIntOr("MaxSpawnDelay", 800));
+ this.minSpawnDelay = input.getIntOr("Paper.MinSpawnDelay", input.getIntOr("MinSpawnDelay", 200));
+ this.maxSpawnDelay = input.getIntOr("Paper.MaxSpawnDelay", input.getIntOr("MaxSpawnDelay", 800));
+ // Paper end - use int if set
this.spawnCount = tag.getIntOr("SpawnCount", 4);
this.maxNearbyEntities = tag.getIntOr("MaxNearbyEntities", 6);
this.requiredPlayerRange = tag.getIntOr("RequiredPlayerRange", 16);
@@ -203,9 +_,19 @@
this.spawnCount = input.getIntOr("SpawnCount", 4);
this.maxNearbyEntities = input.getIntOr("MaxNearbyEntities", 6);
this.requiredPlayerRange = input.getIntOr("RequiredPlayerRange", 16);
@@ -216,9 +_,19 @@
}
public CompoundTag save(CompoundTag tag) {
- tag.putShort("Delay", (short)this.spawnDelay);
- tag.putShort("MinSpawnDelay", (short)this.minSpawnDelay);
- tag.putShort("MaxSpawnDelay", (short)this.maxSpawnDelay);
public void save(ValueOutput output) {
- output.putShort("Delay", (short)this.spawnDelay);
- output.putShort("MinSpawnDelay", (short)this.minSpawnDelay);
- output.putShort("MaxSpawnDelay", (short)this.maxSpawnDelay);
+ // Paper start
+ if (this.spawnDelay > Short.MAX_VALUE) {
+ tag.putInt("Paper.Delay", this.spawnDelay);
+ output.putInt("Paper.Delay", this.spawnDelay);
+ }
+ tag.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay));
+ output.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay));
+
+ if (this.minSpawnDelay > Short.MAX_VALUE || this.maxSpawnDelay > Short.MAX_VALUE) {
+ tag.putInt("Paper.MinSpawnDelay", this.minSpawnDelay);
+ tag.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay);
+ output.putInt("Paper.MinSpawnDelay", this.minSpawnDelay);
+ output.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay);
+ }
+ tag.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay));
+ tag.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay));
+ output.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay));
+ output.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay));
+ // Paper end
tag.putShort("SpawnCount", (short)this.spawnCount);
tag.putShort("MaxNearbyEntities", (short)this.maxNearbyEntities);
tag.putShort("RequiredPlayerRange", (short)this.requiredPlayerRange);
output.putShort("SpawnCount", (short)this.spawnCount);
output.putShort("MaxNearbyEntities", (short)this.maxNearbyEntities);
output.putShort("RequiredPlayerRange", (short)this.requiredPlayerRange);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/GameRules.java
+++ b/net/minecraft/world/level/GameRules.java
@@ -34,6 +_,14 @@
@@ -35,6 +_,14 @@
import org.slf4j.Logger;
public class GameRules {
@@ -15,7 +15,7 @@
public static final int DEFAULT_RANDOM_TICK_SPEED = 3;
static final Logger LOGGER = LogUtils.getLogger();
public static final Map<GameRules.Key<?>, GameRules.Type<?>> GAME_RULE_TYPES = Maps.newTreeMap(Comparator.comparing(entry -> entry.id));
@@ -86,10 +_,10 @@
@@ -87,10 +_,10 @@
"sendCommandFeedback", GameRules.Category.CHAT, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_REDUCEDDEBUGINFO = register(
@@ -28,7 +28,7 @@
serverPlayer.connection.send(new ClientboundEntityEventPacket(serverPlayer, b));
}
})
@@ -113,8 +_,8 @@
@@ -114,8 +_,8 @@
"doWeatherCycle", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_LIMITED_CRAFTING = register(
@@ -39,7 +39,7 @@
serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LIMITED_CRAFTING, value.get() ? 1.0F : 0.0F));
}
})
@@ -138,8 +_,8 @@
@@ -139,8 +_,8 @@
"doInsomnia", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_IMMEDIATE_RESPAWN = register(
@@ -50,7 +50,7 @@
serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, value.get() ? 1.0F : 0.0F));
}
})
@@ -210,11 +_,11 @@
@@ -211,11 +_,11 @@
public static final GameRules.Key<GameRules.IntegerValue> RULE_MINECART_MAX_SPEED = register(
"minecartMaxSpeed",
GameRules.Category.MISC,
@@ -65,7 +65,16 @@
serverLevel.setDefaultSpawnPos(serverLevel.getSharedSpawnPos(), serverLevel.getSharedSpawnAngle());
})
);
@@ -223,6 +_,7 @@
@@ -223,7 +_,7 @@
"tntExplodes", GameRules.Category.MISC, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_LOCATOR_BAR = register(
- "locatorBar", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true, (server, value) -> server.getAllLevels().forEach(level -> {
+ "locatorBar", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true, (server, value) -> java.util.Optional.of(server).ifPresent(level -> { // Paper - per world game rules
ServerWaypointManager waypointManager = level.getWaypointManager();
if (value.get()) {
level.players().forEach(waypointManager::updatePlayer);
@@ -234,6 +_,7 @@
);
private final Map<GameRules.Key<?>, GameRules.Value<?>> rules;
private final FeatureFlagSet enabledFeatures;
@@ -73,7 +82,7 @@
public static <T extends GameRules.Value<T>> GameRules.Type<T> getType(GameRules.Key<T> key) {
return (GameRules.Type<T>)GAME_RULE_TYPES.get(key);
@@ -270,10 +_,21 @@
@@ -281,10 +_,21 @@
private GameRules(Map<GameRules.Key<?>, GameRules.Value<?>> rules, FeatureFlagSet enabledFeatures) {
this.rules = rules;
this.enabledFeatures = enabledFeatures;
@@ -96,7 +105,7 @@
if (value == null) {
throw new IllegalArgumentException("Tried to access invalid game rule");
} else {
@@ -314,13 +_,13 @@
@@ -325,13 +_,13 @@
}
}
@@ -114,16 +123,25 @@
}
public boolean getBoolean(GameRules.Key<GameRules.BooleanValue> key) {
@@ -334,7 +_,7 @@
public static class BooleanValue extends GameRules.Value<GameRules.BooleanValue> {
@@ -346,7 +_,7 @@
private boolean value;
private static GameRules.Type<GameRules.BooleanValue> create(
- boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changeListener, FeatureFlagSet requiredFeatures
+ boolean defaultValue, BiConsumer<ServerLevel, GameRules.BooleanValue> changeListener, FeatureFlagSet requiredFeatures // Paper - per world gamerules
) {
return new GameRules.Type<>(
BoolArgumentType::bool,
@@ -358,7 +_,7 @@
);
}
- static GameRules.Type<GameRules.BooleanValue> create(boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changeListener) {
+ static GameRules.Type<GameRules.BooleanValue> create(boolean defaultValue, BiConsumer<ServerLevel, GameRules.BooleanValue> changeListener) { // CraftBukkit - per-world
+ static GameRules.Type<GameRules.BooleanValue> create(boolean defaultValue, BiConsumer<ServerLevel, GameRules.BooleanValue> changeListener) { // Paper - per world gamerules
return new GameRules.Type<>(
BoolArgumentType::bool,
type -> new GameRules.BooleanValue(type, defaultValue),
@@ -355,17 +_,21 @@
@@ -379,17 +_,21 @@
}
@Override
@@ -149,7 +167,7 @@
}
@Override
@@ -394,9 +_,9 @@
@@ -418,9 +_,9 @@
}
@Override
@@ -161,7 +179,7 @@
}
}
@@ -434,7 +_,7 @@
@@ -458,7 +_,7 @@
public static class IntegerValue extends GameRules.Value<GameRules.IntegerValue> {
private int value;
@@ -170,7 +188,7 @@
return new GameRules.Type<>(
IntegerArgumentType::integer,
type -> new GameRules.IntegerValue(type, defaultValue),
@@ -446,7 +_,7 @@
@@ -470,7 +_,7 @@
}
static GameRules.Type<GameRules.IntegerValue> create(
@@ -179,7 +197,7 @@
) {
return new GameRules.Type<>(
() -> IntegerArgumentType.integer(min, max),
@@ -468,17 +_,21 @@
@@ -492,17 +_,21 @@
}
@Override
@@ -205,7 +223,7 @@
}
@Override
@@ -529,13 +_,17 @@
@@ -553,13 +_,17 @@
}
@Override
@@ -225,7 +243,7 @@
final String id;
private final GameRules.Category category;
@@ -575,7 +_,7 @@
@@ -599,7 +_,7 @@
public static class Type<T extends GameRules.Value<T>> {
final Supplier<ArgumentType<?>> argument;
private final Function<GameRules.Type<T>, T> constructor;
@@ -234,7 +252,7 @@
private final GameRules.VisitorCaller<T> visitorCaller;
final Class<T> valueClass;
final FeatureFlagSet requiredFeatures;
@@ -583,7 +_,7 @@
@@ -607,7 +_,7 @@
Type(
Supplier<ArgumentType<?>> argument,
Function<GameRules.Type<T>, T> constructor,
@@ -243,7 +261,7 @@
GameRules.VisitorCaller<T> visitorCaller,
Class<T> valueClass,
FeatureFlagSet requiredFeatures
@@ -611,6 +_,12 @@
@@ -635,6 +_,12 @@
public FeatureFlagSet requiredFeatures() {
return this.requiredFeatures;
}
@@ -256,7 +274,7 @@
}
public abstract static class Value<T extends GameRules.Value<T>> {
@@ -620,16 +_,16 @@
@@ -644,16 +_,16 @@
this.type = type;
}
@@ -280,7 +298,7 @@
}
}
@@ -648,7 +_,7 @@
@@ -672,7 +_,7 @@
protected abstract T copy();

View File

@@ -547,23 +547,16 @@
public boolean shouldTickDeath(Entity entity) {
return true;
@@ -608,6 +_,19 @@
@@ -608,6 +_,12 @@
@Nullable
@Override
public BlockEntity getBlockEntity(BlockPos pos) {
+ // CraftBukkit start
+ return this.getBlockEntity(pos, true);
+ }
+
+ @Nullable
+ public BlockEntity getBlockEntity(BlockPos pos, boolean validate) {
+ // Paper start - Perf: Optimize capturedTileEntities lookup
+ net.minecraft.world.level.block.entity.BlockEntity blockEntity;
+ if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) {
+ return blockEntity;
+ }
+ // Paper end - Perf: Optimize capturedTileEntities lookup
+ // CraftBukkit end
if (this.isOutsideBuildHeight(pos)) {
return null;
} else {
@@ -580,7 +573,7 @@
this.getChunkAt(blockPos).addAndRegisterBlockEntity(blockEntity);
}
}
@@ -1009,7 +_,8 @@
@@ -1013,7 +_,8 @@
BLOCK("block"),
MOB("mob"),
TNT("tnt"),

View File

@@ -224,7 +224,7 @@
this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center);
List<BlockPos> list = this.calculateExplodedPositions();
this.hurtEntities();
@@ -339,4 +_,86 @@
@@ -338,4 +_,86 @@
}
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/TicketStorage.java
+++ b/net/minecraft/world/level/TicketStorage.java
@@ -161,7 +_,7 @@
@@ -163,7 +_,7 @@
}
private static boolean isTicketSameTypeAndLevel(Ticket first, Ticket second) {
@@ -9,16 +9,16 @@
}
public int getTicketLevelAt(long chunkPos, boolean requireSimulation) {
@@ -264,7 +_,7 @@
@@ -272,7 +_,7 @@
}
public void deactivateTicketsOnClosing() {
- this.removeTicketIf(ticket -> ticket.getType() != TicketType.UNKNOWN, this.deactivatedTickets);
+ this.removeTicketIf(ticket -> ticket.getType() != TicketType.UNKNOWN && ticket.getType() != TicketType.CHUNK_LOAD && ticket.getType() != TicketType.FUTURE_AWAIT, this.deactivatedTickets);
- this.removeTicketIf((_long, ticket) -> ticket.getType() != TicketType.UNKNOWN, this.deactivatedTickets);
+ this.removeTicketIf((_long, ticket) -> ticket.getType() != TicketType.UNKNOWN && ticket.getType() != TicketType.CHUNK_LOAD && ticket.getType() != TicketType.FUTURE_AWAIT, this.deactivatedTickets);
}
public void removeTicketIf(Predicate<Ticket> predicate, @Nullable Long2ObjectOpenHashMap<List<Ticket>> tickets) {
@@ -369,4 +_,19 @@
public void removeTicketIf(BiPredicate<Long, Ticket> biPredicate, @Nullable Long2ObjectOpenHashMap<List<Ticket>> map) {
@@ -378,4 +_,19 @@
public interface ChunkUpdated {
void update(long chunkPos, int i, boolean ticketLevel);
}
@@ -34,7 +34,7 @@
+ }
+
+ public void removeAllPluginRegionTickets(TicketType ticketType, int ticketLevel, org.bukkit.plugin.Plugin ticketIdentifier) {
+ removeTicketIf(ticket -> ticket.getType() == ticketType && ticket.getTicketLevel() == ticketLevel && ticket.getIdentifier() == ticketIdentifier, null);
+ removeTicketIf((chunkKey, ticket) -> ticket.getType() == ticketType && ticket.getTicketLevel() == ticketLevel && ticket.getIdentifier() == ticketIdentifier, null);
+ }
+ // Paper end
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/AbstractCauldronBlock.java
+++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java
@@ -62,7 +_,7 @@
@@ -57,7 +_,7 @@
ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult
) {
CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem());

View File

@@ -90,7 +90,7 @@
+ // Paper end - add entity parameter
if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
- ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount);
+ ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity); // Paper
+ ExperienceOrb.awardWithDirection(level, Vec3.atCenterOf(pos), net.minecraft.world.phys.Vec3.ZERO, amount, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity, null); // Paper
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/CactusBlock.java
+++ b/net/minecraft/world/level/block/CactusBlock.java
@@ -58,25 +_,29 @@
@@ -58,18 +_,22 @@
int ageValue = state.getValue(AGE);
while (level.getBlockState(pos.below(i)).is(this)) {
@@ -29,14 +29,6 @@
BlockState blockState = state.setValue(AGE, 0);
level.setBlock(pos, blockState, 260);
level.neighborChanged(blockState, blockPos, this, null, false);
}
if (ageValue < 15) {
- level.setBlock(pos, state.setValue(AGE, ageValue + 1), 260);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(AGE, ageValue + 1), 260); // Paper
}
}
}
@@ -124,7 +_,8 @@
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -57,8 +_,15 @@
@@ -58,8 +_,15 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
@@ -16,8 +16,8 @@
serverPlayer.showEndCredits();
} else {
entity.setAsInsidePortal(this, pos);
@@ -68,7 +_,7 @@
@@ -70,7 +_,7 @@
@Nullable
@Override
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
- ResourceKey<Level> resourceKey = level.dimension() == Level.END ? Level.OVERWORLD : Level.END;
@@ -25,7 +25,7 @@
ServerLevel level1 = level.getServer().getLevel(resourceKey);
if (level1 == null) {
return null;
@@ -79,7 +_,7 @@
@@ -81,7 +_,7 @@
float f;
Set<Relative> set;
if (flag) {
@@ -34,8 +34,8 @@
f = Direction.WEST.toYRot();
set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT));
if (entity instanceof ServerPlayer) {
@@ -89,15 +_,23 @@
f = 0.0F;
@@ -91,15 +_,23 @@
f = level1.getSharedSpawnAngle();
set = Relative.union(Relative.DELTA, Relative.ROTATION);
if (entity instanceof ServerPlayer serverPlayer) {
- return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING);

View File

@@ -1,15 +1,14 @@
--- a/net/minecraft/world/level/block/LavaCauldronBlock.java
+++ b/net/minecraft/world/level/block/LavaCauldronBlock.java
@@ -33,9 +_,10 @@
@@ -44,8 +_,10 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (this.isEntityInsideContent(state, pos, entity)) {
- entity.lavaIgnite();
- entity.lavaHurt();
+ entity.lavaIgnite(pos); // Paper - track lava contact
+ entity.lavaHurt(pos); // Paper - track lava contact
}
+ BlockPos savedPos = pos.immutable(); // Paper - track lava contact
effectApplier.apply(InsideBlockEffectType.LAVA_IGNITE);
- effectApplier.runAfter(InsideBlockEffectType.LAVA_IGNITE, Entity::lavaHurt);
+ effectApplier.runAfter(InsideBlockEffectType.LAVA_IGNITE, ignitedEntity -> ignitedEntity.lavaHurt(savedPos)); // Paper - track lava contact
}
@Override

View File

@@ -1,23 +1,27 @@
--- a/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -62,35 +_,67 @@
@@ -79,39 +_,71 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (level instanceof ServerLevel serverLevel && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
- entity.clearFire();
- if (entity.mayInteract(serverLevel, pos)) {
- this.handleEntityOnFireInside(state, level, pos);
+ // CraftBukkit start - moved down
+ // entity.clearFire();
+ if ((entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(serverLevel, pos)) { // Paper - Fixes MC-248588
+ if (this.handleEntityOnFireInside(state, level, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities
+ entity.clearFire();
+ }
+ // CraftBukkit end
}
if (level instanceof ServerLevel serverLevel) {
BlockPos blockPos = pos.immutable();
effectApplier.runBefore(InsideBlockEffectType.EXTINGUISH, entity1 -> {
- if (entity1.isOnFire() && entity1.mayInteract(serverLevel, blockPos)) {
- this.handleEntityOnFireInside(state, level, blockPos);
+ if (entity1.isOnFire() && (entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity1.mayInteract(serverLevel, blockPos)) { // Paper - Fixes MC-248588
+ // Paper start - cauldron level change event
+ if (this.handleEntityOnFireInside(state, level, blockPos, entity1)) { // Paper - track entity
+ InsideBlockEffectType.EXTINGUISH.effect().affect(entity1, blockPos); // apply extinguishing if event was not cancelled.
+ }
+ // Paper end - cauldron level change event
}
});
}
- effectApplier.apply(InsideBlockEffectType.EXTINGUISH);
+ // effectApplier.apply(InsideBlockEffectType.EXTINGUISH); // Paper - manually applied above - cauldron level change event - delay to not extinguish when event is cancelled
}
- private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) {
@@ -79,7 +83,7 @@
}
}
@@ -108,8 +_,11 @@
@@ -129,8 +_,11 @@
protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) {
if (!this.isFull(state)) {
BlockState blockState = state.setValue(LEVEL, state.getValue(LEVEL) + 1);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -70,7 +_,7 @@
@@ -65,7 +_,7 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
@@ -9,7 +9,7 @@
&& level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)
&& random.nextInt(2000) < level.getDifficulty().getId()
&& level.anyPlayerCloseEnoughForSpawning(pos)) {
@@ -79,9 +_,13 @@
@@ -74,9 +_,13 @@
}
if (level.getBlockState(pos).isValidSpawn(level, pos, EntityType.ZOMBIFIED_PIGLIN)) {
@@ -24,7 +24,7 @@
Entity vehicle = entity.getVehicle();
if (vehicle != null) {
vehicle.setPortalCooldown();
@@ -112,7 +_,13 @@
@@ -107,7 +_,13 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
@@ -38,7 +38,7 @@
entity.setAsInsidePortal(this, pos);
}
}
@@ -135,22 +_,46 @@
@@ -130,22 +_,46 @@
@Nullable
@Override
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
@@ -90,7 +90,7 @@
BlockUtil.FoundRectangle largestRectangleAround;
TeleportTransition.PostTeleportTransition postTeleportTransition;
if (optional.isPresent()) {
@@ -165,17 +_,22 @@
@@ -160,17 +_,22 @@
blockPos1 -> level.getBlockState(blockPos1) == blockState
);
postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(entity1 -> entity1.placePortalTicket(blockPos));
@@ -116,7 +116,7 @@
return getDimensionTransitionFromExit(entity, pos, largestRectangleAround, level, postTeleportTransition);
}
@@ -221,7 +_,7 @@
@@ -216,7 +_,7 @@
boolean flag = axis1 == Direction.Axis.X;
Vec3 vec3 = new Vec3(blockPos.getX() + (flag ? d2 : d4), blockPos.getY() + d3, blockPos.getZ() + (flag ? d4 : d2));
Vec3 vec31 = PortalShape.findCollisionFreePosition(vec3, level, entity, dimensions);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/SculkSpreader.java
+++ b/net/minecraft/world/level/block/SculkSpreader.java
@@ -45,6 +_,7 @@
@@ -46,6 +_,7 @@
private final int chargeDecayRate;
private final int additionalDecayRate;
private List<SculkSpreader.ChargeCursor> cursors = new ArrayList<>();
@@ -8,16 +8,16 @@
public SculkSpreader(
boolean isWorldGeneration, TagKey<Block> replaceableBlocks, int growthSpawnCoat, int noGrowthRadius, int chargeDecayRate, int additionalDecayRate
@@ -100,7 +_,7 @@
@@ -101,7 +_,7 @@
public void load(CompoundTag tag) {
public void load(ValueInput input) {
this.cursors.clear();
- tag.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach(this::addCursor);
+ tag.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach((cursor) -> this.addCursor(cursor, false)); // Paper - don't fire event for block entity loading
- input.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach(this::addCursor);
+ input.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach((cursor) -> this.addCursor(cursor, false)); // Paper - don't fire event for block entity loading
}
public void save(CompoundTag tag) {
@@ -110,13 +_,24 @@
public void save(ValueOutput output) {
@@ -111,13 +_,24 @@
public void addCursors(BlockPos pos, int charge) {
while (charge > 0) {
int min = Math.min(charge, 1000);

View File

@@ -1,15 +1,15 @@
--- a/net/minecraft/world/level/block/SignBlock.java
+++ b/net/minecraft/world/level/block/SignBlock.java
@@ -133,7 +_,7 @@
} else if (!this.otherPlayerIsEditingSign(player, signBlockEntity)
&& player.mayBuild()
&& this.hasEditableText(player, signBlockEntity, isFacingFrontText)) {
- this.openTextEdit(player, signBlockEntity, isFacingFrontText);
+ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
return InteractionResult.SUCCESS_SERVER;
} else {
return InteractionResult.PASS;
@@ -175,7 +_,34 @@
} else if (!this.otherPlayerIsEditingSign(player, signBlockEntity)
&& player.mayBuild()
&& this.hasEditableText(player, signBlockEntity, isFacingFrontText)) {
- this.openTextEdit(player, signBlockEntity, isFacingFrontText);
+ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
return InteractionResult.SUCCESS_SERVER;
} else {
return InteractionResult.PASS;
@@ -179,7 +_,34 @@
return woodType;
}
@@ -44,7 +44,7 @@
signEntity.setAllowedPlayerEditor(player.getUUID());
player.openTextEdit(signEntity, isFrontText);
}
@@ -188,6 +_,6 @@
@@ -192,6 +_,6 @@
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {

View File

@@ -10,7 +10,7 @@
pos,
6,
65,
@@ -63,8 +_,10 @@
@@ -63,16 +_,18 @@
if (blockPos.equals(pos)) {
return BlockPos.TraversalNodeStatus.ACCEPT;
} else {
@@ -23,7 +23,8 @@
if (!fluidState.is(FluidTags.WATER)) {
return BlockPos.TraversalNodeStatus.SKIP;
} else if (blockState.getBlock() instanceof BucketPickup bucketPickup
@@ -72,7 +_,7 @@
- && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) {
+ && !bucketPickup.pickupBlock(null, blockList, blockPos, blockState).isEmpty()) { // CraftBukkit
return BlockPos.TraversalNodeStatus.ACCEPT;
} else {
if (blockState.getBlock() instanceof LiquidBlock) {
@@ -32,7 +33,7 @@
} else {
if (!blockState.is(Blocks.KELP)
&& !blockState.is(Blocks.KELP_PLANT)
@@ -81,16 +_,55 @@
@@ -81,16 +_,49 @@
return BlockPos.TraversalNodeStatus.SKIP;
}
@@ -42,7 +43,6 @@
+ // CraftBukkit start
+ // BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null;
+ // dropResources(blockState, level, blockPos, blockEntity);
+ // level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3);
+ blockList.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3);
+ // CraftBukkit end
}
@@ -66,22 +66,17 @@
+
+ for (org.bukkit.craftbukkit.block.CraftBlockState snapshot : snapshots) {
+ BlockPos blockPos = snapshot.getPosition();
+ BlockState state = level.getBlockState(blockPos);
+ FluidState fluid = level.getFluidState(blockPos);
+ BlockState blockState = level.getBlockState(blockPos);
+ FluidState fluidState = level.getFluidState(blockPos);
+
+ if (fluid.is(FluidTags.WATER)) {
+ if (state.getBlock() instanceof BucketPickup bucketPickup && !bucketPickup.pickupBlock(null, blockList, blockPos, state).isEmpty()) {
+ // NOP
+ } else if (state.getBlock() instanceof LiquidBlock) {
+ // NOP
+ } else if (state.is(Blocks.KELP) || state.is(Blocks.KELP_PLANT) || state.is(Blocks.SEAGRASS) || state.is(Blocks.TALL_SEAGRASS)) {
+ BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(blockPos) : null;
+ if (!fluidState.is(FluidTags.WATER)) {
+ } else if (blockState.getBlock() instanceof BucketPickup bucketPickup && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) {
+ } else if (blockState.getBlock() instanceof LiquidBlock) {
+ } else if (blockState.is(Blocks.KELP) || blockState.is(Blocks.KELP_PLANT) || blockState.is(Blocks.SEAGRASS) || blockState.is(Blocks.TALL_SEAGRASS)) {
+ BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null;
+
+ // Paper start - Fix SpongeAbsortEvent handling
+ if (snapshot.getHandle().isAir()) {
+ dropResources(state, level, blockPos, blockEntity);
+ }
+ // Paper end - Fix SpongeAbsortEvent handling
+ if (snapshot.getHandle().isAir()) {
+ dropResources(blockState, level, blockPos, blockEntity);
+ }
+ }
+ snapshot.place(snapshot.getFlags());

View File

@@ -52,20 +52,20 @@
private boolean isLit() {
return this.litTimeRemaining > 0;
@@ -125,6 +_,7 @@
this.litTotalTime = tag.getShortOr("lit_total_time", (short)0);
this.litTotalTime = input.getShortOr("lit_total_time", (short)0);
this.recipesUsed.clear();
this.recipesUsed.putAll(tag.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of()));
+ this.cookSpeedMultiplier = tag.getDoubleOr("Paper.CookSpeedMultiplier", 1); // Paper - cook speed multiplier API
this.recipesUsed.putAll(input.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of()));
+ this.cookSpeedMultiplier = input.getDoubleOr("Paper.CookSpeedMultiplier", 1); // Paper - cook speed multiplier API
}
@Override
@@ -134,6 +_,7 @@
tag.putShort("cooking_total_time", (short)this.cookingTotalTime);
tag.putShort("lit_time_remaining", (short)this.litTimeRemaining);
tag.putShort("lit_total_time", (short)this.litTotalTime);
+ tag.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API
ContainerHelper.saveAllItems(tag, this.items, registries);
tag.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed);
output.putShort("cooking_total_time", (short)this.cookingTotalTime);
output.putShort("lit_time_remaining", (short)this.litTimeRemaining);
output.putShort("lit_total_time", (short)this.litTotalTime);
+ output.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API
ContainerHelper.saveAllItems(output, this.items);
output.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed);
}
@@ -160,11 +_,22 @@
@@ -210,9 +210,9 @@
}
- public void awardUsedRecipesAndPopExperience(ServerPlayer player) {
- List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.serverLevel(), player.position());
- List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.level(), player.position());
+ public void awardUsedRecipesAndPopExperience(ServerPlayer player, ItemStack itemstack, int amount) { // CraftBukkit
+ List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.serverLevel(), player.position(), this.worldPosition, player, itemstack, amount); // CraftBukkit - overload for exp spawn events
+ List<RecipeHolder<?>> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.level(), player.position(), this.worldPosition, player, itemstack, amount); // CraftBukkit - overload for exp spawn events
player.awardRecipes(recipesToAwardAndPopExperience);
for (RecipeHolder<?> recipeHolder : recipesToAwardAndPopExperience) {
@@ -268,7 +268,7 @@
+ floor = event.getExpToDrop();
+ // CraftBukkit end
+
+ ExperienceOrb.award(level, popVec, floor, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, serverPlayer); // Paper
+ ExperienceOrb.awardWithDirection(level, popVec, net.minecraft.world.phys.Vec3.ZERO, floor, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, serverPlayer, null); // Paper
}
@Override

View File

@@ -1,24 +1,24 @@
--- a/net/minecraft/world/level/block/entity/BannerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BannerBlockEntity.java
@@ -52,7 +_,7 @@
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
@@ -50,7 +_,7 @@
@Override
protected void saveAdditional(ValueOutput output) {
super.saveAdditional(output);
- if (!this.patterns.equals(BannerPatternLayers.EMPTY)) {
+ if (!this.patterns.equals(BannerPatternLayers.EMPTY) || serialisingForNetwork.get()) { // Paper - always send patterns to client
tag.store("patterns", BannerPatternLayers.CODEC, registryOps, this.patterns);
output.store("patterns", BannerPatternLayers.CODEC, this.patterns);
}
@@ -64,7 +_,7 @@
super.loadAdditional(tag, registries);
this.name = parseCustomNameSafe(tag.get("CustomName"), registries);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
- this.patterns = tag.read("patterns", BannerPatternLayers.CODEC, registryOps).orElse(BannerPatternLayers.EMPTY);
+ this.setPatterns(tag.read("patterns", BannerPatternLayers.CODEC, registryOps).orElse(BannerPatternLayers.EMPTY)); // CraftBukkit - apply limits
@@ -61,7 +_,7 @@
protected void loadAdditional(ValueInput input) {
super.loadAdditional(input);
this.name = parseCustomNameSafe(input, "CustomName");
- this.patterns = input.read("patterns", BannerPatternLayers.CODEC).orElse(BannerPatternLayers.EMPTY);
+ this.setPatterns(input.read("patterns", BannerPatternLayers.CODEC).orElse(BannerPatternLayers.EMPTY)); // CraftBukkit - apply limits
}
@Override
@@ -72,9 +_,18 @@
@@ -69,9 +_,18 @@
return ClientboundBlockEntityDataPacket.create(this);
}
@@ -37,7 +37,7 @@
}
public BannerPatternLayers getPatterns() {
@@ -94,7 +_,7 @@
@@ -91,7 +_,7 @@
@Override
protected void applyImplicitComponents(DataComponentGetter componentGetter) {
super.applyImplicitComponents(componentGetter);
@@ -46,9 +46,9 @@
this.name = componentGetter.get(DataComponents.CUSTOM_NAME);
}
@@ -110,4 +_,13 @@
tag.remove("patterns");
tag.remove("CustomName");
@@ -107,4 +_,13 @@
output.discard("patterns");
output.discard("CustomName");
}
+
+ // CraftBukkit start

View File

@@ -1,7 +1,7 @@
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -21,6 +_,41 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.ValueOutput;
public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
+ // CraftBukkit start - add fields and methods

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -69,17 +_,45 @@
@@ -66,17 +_,45 @@
protected abstract Component getDefaultName();
public boolean canOpen(Player player) {
@@ -48,9 +48,9 @@
}
protected abstract NonNullList<ItemStack> getItems();
@@ -167,4 +_,12 @@
tag.remove("lock");
tag.remove("Items");
@@ -164,4 +_,12 @@
output.discard("lock");
output.discard("Items");
}
+
+ // CraftBukkit start

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
@@ -109,6 +_,53 @@
@@ -110,6 +_,53 @@
return 3;
}
};
@@ -54,7 +54,7 @@
@Nullable
static Holder<MobEffect> filterEffect(@Nullable Holder<MobEffect> effect) {
@@ -166,17 +_,26 @@
@@ -167,17 +_,26 @@
blockEntity.lastCheckY++;
}
@@ -83,7 +83,7 @@
if (blockEntity.lastCheckY >= height) {
blockEntity.lastCheckY = level.getMinY() - 1;
@@ -227,35 +_,100 @@
@@ -228,35 +_,100 @@
@Override
public void setRemoved() {
@@ -202,35 +202,35 @@
public static void playSound(Level level, BlockPos pos, SoundEvent sound) {
level.playSound(null, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F);
@@ -284,7 +_,7 @@
@@ -285,7 +_,7 @@
@Nullable
private static Holder<MobEffect> loadEffect(CompoundTag tag, String key) {
- return tag.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).filter(VALID_EFFECTS::contains).orElse(null);
+ return tag.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).orElse(null); // CraftBukkit - persist manually set non-default beacon effects (SPIGOT-3598)
private static Holder<MobEffect> loadEffect(ValueInput input, String key) {
- return input.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).filter(VALID_EFFECTS::contains).orElse(null);
+ return input.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).orElse(null); // CraftBukkit - persist manually set non-default beacon effects (SPIGOT-3598)
}
@Override
@@ -292,8 +_,10 @@
super.loadAdditional(tag, registries);
this.primaryPower = loadEffect(tag, "primary_effect");
this.secondaryPower = loadEffect(tag, "secondary_effect");
+ this.levels = tag.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available
this.name = parseCustomNameSafe(tag.get("CustomName"), registries);
this.lockKey = LockCode.fromTag(tag, registries);
+ this.effectRange = tag.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges
@@ -293,8 +_,10 @@
super.loadAdditional(input);
this.primaryPower = loadEffect(input, "primary_effect");
this.secondaryPower = loadEffect(input, "secondary_effect");
+ this.levels = input.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available
this.name = parseCustomNameSafe(input, "CustomName");
this.lockKey = LockCode.fromTag(input);
+ this.effectRange = input.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges
}
@Override
@@ -304,6 +_,7 @@
tag.putInt("Levels", this.levels);
tag.storeNullable("CustomName", ComponentSerialization.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.name);
this.lockKey.addToTag(tag, registries);
+ tag.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges
@@ -305,6 +_,7 @@
output.putInt("Levels", this.levels);
output.storeNullable("CustomName", ComponentSerialization.CODEC, this.name);
this.lockKey.addToTag(output);
+ output.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges
}
public void setCustomName(@Nullable Component name) {
@@ -319,7 +_,7 @@
@@ -320,7 +_,7 @@
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -79,6 +_,7 @@
@@ -82,6 +_,7 @@
private List<BeehiveBlockEntity.BeeData> stored = Lists.newArrayList();
@Nullable
public BlockPos savedFlowerPos;
@@ -8,7 +8,7 @@
public BeehiveBlockEntity(BlockPos pos, BlockState blockState) {
super(BlockEntityType.BEEHIVE, pos, blockState);
@@ -112,7 +_,7 @@
@@ -115,7 +_,7 @@
}
public boolean isFull() {
@@ -17,7 +17,7 @@
}
public void emptyAllLivingFromHive(@Nullable Player player, BlockState state, BeehiveBlockEntity.BeeReleaseStatus releaseStatus) {
@@ -121,7 +_,7 @@
@@ -124,7 +_,7 @@
for (Entity entity : list) {
if (entity instanceof Bee bee && player.position().distanceToSqr(entity.position()) <= 16.0) {
if (!this.isSedated()) {
@@ -26,7 +26,7 @@
} else {
bee.setStayOutOfHiveCountdown(400);
}
@@ -131,8 +_,14 @@
@@ -134,8 +_,14 @@
}
private List<Entity> releaseAllOccupants(BlockState state, BeehiveBlockEntity.BeeReleaseStatus releaseStatus) {
@@ -42,7 +42,7 @@
if (!list.isEmpty()) {
super.setChanged();
}
@@ -145,6 +_,11 @@
@@ -148,6 +_,11 @@
return this.stored.size();
}
@@ -54,7 +54,7 @@
public static int getHoneyLevel(BlockState state) {
return state.getValue(BeehiveBlock.HONEY_LEVEL);
}
@@ -155,7 +_,16 @@
@@ -158,7 +_,16 @@
}
public void addOccupant(Bee bee) {
@@ -72,7 +72,7 @@
bee.stopRiding();
bee.ejectPassengers();
bee.dropLeash();
@@ -180,7 +_,7 @@
@@ -183,7 +_,7 @@
this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(bee, this.getBlockState()));
}
@@ -81,7 +81,7 @@
super.setChanged();
}
}
@@ -198,7 +_,21 @@
@@ -201,7 +_,21 @@
BeehiveBlockEntity.BeeReleaseStatus releaseStatus,
@Nullable BlockPos storedFlowerPos
) {
@@ -104,7 +104,7 @@
return false;
} else {
Direction direction = state.getValue(BeehiveBlock.FACING);
@@ -209,6 +_,17 @@
@@ -212,6 +_,17 @@
} else {
Entity entity = occupant.createEntity(level, pos);
if (entity != null) {
@@ -122,7 +122,7 @@
if (entity instanceof Bee bee) {
if (storedFlowerPos != null && !bee.hasSavedFlowerPos() && level.random.nextFloat() < 0.9F) {
bee.setSavedFlowerPos(storedFlowerPos);
@@ -224,7 +_,13 @@
@@ -227,7 +_,13 @@
i--;
}
@@ -137,7 +137,7 @@
}
}
}
@@ -233,17 +_,19 @@
@@ -236,17 +_,19 @@
storedInHives.add(bee);
}
@@ -158,7 +158,7 @@
} else {
return false;
}
@@ -269,6 +_,11 @@
@@ -272,6 +_,11 @@
flag = true;
iterator.remove();
}
@@ -170,23 +170,23 @@
}
}
@@ -292,9 +_,10 @@
@@ -295,9 +_,10 @@
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.loadAdditional(tag, registries);
protected void loadAdditional(ValueInput input) {
super.loadAdditional(input);
- this.stored.clear();
+ this.stored = Lists.newArrayList(); // CraftBukkit - SPIGOT-7790: create new copy (may be modified in physics event triggered by honey change)
tag.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee);
this.savedFlowerPos = tag.read("flower_pos", BlockPos.CODEC).orElse(null);
+ this.maxBees = tag.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants
input.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee);
this.savedFlowerPos = input.read("flower_pos", BlockPos.CODEC).orElse(null);
+ this.maxBees = input.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants
}
@Override
@@ -302,12 +_,13 @@
super.saveAdditional(tag, registries);
tag.store("bees", BeehiveBlockEntity.Occupant.LIST_CODEC, this.getBees());
tag.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
+ tag.putInt("Bukkit.MaxEntities", this.maxBees); // Paper - persist max bukkit occupants
@@ -305,12 +_,13 @@
super.saveAdditional(output);
output.store("bees", BeehiveBlockEntity.Occupant.LIST_CODEC, this.getBees());
output.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos);
+ output.putInt("Bukkit.MaxEntities", this.maxBees); // Paper - persist max bukkit occupants
}
@Override
@@ -197,7 +197,7 @@
List<BeehiveBlockEntity.Occupant> list = componentGetter.getOrDefault(DataComponents.BEES, Bees.EMPTY).bees();
list.forEach(this::storeBee);
}
@@ -330,15 +_,18 @@
@@ -333,15 +_,18 @@
static class BeeData {
private final BeehiveBlockEntity.Occupant occupant;
@@ -217,7 +217,7 @@
}
public BeehiveBlockEntity.Occupant toOccupant() {
@@ -409,6 +_,7 @@
@@ -418,6 +_,7 @@
}
private static void setBeeReleaseData(int ticksInHive, Bee bee) {
@@ -225,7 +225,7 @@
int age = bee.getAge();
if (age < 0) {
bee.setAge(Math.min(0, age + ticksInHive));
@@ -417,6 +_,7 @@
@@ -426,6 +_,7 @@
}
bee.setInLoveTime(Math.max(0, bee.getInLoveTime() - ticksInHive));

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -33,6 +_,10 @@
@@ -35,6 +_,10 @@
import org.slf4j.Logger;
public abstract class BlockEntity {
@@ -11,7 +11,7 @@
private static final Codec<BlockEntityType<?>> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec();
private static final Logger LOGGER = LogUtils.getLogger();
private final BlockEntityType<?> type;
@@ -48,6 +_,7 @@
@@ -50,6 +_,7 @@
this.worldPosition = pos.immutable();
this.validateBlockState(blockState);
this.blockState = blockState;
@@ -19,7 +19,7 @@
}
private void validateBlockState(BlockState state) {
@@ -64,6 +_,7 @@
@@ -66,6 +_,7 @@
int intOr = tag.getIntOr("x", 0);
int intOr1 = tag.getIntOr("y", 0);
int intOr2 = tag.getIntOr("z", 0);
@@ -27,7 +27,7 @@
int sectionPosCoord = SectionPos.blockToSectionCoord(intOr);
int sectionPosCoord1 = SectionPos.blockToSectionCoord(intOr2);
if (sectionPosCoord != chunkPos.x || sectionPosCoord1 != chunkPos.z) {
@@ -71,6 +_,7 @@
@@ -73,6 +_,7 @@
intOr = chunkPos.getBlockX(SectionPos.sectionRelative(intOr));
intOr2 = chunkPos.getBlockZ(SectionPos.sectionRelative(intOr2));
}
@@ -35,45 +35,44 @@
return new BlockPos(intOr, intOr1, intOr2);
}
@@ -89,6 +_,14 @@
@@ -91,6 +_,12 @@
}
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
protected void loadAdditional(ValueInput input) {
+ // Paper start - read persistent data container
+ this.persistentDataContainer.clear(); // Paper - clear instead of init
+
+ net.minecraft.nbt.Tag persistentDataTag = tag.get("PublicBukkitValues");
+ if (persistentDataTag instanceof CompoundTag) {
+ this.persistentDataContainer.putAll((CompoundTag) persistentDataTag);
+ }
+ input.read("PublicBukkitValues", CompoundTag.CODEC)
+ .ifPresent(this.persistentDataContainer::putAll);
+ // Paper end - read persistent data container
}
public final void loadWithComponents(CompoundTag tag, HolderLookup.Provider registries) {
@@ -120,12 +_,22 @@
CompoundTag compoundTag = new CompoundTag();
this.saveAdditional(compoundTag, registries);
compoundTag.store(BlockEntity.ComponentHelper.COMPONENTS_CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.components);
public final void loadWithComponents(ValueInput input) {
@@ -140,6 +_,11 @@
public void saveWithoutMetadata(ValueOutput output) {
this.saveAdditional(output);
output.store("components", DataComponentMap.CODEC, this.components);
+ // CraftBukkit start - store container
+ if (!this.persistentDataContainer.isEmpty()) {
+ compoundTag.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound());
+ output.store("PublicBukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
+ }
+ // CraftBukkit end
return compoundTag;
}
public final CompoundTag saveCustomOnly(HolderLookup.Provider registries) {
CompoundTag compoundTag = new CompoundTag();
this.saveAdditional(compoundTag, registries);
@@ -155,6 +_,11 @@
public void saveCustomOnly(ValueOutput output) {
this.saveAdditional(output);
+ // Paper start - store PDC here as well
+ if (!this.persistentDataContainer.isEmpty()) {
+ compoundTag.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound());
+ output.store("PublicBukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
+ }
+ // Paper end
return compoundTag;
}
@@ -260,6 +_,12 @@
public void saveId(ValueOutput output) {
@@ -287,6 +_,12 @@
}
public final void applyComponents(DataComponentMap components, DataComponentPatch patch) {
@@ -86,7 +85,7 @@
final Set<DataComponentType<?>> set = new HashSet<>();
set.add(DataComponents.BLOCK_ENTITY_DATA);
set.add(DataComponents.BLOCK_STATE);
@@ -280,6 +_,10 @@
@@ -307,6 +_,10 @@
});
DataComponentPatch dataComponentPatch = patch.forget(set::contains);
this.components = dataComponentPatch.split().added();
@@ -97,9 +96,9 @@
}
protected void collectImplicitComponents(DataComponentMap.Builder components) {
@@ -313,6 +_,28 @@
.resultOrPartial(string -> LOGGER.warn("Failed to parse custom name, discarding: {}", string))
.orElse(null);
@@ -339,6 +_,27 @@
public ProblemReporter.PathElement problemPath() {
return new BlockEntity.BlockEntityPathElement(this);
}
+
+ // CraftBukkit start - add method
@@ -122,7 +121,6 @@
+ return tag;
+ }
+ // Paper end - Sanitize sent data
+
static class ComponentHelper {
public static final MapCodec<DataComponentMap> COMPONENTS_CODEC = DataComponentMap.CODEC.optionalFieldOf("components", DataComponentMap.EMPTY);
record BlockEntityPathElement(BlockEntity blockEntity) implements ProblemReporter.PathElement {
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
@@ -65,9 +_,26 @@
@@ -67,9 +_,26 @@
return false;
} else {
this.coolDownEndsAtTick = startTick + 10L;
@@ -29,7 +29,7 @@
this.brushingCompleted(level, brusher, stack);
return true;
} else {
@@ -75,7 +_,7 @@
@@ -77,7 +_,7 @@
int completionState1 = this.getCompletionState();
if (completionState != completionState1) {
BlockState blockState = this.getBlockState();
@@ -38,7 +38,7 @@
level.setBlock(this.getBlockPos(), blockState1, 3);
}
@@ -116,6 +_,11 @@
@@ -118,6 +_,11 @@
this.dropContent(level, brusher, stack);
BlockState blockState = this.getBlockState();
level.levelEvent(3008, this.getBlockPos(), Block.getId(blockState));
@@ -50,7 +50,7 @@
Block turnsInto;
if (this.getBlockState().getBlock() instanceof BrushableBlock brushableBlock) {
turnsInto = brushableBlock.getTurnsInto();
@@ -123,6 +_,11 @@
@@ -125,6 +_,11 @@
turnsInto = Blocks.AIR;
}
@@ -62,7 +62,7 @@
level.setBlock(this.worldPosition, turnsInto.defaultBlockState(), 3);
}
@@ -139,7 +_,12 @@
@@ -141,7 +_,12 @@
double d5 = blockPos.getZ() + 0.5 * d1 + d2;
ItemEntity itemEntity = new ItemEntity(level, d3, d4, d5, this.item.split(level.random.nextInt(21) + 10));
itemEntity.setDeltaMovement(Vec3.ZERO);

View File

@@ -6,8 +6,8 @@
}
+ // Paper start - Configurable sculk sensor listener range
+ @Override
+ protected void saveRangeOverride(final net.minecraft.nbt.CompoundTag nbt) {
+ if (this.rangeOverride != null && this.rangeOverride != 16) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ protected void saveRangeOverride(final net.minecraft.world.level.storage.ValueOutput output) {
+ if (this.rangeOverride != null && this.rangeOverride != 16) output.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ }
+ // Paper end - Configurable sculk sensor listener range

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
@@ -38,6 +_,7 @@
@@ -45,6 +_,7 @@
private final NonNullList<ItemStack> items = NonNullList.withSize(4, ItemStack.EMPTY);
public final int[] cookingProgress = new int[4];
public final int[] cookingTime = new int[4];
@@ -8,7 +8,7 @@
public CampfireBlockEntity(BlockPos pos, BlockState blockState) {
super(BlockEntityType.CAMPFIRE, pos, blockState);
@@ -56,14 +_,44 @@
@@ -63,14 +_,44 @@
ItemStack itemStack = campfire.items.get(i);
if (!itemStack.isEmpty()) {
flag = true;
@@ -55,38 +55,38 @@
campfire.items.set(i, ItemStack.EMPTY);
level.sendBlockUpdated(pos, state, state, 3);
level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state));
@@ -135,6 +_,16 @@
@@ -142,6 +_,16 @@
.ifPresentOrElse(
ints -> System.arraycopy(ints, 0, this.cookingTime, 0, Math.min(this.cookingTime.length, ints.length)), () -> Arrays.fill(this.cookingTime, 0)
);
+
+ // Paper start - Add more Campfire API
+ tag.getByteArray("Paper.StopCooking").ifPresent(bytes -> {
+ input.read("Paper.StopCooking", com.mojang.serialization.Codec.BYTE_BUFFER).ifPresent(bytes -> {
+ final boolean[] cookingState = new boolean[4];
+ for (int index = 0; index < bytes.length; index++) {
+ cookingState[index] = bytes[index] == 1;
+ for (int index = 0; bytes.hasRemaining() && index < cookingState.length; index++) {
+ cookingState[index] = bytes.get() == 1;
+ }
+ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, bytes.length));
+ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, bytes.capacity()));
+ });
+ // Paper end - Add more Campfire API
}
@Override
@@ -143,6 +_,13 @@
ContainerHelper.saveAllItems(tag, this.items, true, registries);
tag.putIntArray("CookingTimes", this.cookingProgress);
tag.putIntArray("CookingTotalTimes", this.cookingTime);
@@ -150,6 +_,13 @@
ContainerHelper.saveAllItems(output, this.items, true);
output.putIntArray("CookingTimes", this.cookingProgress);
output.putIntArray("CookingTotalTimes", this.cookingTime);
+ // Paper start - Add more Campfire API
+ byte[] cookingState = new byte[4];
+ for (int index = 0; index < cookingState.length; index++) {
+ cookingState[index] = (byte) (this.stopCooking[index] ? 1 : 0);
+ }
+ tag.putByteArray("Paper.StopCooking", cookingState);
+ output.store("Paper.StopCooking", com.mojang.serialization.Codec.BYTE_BUFFER, java.nio.ByteBuffer.wrap(cookingState));
+ // Paper end - Add more Campfire API
}
@Override
@@ -167,7 +_,15 @@
@@ -179,7 +_,15 @@
return false;
}

View File

@@ -21,7 +21,7 @@
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
@@ -175,13 +_,19 @@
@@ -175,20 +_,25 @@
if (!entitiesOfClass.isEmpty()) {
for (Player player : entitiesOfClass) {
if (pos.closerThan(player.blockPosition(), i) && player.isInWaterOrRain()) {
@@ -32,31 +32,21 @@
}
}
private static void updateDestroyTarget(Level level, BlockPos pos, BlockState state, List<BlockPos> positions, ConduitBlockEntity blockEntity) {
+ // CraftBukkit start - add "damageTarget" boolean
+ ConduitBlockEntity.updateDestroyTarget(level, pos, state, positions, blockEntity, true);
private static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy) {
+ // CraftBukkit start - add "damageTarget" boolean
+ updateAndAttackTarget(level, pos, state, blockEntity, canDestroy, true);
+ }
+
+ public static void updateDestroyTarget(Level level, BlockPos pos, BlockState state, List<BlockPos> positions, ConduitBlockEntity blockEntity, boolean damageTarget) {
+ // CraftBukkit end
LivingEntity livingEntity = blockEntity.destroyTarget;
int size = positions.size();
if (size < 42) {
@@ -200,7 +_,8 @@
blockEntity.destroyTarget = null;
}
- if (blockEntity.destroyTarget != null) {
+ if (damageTarget && blockEntity.destroyTarget != null) { // CraftBukkit
+ if (blockEntity.destroyTarget.hurtServer((net.minecraft.server.level.ServerLevel) level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit
+ public static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy, boolean damageTarget) {
+ // CraftBukkit end - add "damageTarget" boolean
EntityReference<LivingEntity> entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy);
LivingEntity livingEntity = EntityReference.get(entityReference, level, LivingEntity.class);
- if (livingEntity != null) {
+ if (damageTarget && livingEntity != null) { // CraftBukkit
+ if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit - move up
level.playSound(
null,
blockEntity.destroyTarget.getX(),
@@ -211,7 +_,6 @@
1.0F,
1.0F
null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F
);
- blockEntity.destroyTarget.hurt(level.damageSources().magic(), 4.0F);
- livingEntity.hurtServer(level, level.damageSources().magic(), 4.0F);
}
if (livingEntity != blockEntity.destroyTarget) {
if (!Objects.equals(entityReference, blockEntity.destroyTarget)) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java
@@ -24,6 +_,48 @@
@@ -23,6 +_,48 @@
import net.minecraft.world.ticks.ContainerSingleItem;
public class DecoratedPotBlockEntity extends BlockEntity implements RandomizableContainer, ContainerSingleItem.BlockContainerSingleItem {
@@ -49,18 +49,18 @@
public static final String TAG_SHERDS = "sherds";
public static final String TAG_ITEM = "item";
public static final int EVENT_POT_WOBBLES = 1;
@@ -48,8 +_,8 @@
tag.store("sherds", PotDecorations.CODEC, this.decorations);
@@ -47,8 +_,8 @@
output.store("sherds", PotDecorations.CODEC, this.decorations);
}
- if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) {
- tag.store("item", ItemStack.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.item);
+ if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data
+ tag.store("item", ItemStack.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.item); // Paper - diff on change - hide unnecessary update data
- if (!this.trySaveLootTable(output) && !this.item.isEmpty()) {
- output.store("item", ItemStack.CODEC, this.item);
+ if (!this.trySaveLootTable(output) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data
+ output.store("item", ItemStack.CODEC, this.item); // Paper - diff on change - hide unnecessary update data
}
}
@@ -72,7 +_,14 @@
@@ -70,7 +_,14 @@
@Override
public CompoundTag getUpdateTag(HolderLookup.Provider registries) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
@@ -138,7 +_,12 @@
@@ -140,7 +_,12 @@
public void generate(ServerLevel level, int maxDepth, boolean keepJigsaws) {
BlockPos blockPos = this.getBlockPos().relative(this.getBlockState().getValue(JigsawBlock.ORIENTATION).front());
Registry<StructureTemplatePool> registry = level.registryAccess().lookupOrThrow(Registries.TEMPLATE_POOL);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java
@@ -23,6 +_,44 @@
@@ -20,6 +_,44 @@
import net.minecraft.world.ticks.ContainerSingleItem;
public class JukeboxBlockEntity extends BlockEntity implements ContainerSingleItem.BlockContainerSingleItem {
@@ -45,7 +45,7 @@
public static final String SONG_ITEM_TAG_ID = "RecordItem";
public static final String TICKS_SINCE_SONG_STARTED_TAG_ID = "ticks_since_song_started";
private ItemStack item = ItemStack.EMPTY;
@@ -128,7 +_,7 @@
@@ -123,7 +_,7 @@
@Override
public int getMaxStackSize() {
@@ -54,7 +54,7 @@
}
@Override
@@ -152,11 +_,16 @@
@@ -147,11 +_,16 @@
}
@VisibleForTesting

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/LecternBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/LecternBlockEntity.java
@@ -36,7 +_,53 @@
@@ -33,7 +_,53 @@
public static final int NUM_DATA = 1;
public static final int SLOT_BOOK = 0;
public static final int NUM_SLOTS = 1;
@@ -55,7 +55,7 @@
@Override
public int getContainerSize() {
return 1;
@@ -80,11 +_,19 @@
@@ -77,11 +_,19 @@
@Override
public void setItem(int slot, ItemStack stack) {
@@ -76,7 +76,7 @@
}
@Override
@@ -162,7 +_,7 @@
@@ -159,7 +_,7 @@
if (i != this.page) {
this.page = i;
this.setChanged();
@@ -85,7 +85,7 @@
}
}
@@ -183,6 +_,36 @@
@@ -180,6 +_,36 @@
return stack;
}
@@ -122,7 +122,7 @@
private CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level) {
String string;
Component component;
@@ -195,7 +_,7 @@
@@ -192,7 +_,7 @@
}
Vec3 vec3 = Vec3.atCenterOf(this.worldPosition);
@@ -131,7 +131,7 @@
}
@Override
@@ -237,7 +_,7 @@
@@ -232,7 +_,7 @@
@Override
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {

View File

@@ -1,8 +1,8 @@
--- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
@@ -116,4 +_,13 @@
tag.remove("LootTable");
tag.remove("LootTableSeed");
output.discard("LootTable");
output.discard("LootTableSeed");
}
+
+ // Paper start - LootTable API

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
@@ -24,6 +_,7 @@
@@ -21,6 +_,7 @@
private final VibrationSystem.Listener vibrationListener;
private final VibrationSystem.User vibrationUser;
public int lastVibrationFrequency = 0;
@@ -8,32 +8,31 @@
protected SculkSensorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
@@ -46,15 +_,23 @@
this.lastVibrationFrequency = tag.getIntOr("last_vibration_frequency", 0);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
this.vibrationData = tag.read("listener", VibrationSystem.Data.CODEC, registryOps).orElseGet(VibrationSystem.Data::new);
+ this.rangeOverride = tag.getInt(PAPER_LISTENER_RANGE_NBT_KEY).orElse(null); // Paper start - Configurable sculk sensor listener range
@@ -42,14 +_,22 @@
super.loadAdditional(input);
this.lastVibrationFrequency = input.getIntOr("last_vibration_frequency", 0);
this.vibrationData = input.read("listener", VibrationSystem.Data.CODEC).orElseGet(VibrationSystem.Data::new);
+ this.rangeOverride = input.getInt(PAPER_LISTENER_RANGE_NBT_KEY).orElse(null); // Paper start - Configurable sculk sensor listener range
}
+ protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
tag.putInt("last_vibration_frequency", this.lastVibrationFrequency);
RegistryOps<Tag> registryOps = registries.createSerializationContext(NbtOps.INSTANCE);
tag.store("listener", VibrationSystem.Data.CODEC, registryOps, this.vibrationData);
protected void saveAdditional(ValueOutput output) {
super.saveAdditional(output);
output.putInt("last_vibration_frequency", this.lastVibrationFrequency);
output.store("listener", VibrationSystem.Data.CODEC, this.vibrationData);
- }
+ this.saveRangeOverride(tag); // Paper - Configurable sculk sensor listener range
+ this.saveRangeOverride(output); // Paper - Configurable sculk sensor listener range
+ }
+ // Paper start - Configurable sculk sensor listener range
+ protected void saveRangeOverride(CompoundTag tag) {
+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) tag.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ protected void saveRangeOverride(ValueOutput output) {
+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) output.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
+ }
+ // Paper end - Configurable sculk sensor listener range
@Override
public VibrationSystem.Data getVibrationData() {
@@ -91,6 +_,7 @@
@@ -86,6 +_,7 @@
@Override
public int getListenerRadius() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
@@ -91,6 +_,13 @@
@@ -86,6 +_,13 @@
@Nullable
public static ServerPlayer tryGetPlayer(@Nullable Entity entity) {
@@ -14,7 +14,7 @@
if (entity instanceof ServerPlayer serverPlayer) {
return serverPlayer;
} else if (entity != null && entity.getControllingPassenger() instanceof ServerPlayer serverPlayer) {
@@ -166,7 +_,7 @@
@@ -161,7 +_,7 @@
private boolean trySummonWarden(ServerLevel level) {
return this.warningLevel >= 4
&& SpawnUtil.trySpawnMob(

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SignBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java
@@ -58,10 +_,15 @@
@@ -57,10 +_,15 @@
}
public boolean isFacingFrontText(Player player) {
@@ -18,7 +18,7 @@
float yRotationDegrees = signBlock.getYRotationDegrees(this.getBlockState());
float f = (float)(Mth.atan2(d1, d) * 180.0F / (float)Math.PI) - 90.0F;
return Mth.degreesDifferenceAbs(yRotationDegrees, f) <= 90.0F;
@@ -131,11 +_,13 @@
@@ -128,11 +_,13 @@
public void updateSignText(Player player, boolean isFrontText, List<FilteredText> filteredText) {
if (!this.isWaxed() && player.getUUID().equals(this.getPlayerWhoMayEdit()) && this.level != null) {
@@ -33,7 +33,7 @@
}
}
@@ -144,18 +_,40 @@
@@ -141,19 +_,41 @@
return this.setText(updater.apply(text), isFrontText);
}
@@ -53,7 +53,7 @@
);
}
}
+
+ // CraftBukkit start
+ org.bukkit.entity.Player apiPlayer = ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity();
+ List<net.kyori.adventure.text.Component> lines = new java.util.ArrayList<>(); // Paper - adventure
@@ -74,41 +74,40 @@
+ }
+ }
+ // CraftBukkit end
+
return text;
}
@@ -193,8 +_,24 @@
for (Component component : this.getText(frontText).getMessages(player.isTextFilteringEnabled())) {
@@ -192,7 +_,23 @@
Style style = component.getStyle();
- if (style.getClickEvent() instanceof ClickEvent.RunCommand(String var14)) {
- player.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(player, level, pos), var14);
+ if (style.getClickEvent() instanceof ClickEvent.RunCommand(String var14)) { final String runCommand = var14; // Paper - OBFHELPER
+ // Paper start - Fix commands from signs not firing command events
+ String command = runCommand.startsWith("/") ? runCommand : "/" + runCommand;
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(
+ (org.bukkit.entity.Player) player.getBukkitEntity(),
+ command,
+ new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()),
+ (org.bukkit.block.Sign) org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition).getState(),
+ frontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK
+ );
+ if (!event.callEvent()) {
+ return false;
+ }
+ player.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), level, pos), event.getMessage());
+ // Paper end - Fix commands from signs not firing command events
flag = true;
}
}
@@ -202,10 +_,55 @@
switch (style.getClickEvent()) {
case ClickEvent.RunCommand runCommand:
- level.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(player, level, pos), runCommand.command());
+ // Paper start - Fix commands from signs not firing command events
+ String command = runCommand.command().startsWith("/") ? runCommand.command() : "/" + runCommand.command();
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(
+ (org.bukkit.entity.Player) player.getBukkitEntity(),
+ command,
+ new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()),
+ (org.bukkit.block.Sign) org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition).getState(),
+ isFrontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK
+ );
+ if (!event.callEvent()) {
+ return false;
+ }
+ level.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), level, pos), event.getMessage());
+ // Paper end - Fix commands from signs not firing command events
flag = true;
break;
case ClickEvent.ShowDialog showDialog:
@@ -211,10 +_,55 @@
return flag;
}
- private static CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) {
- private static CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level, BlockPos pos) {
+ // CraftBukkit start
+ private final CommandSource commandSource = new CommandSource() {
+
@@ -136,11 +135,11 @@
+ }
+ };
+
+ private CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) {
+ private CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level, BlockPos pos) {
+ // CraftBukkit end
String string = player == null ? "Sign" : player.getName().getString();
Component component = (Component)(player == null ? Component.literal("Sign") : player.getDisplayName());
- return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player);
- return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player);
+
+ // Paper start - Fix commands from signs not firing command events
+ CommandSource commandSource = level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) {
@@ -158,11 +157,11 @@
+ } : this.commandSource;
+ // Paper end - Fix commands from signs not firing command events
+ // CraftBukkit - this
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events
}
@Override
@@ -224,12 +_,17 @@
@@ -233,12 +_,17 @@
@Nullable
public UUID getPlayerWhoMayEdit() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -40,7 +_,7 @@
@@ -41,7 +_,7 @@
@Nullable
private static LoadingCache<String, CompletableFuture<Optional<GameProfile>>> profileCacheByName;
@Nullable
@@ -9,7 +9,7 @@
public static final Executor CHECKED_MAIN_THREAD_EXECUTOR = runnable -> {
Executor executor = mainThreadExecutor;
if (executor != null) {
@@ -75,9 +_,9 @@
@@ -76,9 +_,9 @@
profileCacheById = CacheBuilder.newBuilder()
.expireAfterAccess(Duration.ofMinutes(10L))
.maximumSize(256L)
@@ -21,7 +21,7 @@
return SkullBlockEntity.fetchProfileById(id, services, booleanSupplier);
}
});
@@ -88,23 +_,29 @@
@@ -89,23 +_,29 @@
.getAsync(name)
.thenCompose(
optional -> {
@@ -56,7 +56,7 @@
}
public static void clear() {
@@ -188,9 +_,11 @@
@@ -189,9 +_,11 @@
: CompletableFuture.completedFuture(Optional.empty());
}

View File

@@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/entity/TestBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TestBlockEntity.java
@@ -36,6 +_,7 @@
@@ -38,6 +_,7 @@
@Override
public void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+ super.loadAdditional(tag, registries); // Paper - load the PDC
this.mode = tag.read("mode", TestBlockMode.CODEC).orElse(TestBlockMode.FAIL);
this.message = tag.getStringOr("message", "");
this.powered = tag.getBooleanOr("powered", false);
protected void loadAdditional(ValueInput input) {
+ super.loadAdditional(input); // Paper - load the PDC
this.mode = input.read("mode", TestBlockMode.CODEC).orElse(TestBlockMode.FAIL);
this.message = input.getStringOr("message", "");
this.powered = input.getBooleanOr("powered", false);

View File

@@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java
@@ -157,6 +_,7 @@
@@ -154,6 +_,7 @@
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+ super.loadAdditional(tag, registries); // Paper - load the PDC
Tag tag1 = tag.get("data");
if (tag1 != null) {
TestInstanceBlockEntity.Data.CODEC.parse(NbtOps.INSTANCE, tag1).ifSuccess(this::set);
@@ -320,7 +_,7 @@
protected void loadAdditional(ValueInput input) {
+ super.loadAdditional(input); // Paper - load the PDC
input.read("data", TestInstanceBlockEntity.Data.CODEC).ifPresent(this::set);
}
@@ -317,7 +_,7 @@
}
private void removeEntities() {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -129,7 +_,7 @@
@@ -131,7 +_,7 @@
@Nullable
public Vec3 getPortalPosition(ServerLevel level, BlockPos pos) {

View File

@@ -1,22 +1,22 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
@@ -238,7 +_,14 @@
nextSpawnData.getEquipment().ifPresent(mob::equip);
}
@@ -214,7 +_,14 @@
nextSpawnData.getEquipment().ifPresent(mob::equip);
}
- if (!level.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason
+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ return Optional.empty();
+ }
+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) {
+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason
return Optional.empty();
} else {
TrialSpawner.FlameParticle flameParticle = this.isOminous ? TrialSpawner.FlameParticle.OMINOUS : TrialSpawner.FlameParticle.NORMAL;
@@ -258,6 +_,19 @@
- if (!level.tryAddFreshEntityWithPassengers(entity)) {
+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason
+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) {
+ return Optional.empty();
+ }
+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) {
+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason
return Optional.empty();
}
@@ -233,6 +_,19 @@
LootParams lootParams = new LootParams.Builder(level).create(LootContextParamSets.EMPTY);
ObjectArrayList<ItemStack> randomItems = lootTable1.getRandomItems(lootParams);
if (!randomItems.isEmpty()) {
@@ -36,3 +36,39 @@
for (ItemStack itemStack : randomItems) {
DefaultDispenseItemBehavior.spawnItem(level, itemStack, 2, Direction.UP, Vec3.atBottomCenterOf(pos).relative(Direction.UP, 1.2));
}
@@ -402,6 +_,35 @@
this.requiredPlayerRange
);
}
+
+ // Paper start - trial spawner API - withers
+ public TrialSpawner.FullConfig overrideTargetCooldownLength(final int targetCooldownLength) {
+ return new TrialSpawner.FullConfig(
+ this.normal,
+ this.ominous,
+ targetCooldownLength,
+ this.requiredPlayerRange
+ );
+ }
+
+ public TrialSpawner.FullConfig overrideRequiredPlayerRange(final int requiredPlayerRange) {
+ return new TrialSpawner.FullConfig(
+ this.normal,
+ this.ominous,
+ this.targetCooldownLength,
+ requiredPlayerRange
+ );
+ }
+
+ public TrialSpawner.FullConfig overrideConfigs(final Holder<TrialSpawnerConfig> normal, final Holder<TrialSpawnerConfig> ominous) {
+ return new TrialSpawner.FullConfig(
+ normal,
+ ominous,
+ this.targetCooldownLength,
+ this.requiredPlayerRange
+ );
+ }
+ // Paper end - trial spawner API - withers
}
public interface StateAccessor {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
@@ -197,7 +_,7 @@
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java
@@ -185,7 +_,7 @@
mob.dropPreservedEquipment(level);
}
@@ -8,4 +8,4 @@
+ entity.remove(Entity.RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause;
}
});
if (!spawner.getOminousConfig().spawnPotentialsDefinition().isEmpty()) {
if (!spawner.ominousConfig().spawnPotentialsDefinition().isEmpty()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
@@ -260,7 +_,12 @@
@@ -257,7 +_,12 @@
if (!list.isEmpty()) {
player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
stack.consume(config.keyItem().getCount(), player);
@@ -14,7 +14,7 @@
serverData.addToRewardedPlayers(player);
sharedData.updateConnectedPlayersWithinRange(level, pos, serverData, config, config.deactivationRange());
}
@@ -269,8 +_,30 @@
@@ -266,8 +_,30 @@
}
static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData) {
@@ -47,7 +47,7 @@
level.setBlock(pos, newState, 3);
vaultState.onTransition(level, pos, vaultState1, config, sharedData, newState.getValue(VaultBlock.OMINOUS));
}
@@ -282,6 +_,11 @@
@@ -279,6 +_,11 @@
ItemStack randomDisplayItemFromLootTable = getRandomDisplayItemFromLootTable(
level, pos, config.overrideLootTableToDisplay().orElse(config.lootTable())
);
@@ -59,7 +59,7 @@
sharedData.setDisplayItem(randomDisplayItemFromLootTable);
}
}
@@ -304,10 +_,24 @@
@@ -301,10 +_,24 @@
VaultSharedData sharedData,
List<ItemStack> itemsToEject
) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -39,7 +_,7 @@
@@ -38,7 +_,7 @@
private static final boolean DEFAULT_EXTENDING = false;
private static final boolean DEFAULT_SOURCE = false;
private BlockState movedState = DEFAULT_BLOCK_STATE;
@@ -9,7 +9,7 @@
private boolean extending = false;
private boolean isSourcePiston = false;
private static final ThreadLocal<Direction> NOCLIP = ThreadLocal.withInitial(() -> null);
@@ -310,7 +_,7 @@
@@ -309,7 +_,7 @@
if (level.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, level, pos);
if (blockState.isAir()) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
@@ -64,7 +_,7 @@
@@ -65,7 +_,7 @@
protected final ShortList[] postProcessing;
private volatile boolean unsaved;
private volatile boolean isLightCorrect;
@@ -9,7 +9,7 @@
private long inhabitedTime;
@Nullable
@Deprecated
@@ -82,6 +_,11 @@
@@ -83,6 +_,11 @@
public final Map<BlockPos, BlockEntity> blockEntities = new Object2ObjectOpenHashMap<>();
protected final LevelHeightAccessor levelHeightAccessor;
protected final LevelChunkSection[] sections;
@@ -21,7 +21,7 @@
public ChunkAccess(
ChunkPos chunkPos,
@@ -92,7 +_,8 @@
@@ -93,7 +_,8 @@
@Nullable LevelChunkSection[] sections,
@Nullable BlendingData blendingData
) {
@@ -31,7 +31,7 @@
this.upgradeData = upgradeData;
this.levelHeightAccessor = levelHeightAccessor;
this.sections = new LevelChunkSection[levelHeightAccessor.getSectionsCount()];
@@ -109,6 +_,7 @@
@@ -110,6 +_,7 @@
}
replaceMissingSections(biomeRegistry, this.sections);
@@ -39,7 +39,7 @@
}
private static void replaceMissingSections(Registry<Biome> biomeRegistry, LevelChunkSection[] sections) {
@@ -123,6 +_,8 @@
@@ -124,6 +_,8 @@
return GameEventListenerRegistry.NOOP;
}
@@ -48,7 +48,7 @@
@Nullable
public BlockState setBlockState(BlockPos pos, BlockState state) {
return this.setBlockState(pos, state, 3);
@@ -278,6 +_,7 @@
@@ -275,6 +_,7 @@
public boolean tryMarkSaved() {
if (this.unsaved) {
this.unsaved = false;
@@ -56,7 +56,7 @@
return true;
} else {
return false;
@@ -285,7 +_,7 @@
@@ -282,7 +_,7 @@
}
public boolean isUnsaved() {
@@ -65,7 +65,7 @@
}
public abstract ChunkStatus getPersistedStatus();
@@ -451,6 +_,22 @@
@@ -448,6 +_,22 @@
throw new ReportedException(crashReport);
}
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -77,7 +_,7 @@
@@ -79,7 +_,7 @@
};
private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = Maps.newHashMap();
public boolean loaded;
@@ -9,7 +9,7 @@
@Nullable
private Supplier<FullChunkStatus> fullStatus;
@Nullable
@@ -86,6 +_,14 @@
@@ -88,6 +_,14 @@
private final LevelChunkTicks<Block> blockTicks;
private final LevelChunkTicks<Fluid> fluidTicks;
private LevelChunk.UnsavedListener unsavedListener = chunkPos -> {};
@@ -24,7 +24,7 @@
public LevelChunk(Level level, ChunkPos pos) {
this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null);
@@ -103,7 +_,7 @@
@@ -105,7 +_,7 @@
@Nullable BlendingData blendingData
) {
super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData);
@@ -33,7 +33,7 @@
this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>();
for (Heightmap.Types types : Heightmap.Types.values()) {
@@ -155,6 +_,10 @@
@@ -157,6 +_,10 @@
this.skyLightSources = chunk.skyLightSources;
this.setLightCorrect(chunk.isLightCorrect());
this.markUnsaved();
@@ -44,7 +44,7 @@
}
public void setUnsavedListener(LevelChunk.UnsavedListener unsavedListener) {
@@ -163,6 +_,12 @@
@@ -165,6 +_,12 @@
unsavedListener.setUnsaved(this.chunkPos);
}
}
@@ -57,7 +57,7 @@
@Override
public void markUnsaved() {
@@ -196,8 +_,28 @@
@@ -198,8 +_,28 @@
: super.getListenerRegistry(sectionY);
}
@@ -86,7 +86,7 @@
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
@@ -232,28 +_,42 @@
@@ -234,28 +_,42 @@
}
}
@@ -131,7 +131,7 @@
}
@Nullable
@@ -313,7 +_,7 @@
@@ -315,7 +_,7 @@
if (!section.getBlockState(i, i1, i2).is(block)) {
return null;
} else {
@@ -140,7 +140,7 @@
state.onPlace(this.level, pos, blockState, flag1);
}
@@ -367,7 +_,12 @@
@@ -369,7 +_,12 @@
@Nullable
public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) {
@@ -154,7 +154,7 @@
if (blockEntity == null) {
CompoundTag compoundTag = this.pendingBlockEntities.remove(pos);
if (compoundTag != null) {
@@ -421,7 +_,13 @@
@@ -424,7 +_,13 @@
BlockPos blockPos = blockEntity.getBlockPos();
BlockState blockState = this.getBlockState(blockPos);
if (!blockState.hasBlockEntity()) {
@@ -169,7 +169,7 @@
} else {
BlockState blockState1 = blockEntity.getBlockState();
if (blockState != blockState1) {
@@ -469,6 +_,11 @@
@@ -472,6 +_,11 @@
public void removeBlockEntity(BlockPos pos) {
if (this.isInLevel()) {
BlockEntity blockEntity = this.blockEntities.remove(pos);
@@ -181,7 +181,7 @@
if (blockEntity != null) {
if (this.level instanceof ServerLevel serverLevel) {
this.removeGameEventListener(blockEntity, serverLevel);
@@ -511,6 +_,65 @@
@@ -514,6 +_,65 @@
}
}
@@ -247,7 +247,7 @@
public boolean isEmpty() {
return false;
}
@@ -719,23 +_,24 @@
@@ -726,23 +_,24 @@
if (this.blockEntity.getType().isValid(blockState)) {
this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
this.loggedInvalidBlockState = false;

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
@@ -30,14 +_,14 @@
@@ -29,14 +_,14 @@
public final IdMap<T> registry;
private volatile PalettedContainer.Data<T> data;
private final PalettedContainer.Strategy strategy;
@@ -18,7 +18,7 @@
}
public static <T> Codec<PalettedContainer<T>> codecRW(IdMap<T> registry, Codec<T> codec, PalettedContainer.Strategy strategy, T value) {
@@ -99,7 +_,7 @@
@@ -98,7 +_,7 @@
}
@Override
@@ -27,7 +27,7 @@
PalettedContainer.Data<T> data = this.data;
PalettedContainer.Data<T> data1 = this.createOrReuseData(data, bits);
data1.copyFrom(data.palette, data.storage);
@@ -107,7 +_,7 @@
@@ -106,7 +_,7 @@
return data1.palette.idFor(objectAdded);
}
@@ -36,7 +36,7 @@
this.acquire();
Object var5;
@@ -130,7 +_,7 @@
@@ -129,7 +_,7 @@
return this.data.palette.valueFor(andSet);
}
@@ -45,7 +45,7 @@
this.acquire();
try {
@@ -163,7 +_,7 @@
@@ -162,7 +_,7 @@
set.forEach(id -> consumer.accept(palette.valueFor(id)));
}
@@ -54,7 +54,7 @@
this.acquire();
try {
@@ -178,7 +_,7 @@
@@ -177,7 +_,7 @@
}
@Override
@@ -63,7 +63,7 @@
this.acquire();
try {
@@ -226,7 +_,7 @@
@@ -225,7 +_,7 @@
}
@Override

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/ProtoChunk.java
+++ b/net/minecraft/world/level/chunk/ProtoChunk.java
@@ -85,14 +_,33 @@
@@ -90,14 +_,33 @@
return new ChunkAccess.PackedTicks(this.blockTicks.pack(gametime), this.fluidTicks.pack(gametime));
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
+++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
@@ -35,7 +_,7 @@
@@ -40,7 +_,7 @@
WorldGenContext worldGenContext, ChunkStep step, StaticCache2D<GenerationChunkHolder> cache, ChunkAccess chunk
) {
ServerLevel serverLevel = worldGenContext.level();
@@ -9,15 +9,15 @@
worldGenContext.generator()
.createStructures(
serverLevel.registryAccess(),
@@ -198,7 +_,58 @@
@@ -207,7 +_,58 @@
public static void postLoadProtoChunk(ServerLevel level, List<CompoundTag> entityTags) {
if (!entityTags.isEmpty()) {
- level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD));
public static void postLoadProtoChunk(ServerLevel level, ValueInput.ValueInputList input) {
if (!input.isEmpty()) {
- level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(input, level, EntitySpawnReason.LOAD));
- }
- }
+ // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities
+ level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD).filter((entity) -> {
+ level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(input, level, EntitySpawnReason.LOAD).filter((entity) -> {
+ boolean needsRemoval = false;
+ net.minecraft.server.dedicated.DedicatedServer server = level.getCraftServer().getServer();
+ if (!level.getChunkSource().spawnFriendlies && (entity instanceof net.minecraft.world.entity.animal.Animal || entity instanceof net.minecraft.world.entity.animal.WaterAnimal)) {

View File

@@ -17,7 +17,7 @@
+ // CraftBukkit end
) {
int version = getVersion(chunkData);
if (version == SharedConstants.getCurrentVersion().getDataVersion().getVersion()) {
if (version == SharedConstants.getCurrentVersion().dataVersion().version()) {
return chunkData;
} else {
try {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
@@ -91,6 +_,7 @@
@@ -93,6 +_,7 @@
List<CompoundTag> entities,
List<CompoundTag> blockEntities,
CompoundTag structureData
@@ -8,7 +8,7 @@
) {
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(
Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState()
@@ -109,12 +_,38 @@
@@ -111,12 +_,38 @@
public static final String BLOCK_LIGHT_TAG = "BlockLight";
public static final String SKY_LIGHT_TAG = "SkyLight";
@@ -26,7 +26,7 @@
+ // Paper end - guard against serializing mismatching coordinates
+
+ // Paper start - Do not let the server load chunks from newer versions
+ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion();
+ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().dataVersion().version();
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion");
+ // Paper end - Do not let the server load chunks from newer versions
+
@@ -48,7 +48,7 @@
long longOr = tag.getLongOr("LastUpdate", 0L);
long longOr1 = tag.getLongOr("InhabitedTime", 0L);
ChunkStatus chunkStatus = tag.read("Status", ChunkStatus.CODEC).orElse(ChunkStatus.EMPTY);
@@ -154,7 +_,7 @@
@@ -156,7 +_,7 @@
ListTag listOrEmpty2 = tag.getListOrEmpty("sections");
List<SerializableChunkData.SectionData> list5 = new ArrayList<>(listOrEmpty2.size());
Registry<Biome> registry = registries.lookupOrThrow(Registries.BIOME);
@@ -57,7 +57,7 @@
for (int i2 = 0; i2 < listOrEmpty2.size(); i2++) {
Optional<CompoundTag> compound = listOrEmpty2.getCompound(i2);
@@ -174,7 +_,7 @@
@@ -176,7 +_,7 @@
Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES
)
);
@@ -66,7 +66,7 @@
.map(
compoundTag1 -> codec.parse(NbtOps.INSTANCE, compoundTag1)
.promotePartial(string -> logErrors(chunkPos, byteOr, string))
@@ -215,6 +_,7 @@
@@ -217,6 +_,7 @@
list3,
list4,
compoundOrEmpty
@@ -74,7 +74,7 @@
);
}
}
@@ -292,6 +_,12 @@
@@ -294,6 +_,12 @@
}
}
@@ -87,7 +87,7 @@
chunkAccess.setLightCorrect(this.lightCorrect);
EnumSet<Heightmap.Types> set = EnumSet.noneOf(Heightmap.Types.class);
@@ -346,6 +_,12 @@
@@ -348,6 +_,12 @@
);
}
@@ -100,7 +100,7 @@
public static SerializableChunkData copyOf(ServerLevel level, ChunkAccess chunk) {
if (!chunk.canBeSerialized()) {
throw new IllegalArgumentException("Chunk can't be serialized: " + chunk);
@@ -404,6 +_,12 @@
@@ -406,6 +_,12 @@
CompoundTag compoundTag = packStructureData(
StructurePieceSerializationContext.fromLevel(level), pos, chunk.getAllStarts(), chunk.getAllReferences()
);
@@ -113,7 +113,7 @@
return new SerializableChunkData(
level.registryAccess().lookupOrThrow(Registries.BIOME),
pos,
@@ -423,6 +_,7 @@
@@ -425,6 +_,7 @@
list2,
list1,
compoundTag
@@ -121,7 +121,7 @@
);
}
}
@@ -489,6 +_,11 @@
@@ -491,6 +_,11 @@
this.heightmaps.forEach((types, longs) -> compoundTag2.put(types.getSerializationKey(), new LongArrayTag(longs)));
compoundTag.put("Heightmaps", compoundTag2);
compoundTag.put("structures", this.structureData);
@@ -133,7 +133,7 @@
return compoundTag;
}
@@ -562,6 +_,12 @@
@@ -572,6 +_,12 @@
} else {
StructureStart structureStart = StructureStart.loadStaticStart(context, compoundOrEmpty.getCompoundOrEmpty(string), seed);
if (structureStart != null) {

View File

@@ -141,7 +141,7 @@
@@ -231,14 +_,20 @@
}
private void processPendingLoads() {
public void processPendingLoads() {
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk process pending loads"); // Paper
ChunkEntities<T> chunkEntities;
while ((chunkEntities = this.loadingInbox.poll()) != null) {

View File

@@ -12,11 +12,12 @@
FluidState fluidState = level.getFluidState(worldPos);
if (!fluidState.isEmpty()) {
level.scheduleTick(worldPos, fluidState.getType(), 0);
@@ -193,6 +_,39 @@
@@ -193,6 +_,48 @@
}
}
+ // CraftBukkit start
+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger();
+ protected boolean placeCraftBlockEntity(ServerLevelAccessor levelAccessor, BlockPos pos, org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState, int flags) {
+ if (levelAccessor instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess && transformerAccess.canTransformBlocks()) {
+ return transformerAccess.setCraftBlock(pos, craftBlockEntityState, flags);
@@ -25,7 +26,15 @@
+ boolean result = levelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags);
+ BlockEntity blockEntity = levelAccessor.getBlockEntity(pos);
+ if (blockEntity != null) {
+ blockEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), levelAccessor.registryAccess());
+ try (final net.minecraft.util.ProblemReporter.ScopedCollector problemReporter = new net.minecraft.util.ProblemReporter.ScopedCollector(
+ () -> "StructurePieceTranformers@" + pos.toShortString(), LOGGER
+ )) {
+ blockEntity.loadWithComponents(net.minecraft.world.level.storage.TagValueInput.create(
+ problemReporter,
+ levelAccessor.registryAccess(),
+ craftBlockEntityState.getSnapshotNBT()
+ ));
+ }
+ }
+ return result;
+ }

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
@@ -73,6 +_,10 @@
@@ -79,6 +_,10 @@
public final List<StructureTemplate.StructureEntityInfo> entityInfoList = Lists.newArrayList();
private Vec3i size = Vec3i.ZERO;
private String author = "?";
@@ -11,7 +11,7 @@
public Vec3i getSize() {
return this.size;
@@ -247,6 +_,19 @@
@@ -255,6 +_,19 @@
if (this.palettes.isEmpty()) {
return false;
} else {
@@ -31,83 +31,83 @@
List<StructureTemplate.StructureBlockInfo> list = settings.getRandomPalette(this.palettes, offset).blocks();
if ((!list.isEmpty() || !settings.isIgnoreEntities() && !this.entityInfoList.isEmpty())
&& this.size.getX() >= 1
@@ -272,6 +_,21 @@
serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 820);
}
@@ -282,6 +_,21 @@
serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 820);
}
+ // CraftBukkit start
+ if (structureTransformer != null) {
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null);
+ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> entityState) {
+ entityState.loadData(structureBlockInfo.nbt);
+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable<?> craftLootable) {
+ craftLootable.setSeed(random.nextLong());
+ // CraftBukkit start
+ if (structureTransformer != null) {
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null);
+ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> entityState) {
+ entityState.loadData(structureBlockInfo.nbt);
+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable<?> craftLootable) {
+ craftLootable.setSeed(random.nextLong());
+ }
+ }
+ craftBlockState = structureTransformer.transformCraftState(craftBlockState);
+ blockState = craftBlockState.getHandle();
+ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null));
+ }
+ craftBlockState = structureTransformer.transformCraftState(craftBlockState);
+ blockState = craftBlockState.getHandle();
+ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null));
+ }
+ // CraftBukkit end
+ // CraftBukkit end
+
if (serverLevel.setBlock(blockPos, blockState, flags)) {
i = Math.min(i, blockPos.getX());
i1 = Math.min(i1, blockPos.getY());
@@ -283,7 +_,7 @@
if (structureBlockInfo.nbt != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity != null) {
- if (blockEntity instanceof RandomizableContainer) {
+ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above
structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong());
}
if (serverLevel.setBlock(blockPos, blockState, flags)) {
i = Math.min(i, blockPos.getX());
i1 = Math.min(i1, blockPos.getY());
@@ -293,7 +_,7 @@
if (structureBlockInfo.nbt != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity != null) {
- if (blockEntity instanceof RandomizableContainer) {
+ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above
structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong());
}
@@ -366,7 +_,11 @@
if (pair1.getSecond() != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4);
if (blockEntity != null) {
- blockEntity.setChanged();
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
+ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) {
+ blockEntity.setChanged();
+ }
+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock
@@ -380,7 +_,11 @@
if (pair1.getSecond() != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4);
if (blockEntity != null) {
- blockEntity.setChanged();
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
+ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) {
+ blockEntity.setChanged();
+ }
+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock
}
}
}
}
@@ -374,7 +_,7 @@
@@ -388,7 +_,7 @@
if (!settings.isIgnoreEntities()) {
this.placeEntities(
- serverLevel,
+ wrappedAccess, // CraftBukkit
offset,
settings.getMirror(),
settings.getRotation(),
@@ -488,14 +_,17 @@
);
if (!settings.isIgnoreEntities()) {
this.placeEntities(
- serverLevel,
+ wrappedAccess, // CraftBukkit
offset,
settings.getMirror(),
settings.getRotation(),
@@ -499,14 +_,17 @@
});
}
}
+
}
private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor level, CompoundTag tag) {
private static Optional<Entity> createEntityIgnoreException(ProblemReporter problemReporter, ServerLevelAccessor level, CompoundTag tag) {
- try {
- return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE);
- } catch (Exception var3) {
- return EntityType.create(TagValueInput.create(problemReporter, level.registryAccess(), tag), level.getLevel(), EntitySpawnReason.STRUCTURE);
- } catch (Exception var4) {
- return Optional.empty();
- }
+ // CraftBukkit start
+ // try {
+ return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation
+ // } catch (Exception var3) {
+ return EntityType.create(TagValueInput.create(problemReporter, level.registryAccess(), tag), level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation
+ // } catch (Exception var4) {
+ // return Optional.empty();
+ // }
+ // CraftBukkit end
}
public Vec3i getSize(Rotation rotation) {
@@ -688,6 +_,11 @@
@@ -699,6 +_,11 @@
tag.put("entities", listTag3);
tag.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ()));
@@ -119,7 +119,7 @@
return NbtUtils.addCurrentDataVersion(tag);
}
@@ -718,6 +_,11 @@
@@ -729,6 +_,11 @@
.ifPresent(compoundTag1 -> this.entityInfoList.add(new StructureTemplate.StructureEntityInfo(vec3, blockPos, compoundTag1)));
}
);
@@ -131,7 +131,7 @@
}
private void loadPalette(HolderGetter<Block> blockGetter, ListTag paletteTag, ListTag blocksTag) {
@@ -817,7 +_,7 @@
@@ -828,7 +_,7 @@
public static final class Palette {
private final List<StructureTemplate.StructureBlockInfo> blocks;

View File

@@ -140,7 +140,7 @@
BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1))
+ .forEach(pos -> this.blocks.setBlock(pos, blockState, 18));
+ org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) this.blocks.getSnapshotBlocks(), bworld, (entity == null) ? null : entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.FIRE);
+ level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event);
+ level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event); // todo the list is not really mutable here unlike other call and the portal frame is included
+
+ if (event.isCancelled()) {
+ return false;

View File

@@ -59,22 +59,13 @@
}
public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) {
- this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), postTeleportTransition);
- this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition);
+ // CraftBukkit start
+ this(level, entity, postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ }
+ public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) {
+ this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition, cause); // Paper - MC-200092 - fix first spawn pos yaw being ignored
+ this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition, cause);
+ // CraftBukkit end
}
private static void playPortalSound(Entity entity) {
@@ -57,7 +_,7 @@
}
public static TeleportTransition missingRespawnBlock(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) {
- return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, true, false, Set.of(), postTeleportTransition);
+ return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, true, false, Set.of(), postTeleportTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored
}
private static Vec3 findAdjustedSharedSpawnPos(ServerLevel level, Entity entity) {

View File

@@ -1,19 +1,19 @@
--- a/net/minecraft/world/level/storage/PlayerDataStorage.java
+++ b/net/minecraft/world/level/storage/PlayerDataStorage.java
@@ -31,6 +_,7 @@
@@ -32,6 +_,7 @@
}
public void save(Player player) {
+ if (org.spigotmc.SpigotConfig.disablePlayerDataSaving) return; // Spigot
try {
CompoundTag compoundTag = player.saveWithoutId(new CompoundTag());
Path path = this.playerDir.toPath();
@@ -40,30 +_,46 @@
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), LOGGER)) {
TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector, player.registryAccess());
player.saveWithoutId(tagValueOutput);
@@ -43,30 +_,46 @@
Path path3 = path.resolve(player.getStringUUID() + ".dat_old");
Util.safeReplaceFile(path2, path1, path3);
} catch (Exception var7) {
} catch (Exception var11) {
- LOGGER.warn("Failed to save player data for {}", player.getName().getString());
+ LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), var7); // Paper - Print exception
+ LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), var11); // Paper - Print exception
}
}
@@ -64,13 +64,13 @@
}
}
@@ -71,16 +_,40 @@
@@ -74,17 +_,40 @@
}
public Optional<CompoundTag> load(Player player) {
public Optional<ValueInput> load(Player player, ProblemReporter problemReporter) {
- Optional<CompoundTag> optional = this.load(player, ".dat");
+ // CraftBukkit start
+ return this.load(player.getName().getString(), player.getStringUUID()).map((tag) -> {
+ return this.load(player.getName().getString(), player.getStringUUID(), problemReporter).map((tag) -> {
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
+ org.bukkit.craftbukkit.entity.CraftPlayer craftPlayer = serverPlayer.getBukkitEntity();
+ // Only update first played if it is older than the one we have
@@ -80,12 +80,13 @@
+ }
+ }
+
+ player.load(tag); // From below
+ return tag;
+ ValueInput valueInput = TagValueInput.create(problemReporter, player.registryAccess(), tag);
+ player.load(valueInput); // From below
+ return valueInput;
+ });
+ }
+
+ public Optional<CompoundTag> load(String name, String uuid) {
+ public Optional<CompoundTag> load(String name, String uuid, ProblemReporter problemReporter) {
+ // CraftBukkit end
+ Optional<CompoundTag> optional = this.load(name, uuid, ".dat"); // CraftBukkit
if (optional.isEmpty()) {
@@ -97,9 +98,10 @@
+ return optional.or(() -> this.load(name, uuid, ".dat_old")).map(compoundTag -> { // CraftBukkit
int dataVersion = NbtUtils.getDataVersion(compoundTag, -1);
compoundTag = DataFixTypes.PLAYER.updateToCurrentVersion(this.fixerUpper, compoundTag, dataVersion);
- player.load(compoundTag);
+ // player.load(compoundTag); // CraftBukkit - handled above
return compoundTag;
- ValueInput valueInput = TagValueInput.create(problemReporter, player.registryAccess(), compoundTag);
- player.load(valueInput);
- return valueInput;
+ return compoundTag; // CraftBukkit - handled above
});
}
+

View File

@@ -0,0 +1,18 @@
--- a/net/minecraft/world/level/storage/TagValueInput.java
+++ b/net/minecraft/world/level/storage/TagValueInput.java
@@ -37,6 +_,15 @@
this.input = input;
}
+ // Paper start - utility methods
+ public static ValueInput createGlobal(
+ final ProblemReporter problemReporter,
+ final CompoundTag compoundTag
+ ) {
+ return create(problemReporter, net.minecraft.server.MinecraftServer.getServer().registryAccess(), compoundTag);
+ }
+ // Paper end - utility methods
+
public static ValueInput create(ProblemReporter problemReporter, HolderLookup.Provider lookup, CompoundTag input) {
return new TagValueInput(problemReporter, new ValueInputContextHelper(lookup, NbtOps.INSTANCE), input);
}

View File

@@ -0,0 +1,26 @@
--- a/net/minecraft/world/level/storage/TagValueOutput.java
+++ b/net/minecraft/world/level/storage/TagValueOutput.java
@@ -24,6 +_,23 @@
this.output = tag;
}
+ // Paper start - utility methods
+ public static TagValueOutput createWrappingGlobal(
+ final ProblemReporter problemReporter,
+ final CompoundTag compoundTag
+ ) {
+ return new TagValueOutput(problemReporter, NbtOps.INSTANCE, compoundTag);
+ }
+
+ public static TagValueOutput createWrappingWithContext(
+ final ProblemReporter problemReporter,
+ final HolderLookup.Provider lookup,
+ final CompoundTag compoundTag
+ ) {
+ return new TagValueOutput(problemReporter, lookup.createSerializationContext(NbtOps.INSTANCE), compoundTag);
+ }
+ // Paper end - utility methods
+
public static TagValueOutput createWithContext(ProblemReporter problemReporter, HolderLookup.Provider lookup) {
return new TagValueOutput(problemReporter, lookup.createSerializationContext(NbtOps.INSTANCE), new CompoundTag());
}

View File

@@ -1,16 +1,16 @@
--- a/net/minecraft/world/level/storage/loot/LootDataType.java
+++ b/net/minecraft/world/level/storage/loot/LootDataType.java
@@ -31,9 +_,14 @@
@@ -32,9 +_,14 @@
}
private static LootDataType.Validator<LootTable> createLootTableValidator() {
- return (context, key, value) -> value.validate(
- context.setContextKeySet(value.getParamSet()).enterElement("{" + key.registry() + "/" + key.location() + "}", key)
- context.setContextKeySet(value.getParamSet()).enterElement(new ProblemReporter.RootElementPathElement(key), key)
- );
+ // CraftBukkit start
+ return (context, key, value) -> {
+ value.validate(
+ context.setContextKeySet(value.getParamSet()).enterElement("{" + key.registry() + "/" + key.location() + "}", key)
+ context.setContextKeySet(value.getParamSet()).enterElement(new ProblemReporter.RootElementPathElement(key), key)
+ );
+ value.craftLootTable = new org.bukkit.craftbukkit.CraftLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(key.location()), value);
+ // CraftBukkit end

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/storage/loot/LootTable.java
+++ b/net/minecraft/world/level/storage/loot/LootTable.java
@@ -52,6 +_,7 @@
@@ -53,6 +_,7 @@
private final List<LootPool> pools;
private final List<LootItemFunction> functions;
private final BiFunction<ItemStack, LootContext, ItemStack> compositeFunction;
@@ -8,7 +8,7 @@
LootTable(ContextKeySet paramSet, Optional<ResourceLocation> randomSequence, List<LootPool> pools, List<LootItemFunction> functions) {
this.paramSet = paramSet;
@@ -62,9 +_,10 @@
@@ -63,9 +_,10 @@
}
public static Consumer<ItemStack> createStackSplitter(ServerLevel level, Consumer<ItemStack> output) {
@@ -20,7 +20,7 @@
output.accept(itemStack);
} else {
int count = itemStack.getCount();
@@ -145,9 +_,22 @@
@@ -146,9 +_,22 @@
}
public void fill(Container container, LootParams params, long seed) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
+++ b/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
@@ -32,6 +_,10 @@
@@ -33,6 +_,10 @@
);
}
};
@@ -11,7 +11,7 @@
protected LootPoolSingletonContainer(int weight, int quality, List<LootItemCondition> conditions, List<LootItemFunction> functions) {
super(conditions);
@@ -126,7 +_,31 @@
@@ -127,7 +_,31 @@
protected abstract class EntryBase implements LootPoolEntry {
@Override
public int getWeight(float luck) {