1
0
Fork 0
mirror of https://github.com/PaperMC/Paper.git synced 2025-02-03 13:27:23 +01:00

[ci skip] Add more identifying patch comments

This commit is contained in:
Nassim Jahnke 2024-01-18 22:00:40 +01:00
parent 0f611e7b4f
commit 864f4072c1
37 changed files with 220 additions and 225 deletions
patches/server
Add-GameEvent-tags.patchAdd-PlayerItemFrameChangeEvent.patchAdd-configurable-height-for-slime-spawn.patchAdd-missing-structure-set-seed-configs.patchAdd-more-Campfire-API.patchAdd-option-to-disable-block-updates.patchAllow-delegation-to-vanilla-chunk-gen.patchConfigurable-max-block-light-for-monster-spawning.patchConfigurable-sculk-sensor-listener-range.patchDolphin-API.patchExpose-vanilla-BiomeProvider-from-WorldInfo.patchFix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patchFix-EntityArgument-suggestion-permissions-to-align-w.patchFix-NotePlayEvent.patchFix-Spigot-growth-modifiers.patchFix-bees-aging-inside-hives.patchFix-cancelled-powdered-snow-bucket-placement.patchFix-entity-type-tags-suggestions-in-selectors.patchFix-removing-recipes-from-RecipeIterator.patchFix-sticky-pistons-and-BlockPistonRetractEvent.patchFix-tripwire-state-inconsistency.patchFix-xp-reward-for-baby-zombies.patchForward-CraftEntity-in-teleport-command.patchHide-unnecessary-itemmeta-from-clients.patchImplement-regenerateChunk.patchMake-water-animal-spawn-height-configurable.patchMissing-Entity-API.patchMulti-Block-Change-API-Implementation.patchMultiple-Entries-with-Scoreboards.patchOnly-write-chunk-data-to-disk-if-it-serializes-witho.patchOptimize-HashMapPalette.patchPrevent-ContainerOpenersCounter-openCount-from-going.patchPrevent-sending-oversized-item-data-in-equipment-and.patchRemove-client-side-code-using-deprecated-for-removal.patchReset-placed-block-on-exception.patchUse-a-CHM-for-StructureTemplate.Pallete-cache.patchValidate-usernames.patch

View file

@ -74,8 +74,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class);
+ net.minecraft.core.Registry<net.minecraft.world.level.gameevent.GameEvent> gameEvents = net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT;
+ return gameEvents.getTags().map(pair -> (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(gameEvents, pair.getFirst())).collect(ImmutableList.toImmutableList());
+ // Paper end
+ }
+ // Paper end
default -> throw new IllegalArgumentException();
}
}

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import com.mojang.logging.LogUtils;
import java.util.OptionalInt;
import javax.annotation.Nullable;
+import io.papermc.paper.event.player.PlayerItemFrameChangeEvent; // Paper
+import io.papermc.paper.event.player.PlayerItemFrameChangeEvent; // Paper - Add PlayerItemFrameChangeEvent
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -20,13 +20,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return true;
}
// CraftBukkit end
+ // Paper start - call PlayerItemFrameChangeEvent
+ // Paper start - Add PlayerItemFrameChangeEvent
+ if (source.getEntity() instanceof Player player) {
+ var event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.REMOVE);
+ if (!event.callEvent()) return true; // return true here because you aren't cancelling the damage, just the change
+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false);
+ }
+ // Paper end
+ // Paper end - Add PlayerItemFrameChangeEvent
this.dropItem(source.getEntity(), false);
this.gameEvent(GameEvent.BLOCK_CHANGE, source.getEntity());
this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F);
@ -35,26 +35,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- this.setItem(itemstack);
+ // Paper start - call PlayerItemFrameChangeEvent
+ // Paper start - Add PlayerItemFrameChangeEvent
+ PlayerItemFrameChangeEvent event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), itemstack.asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.PLACE);
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()));
+ // Paper end
+ // Paper end - Add PlayerItemFrameChangeEvent
this.gameEvent(GameEvent.BLOCK_CHANGE, player);
if (!player.getAbilities().instabuild) {
itemstack.shrink(1);
}
}
} else {
+ // Paper start - call PlayerItemFrameChangeEvent
+ // Paper start - Add PlayerItemFrameChangeEvent
+ PlayerItemFrameChangeEvent event = new PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), PlayerItemFrameChangeEvent.ItemFrameChangeAction.ROTATE);
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ setItem(ItemStack.fromBukkitCopy(event.getItemStack()), false, false);
+ // Paper end
+ // Paper end - Add PlayerItemFrameChangeEvent
this.playSound(this.getRotateItemSound(), 1.0F, 1.0F);
this.setRotation(this.getRotation() + 1);
this.gameEvent(GameEvent.BLOCK_CHANGE, player);

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final double maxHeightSwamp = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.surfaceBiome.maximum;
+ final double minHeightSwamp = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.surfaceBiome.minimum;
+ if (world.getBiome(pos).is(BiomeTags.ALLOWS_SURFACE_SLIME_SPAWNS) && pos.getY() > minHeightSwamp && pos.getY() < maxHeightSwamp && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) {
+ // Paper end
+ // Paper end - Replace rules for Height in Swamp Biome
return checkMobSpawnRules(type, world, spawnReason, pos, random);
}
@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - Replace rules for Height in Slime Chunks
+ final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum;
+ if (random.nextInt(10) == 0 && flag && pos.getY() < maxHeightSlimeChunk) {
+ // Paper end
+ // Paper end - Replace rules for Height in Swamp Biome
return checkMobSpawnRules(type, world, spawnReason, pos, random);
}
}

View file

