diff --git a/build-data/paper.at b/build-data/paper.at index f42afed8e5..013280cb0b 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -140,6 +140,7 @@ public net.minecraft.world.effect.MobEffect attributeModifiers public net.minecraft.world.effect.MobEffect$AttributeTemplate public net.minecraft.world.effect.MobEffectInstance hiddenEffect public net.minecraft.world.entity.AreaEffectCloud durationOnUse +public net.minecraft.world.entity.AreaEffectCloud owner public net.minecraft.world.entity.AreaEffectCloud potionContents public net.minecraft.world.entity.AreaEffectCloud radiusOnUse public net.minecraft.world.entity.AreaEffectCloud radiusPerTick @@ -678,6 +679,7 @@ public net.minecraft.world.level.chunk.LevelChunk level public net.minecraft.world.level.chunk.LevelChunk loaded public net.minecraft.world.level.chunk.LevelChunkSection states public net.minecraft.world.level.chunk.PalettedContainer registry +public net.minecraft.world.level.chunk.status.ChunkStatusTasks postLoadProtoChunk(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/storage/ValueInput$ValueInputList;)V public net.minecraft.world.level.chunk.storage.EntityStorage entityDeserializerQueue public net.minecraft.world.level.chunk.storage.EntityStorage level public net.minecraft.world.level.chunk.storage.RegionFileStorage regionCache diff --git a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch index d736409b62..d2634384c2 100644 --- a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch +++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -1,0 +_,241 @@ +@@ -1,0 +_,249 @@ +package ca.spottedleaf.moonrise.paper; + +import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -150,6 +150,11 @@ + } + + @Override ++ public long[] getCounterTypesUncached(final net.minecraft.server.level.TicketType type) { ++ return new long[0]; ++ } ++ ++ @Override + public boolean configFixMC224294() { + return true; + } @@ -234,7 +239,10 @@ + + @Override + public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { -+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); ++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk( ++ world, ++ net.minecraft.world.level.storage.TagValueInput.create(net.minecraft.util.ProblemReporter.DISCARDING, world.registryAccess(), chunk.getEntities()) ++ ); + } + + @Override diff --git a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch index 3f95b375a8..71b326b986 100644 --- a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch +++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch @@ -300,7 +300,7 @@ + + @Override + public int getViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + if (level == null) { + return Bukkit.getViewDistance(); + } @@ -309,7 +309,7 @@ + + @Override + public int getTickViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + if (level == null) { + return Bukkit.getSimulationDistance(); + } diff --git a/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch b/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch index cdbc56fdd1..bfc7cf4e96 100644 --- a/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch +++ b/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch @@ -64,7 +64,7 @@ + + public static Set getSentChunks(final ServerPlayer player) { + final ObjectSet chunks = new ObjectOpenHashSet<>(); -+ final World world = player.serverLevel().getWorld(); ++ final World world = player.level().getWorld(); + player.getChunkTrackingView().forEach(pos -> { + final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey); + chunks.add(chunk); diff --git a/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch b/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch index d39db32c3a..4a154e157e 100644 --- a/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch @@ -16,7 +16,7 @@ if (entitySelector.getMaxResults() > 1 && this.single) { if (this.playersOnly) { reader.setCursor(0); -@@ -129,7 +_,12 @@ +@@ -129,7 +_,13 @@ if (context.getSource() instanceof SharedSuggestionProvider sharedSuggestionProvider) { StringReader stringReader = new StringReader(builder.getInput()); stringReader.setCursor(builder.getStart()); @@ -24,7 +24,8 @@ + // Paper start - Fix EntityArgument permissions + final boolean permission = sharedSuggestionProvider instanceof CommandSourceStack stack + ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector") -+ : sharedSuggestionProvider.hasPermission(2); ++ // Only CommandSourceStack implements SharedSuggestionProvider. If *somehow* anything else ends up here, try to query its permission level, otherwise yield false. ++ : (sharedSuggestionProvider instanceof final net.minecraft.commands.PermissionSource permissionSource && permissionSource.hasPermission(2)); + EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission); + // Paper end - Fix EntityArgument permissions diff --git a/paper-server/patches/sources/net/minecraft/server/Main.java.patch b/paper-server/patches/sources/net/minecraft/server/Main.java.patch index b5d94d21fb..1e32c74c86 100644 --- a/paper-server/patches/sources/net/minecraft/server/Main.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/Main.java.patch @@ -141,7 +141,7 @@ + "pack_format": %d + } + } -+ """.formatted(SharedConstants.getCurrentVersion().getPackVersion(net.minecraft.server.packs.PackType.SERVER_DATA)) ++ """.formatted(SharedConstants.getCurrentVersion().packVersion(net.minecraft.server.packs.PackType.SERVER_DATA)) + ); + } catch (java.io.IOException ex) { + throw new RuntimeException("Could not initialize Bukkit datapack", ex); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index eee7778a78..3553abdf60 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -1564,7 +1564,7 @@ public void onItemPickup(ItemEntity itemEntity) { - Entity owner = itemEntity.getOwner(); -+ Entity owner = itemEntity.thrower != null ? itemEntity.thrower.getEntity(this.level()::getGlobalPlayerByUUID, Entity.class) : null; // Paper - check global player list where appropriate ++ Entity owner = EntityReference.get(itemEntity.thrower, this.level()::getGlobalPlayerByUUID, Entity.class); // Paper - check global player list where appropriate if (owner instanceof ServerPlayer) { CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.trigger((ServerPlayer)owner, itemEntity.getItem(), this); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch index ac186e3605..1ba0031bec 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch @@ -5,7 +5,7 @@ LivingEntity livingEntity = instance.get(memoryAccessor); if (entity.closerThan(livingEntity, followRange.getMaxValue() + 1) && !entity.closerThan(livingEntity, followRange.getMinValue())) { + // CraftBukkit start -+ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(mob, ageableMob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER); ++ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(entity, livingEntity, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER); + if (event.isCancelled()) { + return false; + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch index 57b67674cb..a6ccd9f317 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -186,7 +186,7 @@ - if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - ExperienceOrb.award(serverLevel, this.position(), Mth.floor(i * 0.08F)); + if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp -+ ExperienceOrb.awardWithDirection(serverLevel, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.Optionull.map(this.lastHurtByPlayer, lastHurtByPlayer -> lastHurtByPlayer.getEntity(this.level(), Player.class)), this); // Paper ++ ExperienceOrb.awardWithDirection(serverLevel, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.world.entity.EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class), this); // Paper } if (this.dragonDeathTime == 1 && !this.isSilent()) { @@ -220,7 +220,7 @@ - if (serverLevel1.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - ExperienceOrb.award(serverLevel1, this.position(), Mth.floor(i * 0.2F)); + if (true) { // Paper - SPIGOT-2420: Already checked for the game rule when calculating the xp -+ ExperienceOrb.awardWithDirection(serverLevel1, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.Optionull.map(this.lastHurtByPlayer, lastHurtByPlayer -> lastHurtByPlayer.getEntity(this.level(), Player.class)), this); // Paper ++ ExperienceOrb.awardWithDirection(serverLevel1, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.world.entity.EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class), this); // Paper } if (this.dragonFight != null) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch index fae0a7a1dd..1cad2ef152 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch @@ -11,7 +11,7 @@ + // CraftBukkit start + @Nullable + public Entity getTarget() { -+ return this.finalTarget.getEntity(this.level(), Entity.class); ++ return EntityReference.get(this.finalTarget, this.level(), Entity.class); + } + + public void setTarget(@Nullable Entity finalTarget) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch index 6783a13227..d963210594 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch @@ -11,7 +11,7 @@ serverLevel.registryAccess(), @@ -207,7 +_,58 @@ - private static void postLoadProtoChunk(ServerLevel level, ValueInput.ValueInputList input) { + public static void postLoadProtoChunk(ServerLevel level, ValueInput.ValueInputList input) { if (!input.isEmpty()) { - level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(input, level, EntitySpawnReason.LOAD)); - } diff --git a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java index a786d75794..804bb4fa38 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java @@ -59,7 +59,6 @@ public class MobGoalHelper { bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class); bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class); - bukkitMap.put(net.minecraft.world.entity.FlyingMob.class, Flying.class); bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java index f38992f1eb..21443c9cbb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java @@ -119,23 +119,17 @@ public class CraftConduit extends CraftBlockEntityState impl return null; } - final EntityReference entityReference = conduit.destroyTarget; - if (entityReference == null) return null; - - final net.minecraft.world.entity.LivingEntity resolvedTarget = entityReference.getEntity(this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class); - return resolvedTarget == null ? null : resolvedTarget.getBukkitLivingEntity(); + final net.minecraft.world.entity.LivingEntity nmsEntity = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class); + return nmsEntity == null ? null : nmsEntity.getBukkitLivingEntity(); } @Override public boolean hasTarget() { ConduitBlockEntity conduit = (ConduitBlockEntity) this.getBlockEntityFromWorld(); - return conduit != null - && conduit.destroyTarget != null - && Optionull.mapOrDefault( - conduit.destroyTarget.getEntity(this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class), - net.minecraft.world.entity.LivingEntity::isAlive, - false - ); + if (conduit == null) return false; + + final net.minecraft.world.entity.LivingEntity destroyTarget = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class); + return destroyTarget != null && destroyTarget.isAlive(); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java index 30dea480db..443924114a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java @@ -3,9 +3,11 @@ package org.bukkit.craftbukkit.entity; import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Optional; +import net.minecraft.Optionull; import net.minecraft.core.Holder; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.item.alchemy.PotionContents; import org.bukkit.Color; import org.bukkit.Particle; @@ -115,7 +117,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud @Override public void setParticle(Particle particle, T data) { - this.getHandle().setParticle(CraftParticle.createParticleParam(particle, data)); + this.getHandle().setCustomParticle(CraftParticle.createParticleParam(particle, data)); } @Override @@ -226,13 +228,12 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud // Paper start - owner API @Override public java.util.UUID getOwnerUniqueId() { - return this.getHandle().ownerUUID; + return Optionull.map(this.getHandle().owner, EntityReference::getUUID); } @Override public void setOwnerUniqueId(final java.util.UUID ownerUuid) { - this.getHandle().setOwner(null); - this.getHandle().ownerUUID = ownerUuid; + this.getHandle().owner = new EntityReference<>(ownerUuid); } // Paper end } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index e8371e5153..ac3550c65c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -72,7 +72,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getBodyPose() { - return CraftArmorStand.fromNMS(this.getHandle().bodyPose); + return CraftArmorStand.fromNMS(this.getHandle().getBodyPose()); } @Override @@ -82,7 +82,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getLeftArmPose() { - return CraftArmorStand.fromNMS(this.getHandle().leftArmPose); + return CraftArmorStand.fromNMS(this.getHandle().getLeftArmPose()); } @Override @@ -92,7 +92,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getRightArmPose() { - return CraftArmorStand.fromNMS(this.getHandle().rightArmPose); + return CraftArmorStand.fromNMS(this.getHandle().getRightArmPose()); } @Override @@ -102,7 +102,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getLeftLegPose() { - return CraftArmorStand.fromNMS(this.getHandle().leftLegPose); + return CraftArmorStand.fromNMS(this.getHandle().getLeftLegPose()); } @Override @@ -112,7 +112,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getRightLegPose() { - return CraftArmorStand.fromNMS(this.getHandle().rightLegPose); + return CraftArmorStand.fromNMS(this.getHandle().getRightLegPose()); } @Override @@ -122,7 +122,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getHeadPose() { - return CraftArmorStand.fromNMS(this.getHandle().headPose); + return CraftArmorStand.fromNMS(this.getHandle().getHeadPose()); } @Override @@ -293,7 +293,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getBodyRotations() { - return fromNMSRotations(this.getHandle().bodyPose); + return fromNMSRotations(this.getHandle().getBodyPose()); } @Override @@ -303,7 +303,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getLeftArmRotations() { - return fromNMSRotations(this.getHandle().leftArmPose); + return fromNMSRotations(this.getHandle().getLeftArmPose()); } @Override @@ -313,7 +313,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getRightArmRotations() { - return fromNMSRotations(this.getHandle().rightArmPose); + return fromNMSRotations(this.getHandle().getRightArmPose()); } @Override @@ -323,7 +323,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getLeftLegRotations() { - return fromNMSRotations(this.getHandle().leftLegPose); + return fromNMSRotations(this.getHandle().getLeftLegPose()); } @Override @@ -333,7 +333,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getRightLegRotations() { - return fromNMSRotations(this.getHandle().rightLegPose); + return fromNMSRotations(this.getHandle().getRightLegPose()); } @Override @@ -343,7 +343,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getHeadRotations() { - return fromNMSRotations(this.getHandle().headPose); + return fromNMSRotations(this.getHandle().getHeadPose()); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java index 59ef331b2f..c4ac10b88f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java @@ -4,8 +4,11 @@ import com.google.common.base.Preconditions; import java.util.function.Function; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Entity; import org.bukkit.entity.EntitySnapshot; @@ -55,7 +58,7 @@ public class CraftEntitySnapshot implements EntitySnapshot { } Preconditions.checkArgument(internal != null, "Error creating new entity."); // This should only fail if the stored CompoundTag is malformed. - internal.load(this.data); + internal.load(TagValueInput.createGlobalDiscarding(this.data)); return internal; } @@ -65,12 +68,12 @@ public class CraftEntitySnapshot implements EntitySnapshot { } public static CraftEntitySnapshot create(CraftEntity entity) { - CompoundTag tag = new CompoundTag(); - if (!entity.getHandle().saveAsPassenger(tag, false, false, false)) { + final TagValueOutput output = TagValueOutput.createDiscardingWithContext(CraftRegistry.getMinecraftRegistry()); + if (!entity.getHandle().saveAsPassenger(output, false, false, false)) { return null; } - return new CraftEntitySnapshot(tag, entity.getType()); + return new CraftEntitySnapshot(output.buildResult(), entity.getType()); } public static CraftEntitySnapshot create(CompoundTag tag, EntityType type) { @@ -82,7 +85,9 @@ public class CraftEntitySnapshot implements EntitySnapshot { } public static CraftEntitySnapshot create(CompoundTag tag) { - EntityType type = net.minecraft.world.entity.EntityType.by(tag).map(CraftEntityType::minecraftToBukkit).orElse(null); + EntityType type = net.minecraft.world.entity.EntityType.by( + TagValueInput.createGlobalDiscarding(tag) + ).map(CraftEntityType::minecraftToBukkit).orElse(null); return CraftEntitySnapshot.create(tag, type); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java index ca656d97a0..bb2f1e805e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -1,7 +1,9 @@ package org.bukkit.craftbukkit.entity; -import java.util.UUID; import com.google.common.base.Preconditions; +import java.util.UUID; +import net.minecraft.Optionull; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.entity.item.ItemEntity; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -136,11 +138,11 @@ public class CraftItem extends CraftEntity implements Item { @Override public void setThrower(UUID uuid) { - this.getHandle().thrower = uuid; + this.getHandle().thrower = new EntityReference<>(uuid); } @Override public UUID getThrower() { - return this.getHandle().thrower; + return Optionull.map(this.getHandle().thrower, EntityReference::getUUID); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java index 704635f202..2766c70ef7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java @@ -8,6 +8,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.util.random.WeightedList; import net.minecraft.world.entity.vehicle.MinecartSpawner; import net.minecraft.world.level.SpawnData; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.block.spawner.SpawnRule; import org.bukkit.block.spawner.SpawnerEntry; import org.bukkit.craftbukkit.CraftServer; @@ -34,7 +35,9 @@ public class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMin return null; } - Optional> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn()); + Optional> type = net.minecraft.world.entity.EntityType.by( + TagValueInput.createGlobalDiscarding(spawnData.getEntityToSpawn()) + ); return type.map(CraftEntityType::minecraftToBukkit).orElse(null); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java index eea78db7f1..4a62bd61ad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.entity.item.PrimedTnt; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Entity; @@ -57,7 +58,7 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { @Override public void setSource(Entity source) { if (source instanceof LivingEntity) { - this.getHandle().owner = ((CraftLivingEntity) source).getHandle(); + this.getHandle().owner = new EntityReference<>(((CraftLivingEntity) source).getHandle()); } else { this.getHandle().owner = null; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 07c305b862..5ceb08265f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -882,7 +882,7 @@ public class CraftEventFactory { public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean showDeathMessages, boolean keepInventory) { CraftPlayer entity = victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); - PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage, showDeathMessages); + PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.level(), damageSource.getEntity()), 0, deathMessage, showDeathMessages); event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java index e48620d68b..4ac73b2f9b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java @@ -116,7 +116,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setSlot(EquipmentSlot slot) { - this.handle = new Equippable(CraftEquipmentSlot.getNMS(slot), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(CraftEquipmentSlot.getNMS(slot), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -126,7 +126,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setEquipSound(Sound sound) { - this.handle = new Equippable(this.handle.slot(), (sound != null) ? CraftSound.bukkitToMinecraftHolder(sound) : SoundEvents.ARMOR_EQUIP_GENERIC, this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), (sound != null) ? CraftSound.bukkitToMinecraftHolder(sound) : SoundEvents.ARMOR_EQUIP_GENERIC, this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -136,7 +136,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setModel(NamespacedKey key) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft).map((k) -> ResourceKey.create(EquipmentAssets.ROOT_ID, k)), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft).map((k) -> ResourceKey.create(EquipmentAssets.ROOT_ID, k)), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -146,7 +146,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setCameraOverlay(NamespacedKey key) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -158,7 +158,7 @@ public final class CraftEquippableComponent implements EquippableComponent { public void setAllowedEntities(EntityType entities) { this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), (entities != null) ? Optional.of(HolderSet.direct(CraftEntityType.bukkitToMinecraftHolder(entities))) : Optional.empty(), - this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract() + this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound() ); } @@ -166,7 +166,7 @@ public final class CraftEquippableComponent implements EquippableComponent { public void setAllowedEntities(Collection entities) { this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), (entities != null) ? Optional.of(HolderSet.direct(entities.stream().map(CraftEntityType::bukkitToMinecraftHolder).collect(Collectors.toList()))) : Optional.empty(), - this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract() + this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound() ); } @@ -176,7 +176,7 @@ public final class CraftEquippableComponent implements EquippableComponent { this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), (tag != null) ? Optional.of(((CraftEntityTag) tag).getHandle()) : Optional.empty(), - this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract() + this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound() ); } @@ -187,7 +187,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setDispensable(boolean dispensable) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), dispensable, this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), dispensable, this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -197,7 +197,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setSwappable(boolean swappable) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), swappable, this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), swappable, this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -207,7 +207,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setDamageOnHurt(boolean damage) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), damage, this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), damage, this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -217,7 +217,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setEquipOnInteract(final boolean equip) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), equip); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), equip, this.handle.canBeSheared(), this.handle.shearingSound()); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java b/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java index 22bf130fcd..71a8d4455a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java @@ -19,6 +19,7 @@ import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.levelgen.structure.templatesystem.BlockRotProcessor; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.RegionAccessor; @@ -121,7 +122,7 @@ public class CraftStructure implements Structure { Preconditions.checkArgument(size != null, "BlockVector size cannot be null"); Preconditions.checkArgument(size.getBlockX() >= 1 && size.getBlockY() >= 1 && size.getBlockZ() >= 1, "Size must be at least 1x1x1 but was %sx%sx%s", size.getBlockX(), size.getBlockY(), size.getBlockZ()); - this.structure.fillFromWorld(((CraftWorld) world).getHandle(), CraftLocation.toBlockPosition(origin), CraftBlockVector.toBlockPosition(size), includeEntities, Blocks.STRUCTURE_VOID); + this.structure.fillFromWorld(((CraftWorld) world).getHandle(), CraftLocation.toBlockPosition(origin), CraftBlockVector.toBlockPosition(size), includeEntities, List.of(Blocks.STRUCTURE_VOID)); } @Override @@ -133,7 +134,7 @@ public class CraftStructure implements Structure { public List getEntities() { List entities = new ArrayList<>(); for (StructureTemplate.StructureEntityInfo entity : this.structure.entityInfoList) { - EntityType.create(entity.nbt, ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(), EntitySpawnReason.STRUCTURE).ifPresent(dummyEntity -> { + EntityType.create(TagValueInput.createGlobalDiscarding(entity.nbt), ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(), EntitySpawnReason.STRUCTURE).ifPresent(dummyEntity -> { dummyEntity.setPos(entity.pos.x, entity.pos.y, entity.pos.z); entities.add(dummyEntity.getBukkitEntity()); }); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index 80835b5688..2ef53e39b6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -2,6 +2,9 @@ package org.bukkit.craftbukkit.util; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import java.net.URI; import java.util.ArrayList; @@ -11,6 +14,7 @@ import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.mojang.serialization.JsonOps; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.chat.ChatVersion; import net.md_5.bungee.chat.VersionedComponentSerializer; @@ -18,6 +22,7 @@ import com.mojang.serialization.JavaOps; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.TextColor; @@ -28,6 +33,7 @@ import org.bukkit.craftbukkit.CraftRegistry; public final class CraftChatMessage { + private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); private static final Map formatMap; static { @@ -223,7 +229,11 @@ public final class CraftChatMessage { } public static String toJSON(Component component) { - return Component.Serializer.toJson(component, CraftRegistry.getMinecraftRegistry()); + return GSON.toJson( + ComponentSerialization.CODEC + .encodeStart(JsonOps.INSTANCE, component) + .getOrThrow(JsonParseException::new) + ); } public static String toJSONOrNull(Component component) { @@ -234,7 +244,10 @@ public final class CraftChatMessage { public static Component fromJSON(String jsonMessage) throws JsonParseException { // Note: This also parses plain Strings to text components. // Note: An empty message (empty, or only consisting of whitespace) results in null rather than a parse exception. - return Component.Serializer.fromJson(jsonMessage, CraftRegistry.getMinecraftRegistry()); + final JsonElement jsonElement = GSON.fromJson(jsonMessage, JsonElement.class); + return jsonElement == null ? null : ComponentSerialization.CODEC.parse( + CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE), jsonElement + ).getOrThrow(JsonParseException::new); } public static Component fromJSONOrNull(String jsonMessage) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index 5508b1a4ec..eba331b36d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -50,6 +50,7 @@ import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.LevelResource; +import net.minecraft.world.level.storage.TagValueInput; import net.minecraft.world.level.storage.TagValueOutput; import org.bukkit.Bukkit; import org.bukkit.Keyed; @@ -281,7 +282,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public int getDataVersion() { - return SharedConstants.getCurrentVersion().dataVersion().getVersion(); + return SharedConstants.getCurrentVersion().dataVersion().version(); } @Override @@ -726,8 +727,11 @@ public final class CraftMagicNumbers implements UnsafeValues { // Generate a new UUID, so we don't have to worry about deserializing the same entity twice compound.remove("UUID"); } - net.minecraft.world.entity.Entity nmsEntity = net.minecraft.world.entity.EntityType.create(compound, world, net.minecraft.world.entity.EntitySpawnReason.LOAD) - .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")); + net.minecraft.world.entity.Entity nmsEntity = net.minecraft.world.entity.EntityType.create( + TagValueInput.createDiscarding(world.registryAccess(), compound), + world, + net.minecraft.world.entity.EntitySpawnReason.LOAD + ).orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")); compound.getList("Passengers").ifPresent(passengers -> { for (final Tag tag : passengers) { if (!(tag instanceof final CompoundTag serializedPassenger)) {