@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z)) {
+ if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z, structureplacement instanceof net.minecraft.world.level.chunk.ChunkGeneratorStructureState.KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - add missing structure set configs
+ if (structureplacement.isStructureChunk(placementCalculator, chunkcoordintpair.x, chunkcoordintpair.z, structureplacement instanceof net.minecraft.world.level.chunk.ChunkGeneratorStructureState.KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - Add missing structure set seed configs
if (list.size() == 1) {
this.tryGenerateStructure((StructureSet.StructureSelectionEntry) list.get(0), structureAccessor, registryManager, randomstate, structureTemplateManager, placementCalculator.getLevelSeed(), chunk, chunkcoordintpair, sectionposition);
} else {
@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> ringPositions = new Object2ObjectArrayMap();
private boolean hasGeneratedPositions;
private final List<Holder<StructureSet>> possibleStructureSets;
+ public final SpigotWorldConfig conf; // Paper
+ public final SpigotWorldConfig conf; // Paper - Add missing structure set seed configs
public static ChunkGeneratorStructureState createForFlat(RandomState randomstate, long i, BiomeSource worldchunkmanager, Stream<Holder<StructureSet>> stream, SpigotWorldConfig conf) { // Spigot
List<Holder<StructureSet>> list = stream.filter((holder) -> {
@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, i, ChunkGeneratorStructureState.injectSpigot(list, conf)); // Spigot
+ return new ChunkGeneratorStructureState(randomstate, worldchunkmanager, i, i, ChunkGeneratorStructureState.injectSpigot(list, conf), conf); // Spigot
}
+ // Paper start - horrible hack because spigot creates a ton of direct Holders which lose track of the identifying key
+ // Paper start - Add missing structure set seed configs; horrible hack because spigot creates a ton of direct Holders which lose track of the identifying key
+ public static final class KeyedRandomSpreadStructurePlacement extends RandomSpreadStructurePlacement {
+ public final net.minecraft.resources.ResourceKey<StructureSet> key;
+ public KeyedRandomSpreadStructurePlacement(net.minecraft.resources.ResourceKey<StructureSet> key, net.minecraft.core.Vec3i locateOffset, FrequencyReductionMethod frequencyReductionMethod, float frequency, int salt, java.util.Optional<StructurePlacement.ExclusionZone> exclusionZone, int spacing, int separation, net.minecraft.world.level.levelgen.structure.placement.RandomSpreadType spreadType) {
@ -67,15 +67,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.key = key;
+ }
+ }
+ // Paper end
+ // Paper end - Add missing structure set seed configs
// Spigot start
private static List<Holder<StructureSet>> injectSpigot(List<Holder<StructureSet>> list, SpigotWorldConfig conf) {
return list.stream().map((holder) -> {
StructureSet structureset = holder.value();
- if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig) {
+ final Holder<StructureSet> newHolder; // Paper
+ if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig && holder.unwrapKey().orElseThrow().location().getNamespace().equals(net.minecraft.resources.ResourceLocation.DEFAULT_NAMESPACE)) { // Paper - check namespace cause datapacks could add structure sets with the same path
+ final Holder<StructureSet> newHolder; // Paper - Add missing structure set seed configs
+ if (structureset.placement() instanceof RandomSpreadStructurePlacement randomConfig && holder.unwrapKey().orElseThrow().location().getNamespace().equals(net.minecraft.resources.ResourceLocation.DEFAULT_NAMESPACE)) { // Paper - Add missing structure set seed configs; check namespace cause datapacks could add structure sets with the same path
String name = holder.unwrapKey().orElseThrow().location().getPath();
int seed = randomConfig.salt;
@ -83,7 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
case "villages":
seed = conf.villageSeed;
break;
+ // Paper start
+ // Paper start - Add missing structure set seed configs
+ case "ancient_cities":
+ seed = conf.ancientCitySeed;
+ break;
@ -93,11 +93,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ case "trial_chambers":
+ seed = conf.trialChambersSeed;
+ break;
+ // Paper end
+ // Paper end - Add missing structure set seed configs
}
- structureset = new StructureSet(structureset.structures(), new RandomSpreadStructurePlacement(randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType()));
+ // Paper start
+ // Paper start - Add missing structure set seed configs
+ structureset = new StructureSet(structureset.structures(), new KeyedRandomSpreadStructurePlacement(holder.unwrapKey().orElseThrow(), randomConfig.locateOffset, randomConfig.frequencyReductionMethod, randomConfig.frequency, seed, randomConfig.exclusionZone, randomConfig.spacing(), randomConfig.separation(), randomConfig.spreadType()));
+ newHolder = Holder.direct(structureset); // I really wish we didn't have to do this here
+ } else {
@ -105,7 +105,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- return Holder.direct(structureset);
+ return newHolder;
+ // Paper end
+ // Paper end - Add missing structure set seed configs
}).collect(Collectors.toUnmodifiableList());
}
// Spigot end
@ -114,13 +114,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- private ChunkGeneratorStructureState(RandomState noiseConfig, BiomeSource biomeSource, long structureSeed, long concentricRingSeed, List<Holder<StructureSet>> structureSets) {
+ private ChunkGeneratorStructureState(RandomState noiseConfig, BiomeSource biomeSource, long structureSeed, long concentricRingSeed, List<Holder<StructureSet>> structureSets, SpigotWorldConfig conf) { // Paper
+ private ChunkGeneratorStructureState(RandomState noiseConfig, BiomeSource biomeSource, long structureSeed, long concentricRingSeed, List<Holder<StructureSet>> structureSets, SpigotWorldConfig conf) { // Paper - Add missing structure set seed configs
this.randomState = noiseConfig;
this.levelSeed = structureSeed;
this.biomeSource = biomeSource;
this.concentricRingsSeed = concentricRingSeed;
this.possibleStructureSets = structureSets;
+ this.conf = conf; // Paper
+ this.conf = conf; // Paper - Add missing structure set seed configs
}
public List<Holder<StructureSet>> possibleStructureSets() {
@ -128,13 +128,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
HolderSet<Biome> holderset = placement.preferredBiomes();
RandomSource randomsource = RandomSource.create();
+ // Paper start
+ // Paper start - Add missing structure set seed configs
+ if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
+ randomsource.setSeed(this.conf.strongholdSeed);
+ } else {
+ // Paper end
+ // Paper end - Add missing structure set seed configs
randomsource.setSeed(this.concentricRingsSeed);
+ } // Paper
+ } // Paper - Add missing structure set seed configs
double d0 = randomsource.nextDouble() * 3.141592653589793D * 2.0D;
int l = 0;
int i1 = 0;
@ -143,7 +143,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
for (int l = centerChunkX - chunkCount; l <= centerChunkX + chunkCount; ++l) {
for (int i1 = centerChunkZ - chunkCount; i1 <= centerChunkZ + chunkCount; ++i1) {
- if (structureplacement.isStructureChunk(this, l, i1)) {
+ if (structureplacement.isStructureChunk(this, l, i1, structureplacement instanceof KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - add missing structure set configs
+ if (structureplacement.isStructureChunk(this, l, i1, structureplacement instanceof KeyedRandomSpreadStructurePlacement keyed ? keyed.key : null)) { // Paper - Add missing structure set seed configs
return true;
}
}
@ -155,9 +155,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.exclusionZone;
}
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add missing structure set seed configs
public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ) {
+ // Paper start - add missing structure set configs
+ // Paper start - Add missing structure set seed configs
+ return this.isStructureChunk(calculator, chunkX, chunkZ, null);
+ }
+ public boolean isStructureChunk(ChunkGeneratorStructureState calculator, int chunkX, int chunkZ, @org.jetbrains.annotations.Nullable net.minecraft.resources.ResourceKey<StructureSet> structureSetKey) {
@ -169,11 +169,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ saltOverride = calculator.conf.buriedTreasureSeed;
+ }
+ }
+ // Paper end
+ // Paper end - Add missing structure set seed configs
if (!this.isPlacementChunk(calculator, chunkX, chunkZ)) {
return false;
- } else if (this.frequency < 1.0F && !this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency)) {
+ } else if (this.frequency < 1.0F && !this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency, saltOverride)) { // Paper
+ } else if (this.frequency < 1.0F && !this.frequencyReductionMethod.shouldGenerate(calculator.getLevelSeed(), this.salt, chunkX, chunkZ, this.frequency, saltOverride)) { // Paper - Add missing structure set seed configs
return false;
} else {
return !this.exclusionZone.isPresent() || !this.exclusionZone.get().isPlacementForbidden(calculator, chunkX, chunkZ);
@ -182,35 +182,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public abstract StructurePlacementType<?> type();
- private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) {
+ private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - ignore here
+ private static boolean probabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
worldgenRandom.setLargeFeatureWithSalt(seed, salt, chunkX, chunkZ);
return worldgenRandom.nextFloat() < frequency;
}
- private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency) {
+ private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper
+ private static boolean legacyProbabilityReducerWithDouble(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
+ if (saltOverride == null) { // Paper
+ if (saltOverride == null) { // Paper - Add missing structure set seed configs
worldgenRandom.setLargeFeatureSeed(seed, chunkX, chunkZ);
+ // Paper start
+ // Paper start - Add missing structure set seed configs
+ } else {
+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride);
+ }
+ // Paper end
+ // Paper end - Add missing structure set seed configs
return worldgenRandom.nextDouble() < (double)frequency;
}
- private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) {
+ private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper
+ private static boolean legacyArbitrarySaltProbabilityReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
- worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, 10387320);
+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride != null ? saltOverride : HIGHLY_ARBITRARY_RANDOM_SALT); // Paper
+ worldgenRandom.setLargeFeatureWithSalt(seed, chunkX, chunkZ, saltOverride != null ? saltOverride : HIGHLY_ARBITRARY_RANDOM_SALT); // Paper - Add missing structure set seed configs
return worldgenRandom.nextFloat() < frequency;
}
- private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency) {
+ private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - ignore here
+ private static boolean legacyPillagerOutpostReducer(long seed, int salt, int chunkX, int chunkZ, float frequency, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
int i = chunkX >> 4;
int j = chunkZ >> 4;
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
@ -219,7 +219,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@FunctionalInterface
public interface FrequencyReducer {
- boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance);
+ boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride); // Paper
+ boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride); // Paper - Add missing structure set seed configs
}
public static enum FrequencyReductionMethod implements StringRepresentable {
@ -229,8 +229,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance) {
- return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance);
+ public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper
+ return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance, saltOverride); // Paper
+ public boolean shouldGenerate(long seed, int salt, int chunkX, int chunkZ, float chance, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs
+ return this.reducer.shouldGenerate(seed, salt, chunkX, chunkZ, chance, saltOverride); // Paper - Add missing structure set seed configs
}
@Override

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final int[] cookingProgress;
public final int[] cookingTime;
private final RecipeManager.CachedCheck<Container, CampfireCookingRecipe> quickCheck;
+ public final boolean[] stopCooking; // Paper
+ public final boolean[] stopCooking; // Paper - Add more Campfire API
public CampfireBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.CAMPFIRE, pos, state);
@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.cookingProgress = new int[4];
this.cookingTime = new int[4];
this.quickCheck = RecipeManager.createCheck(RecipeType.CAMPFIRE_COOKING);
+ this.stopCooking = new boolean[4]; // Paper
+ this.stopCooking = new boolean[4]; // Paper - Add more Campfire API
}
public static void cookTick(Level world, BlockPos pos, BlockState state, CampfireBlockEntity campfire) {
@ -28,9 +28,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!itemstack.isEmpty()) {
flag = true;
+ if (!campfire.stopCooking[i]) { // Paper
+ if (!campfire.stopCooking[i]) { // Paper - Add more Campfire API
int j = campfire.cookingProgress[i]++;
+ } // Paper
+ } // Paper - Add more Campfire API
if (campfire.cookingProgress[i] >= campfire.cookingTime[i]) {
SimpleContainer inventorysubcontainer = new SimpleContainer(new ItemStack[]{itemstack});
@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
System.arraycopy(aint, 0, this.cookingTime, 0, Math.min(this.cookingTime.length, aint.length));
}
+ // Paper start
+ // Paper start - Add more Campfire API
+ if (nbt.contains("Paper.StopCooking", org.bukkit.craftbukkit.util.CraftMagicNumbers.NBT.TAG_BYTE_ARRAY)) {
+ byte[] abyte = nbt.getByteArray("Paper.StopCooking");
+ boolean[] cookingState = new boolean[4];
@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, abyte.length));
+ }
+ // Paper end
+ // Paper end - Add more Campfire API
}
@Override
@ -55,13 +55,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ContainerHelper.saveAllItems(nbt, this.items, true);
nbt.putIntArray("CookingTimes", this.cookingProgress);
nbt.putIntArray("CookingTotalTimes", this.cookingTime);
+ // Paper start
+ // 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);
+ }
+ nbt.putByteArray("Paper.StopCooking", cookingState);
+ // Paper end
+ // Paper end - Add more Campfire API
}
@Override

View file

@ -139,7 +139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
if (!moved && !state.is(newState.getBlock())) {
this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix state inconsistency
this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix tripwire state inconsistency
}
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
@ -154,7 +154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private void updateSource(Level world, BlockPos pos, BlockState state) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
// Paper start - fix state inconsistency
// Paper start - fix tripwire state inconsistency
this.updateSource(world, pos, state, false);
}
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
}
+ // Paper start
+ // Paper start - Allow delegation to vanilla chunk gen
+ private static final List<net.minecraft.world.level.chunk.ChunkStatus> VANILLA_GEN_STATUSES = List.of(
+ net.minecraft.world.level.chunk.ChunkStatus.EMPTY,
+ net.minecraft.world.level.chunk.ChunkStatus.STRUCTURE_STARTS,
@ -92,7 +92,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // hooray!
+ return data;
+ }
+ // Paper end
+ // Paper end - Allow delegation to vanilla chunk gen
+
@Override
public BossBar createBossBar(String title, BarColor color, BarStyle style, BarFlag... flags) {
@ -106,7 +106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final int minHeight;
private final int maxHeight;
- private final LevelChunkSection[] sections;
+ private LevelChunkSection[] sections; // Paper
+ private LevelChunkSection[] sections; // Paper - Allow delegation to vanilla chunk gen
private final Registry<net.minecraft.world.level.biome.Biome> biomes;
private Set<BlockPos> tiles;
private final Set<BlockPos> lights = new HashSet<>();
@ -115,13 +115,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- Set<BlockPos> getLights() {
+ public Set<BlockPos> getLights() { // Paper
+ public Set<BlockPos> getLights() { // Paper - Allow delegation to vanilla chunk gen
return this.lights;
}
+
+ // Paper start
+ // Paper start - Allow delegation to vanilla chunk gen
+ public void setRawChunkData(LevelChunkSection[] sections) {
+ this.sections = sections;
+ }
+ // Paper end
+ // Paper end - Allow delegation to vanilla chunk gen
}

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else {
DimensionType dimensionType = world.dimensionType();
- int i = dimensionType.monsterSpawnBlockLightLimit();
+ int i = world.getLevel().paperConfig().entities.spawning.monsterSpawnMaxLightLevel.or(dimensionType.monsterSpawnBlockLightLimit()); // Paper
+ int i = world.getLevel().paperConfig().entities.spawning.monsterSpawnMaxLightLevel.or(dimensionType.monsterSpawnBlockLightLimit()); // Paper - Configurable max block light for monster spawning
if (i < 15 && world.getBrightness(LightLayer.BLOCK, pos) > i) {
return false;
} else {

View file

@ -14,12 +14,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public VibrationSystem.User createVibrationUser() {
return new CalibratedSculkSensorBlockEntity.VibrationUser(this.getBlockPos());
}
+ // Paper start
+ // 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
+ }
+ // Paper end
+ // Paper end - Configurable sculk sensor listener range
protected class VibrationUser extends SculkSensorBlockEntity.VibrationUser {
public VibrationUser(BlockPos pos) {
@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public int getListenerRadius() {
+ if (CalibratedSculkSensorBlockEntity.this.rangeOverride != null) return CalibratedSculkSensorBlockEntity.this.rangeOverride; // Paper
+ if (CalibratedSculkSensorBlockEntity.this.rangeOverride != null) return CalibratedSculkSensorBlockEntity.this.rangeOverride; // Paper - Configurable sculk sensor listener range
return 16;
}
@ -39,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final VibrationSystem.Listener vibrationListener;
private final VibrationSystem.User vibrationUser = this.createVibrationUser();
public int lastVibrationFrequency;
+ @Nullable public Integer rangeOverride = null; // Paper
+ @Nullable public Integer rangeOverride = null; // Paper - Configurable sculk sensor listener range
protected SculkSensorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
@ -47,17 +47,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.vibrationData = listener;
});
}
+ // Paper start
+ // Paper start - Configurable sculk sensor listener range
+ if (nbt.contains(PAPER_LISTENER_RANGE_NBT_KEY)) {
+ this.rangeOverride = nbt.getInt(PAPER_LISTENER_RANGE_NBT_KEY);
+ } else {
+ this.rangeOverride = null;
+ }
+ // Paper end
+ // Paper end - Configurable sculk sensor listener range
}
+ protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper
+ protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range
@Override
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
@ -65,13 +65,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
VibrationSystem.Data.CODEC.encodeStart(NbtOps.INSTANCE, this.vibrationData).resultOrPartial(LOGGER::error).ifPresent((listenerNbt) -> {
nbt.put("listener", listenerNbt);
});
+ this.saveRangeOverride(nbt); // Paper
+ this.saveRangeOverride(nbt); // Paper - Configurable sculk sensor listener range
+ }
+ // Paper start
+ // Paper start - Configurable sculk sensor listener range
+ protected void saveRangeOverride(CompoundTag nbt) {
+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default
}
+ // Paper end
+ // Paper end - Configurable sculk sensor listener range
@Override
public VibrationSystem.Data getVibrationData() {
@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public int getListenerRadius() {
+ if (SculkSensorBlockEntity.this.rangeOverride != null) return SculkSensorBlockEntity.this.rangeOverride; // Paper
+ if (SculkSensorBlockEntity.this.rangeOverride != null) return SculkSensorBlockEntity.this.rangeOverride; // Paper - Configurable sculk sensor listener range
return 8;
}

View file

@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Tue, 7 Dec 2021 19:34:23 -0500
Subject: [PATCH] Dolphin API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
@@ -0,0 +0,0 @@ public class CraftDolphin extends CraftWaterMob implements Dolphin {
public String toString() {
return "CraftDolphin";
}
+
+ // Paper start - Missing Dolphin API
+ @Override
+ public int getMoistness() {
+ return this.getHandle().getMoistnessLevel();
+ }
+
+ @Override
+ public void setMoistness(int moistness) {
+ this.getHandle().setMoisntessLevel(moistness);
+ }
+
+ @Override
+ public void setHasFish(boolean hasFish) {
+ this.getHandle().setGotFish(hasFish);
+ }
+
+ @Override
+ public boolean hasFish() {
+ return this.getHandle().gotFish();
+ }
+
+ @Override
+ public org.bukkit.Location getTreasureLocation() {
+ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().level(), this.getHandle().getTreasurePos());
+ }
+
+ @Override
+ public void setTreasureLocation(org.bukkit.Location location) {
+ this.getHandle().setTreasurePos(io.papermc.paper.util.MCUtil.toBlockPosition(location));
+ }
+ // Paper end - Missing Dolphin API
}

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
LevelStem worlddimension = (LevelStem) dimensions.get(dimensionKey);
- org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value());
+ org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper
+ org.bukkit.generator.WorldInfo worldInfo = new org.bukkit.craftbukkit.generator.CraftWorldInfo(iworlddataserver, worldSession, org.bukkit.World.Environment.getEnvironment(dimension), worlddimension.type().value(), worlddimension.generator(), this.registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
if (biomeProvider == null && gen != null) {
biomeProvider = gen.getDefaultBiomeProvider(worldInfo);
}
@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
LevelStem worlddimension = iregistry.get(actualDimension);
- WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value());
+ WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper
+ WorldInfo worldInfo = new CraftWorldInfo(worlddata, worldSession, creator.environment(), worlddimension.type().value(), worlddimension.generator(), this.getHandle().getServer().registryAccess()); // Paper - Expose vanilla BiomeProvider from WorldInfo
if (biomeProvider == null && generator != null) {
biomeProvider = generator.getDefaultBiomeProvider(worldInfo);
}

View file

@ -20,14 +20,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- data.put("block_states", ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, cs[i].getStates()).get().left().get());
- sectionBlockIDs[i] = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, data.getCompound("block_states")).get().left().get();
+ // Paper start
+ sectionEmpty[i] = cs[i].hasOnlyAir(); // Paper - fix sectionEmpty array not being filled
+ // Paper start - Fix ChunkSnapshot#isSectionEmpty(int); and remove codec usage
+ sectionEmpty[i] = cs[i].hasOnlyAir(); // fix sectionEmpty array not being filled
+ if (!sectionEmpty[i]) {
+ sectionBlockIDs[i] = cs[i].getStates().copy(); // Paper - use copy instead of round tripping with codecs
+ sectionBlockIDs[i] = cs[i].getStates().copy(); // use copy instead of round tripping with codecs
+ } else {
+ sectionBlockIDs[i] = CraftChunk.emptyBlockIDs; // Paper - use cached instance for empty block sections
+ sectionBlockIDs[i] = CraftChunk.emptyBlockIDs; // use cached instance for empty block sections
+ }
+ // Paper end
+ // Paper end - Fix ChunkSnapshot#isSectionEmpty(int)
LevelLightEngine lightengine = this.worldServer.getLightEngine();
DataLayer skyLightArray = lightengine.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(this.x, chunk.getSectionYFromSectionIndex(i), this.z)); // SPIGOT-7498: Convert section index
@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (biome != null) {
- data.put("biomes", biomeCodec.encodeStart(NbtOps.INSTANCE, cs[i].getBiomes()).get().left().get());
- biome[i] = biomeCodec.parse(NbtOps.INSTANCE, data.getCompound("biomes")).get().left().get();
+ biome[i] = ((PalettedContainer<Holder<net.minecraft.world.level.biome.Biome>>) cs[i].getBiomes()).copy(); // Paper - use copy instead of round tripping with codecs
+ biome[i] = ((PalettedContainer<Holder<net.minecraft.world.level.biome.Biome>>) cs[i].getBiomes()).copy(); // Paper - Perf: use copy instead of round tripping with codecs
}
}

View file

@ -16,12 +16,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
StringReader stringreader = new StringReader(suggestionsbuilder.getInput());
stringreader.setCursor(suggestionsbuilder.getStart());
- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper
- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper - tell clients to ask server for suggestions for EntityArguments
+ // Paper start - Fix EntityArgument suggestion permissions
+ final boolean permission = object instanceof CommandSourceStack stack
+ ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector")
+ : icompletionprovider.hasPermission(2);
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission, true); // Paper
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission, true); // Paper - tell clients to ask server for suggestions for EntityArguments
+ // Paper end - Fix EntityArgument suggestion permissions
try {

View file

@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // return;
+ // }
// CraftBukkit end
+ // Paper - TODO any way to cancel the game event?
+ // Paper - move NotePlayEvent call to fix instrument/note changes; TODO any way to cancel the game event?
world.blockEvent(pos, this, 0, 0);
world.gameEvent(entity, GameEvent.NOTE_BLOCK_PLAY, pos);
}
@ -34,12 +34,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - move NotePlayEvent call to fix instrument/note changes
+ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, blockpropertyinstrument, state.getValue(NOTE));
+ if (event.isCancelled()) return false;
+ // Paper end
+ // Paper end - move NotePlayEvent call to fix instrument/note changes
float f;
if (blockpropertyinstrument.isTunable()) {
- int k = (Integer) state.getValue(NoteBlock.NOTE);
+ int k = event.getNote().getId(); // Paper
+ int k = event.getNote().getId(); // Paper - move NotePlayEvent call to fix instrument/note changes
f = NoteBlock.getPitchFromNote(k);
world.addParticle(ParticleTypes.NOTE, (double) pos.getX() + 0.5D, (double) pos.getY() + 1.2D, (double) pos.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D);
@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
holder = Holder.direct(SoundEvent.createVariableRangeEvent(minecraftkey));
} else {
- holder = blockpropertyinstrument.getSoundEvent();
+ holder = org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(); // Paper
+ holder = org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(); // Paper - move NotePlayEvent call to fix instrument/note changes
}
world.playSeededSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, holder, SoundSource.RECORDS, 3.0F, f, world.random.nextLong());

View file

@ -20,17 +20,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return to.setValue(BERRIES, from.getValue(BERRIES));
}
+ // Paper start - Fix Spigot growth modifiers
+ @Override
+ protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) {
+ final boolean value = random.nextFloat() < (level != null ? (0.11F * (level.spigotConfig.glowBerryModifier / 100.0F)) : 0.11F);
+ return (BlockState) super.getGrowIntoState(state, random).setValue(CaveVinesBlock.BERRIES, value);
+ }
+ // Paper end
+ // Paper end - Fix Spigot growth modifiers
+
@Override
protected BlockState getGrowIntoState(BlockState state, RandomSource random) {
- return super.getGrowIntoState(state, random).setValue(BERRIES, Boolean.valueOf(random.nextFloat() < 0.11F));
+ // Paper start
+ // Paper start - Fix Spigot growth modifiers
+ return this.getGrowIntoState(state, random, null);
}
@ -43,10 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
modifier = world.spigotConfig.carrotModifier;
} else if (this == Blocks.POTATOES) {
modifier = world.spigotConfig.potatoModifier;
+ // Paper start
+ // Paper start - Fix Spigot growth modifiers
+ } else if (this == Blocks.TORCHFLOWER_CROP) {
+ modifier = world.spigotConfig.torchFlowerModifier;
+ // Paper end
+ // Paper end - Fix Spigot growth modifiers
} else {
modifier = world.spigotConfig.wheatModifier;
}
@ -59,17 +60,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.canGrowInto(world.getBlockState(blockposition1))) {
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, this.getGrowIntoState(state, world.random)); // CraftBukkit
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, this.getGrowIntoState(state, world.random, world)); // CraftBukkit // Paper
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, this.getGrowIntoState(state, world.random, world)); // CraftBukkit // Paper - Fix Spigot growth modifiers
}
}
}
+ // Paper start
+ // Paper start - Fix Spigot growth modifiers
+ protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) {
+ return this.getGrowIntoState(state, random);
+ }
+ // Paper end
+ // Paper end - Fix Spigot growth modifiers
+
protected BlockState getGrowIntoState(BlockState state, RandomSource random) {
return (BlockState) state.cycle(GrowingPlantHeadBlock.AGE);
@ -83,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
if (!isHanging(state)) {
- if (random.nextInt(7) == 0) {
+ if (random.nextFloat() < (world.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper
+ if (random.nextFloat() < (world.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper - Fix Spigot growth modifiers
this.advanceTree(world, pos, state, random);
}
@ -96,7 +97,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
float f = CropBlock.getGrowthSpeed(this, world, pos);
- boolean bl = random.nextInt((int)(25.0F / f) + 1) == 0;
+ boolean bl = random.nextFloat() < (world.spigotConfig.pitcherPlantModifier / (100.0F * (Math.floor(25.0F / f) + 1))); // Paper
+ boolean bl = random.nextFloat() < (world.spigotConfig.pitcherPlantModifier / (100.0F * (Math.floor(25.0F / f) + 1))); // Paper - Fix Spigot growth modifiers
if (bl) {
this.grow(world, state, pos, 1);
}

View file

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
for (Iterator iterator = bees.iterator(); iterator.hasNext(); ++tileentitybeehive_hivebee.ticksInHive) {
tileentitybeehive_hivebee = (BeehiveBlockEntity.BeeData) iterator.next();
- if (tileentitybeehive_hivebee.ticksInHive > tileentitybeehive_hivebee.minOccupationTicks) {
+ if (tileentitybeehive_hivebee.exitTickCounter > tileentitybeehive_hivebee.minOccupationTicks) { // Paper - use exitTickCounter
+ if (tileentitybeehive_hivebee.exitTickCounter > tileentitybeehive_hivebee.minOccupationTicks) { // Paper - Fix bees aging inside hives; use exitTickCounter
BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus = tileentitybeehive_hivebee.entityData.getBoolean("HasNectar") ? BeehiveBlockEntity.BeeReleaseStatus.HONEY_DELIVERED : BeehiveBlockEntity.BeeReleaseStatus.BEE_RELEASED;
if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee, (List) null, tileentitybeehive_releasestatus, flowerPos)) {
@ -24,11 +24,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
} else {
- tileentitybeehive_hivebee.ticksInHive = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable
+ tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - use exitTickCounter to keep actual bee life
+ tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - Fix bees aging inside hives; use exitTickCounter to keep actual bee life
// CraftBukkit end
}
}
+ tileentitybeehive_hivebee.exitTickCounter++; // Paper
+ tileentitybeehive_hivebee.exitTickCounter++; // Paper - Fix bees aging inside hives
}
if (flag) {
@ -36,14 +36,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
final CompoundTag entityData;
int ticksInHive;
+ int exitTickCounter; // Paper - separate counter for checking if bee should exit to reduce exit attempts
+ int exitTickCounter; // Paper - Fix bees aging inside hives; separate counter for checking if bee should exit to reduce exit attempts
final int minOccupationTicks;
BeeData(CompoundTag entityData, int ticksInHive, int minOccupationTicks) {
BeehiveBlockEntity.removeIgnoredBeeTags(entityData);
this.entityData = entityData;
this.ticksInHive = ticksInHive;
+ this.exitTickCounter = ticksInHive; // Paper
+ this.exitTickCounter = ticksInHive; // Paper - Fix bees aging inside hives
this.minOccupationTicks = minOccupationTicks;
}
}

View file

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ServerLevel world = (ServerLevel) context.getLevel();
- if (!(item instanceof BucketItem || item instanceof SolidBucketItem)) { // if not bucket
+ if (!(item instanceof BucketItem/* || item instanceof SolidBucketItem*/)) { // if not bucket // Paper - capture block states for snow buckets
+ if (!(item instanceof BucketItem/* || item instanceof SolidBucketItem*/)) { // if not bucket // Paper - Fix cancelled powdered snow bucket placement
world.captureBlockStates = true;
// special case bonemeal
if (item == Items.BONE_MEAL) {
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (blocks.size() > 1) {
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
- } else if (blocks.size() == 1) {
+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - don't call event twice for snow buckets
+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
}

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.source.getBukkitSender(this);
}
// CraftBukkit end
+ // Paper start - override getSelectedEntities
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
+ @Override
+ public Collection<String> getSelectedEntities() {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && this.source instanceof ServerPlayer player) {
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ return SharedSuggestionProvider.super.getSelectedEntities();
+ }
+ // Paper end
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
}
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -68,7 +68,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
stringreader.setCursor(suggestionsbuilder.getStart());
- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2));
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper - tell clients to ask server for suggestions for EntityArguments
try {
argumentparserselector.parse();
@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return argumentparserselector.fillSuggestions(suggestionsbuilder, (suggestionsbuilder1) -> {
- Collection<String> collection = icompletionprovider.getOnlinePlayerNames();
+ // Paper start
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
+ final Collection<String> collection;
+ if (icompletionprovider instanceof CommandSourceStack commandSourceStack && commandSourceStack.getEntity() instanceof ServerPlayer sourcePlayer) {
+ collection = new java.util.ArrayList<>();
@ -89,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } else {
+ collection = icompletionprovider.getOnlinePlayerNames();
+ }
+ // Paper end
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
Iterable<String> iterable = this.playersOnly ? collection : Iterables.concat(collection, icompletionprovider.getSelectedEntities());
SharedSuggestionProvider.suggest((Iterable) iterable, suggestionsbuilder1);
@ -101,19 +101,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean hasScores;
private boolean hasAdvancements;
private boolean usesSelectors;
+ public boolean parsingEntityArgumentSuggestions; // Paper - track when parsing EntityArgument suggestions
+ public boolean parsingEntityArgumentSuggestions; // Paper - tell clients to ask server for suggestions for EntityArguments
public EntitySelectorParser(StringReader reader) {
this(reader, true);
}
public EntitySelectorParser(StringReader reader, boolean atAllowed) {
+ // Paper start
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
+ this(reader, atAllowed, false);
+ }
+ public EntitySelectorParser(StringReader reader, boolean atAllowed, boolean parsingEntityArgumentSuggestions) {
+ this.parsingEntityArgumentSuggestions = parsingEntityArgumentSuggestions;
+ // Paper end
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
this.distance = MinMaxBounds.Doubles.ANY;
this.level = MinMaxBounds.Ints.ANY;
this.rotX = WrappedMinMaxBounds.ANY;
@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType((entity) -> {
return Component.translatableEscape("argument.entity.options.type.invalid", entity);
});
+ // Paper start
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
+ public static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> {
+ return io.papermc.paper.adventure.PaperAdventure
+ .asVanilla(net.kyori.adventure.text.Component
@ -137,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ )
+ );
+ });
+ // Paper end
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
private static void register(String id, EntitySelectorOptions.Modifier handler, Predicate<EntitySelectorParser> condition, Component description) {
OPTIONS.put(id, new EntitySelectorOptions.Option(handler, condition, description));
@ -145,12 +145,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (reader.isTag()) {
TagKey<EntityType<?>> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(reader.getReader()));
+ // Paper start - throw error if invalid entity tag (only on suggestions to keep cmd success behavior)
+ // Paper start - tell clients to ask server for suggestions for EntityArguments; throw error if invalid entity tag (only on suggestions to keep cmd success behavior)
+ if (reader.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getTag(tagKey).isEmpty()) {
+ reader.getReader().setCursor(i);
+ throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey);
+ }
+ // Paper end
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
reader.addPredicate((entity) -> {
return entity.getType().is(tagKey) != bl;
});

View file

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class RecipeIterator implements Iterator<Recipe> {
private final Iterator<Map.Entry<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>>> recipes;
private Iterator<RecipeHolder<?>> current;
+ private Recipe currentRecipe; // Paper - fix removing recipes
+ private Recipe currentRecipe; // Paper - fix removing recipes from RecipeIterator
public RecipeIterator() {
this.recipes = MinecraftServer.getServer().getRecipeManager().recipes.entrySet().iterator();
@ -23,28 +23,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.current == null || !this.current.hasNext()) {
this.current = this.recipes.next().getValue().values().iterator();
- return this.next();
+ // Paper start - fix removing recipes
+ // Paper start - fix removing recipes from RecipeIterator
+ this.currentRecipe = this.next();
+ return this.currentRecipe;
+ // Paper end
+ // Paper end - fix removing recipes from RecipeIterator
}
- return this.current.next().toBukkitRecipe();
+ // Paper start - fix removing recipes
+ // Paper start - fix removing recipes from RecipeIterator
+ this.currentRecipe = this.current.next().toBukkitRecipe();
+ return this.currentRecipe;
+ // Paper end
+ // Paper end - fix removing recipes from RecipeIterator
}
@Override
public void remove() {
Preconditions.checkState(this.current != null, "next() not yet called");
+
+ // Paper start - fix removing recipes
+ // Paper start - fix removing recipes from RecipeIterator
+ if (this.currentRecipe instanceof org.bukkit.Keyed keyed) {
+ MinecraftServer.getServer().getRecipeManager().byName.remove(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(keyed.getKey()));
+ }
+ // Paper end
+ // Paper end - fix removing recipes from RecipeIterator
this.current.remove();
}
}

View file

@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return;
- }
- }
+ // if (!this.isSticky) { // Paper - Move further down
+ // if (!this.isSticky) { // Paper - Fix sticky pistons and BlockPistonRetractEvent; Move further down
+ // org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ // BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.<org.bukkit.block.Block>of(), CraftBlock.notchToBlockFace(enumdirection));
+ // world.getCraftServer().getPluginManager().callEvent(event);
@ -59,13 +59,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockState iblockdata2 = (BlockState) ((BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(MovingPistonBlock.FACING, enumdirection)).setValue(MovingPistonBlock.TYPE, this.isSticky ? PistonType.STICKY : PistonType.DEFAULT);
+ // Paper start - Move empty piston retract call to fix multiple event fires
+ // Paper start - Fix sticky pistons and BlockPistonRetractEvent; Move empty piston retract call to fix multiple event fires
+ if (!this.isSticky) {
+ if (!new BlockPistonRetractEvent(CraftBlock.at(world, pos), java.util.Collections.emptyList(), CraftBlock.notchToBlockFace(enumdirection)).callEvent()) {
+ return false;
+ }
+ }
+ // Paper end
+ // Paper end - Fix sticky pistons and BlockPistonRetractEvent
world.setBlock(pos, iblockdata2, 20);
world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - diff on change
world.blockUpdated(pos, iblockdata2.getBlock());
@ -73,13 +73,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (type == 1 && !iblockdata3.isAir() && PistonBaseBlock.isPushable(iblockdata3, world, blockposition1, enumdirection.getOpposite(), false, enumdirection) && (iblockdata3.getPistonPushReaction() == PushReaction.NORMAL || iblockdata3.is(Blocks.PISTON) || iblockdata3.is(Blocks.STICKY_PISTON))) {
this.moveBlocks(world, pos, enumdirection, false);
} else {
+ // Paper start - fire BlockPistonRetractEvent for sticky pistons retracting nothing (air)
+ // Paper start - Fix sticky pistons and BlockPistonRetractEvent; fire BlockPistonRetractEvent for sticky pistons retracting nothing (air)
+ if (type == TRIGGER_CONTRACT && iblockdata2.isAir()) {
+ if (!new BlockPistonRetractEvent(CraftBlock.at(world, pos), java.util.Collections.emptyList(), CraftBlock.notchToBlockFace(enumdirection)).callEvent()) {
+ return false;
+ }
+ }
+ // Paper end
+ // Paper end - Fix sticky pistons and BlockPistonRetractEvent
world.removeBlock(pos.relative(enumdirection), false);
}
}

View file

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
if (!moved && !state.is(newState.getBlock())) {
- this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true));
+ this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix state inconsistency
+ this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix tripwire state inconsistency
}
}
@ -22,12 +22,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
private void updateSource(Level world, BlockPos pos, BlockState state) {
+ // Paper start - fix state inconsistency
+ // Paper start - fix tripwire state inconsistency
+ this.updateSource(world, pos, state, false);
+ }
+
+ private void updateSource(Level world, BlockPos pos, BlockState state, boolean beingRemoved) {
+ // Paper end
+ // Paper end - fix tripwire state inconsistency
Direction[] aenumdirection = new Direction[]{Direction.SOUTH, Direction.WEST};
int i = aenumdirection.length;
int j = 0;
@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (iblockdata1.is(this.hook)) {
if (iblockdata1.getValue(TripWireHookBlock.FACING) == enumdirection.getOpposite()) {
- TripWireHookBlock.calculateState(world, blockposition1, iblockdata1, false, true, k, state);
+ TripWireHookBlock.calculateState(world, blockposition1, iblockdata1, false, true, k, state, beingRemoved); // Paper - fix state inconsistency
+ TripWireHookBlock.calculateState(world, blockposition1, iblockdata1, false, true, k, state, beingRemoved); // Paper - fix tripwire state inconsistency
}
} else if (iblockdata1.is((Block) this)) {
++k;
@ -50,12 +50,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- public static void calculateState(Level world, BlockPos pos, BlockState state, boolean flag, boolean flag1, int i, @Nullable BlockState iblockdata1) {
+ public static void calculateState(Level world, BlockPos pos, BlockState state, boolean beingRemoved, boolean flag1, int i, @Nullable BlockState iblockdata1) {
+ // Paper start - fix tripwire inconsistency
+ // Paper start - fix tripwire state inconsistency
+ calculateState(world, pos, state, beingRemoved, flag1, i, iblockdata1, false);
+ }
+
+ public static void calculateState(Level world, BlockPos pos, BlockState state, boolean beingRemoved, boolean flag1, int i, @Nullable BlockState iblockdata1, boolean tripWireBeingRemoved) {
+ // Paper end
+ // Paper end - fix tripwire state inconsistency
Optional<Direction> optional = state.getOptionalValue(TripWireHookBlock.FACING);
if (optional.isPresent()) {
@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
boolean flag3 = (Boolean) state.getOptionalValue(TripWireHookBlock.POWERED).orElse(false);
Block block = state.getBlock();
- boolean flag4 = !flag;
+ boolean flag4 = !beingRemoved; // Paper
+ boolean flag4 = !beingRemoved; // Paper - fix tripwire state inconsistency
boolean flag5 = false;
int j = 0;
BlockState[] aiblockdata = new BlockState[42];
@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
boolean flag7 = (Boolean) iblockdata2.getValue(TripWireBlock.POWERED);
flag5 |= flag6 && flag7;
+ if (k != i || !tripWireBeingRemoved || !flag6) // Paper - don't update the tripwire again if being removed and not disarmed
+ if (k != i || !tripWireBeingRemoved || !flag6) // Paper - fix tripwire state inconsistency; don't update the tripwire again if being removed and not disarmed
aiblockdata[k] = iblockdata2;
if (k == i) {
world.scheduleTick(pos, block, 10);
@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
TripWireHookBlock.emitState(world, pos, flag4, flag5, flag2, flag3);
- if (!flag) {
+ if (!beingRemoved) { // Paper
+ if (!beingRemoved) { // Paper - fix tripwire state inconsistency
if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - validate
world.setBlock(pos, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection), 3);
if (flag1) {

View file

@ -22,11 +22,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- return super.getExperienceReward();
+ // Paper start - only change the XP reward for the calculations in the super method
+ // Paper start - store previous value to reset after calculating XP reward
+ int reward = super.getExperienceReward();
+ this.xpReward = previousReward;
+ return reward;
+ // Paper end
+ // Paper end - store previous value to reset after calculating XP reward
}
@Override

View file

@ -12,13 +12,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public void restoreFrom(Entity original) {
+ // Paper start
+ // Paper start - Forward CraftEntity in teleport command
+ CraftEntity bukkitEntity = original.bukkitEntity;
+ if (bukkitEntity != null) {
+ bukkitEntity.setHandle(this);
+ this.bukkitEntity = bukkitEntity;
+ }
+ // Paper end
+ // Paper end - Forward CraftEntity in teleport command
CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag());
nbttagcompound.remove("Dimension");
@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.getBukkitEntity().setHandle(entity);
- entity.bukkitEntity = this.getBukkitEntity();
- // CraftBukkit end
+ // // CraftBukkit start - Forward the CraftEntity to the new entity // Paper - moved to Entity#restoreFrom
+ // // CraftBukkit start - Forward the CraftEntity to the new entity // Paper - Forward CraftEntity in teleport command; moved to Entity#restoreFrom
+ // this.getBukkitEntity().setHandle(entity);
+ // entity.bukkitEntity = this.getBukkitEntity();
+ // // CraftBukkit end

View file

@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start - prevent oversized data
final ItemStack sanitized = LivingEntity.sanitizeItemStack(itemstack.copy(), false);
- list.add(Pair.of(enumitemslot, sanitized));
+ list.add(Pair.of(enumitemslot, ((LivingEntity) this.entity).stripMeta(sanitized, false))); // Paper - remove unnecessary item meta
// Paper end
+ list.add(Pair.of(enumitemslot, ((LivingEntity) this.entity).stripMeta(sanitized, false))); // Paper - Hide unnecessary item meta
// Paper end - prevent oversized data
}
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@ -27,8 +27,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// SPIGOT-7136 - Allays
- if (entity instanceof Allay) {
- ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
+ if (entity instanceof Allay allay) { // Paper
+ ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, allay.stripMeta(allay.getItemBySlot(slot), true))).collect(Collectors.toList()))); // Paper - remove unnecessary item meta
+ if (entity instanceof Allay allay) { // Paper - Hide unnecessary item meta
+ ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, allay.stripMeta(allay.getItemBySlot(slot), true))).collect(Collectors.toList()))); // Paper - Hide unnecessary item meta
ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote();
}
}
@ -41,15 +41,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start - prevent oversized data
ItemStack toSend = sanitizeItemStack(itemstack1, true);
- list.add(Pair.of(enumitemslot, toSend));
+ list.add(Pair.of(enumitemslot, stripMeta(toSend, toSend == itemstack1))); // Paper - hide unnecessary item meta
// Paper end
+ list.add(Pair.of(enumitemslot, stripMeta(toSend, toSend == itemstack1))); // Paper - Hide unnecessary item meta
// Paper end - prevent oversized data
switch (enumitemslot.getType()) {
case HAND:
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
((ServerLevel) this.level()).getChunkSource().broadcast(this, new ClientboundSetEquipmentPacket(this.getId(), list));
}
+ // Paper start - hide unnecessary item meta
+ // Paper start - Hide unnecessary item meta
+ public ItemStack stripMeta(final ItemStack itemStack, final boolean copyItemStack) {
+ if (itemStack.isEmpty() || (!itemStack.hasTag() && itemStack.getCount() < 2)) {
+ return itemStack;
@ -118,7 +118,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ return copy;
+ }
+ // Paper end
+ // Paper end - Hide unnecessary item meta
+
// Paper start - prevent oversized data
public static ItemStack sanitizeItemStack(final ItemStack itemStack, final boolean copyItemStack) {

View file

@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ serverChunkCache.getLightEngine().relight(chunksToRelight, pos -> {}, relit -> {});
+ return true;
+ // Paper end
+ // Paper end - implement regenerate chunk method
}
@Override

View file

@ -12,10 +12,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static boolean checkSurfaceWaterAnimalSpawnRules(EntityType<? extends WaterAnimal> type, LevelAccessor world, MobSpawnType reason, BlockPos pos, RandomSource random) {
int i = world.getSeaLevel();
int j = i - 13;
+ // Paper start
+ // Paper start - Make water animal spawn height configurable
+ i = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(i);
+ j = world.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(j);
+ // Paper end
+ // Paper end - Make water animal spawn height configurable
return pos.getY() >= j && pos.getY() <= i && world.getFluidState(pos.below()).is(FluidTags.WATER) && world.getBlockState(pos.above()).is(Blocks.WATER);
}
}

View file

@ -585,6 +585,47 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public CraftCod(CraftServer server, net.minecraft.world.entity.animal.Cod entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
@@ -0,0 +0,0 @@ public class CraftDolphin extends CraftWaterMob implements Dolphin {
public String toString() {
return "CraftDolphin";
}
+
+ // Paper start - Missing Dolphin API
+ @Override
+ public int getMoistness() {
+ return this.getHandle().getMoistnessLevel();
+ }
+
+ @Override
+ public void setMoistness(int moistness) {
+ this.getHandle().setMoisntessLevel(moistness);
+ }
+
+ @Override
+ public void setHasFish(boolean hasFish) {
+ this.getHandle().setGotFish(hasFish);
+ }
+
+ @Override
+ public boolean hasFish() {
+ return this.getHandle().gotFish();
+ }
+
+ @Override
+ public org.bukkit.Location getTreasureLocation() {
+ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().level(), this.getHandle().getTreasurePos());
+ }
+
+ @Override
+ public void setTreasureLocation(org.bukkit.Location location) {
+ this.getHandle().setTreasurePos(io.papermc.paper.util.MCUtil.toBlockPosition(location));
+ }
+ // Paper end - Missing Dolphin API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java

View file

@ -12,13 +12,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ // Paper start
+ // Paper start - Multi Block Change API
+ public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<BlockState> blockChanges) {
+ this.sectionPos = sectionPos;
+ this.positions = blockChanges.keySet().toShortArray();
+ this.states = blockChanges.values().toArray(new BlockState[0]);
+ }
+ // Paper end
+ // Paper end - Multi Block Change API
+
@Override
public void write(FriendlyByteBuf buf) {

View file

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), ImmutableList.of(playerName));
}
+ // Paper start
+ // Paper start - Multiple Entries with Scoreboards
+ public static ClientboundSetPlayerTeamPacket createMultiplePlayerPacket(PlayerTeam team, Collection<String> players, ClientboundSetPlayerTeamPacket.Action operation) {
+ return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), players);
+ }
+ // Paper end
+ // Paper end - Multiple Entries with Scoreboards
+
public ClientboundSetPlayerTeamPacket(FriendlyByteBuf buf) {
this.name = buf.readUtf();
@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
+ // Paper start
+ // Paper start - Multiple Entries with Scoreboards
+ public boolean addPlayersToTeam(java.util.Collection<String> players, PlayerTeam team) {
+ boolean anyAdded = false;
+ for (String playerName : players) {
@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return false;
+ }
+ }
+ // Paper end
+ // Paper end - Multiple Entries with Scoreboards
+
@Override
public void removePlayerFromTeam(String scoreHolderName, PlayerTeam team) {
@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.setDirty();
}
+ // Paper start
+ // Paper start - Multiple Entries with Scoreboards
+ public void removePlayersFromTeam(java.util.Collection<String> players, PlayerTeam team) {
+ for (String playerName : players) {
+ super.removePlayerFromTeam(playerName, team);
@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.REMOVE));
+ this.setDirty();
+ }
+ // Paper end
+ // Paper end - Multiple Entries with Scoreboards
+
@Override
public void onObjectiveAdded(Objective objective) {
@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
scoreboard.board.addPlayerToTeam(entry, this.team);
}
+ // Paper start
+ // Paper start - Multiple Entries with Scoreboards
+ @Override
+ public void addEntities(java.util.Collection<org.bukkit.entity.Entity> entities) throws IllegalStateException, IllegalArgumentException {
+ this.addEntries(entities.stream().map(entity -> ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName()).toList());
@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ ((net.minecraft.server.ServerScoreboard) scoreboard.board).addPlayersToTeam(entries, this.team);
+ }
+ // Paper end
+ // Paper end - Multiple Entries with Scoreboards
+
@Override
public boolean removePlayer(OfflinePlayer player) {
@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return true;
}
+ // Paper start
+ // Paper start - Multiple Entries with Scoreboards
+ @Override
+ public boolean removeEntities(java.util.Collection<org.bukkit.entity.Entity> entities) throws IllegalStateException, IllegalArgumentException {
+ return this.removeEntries(entities.stream().map(entity -> ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName()).toList());
@ -119,7 +119,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ return false;
+ }
+ // Paper end
+ // Paper end - Multiple Entries with Scoreboards
+
@Override
public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException {

View file

@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ super.write(b, off, len);
+ }
+ // Paper end
+ // Paper end - don't write garbage data to disk if writing serialization fails
+
public void close() throws IOException {
ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count);
@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- if (dataoutputstream != null) {
- dataoutputstream.close();
- }
+ // Paper - move into try block to only write if successfully serialized
+ // Paper - don't write garbage data to disk if writing serialization fails; move into try block to only write if successfully serialized
}
// Paper start
return;
@ -86,12 +86,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+
+ // Paper start
+ // Paper start - don't write garbage data to disk if writing serialization fails
+ public static final class RegionFileSizeException extends RuntimeException {
+
+ public RegionFileSizeException(String message) {
+ super(message);
+ }
+ }
+ // Paper end
+ // Paper end - don't write garbage data to disk if writing serialization fails
}

View file

@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public HashMapPalette(IdMap<T> idList, int indexBits, PaletteResize<T> listener) {
- this(idList, indexBits, listener, CrudeIncrementalIntIdentityHashBiMap.create(1 << indexBits));
+ this(idList, indexBits, listener, CrudeIncrementalIntIdentityHashBiMap.create((1 << indexBits) + 1)); // Paper - Avoid unnecessary resize operation in CrudeIncrementalIntIdentityHashBiMap
+ this(idList, indexBits, listener, CrudeIncrementalIntIdentityHashBiMap.create((1 << indexBits) + 1)); // Paper - Perf: Avoid unnecessary resize operation in CrudeIncrementalIntIdentityHashBiMap
}
private HashMapPalette(IdMap<T> idList, int indexBits, PaletteResize<T> listener, CrudeIncrementalIntIdentityHashBiMap<T> map) {
@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (i == -1) {
- i = this.values.add(object);
- if (i >= 1 << this.bits) {
+ // Paper start - Avoid unnecessary resize operation in CrudeIncrementalIntIdentityHashBiMap and optimize
+ // Paper start - Perf: Avoid unnecessary resize operation in CrudeIncrementalIntIdentityHashBiMap and optimize
+ // We use size() instead of the result from add(K)
+ // This avoids adding another object unnecessarily
+ // Without this change, + 2 would be required in the constructor
@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } else {
+ i = this.values.add(object);
}
+ // Paper end
+ // Paper end - Perf: Avoid unnecessary resize operation in CrudeIncrementalIntIdentityHashBiMap and optimize
}
return i;

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void decrementOpeners(Player player, Level world, BlockPos pos, BlockState state) {
int oldPower = Math.max(0, Math.min(15, this.openCount)); // CraftBukkit - Get power before new viewer is added
+ if (this.openCount == 0) return; // Paper
+ if (this.openCount == 0) return; // Paper - Prevent ContainerOpenersCounter openCount from going negative
int i = this.openCount--;
// CraftBukkit start - Call redstone event

View file

@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - prevent oversized data
+ final ItemStack sanitized = LivingEntity.sanitizeItemStack(itemstack.copy(), false);
+ list.add(Pair.of(enumitemslot, sanitized));
+ // Paper end
+ // Paper end - prevent oversized data
}
}
@ -45,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - prevent oversized data
+ ItemStack toSend = sanitizeItemStack(itemstack1, true);
+ list.add(Pair.of(enumitemslot, toSend));
+ // Paper end
+ // Paper end - prevent oversized data
switch (enumitemslot.getType()) {
case HAND:
this.setLastHandItem(enumitemslot, itemstack1);
@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ return copy;
+ }
+ // Paper end
+ // Paper end - prevent oversized data
+
private ItemStack getLastArmorItem(EquipmentSlot slot) {
return (ItemStack) this.lastArmorItemStacks.get(slot.getIndex());

View file

@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- Util.LOGGER.error("Couldn't open url '{}'", url, var3);
- }
-
+ throw new IllegalStateException("This method is not useful on dedicated servers."); // Paper
+ throw new IllegalStateException("This method is not useful on dedicated servers."); // Paper - Fix warnings on build by removing client-only code
}
public void openUri(URI uri) {

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem) {
blockstate = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos());
}
+ final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper
+ final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper - Reset placed block on exception
// CraftBukkit end
if (iblockdata == null) {
@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (iblockdata1.is(iblockdata.getBlock())) {
iblockdata1 = this.updateBlockStateFromTag(blockposition, world, itemstack, iblockdata1);
+ // Paper start - reset block on exception
+ // Paper start - Reset placed block on exception
+ try {
this.updateCustomBlockEntityTag(blockposition, world, entityhuman, itemstack, iblockdata1);
+ } catch (Exception e) {
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ throw e; // Rethrow exception if not placed by a player
+ }
+ // Paper end
+ // Paper end - Reset placed block on exception
iblockdata1.getBlock().setPlacedBy(world, blockposition, iblockdata1, entityhuman, itemstack);
// CraftBukkit start
if (blockstate != null) {

View file

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final List<StructureTemplate.StructureBlockInfo> blocks;
- private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newHashMap();
+ private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newConcurrentMap(); // Paper
+ private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads
Palette(List<StructureTemplate.StructureBlockInfo> infos) {
this.blocks = infos;

View file

@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return name.length() > 16 ? false : name.chars().filter((i) -> {
- return i <= 32 || i >= 127;
- }).findAny().isEmpty();
+ // Paper start
+ // Paper start - username validation overriding
+ if (name == null || name.isEmpty() || name.length() > 16) {
+ return false;
+ }
@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ return true;
+ // Paper end
+ // Paper end - username validation overriding
}
public static float getPickRange(boolean creative) {