diff --git a/parchment-server/minecraft-patches/sources/io/papermc/paper/command/subcommands/FixLightCommand.java.patch b/parchment-server/minecraft-patches/sources/io/papermc/paper/command/subcommands/FixLightCommand.java.patch new file mode 100644 index 0000000..e9669ca --- /dev/null +++ b/parchment-server/minecraft-patches/sources/io/papermc/paper/command/subcommands/FixLightCommand.java.patch @@ -0,0 +1,28 @@ +--- a/io/papermc/paper/command/subcommands/FixLightCommand.java ++++ b/io/papermc/paper/command/subcommands/FixLightCommand.java +@@ -95,16 +_,20 @@ + ((StarLightLightingProvider)lightengine).starlight$serverRelightChunks(chunks, + (final ChunkPos chunkPos) -> { + ++relitChunks[0]; +- sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( +- text("Relit chunk ", BLUE), text(chunkPos.toString()), +- text(", progress: ", BLUE), text(ONE_DECIMAL_PLACES.get().format(100.0 * (double) (relitChunks[0]) / (double) pending[0]) + "%") ++ sender.getBukkitEntity().sendActionBar(text().color(DARK_AQUA).append( ++ text("Relighting Chunks: ", DARK_AQUA), text(chunkPos.toString()), ++ text(" " + relitChunks[0], net.kyori.adventure.text.format.NamedTextColor.YELLOW), ++ text("/", DARK_AQUA), ++ text(pending[0] + " ", net.kyori.adventure.text.format.NamedTextColor.YELLOW), ++ text("(" + (int) (Math.round(100.0 * (double) (relitChunks[0]) / (double) pending[0])) + "%)", net.kyori.adventure.text.format.NamedTextColor.YELLOW) + )); + }, + (final int totalRelit) -> { + final long end = System.nanoTime(); ++ final long diff = Math.round(1.0e-6 * (end - start)); + sender.getBukkitEntity().sendMessage(text().color(DARK_AQUA).append( +- text("Relit ", BLUE), text(totalRelit), +- text(" chunks. Took ", BLUE), text(ONE_DECIMAL_PLACES.get().format(1.0e-6 * (end - start)) + "ms") ++ text("Relit ", DARK_AQUA), text(totalRelit, net.kyori.adventure.text.format.NamedTextColor.YELLOW), ++ text(" chunks. Took ", DARK_AQUA), text(diff + "ms", net.kyori.adventure.text.format.NamedTextColor.YELLOW) + )); + if (done != null) { + done.run(); diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/core/Holder.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/core/Holder.java.patch new file mode 100644 index 0000000..7cfd0d3 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/core/Holder.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/core/Holder.java ++++ b/net/minecraft/core/Holder.java +@@ -138,6 +_,12 @@ + return new Holder.Reference<>(Holder.Reference.Type.INTRUSIVE, owner, null, value); + } + ++ // Parchment start ++ public static Holder.Reference create(HolderOwner owner, @Nullable ResourceKey registryKey, @Nullable T value) { ++ return new Holder.Reference<>(Holder.Reference.Type.STAND_ALONE, owner, registryKey, value); ++ } ++ // Parchment end ++ + public ResourceKey key() { + if (this.key == null) { + throw new IllegalStateException("Trying to access unbound value '" + this.value + "' from registry " + this.owner); diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch new file mode 100644 index 0000000..8853496 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/dedicated/DedicatedServer.java ++++ b/net/minecraft/server/dedicated/DedicatedServer.java +@@ -272,6 +_,8 @@ + return false; + } + ++ gg.projecteden.parchment.entity.EntityDataServices.init(); ++ + // CraftBukkit start + // this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage)); // Spigot - moved up + this.server.loadPlugins(); diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch new file mode 100644 index 0000000..df9f147 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -0,0 +1,77 @@ +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -1053,7 +_,7 @@ + + private void announceSleepStatus() { + if (this.canSleepThroughNights()) { +- if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) { ++ if (false && !this.getServer().isSingleplayer() || this.getServer().isPublished()) { + int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); + Component component; + if (this.sleepStatus.areEnoughSleeping(_int)) { +@@ -1623,28 +_,47 @@ + + @Override + public void playSeededSound( +- @Nullable Player player, double x, double y, double z, Holder sound, SoundSource category, float volume, float pitch, long seed +- ) { +- this.server +- .getPlayerList() +- .broadcast( +- player, x, y, z, sound.value().getRange(volume), this.dimension(), new ClientboundSoundPacket(sound, category, x, y, z, volume, pitch, seed) +- ); ++ @Nullable Player player, double x, double y, double z, Holder sound, SoundSource category, float volume, float pitch, long seed) { ++ // Parchment start - sound event ++ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new gg.projecteden.parchment.event.sound.SoundEvent( ++ player == null ? null : player.getBukkitEntity(), ++ net.kyori.adventure.sound.Sound.sound() ++ .type(sound.unwrap().map( ++ key -> io.papermc.paper.adventure.PaperAdventure.asAdventure(key.location()), ++ soundEvent -> io.papermc.paper.adventure.PaperAdventure.asAdventure(soundEvent.location()) ++ )) ++ .source(io.papermc.paper.adventure.PaperAdventure.asAdventure(category)) ++ .volume(volume) ++ .pitch(pitch) ++ .seed(seed) ++ .build(), ++ gg.projecteden.parchment.event.sound.ParchmentSoundEvent.createEmitter(this, x, y, z), ++ gg.projecteden.parchment.event.sound.ParchmentSoundEvent.DISTANCE_FUNCTION, ++ null ++ )); ++ // Parchment end + } + + @Override + public void playSeededSound(@Nullable Player player, Entity entity, Holder sound, SoundSource category, float volume, float pitch, long seed) { +- this.server +- .getPlayerList() +- .broadcast( +- player, +- entity.getX(), +- entity.getY(), +- entity.getZ(), +- sound.value().getRange(volume), +- this.dimension(), +- new ClientboundSoundEntityPacket(sound, category, entity, volume, pitch, seed) +- ); ++ // Parchment start - sound event ++ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new gg.projecteden.parchment.event.sound.SoundEvent( ++ player == null ? null : player.getBukkitEntity(), ++ net.kyori.adventure.sound.Sound.sound() ++ .type(sound.unwrap().map( ++ key -> io.papermc.paper.adventure.PaperAdventure.asAdventure(key.location()), ++ soundEvent -> io.papermc.paper.adventure.PaperAdventure.asAdventure(soundEvent.location()) ++ )) ++ .source(io.papermc.paper.adventure.PaperAdventure.asAdventure(category)) ++ .volume(volume) ++ .pitch(pitch) ++ .seed(seed) ++ .build(), ++ gg.projecteden.parchment.event.sound.ParchmentSoundEvent.createEmitter(entity), ++ gg.projecteden.parchment.event.sound.ParchmentSoundEvent.DISTANCE_FUNCTION, ++ null ++ )); ++ // Parchment end + } + + @Override diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch new file mode 100644 index 0000000..1bb058d --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -0,0 +1,46 @@ +--- a/net/minecraft/server/level/ServerPlayer.java ++++ b/net/minecraft/server/level/ServerPlayer.java +@@ -176,6 +_,7 @@ + import net.minecraft.world.scores.ScoreHolder; + import net.minecraft.world.scores.Team; + import net.minecraft.world.scores.criteria.ObjectiveCriteria; ++import org.bukkit.SoundCategory; + import org.slf4j.Logger; + + public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system +@@ -2546,7 +_,7 @@ + // Paper end - Add PlayerSetSpawnEvent + + if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper - Add PlayerSetSpawnEvent +- this.sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getNotification())); // Paper - Add PlayerSetSpawnEvent ++ //this.sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getNotification())); // Paper - Add PlayerSetSpawnEvent + } + + this.respawnPosition = position; +@@ -2581,12 +_,20 @@ + + @Override + public void playNotifySound(SoundEvent sound, SoundSource source, float volume, float pitch) { +- this.connection +- .send( +- new ClientboundSoundPacket( +- BuiltInRegistries.SOUND_EVENT.wrapAsHolder(sound), source, this.getX(), this.getY(), this.getZ(), volume, pitch, this.random.nextLong() +- ) +- ); ++ // Parchment start - sound event ++ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new gg.projecteden.parchment.event.sound.SoundEvent( ++ null, ++ net.kyori.adventure.sound.Sound.sound() ++ .type(io.papermc.paper.adventure.PaperAdventure.asAdventure(sound.location())) ++ .source(io.papermc.paper.adventure.PaperAdventure.asAdventure(source)) ++ .volume(volume) ++ .pitch(pitch) ++ .seed(this.random.nextLong()) ++ .build(), ++ gg.projecteden.parchment.event.sound.ParchmentSoundEvent.createEmitter(level(), getX(), getY(), getZ()), ++ _sound -> 0d, soundEvent -> java.util.Collections.singletonList(getBukkitEntity()) ++ )); ++ // Parchment end + } + + @Override diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch new file mode 100644 index 0000000..4b7b11d --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -778,9 +_,12 @@ + public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { + // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async + // CraftBukkit start +- if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits +- this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect +- return; ++ if (!this.getCraftPlayer().hasPermission("spam.bypass")) { // Parchment - spam bypass ++ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits ++ this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect ++ return; ++ ++ } + } + // CraftBukkit end + // Paper start - Don't suggest if tab-complete is disabled +@@ -2490,6 +_,7 @@ + + // Spigot start - spam exclusions + private void detectRateSpam(String message) { ++ if (this.getCraftPlayer().hasPermission("spam.bypass")) return; // Parchment - spam bypass + // CraftBukkit start - replaced with thread safe throttle + for (String exclude : org.spigotmc.SpigotConfig.spamExclusions) { + if (exclude != null && message.startsWith(exclude)) { +@@ -3245,9 +_,11 @@ + public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { + // Paper start - auto recipe limit + if (!org.bukkit.Bukkit.isPrimaryThread()) { +- if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { +- this.disconnectAsync(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect +- return; ++ if (!this.getCraftPlayer().hasPermission("spam.bypass")) { // Parchment - spam bypass ++ if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { ++ this.disconnectAsync(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect ++ return; ++ } + } + } + // Paper end - auto recipe limit diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/server/players/PlayerList.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/server/players/PlayerList.java.patch new file mode 100644 index 0000000..4dc8b8a --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/server/players/PlayerList.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -802,19 +_,7 @@ + if (!keepInventory && respawnPosition != null && level1 != null) { + BlockState blockState = level1.getBlockState(respawnPosition); + if (blockState.is(Blocks.RESPAWN_ANCHOR)) { +- serverPlayer.connection +- .send( +- new ClientboundSoundPacket( +- SoundEvents.RESPAWN_ANCHOR_DEPLETE, +- SoundSource.BLOCKS, +- respawnPosition.getX(), +- respawnPosition.getY(), +- respawnPosition.getZ(), +- 1.0F, +- 1.0F, +- level.getRandom().nextLong() +- ) +- ); ++ player.playNotifySound(SoundEvents.RESPAWN_ANCHOR_DEPLETE.value(), SoundSource.BLOCKS, 1.0F, 1.0F); // Parchment - use existing play sound method + } + // Paper start - Add PlayerPostRespawnEvent + if (blockState.is(net.minecraft.tags.BlockTags.BEDS) && !teleportTransition.missingRespawnBlock()) { diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch new file mode 100644 index 0000000..259b8cd --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -5081,4 +_,31 @@ + return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition()); + } + // Paper end - Expose entity id counter ++ ++ ++ @javax.annotation.Nullable ++ private gg.projecteden.parchment.entity.EntityData storedEntityData; ++ ++ /** ++ * Retrieves the stored EntityData for this entity ++ * @return The currently stored EntityData ++ */ ++ public gg.projecteden.parchment.entity.EntityData getStoredEntityData() { ++ if (this.storedEntityData == null) { ++ this.storedEntityData = gg.projecteden.parchment.entity.EntityData.create(this.getBukkitEntity()); ++ } ++ return this.storedEntityData; ++ } ++ ++ /** ++ * Clears the currently stored EntityData for this entity ++ * @return the previously stored EntityData ++ */ ++ public @javax.annotation.Nullable gg.projecteden.parchment.entity.EntityData clearStoredEntityData() { ++ gg.projecteden.parchment.entity.EntityData data = this.storedEntityData; ++ this.storedEntityData = null; ++ ++ return data; ++ } ++ + } diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch new file mode 100644 index 0000000..0235a32 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/LivingEntity.java ++++ b/net/minecraft/world/entity/LivingEntity.java +@@ -4087,7 +_,7 @@ + Vec3 direction = this.getLookAngle(); + Vec3 end = start.add(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance); + +- List entityList = this.level().getEntities(this, getBoundingBox().expandTowards(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).inflate(1.0D, 1.0D, 1.0D), EntitySelector.NO_SPECTATORS.and(Entity::isPickable)); ++ List entityList = this.level().getEntities(this, getBoundingBox().expandTowards(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).inflate(1.0D, 1.0D, 1.0D), EntitySelector.NO_SPECTATORS.and(entity -> entity.isPickable() || entity instanceof Display)); // Parchment - add displays; + + double distance = 0.0D; + net.minecraft.world.phys.EntityHitResult result = null; diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/decoration/HangingEntity.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/decoration/HangingEntity.java.patch new file mode 100644 index 0000000..13ed630 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/decoration/HangingEntity.java.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/world/entity/decoration/HangingEntity.java ++++ b/net/minecraft/world/entity/decoration/HangingEntity.java +@@ -23,6 +_,9 @@ + protected static final Predicate HANGING_ENTITY = entity -> entity instanceof HangingEntity; + protected Direction direction = Direction.SOUTH; + ++ private int checkInterval; { this.checkInterval = this.getId() % this.level().spigotConfig.hangingTickFrequency; } // Paper - Perf: offset item frame ticking ++ public boolean tick = true; // Parchment ++ + protected HangingEntity(EntityType entityType, Level level) { + super(entityType, level); + } +@@ -116,4 +_,38 @@ + public float mirror(Mirror transformMirror) { + return this.rotate(transformMirror.getRotation(this.direction)); + } ++ ++ @Override ++ public void tick() { ++ if (tick && !this.level().isClientSide) { // Parchment ++ this.checkBelowWorld(); ++ if (this.checkInterval++ == this.level().spigotConfig.hangingTickFrequency) { // Spigot ++ this.checkInterval = 0; ++ if (!this.isRemoved() && !this.survives()) { ++ // CraftBukkit start - fire break events ++ BlockState material = this.level().getBlockState(this.blockPosition()); ++ org.bukkit.event.hanging.HangingBreakEvent.RemoveCause cause; ++ ++ if (!material.isAir()) { ++ // TODO: This feels insufficient to catch 100% of suffocation cases ++ cause = org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.OBSTRUCTION; ++ } else { ++ cause = org.bukkit.event.hanging.HangingBreakEvent.RemoveCause.PHYSICS; ++ } ++ ++ org.bukkit.event.hanging.HangingBreakEvent event = new org.bukkit.event.hanging.HangingBreakEvent((org.bukkit.entity.Hanging) this.getBukkitEntity(), cause); ++ this.level().getCraftServer().getPluginManager().callEvent(event); ++ ++ if (this.isRemoved() || event.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause ++ this.dropItem((ServerLevel) this.level(), (Entity) null); ++ } ++ } ++ } ++ ++ } ++ + } diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch new file mode 100644 index 0000000..e80d72c --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/entity/monster/AbstractSkeleton.java ++++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java +@@ -202,6 +_,12 @@ + ItemStack itemInHand = this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW)); + ItemStack projectile = this.getProjectile(itemInHand); + AbstractArrow arrow = this.getArrow(projectile, distanceFactor, itemInHand); ++ ++ // Parchment start ++ gg.projecteden.parchment.event.entity.PreEntityShootBowEvent preEvent = new gg.projecteden.parchment.event.entity.PreEntityShootBowEvent(this.getBukkitEntity(), this.getMainHandItem().asBukkitCopy(), itemstack1.asBukkitCopy()); ++ if (!preEvent.callEvent()) return; ++ // Parchment end ++ + double d = target.getX() - this.getX(); + double d1 = target.getY(0.3333333333333333) - arrow.getY(); + double d2 = target.getZ() - this.getZ(); +@@ -217,7 +_,7 @@ + if (event.getProjectile() == arrow.getBukkitEntity()) { + // CraftBukkit end + Projectile.spawnProjectileUsingShoot( +- arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4 ++ arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4, preEvent.isRelative() + ); + } // CraftBukkit + } diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch new file mode 100644 index 0000000..946ab81 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/world/entity/monster/Illusioner.java ++++ b/net/minecraft/world/entity/monster/Illusioner.java +@@ -175,6 +_,11 @@ + ItemStack itemInHand = this.getItemInHand(ProjectileUtil.getWeaponHoldingHand(this, Items.BOW)); + ItemStack projectile = this.getProjectile(itemInHand); + AbstractArrow mobArrow = ProjectileUtil.getMobArrow(this, projectile, distanceFactor, itemInHand); ++ ++ gg.projecteden.parchment.event.entity.PreEntityShootBowEvent preEvent = new gg.projecteden.parchment.event.entity.PreEntityShootBowEvent(this.getBukkitEntity(), this.getMainHandItem().asBukkitCopy(), itemstack1.asBukkitCopy()); ++ if (!preEvent.callEvent()) return; ++ // Parchment end ++ + double d = target.getX() - this.getX(); + double d1 = target.getY(0.3333333333333333) - mobArrow.getY(); + double d2 = target.getZ() - this.getZ(); +@@ -189,7 +_,7 @@ + + if (event.getProjectile() == mobArrow.getBukkitEntity()) { + Projectile.spawnProjectileUsingShoot( +- mobArrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4 ++ mobArrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4, preEvent.isRelative() + ); + } + // Paper end - EntityShootBowEvent diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch new file mode 100644 index 0000000..95c7c83 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -0,0 +1,50 @@ +--- a/net/minecraft/world/entity/player/Player.java ++++ b/net/minecraft/world/entity/player/Player.java +@@ -314,7 +_,7 @@ + this.awardStat(Stats.CROUCH_TIME); + } + +- if (!this.isSleeping()) { ++ if (!this.isSleeping() && this.level().paperConfig().entities.behavior.tickTimeSinceSleep) { // Parchment + this.awardStat(Stats.TIME_SINCE_REST); + } + } +@@ -1824,9 +_,23 @@ + + // Paper start - send while respecting visibility + private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { +- fromEntity.level().playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity itself +- if (fromEntity instanceof ServerPlayer serverPlayer) { +- serverPlayer.connection.send(new net.minecraft.network.protocol.game.ClientboundSoundPacket(net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(soundEffect), soundCategory, x, y, z, volume, pitch, fromEntity.random.nextLong())); ++ fromEntity.level().playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself ++ if (fromEntity instanceof ServerPlayer) { ++ // Parchment start - sound event ++ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new gg.projecteden.parchment.event.sound.SoundEvent( ++ null, ++ net.kyori.adventure.sound.Sound.sound() ++ .type(io.papermc.paper.adventure.PaperAdventure.asAdventure(soundEffect.location())) ++ .source(io.papermc.paper.adventure.PaperAdventure.asAdventure(soundCategory)) ++ .volume(volume) ++ .pitch(pitch) ++ .seed(fromEntity.random.nextLong()) ++ .build(), ++ gg.projecteden.parchment.event.sound.ParchmentSoundEvent.createEmitter(fromEntity.level(), x, y, z), ++ sound -> 0d, ++ soundEvent -> java.util.Collections.singletonList(((ServerPlayer) fromEntity).getBukkitEntity()) ++ )); ++ // Parchment end + } + } + // Paper end - send while respecting visibility +@@ -2432,4 +_,11 @@ + return this.message; + } + } ++ ++ // Parchment start ++ public void setProfile(GameProfile gameProfile) { ++ this.gameProfile = gameProfile; ++ } ++ // Parchment end ++ + } diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch new file mode 100644 index 0000000..2e4ae69 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/entity/projectile/AbstractArrow.java ++++ b/net/minecraft/world/entity/projectile/AbstractArrow.java +@@ -146,8 +_,9 @@ + } + + @Override +- public void shoot(double x, double y, double z, float velocity, float inaccuracy) { +- super.shoot(x, y, z, velocity, inaccuracy); ++ public void shoot(double x, double y, double z, float speed, float divergence, boolean relative) { ++ super.shoot(x, y, z, speed, divergence, relative); ++ // Parchment end + this.life = 0; + } + diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch new file mode 100644 index 0000000..0009f75 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -0,0 +1,73 @@ +--- a/net/minecraft/world/entity/projectile/Projectile.java ++++ b/net/minecraft/world/entity/projectile/Projectile.java +@@ -182,8 +_,14 @@ + } + + public void shoot(double x, double y, double z, float velocity, float inaccuracy) { ++ shoot(x, y, z, velocity, inaccuracy, true); ++ } ++ ++ public void shoot(double x, double y, double z, float velocity, float inaccuracy, boolean relative) { + Vec3 movementToShoot = this.getMovementToShoot(x, y, z, velocity, inaccuracy); +- this.setDeltaMovement(movementToShoot); ++ if (relative) { // Parchment ++ this.setDeltaMovement(movementToShoot); ++ } // Parchment + this.hasImpulse = true; + double d = movementToShoot.horizontalDistance(); + this.setYRot((float)(Mth.atan2(movementToShoot.x, movementToShoot.z) * 180.0F / (float)Math.PI)); +@@ -193,14 +_,19 @@ + } + + public void shootFromRotation(Entity shooter, float x, float y, float z, float velocity, float inaccuracy) { ++ // Parchment start ++ shootFromRotation(shooter, x, y, z, velocity, inaccuracy, true); ++ } ++ ++ public void shootFromRotation(Entity shooter, float x, float y, float z, float velocity, float inaccuracy, boolean relative) { + float f = -Mth.sin(y * (float) (Math.PI / 180.0)) * Mth.cos(x * (float) (Math.PI / 180.0)); + float f1 = -Mth.sin((x + z) * (float) (Math.PI / 180.0)); + float f2 = Mth.cos(y * (float) (Math.PI / 180.0)) * Mth.cos(x * (float) (Math.PI / 180.0)); + this.shoot(f, f1, f2, velocity, inaccuracy); + Vec3 knownMovement = shooter.getKnownMovement(); + // Paper start - allow disabling relative velocity +- if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity) { +- this.setDeltaMovement(this.getDeltaMovement().add(knownMovement.x, shooter.onGround() ? 0.0 : knownMovement.y, knownMovement.z)); ++ if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity && relative) { ++ this.setDeltaMovement(this.getDeltaMovement().add(knownMovement.x, shooter.onGround() ? 0.0 : knownMovement.y, knownMovement.z)); + } + // Paper end - allow disabling relative velocity + } +@@ -232,7 +_,11 @@ + float velocity, + float inaccuracy + ) { +- return spawnProjectile(factory.create(level, owner, spawnedFrom), level, spawnedFrom, projectile -> projectile.shoot(x, y, z, velocity, inaccuracy)); ++ return Projectile.spawnProjectileUsingShoot(factory, level, spawnedFrom, owner, x, y, z, velocity, inaccuracy, true); ++ } ++ ++ public static T spawnProjectileUsingShoot(Projectile.ProjectileFactory factory, ServerLevel level, ItemStack spawnedFrom, LivingEntity owner, double x, double y, double z, float velocity, float inaccuracy, boolean relative) { ++ return spawnProjectile(factory.create(level, owner, spawnedFrom), level, spawnedFrom, projectile -> projectile.shoot(x, y, z, velocity, inaccuracy, relative)); + } + + public static T spawnProjectileUsingShoot( +@@ -241,9 +_,19 @@ + // Paper start - fixes and addition to spawn reason API + return spawnProjectileUsingShootDelayed(projectile, level, spawnedFrom, x, y, z, velocity, inaccuracy).spawn(); + } ++ public static T spawnProjectileUsingShoot(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence, boolean relative) { ++ // Paper start - fixes and addition to spawn reason API ++ return spawnProjectileUsingShootDelayed(projectile, world, projectileStack, velocityX, velocityY, velocityZ, power, divergence, relative).spawn(); ++ } + public static Delayed spawnProjectileUsingShootDelayed(T projectile, ServerLevel level, ItemStack spawnedFrom, double x, double y, double z, float velocity, float inaccuracy) { + return spawnProjectileDelayed(projectile, level, spawnedFrom, projectile1 -> projectile.shoot(x, y, z, velocity, inaccuracy)); + // Paper end - fixes and addition to spawn reason API ++ } ++ public static Delayed spawnProjectileUsingShootDelayed(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence, boolean relative) { ++ return Projectile.spawnProjectileDelayed(projectile, world, projectileStack, (iprojectile) -> { ++ // Paper end - fixes and addition to spawn reason API ++ projectile.shoot(velocityX, velocityY, velocityZ, power, divergence, relative); ++ }); + } + + public static T spawnProjectile(T projectile, ServerLevel level, ItemStack spawnedFrom) { diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/raid/Raid.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/raid/Raid.java.patch new file mode 100644 index 0000000..8976090 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/entity/raid/Raid.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/entity/raid/Raid.java ++++ b/net/minecraft/world/entity/raid/Raid.java +@@ -503,8 +_,7 @@ + double d = vec3.x + 13.0 / squareRoot * (vec31.x - vec3.x); + double d1 = vec3.z + 13.0 / squareRoot * (vec31.z - vec3.z); + if (squareRoot <= 64.0 || players.contains(serverPlayer)) { +- serverPlayer.connection +- .send(new ClientboundSoundPacket(SoundEvents.RAID_HORN, SoundSource.NEUTRAL, d, serverPlayer.getY(), d1, 64.0F, 1.0F, randomLong)); ++ serverPlayer.playNotifySound(SoundEvents.RAID_HORN.value(), SoundSource.NEUTRAL, 64.0F, 1.0F); // Parchment - use existing play sound method + } + } + } diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/item/BowItem.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/item/BowItem.java.patch new file mode 100644 index 0000000..612d793 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/item/BowItem.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/item/BowItem.java ++++ b/net/minecraft/world/item/BowItem.java +@@ -37,8 +_,12 @@ + return false; + } else { + List list = draw(stack, projectile, player); +- if (level instanceof ServerLevel serverLevel && !list.isEmpty()) { +- this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, 1.0F, powerForTime == 1.0F, null); ++ if (!level.isClientSide() && !list.isEmpty()) { ++ // Parchment start ++ gg.projecteden.parchment.event.entity.PreEntityShootBowEvent preEvent = new gg.projecteden.parchment.event.entity.PreEntityShootBowEvent(player.getBukkitEntity(), stack.asBukkitCopy(), stack.asBukkitCopy()); ++ if (!preEvent.callEvent()) return false; ++ // Parchment end ++ this.shoot((ServerLevel) level, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, 1.0F, powerForTime == 1.0F, null, preEvent.isRelative()); + } + + level.playSound( +@@ -60,9 +_,9 @@ + + @Override + protected void shootProjectile( +- LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target ++ LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target, boolean relative + ) { +- projectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot() + angle, 0.0F, velocity, inaccuracy); ++ projectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot() + angle, 0.0F, velocity, inaccuracy, relative); + } + + public static float getPowerForTime(int charge) { diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/item/CrossbowItem.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/item/CrossbowItem.java.patch new file mode 100644 index 0000000..afb9d4a --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/item/CrossbowItem.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/world/item/CrossbowItem.java ++++ b/net/minecraft/world/item/CrossbowItem.java +@@ -141,7 +_,7 @@ + + @Override + protected void shootProjectile( +- LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target ++ LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target, boolean relative + ) { + Vector3f projectileShotVector; + if (target != null) { +@@ -202,8 +_,15 @@ + ) { + if (level instanceof ServerLevel serverLevel) { + ChargedProjectiles chargedProjectiles = weapon.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.EMPTY); ++ ++ // Parchment start ++ gg.projecteden.parchment.event.entity.PreEntityShootBowEvent preEvent = new gg.projecteden.parchment.event.entity.PreEntityShootBowEvent(shooter.getBukkitEntity(), stack.asBukkitCopy(), chargedProjectiles.getItems().get(0).asBukkitCopy()); ++ if (!preEvent.callEvent()) return; ++ // TODO: handle relative flag in CrossbowAttackMob#shootCrossbowProjectile ++ // Parchment end ++ + if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { +- this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target); ++ this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target, preEvent.isRelative()); + if (shooter instanceof ServerPlayer serverPlayer) { + CriteriaTriggers.SHOT_CROSSBOW.trigger(serverPlayer, weapon); + serverPlayer.awardStat(Stats.ITEM_USED.get(weapon.getItem())); diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch new file mode 100644 index 0000000..e8cf992 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/item/ProjectileWeaponItem.java ++++ b/net/minecraft/world/item/ProjectileWeaponItem.java +@@ -49,7 +_,8 @@ + float velocity, + float inaccuracy, + boolean isCrit, +- @Nullable LivingEntity target ++ @Nullable LivingEntity target, ++ boolean relative + ) { + float f = EnchantmentHelper.processProjectileSpread(level, weapon, shooter, 0.0F); + float f1 = projectileItems.size() == 1 ? 0.0F : 2.0F * f / (projectileItems.size() - 1); +@@ -64,7 +_,7 @@ + int i1 = i; + // CraftBukkit start + Projectile projectile = this.createProjectile(level, shooter, weapon, itemStack, isCrit); +- this.shootProjectile(shooter, projectile, i1, velocity, inaccuracy, f4, target); ++ this.shootProjectile(shooter, projectile, i1, velocity, inaccuracy, f4, target, relative); + + org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, weapon, itemStack, projectile, hand, velocity, true); + if (event.isCancelled()) { +@@ -98,7 +_,7 @@ + } + + protected abstract void shootProjectile( +- LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target ++ LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target, boolean relative + ); + + protected Projectile createProjectile(Level level, LivingEntity shooter, ItemStack weapon, ItemStack ammo, boolean isCrit) { diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/Block.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/Block.java.patch new file mode 100644 index 0000000..c86aece --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -0,0 +1,73 @@ +--- a/net/minecraft/world/level/block/Block.java ++++ b/net/minecraft/world/level/block/Block.java +@@ -308,30 +_,46 @@ + } + // Paper end - Add BlockBreakBlockEvent + +- public static void dropResources(BlockState state, Level level, BlockPos pos) { ++ public static List dropResources(BlockState state, Level level, BlockPos pos) { + if (level instanceof ServerLevel) { +- getDrops(state, (ServerLevel)level, pos, null).forEach(itemStack -> popResource(level, pos, itemStack)); ++ List itemEntities = new java.util.ArrayList<>(); ++ org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDropResourcesEvent(level, pos, Block.getDrops(state, (ServerLevel) level, pos, (BlockEntity) null)).forEach((itemstack) -> { // Parchment ++ itemEntities.add(Block.popResourceWithReturn(level, pos, itemstack)); ++ }); + state.spawnAfterBreak((ServerLevel)level, pos, ItemStack.EMPTY, true); ++ return itemEntities; + } ++ return new java.util.ArrayList<>(); + } + +- public static void dropResources(BlockState state, LevelAccessor level, BlockPos pos, @Nullable BlockEntity blockEntity) { ++ public static List dropResources(BlockState state, LevelAccessor level, BlockPos pos, @Nullable BlockEntity blockEntity) { + if (level instanceof ServerLevel) { +- getDrops(state, (ServerLevel)level, pos, blockEntity).forEach(itemStack -> popResource((ServerLevel)level, pos, itemStack)); ++ List itemEntities = new java.util.ArrayList<>(); ++ org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDropResourcesEvent(level, pos, Block.getDrops(state, (ServerLevel) level, pos, blockEntity)).forEach((itemstack) -> { // Parchment ++ itemEntities.add(Block.popResourceWithReturn((ServerLevel) level, pos, itemstack)); ++ }); + state.spawnAfterBreak((ServerLevel)level, pos, ItemStack.EMPTY, true); ++ return itemEntities; + } ++ return new java.util.ArrayList<>(); + } + + public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { + // Paper start - Properly handle xp dropping + dropResources(state, level, pos, blockEntity, entity, tool, true); + } +- public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) { ++ public static List dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) { + // Paper end - Properly handle xp dropping + if (level instanceof ServerLevel) { +- getDrops(state, (ServerLevel)level, pos, blockEntity, entity, tool).forEach(itemStack -> popResource(level, pos, itemStack)); ++ List itemEntities = new java.util.ArrayList<>(); ++ org.bukkit.craftbukkit.event.CraftEventFactory.callBlockDropResourcesEvent(level, pos, Block.getDrops(state, (ServerLevel) level, pos, blockEntity, entity, tool)).forEach((itemstack1) -> { // Parchment ++ Block.popResource(level, pos, itemstack1); ++ itemEntities.add(Block.popResourceWithReturn(level, pos, itemstack1)); ++ }); + state.spawnAfterBreak((ServerLevel) level, pos, tool, dropExperience); // Paper - Properly handle xp dropping ++ return itemEntities; + } ++ return new java.util.ArrayList<>(); + } + + public static void popResource(Level level, BlockPos pos, ItemStack stack) { +@@ -340,6 +_,17 @@ + double d2 = pos.getY() + 0.5 + Mth.nextDouble(level.random, -0.25, 0.25) - d; + double d3 = pos.getZ() + 0.5 + Mth.nextDouble(level.random, -0.25, 0.25); + popResource(level, () -> new ItemEntity(level, d1, d2, d3, stack), stack); ++ } ++ ++ public static ItemEntity popResourceWithReturn(Level world, BlockPos pos, ItemStack stack) { ++ double d0 = (double) EntityType.ITEM.getHeight() / 2.0D; ++ double d1 = (double) pos.getX() + 0.5D + Mth.nextDouble(world.random, -0.25D, 0.25D); ++ double d2 = (double) pos.getY() + 0.5D + Mth.nextDouble(world.random, -0.25D, 0.25D) - d0; ++ double d3 = (double) pos.getZ() + 0.5D + Mth.nextDouble(world.random, -0.25D, 0.25D); ++ ++ ItemEntity itemEntity = new ItemEntity(world, d1, d2, d3, stack); ++ Block.popResource(world, () -> itemEntity, stack); ++ return itemEntity; + } + + public static void popResourceFromFace(Level level, BlockPos pos, Direction direction, ItemStack stack) { diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch new file mode 100644 index 0000000..9dcb113 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/world/level/block/NoteBlock.java ++++ b/net/minecraft/world/level/block/NoteBlock.java +@@ -70,6 +_,7 @@ + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(this.defaultBlockState()), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.INSTRUMENT).callEvent()) return this.defaultBlockState(); + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return this.defaultBlockState(); // Paper - place without considering instrument + return this.setInstrument(context.getLevel(), context.getClickedPos(), this.defaultBlockState()); + } +@@ -85,6 +_,7 @@ + BlockState neighborState, + RandomSource random + ) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.INSTRUMENT, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, (Level) level)).callEvent()) return state; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return state; // Paper - prevent noteblock instrument from updating + boolean flag = direction.getAxis() == Direction.Axis.Y; + return flag +@@ -94,6 +_,7 @@ + + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(this.defaultBlockState()), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.POWERED, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating + boolean hasNeighborSignal = level.hasNeighborSignal(pos); + if (hasNeighborSignal != state.getValue(POWERED)) { +@@ -125,7 +_,9 @@ + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { +- if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating ++ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates || ++ !new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(this.defaultBlockState()), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.PITCH, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) ++ state = (BlockState) state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating + level.setBlock(pos, state, 3); + this.playNote(player, state, level, pos); + player.awardStat(Stats.TUNE_NOTEBLOCK); diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch new file mode 100644 index 0000000..32b1603 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/world/level/block/RespawnAnchorBlock.java ++++ b/net/minecraft/world/level/block/RespawnAnchorBlock.java +@@ -75,7 +_,32 @@ + protected InteractionResult useItemOn( + ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult + ) { ++ // Parchment start -- PlayerUseRespawnAnchorEvent ++ org.bukkit.entity.Player bukkitPlayer = player.getBukkitEntity() instanceof org.bukkit.entity.Player ? (org.bukkit.entity.Player) player.getBukkitEntity() : null; ++ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult result; ++ // Parchment end + if (isRespawnFuel(stack) && canBeCharged(state)) { ++ // Parchment start -- PlayerUseRespawnAnchorEvent ++ result = gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult.CHARGE; ++ } else if (state.getValue(CHARGE) == 0) { ++ result = gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult.NOTHING; ++ } else if (!canSetSpawn(level) && !level.isClientSide) { ++ result = gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult.EXPLODE; ++ } else if (!level.isClientSide) { ++ result = gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult.SET_SPAWN; ++ } else { ++ return InteractionResult.SUCCESS; ++ } ++ if (bukkitPlayer != null) { ++ gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent event = new gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent(bukkitPlayer, block, result); ++ event.callEvent(); ++ result = event.getResult(); ++ } ++ if (result == gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult.NOTHING) { ++ return InteractionResult.PASS; ++ } else if (result == gg.projecteden.parchment.event.player.PlayerUseRespawnAnchorEvent.RespawnAnchorResult.CHARGE) { ++ // Parchment end + charge(player, level, pos, state); + stack.consume(1, player); + return InteractionResult.SUCCESS; diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch new file mode 100644 index 0000000..ff349e4 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch @@ -0,0 +1,66 @@ +--- a/net/minecraft/world/level/block/TripWireBlock.java ++++ b/net/minecraft/world/level/block/TripWireBlock.java +@@ -75,6 +_,7 @@ + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return this.defaultBlockState(); // Paper - place tripwire without updating + BlockGetter level = context.getLevel(); + BlockPos clickedPos = context.getClickedPos(); ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(this.defaultBlockState()), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.SHAPE).callEvent()) return this.defaultBlockState(); + return this.defaultBlockState() + .setValue(NORTH, Boolean.valueOf(this.shouldConnectTo(level.getBlockState(clickedPos.north()), Direction.NORTH))) + .setValue(EAST, Boolean.valueOf(this.shouldConnectTo(level.getBlockState(clickedPos.east()), Direction.EAST))) +@@ -93,6 +_,7 @@ + BlockState neighborState, + RandomSource random + ) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.SHAPE, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, (Level) level)).callEvent()) return state; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating + return direction.getAxis().isHorizontal() + ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(this.shouldConnectTo(neighborState, direction))) +@@ -101,6 +_,7 @@ + + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.SHAPE, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + if (!oldState.is(state.getBlock())) { + this.updateSource(level, pos, state); +@@ -109,6 +_,7 @@ + + @Override + protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.SHAPE, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + if (!isMoving && !state.is(newState.getBlock())) { + this.updateSource(level, pos, state.setValue(POWERED, Boolean.valueOf(true))); +@@ -117,6 +_,7 @@ + + @Override + public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.SHAPE, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return state; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent disarming tripwires + if (!level.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) { + level.setBlock(pos, state.setValue(DISARMED, Boolean.valueOf(true)), 4); +@@ -127,6 +_,7 @@ + } + + private void updateSource(Level level, BlockPos pos, BlockState state) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.SHAPE, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + for (Direction direction : new Direction[]{Direction.SOUTH, Direction.WEST}) { + for (int i = 1; i < 42; i++) { +@@ -153,6 +_,7 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.POWERED, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwires from detecting collision + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide) { +@@ -164,6 +_,7 @@ + + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { ++ if (!new gg.projecteden.parchment.event.block.CustomBlockUpdateEvent(org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), gg.projecteden.parchment.event.block.CustomBlockUpdateEvent.UpdateType.POWERED, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level)).callEvent()) return; + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwire pressed check + if (level.getBlockState(pos).getValue(POWERED)) { + this.checkPressed(level, pos); diff --git a/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch new file mode 100644 index 0000000..1d9d061 --- /dev/null +++ b/parchment-server/minecraft-patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +@@ -55,7 +_,7 @@ + this.maxStack = i; + } + // CraftBukkit end +- private NonNullList items = NonNullList.withSize(27, ItemStack.EMPTY); ++ private NonNullList items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); + public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() { + @Override + protected void onOpen(Level level, BlockPos pos, BlockState state) { +@@ -107,7 +_,7 @@ + + @Override + public int getContainerSize() { +- return 27; ++ return 54; + } + + @Override +@@ -127,7 +_,7 @@ + + @Override + protected AbstractContainerMenu createMenu(int id, Inventory player) { +- return ChestMenu.threeRows(id, player, this); ++ return ChestMenu.sixRows(id, player, this); + } + + @Override diff --git a/parchment-server/paper-patches/files/src/main/java/com/destroystokyo/paper/Metrics.java.patch b/parchment-server/paper-patches/files/src/main/java/com/destroystokyo/paper/Metrics.java.patch new file mode 100644 index 0000000..288483f --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/com/destroystokyo/paper/Metrics.java.patch @@ -0,0 +1,11 @@ +--- a/src/main/java/com/destroystokyo/paper/Metrics.java ++++ b/src/main/java/com/destroystokyo/paper/Metrics.java +@@ -73,7 +_,7 @@ + Metrics.logger = logger; + + // Start submitting the data +- startSubmitting(); ++ // startSubmitting(); // Parchment + } + + /** diff --git a/parchment-server/paper-patches/files/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java.patch b/parchment-server/paper-patches/files/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java.patch new file mode 100644 index 0000000..d8651f6 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java.patch @@ -0,0 +1,11 @@ +--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java ++++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +@@ -49,7 +_,7 @@ + if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) { + updateMessage = text("You are running a development version without access to version information", color(0xFF5300)); + } else { +- updateMessage = getUpdateStatusMessage("PaperMC/Paper", build); ++ updateMessage = getUpdateStatusMessage("ProjectEdenGG/Parchment", build); + } + final @Nullable Component history = this.getHistory(); + diff --git a/parchment-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/PaperAdventure.java.patch b/parchment-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/PaperAdventure.java.patch new file mode 100644 index 0000000..8dbd7b6 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/io/papermc/paper/adventure/PaperAdventure.java.patch @@ -0,0 +1,39 @@ +--- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java ++++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +@@ -504,4 +_,36 @@ + return AdventureCodecs.STYLE_MAP_CODEC.codec() + .parse(ops, encoded).getOrThrow(IllegalStateException::new); + } ++ ++ // Parchment start ++ public static Sound.Source asAdventure(final SoundSource source) { ++ return switch (source) { ++ case MASTER -> Sound.Source.MASTER; ++ case MUSIC -> Sound.Source.MUSIC; ++ case RECORDS -> Sound.Source.RECORD; ++ case WEATHER -> Sound.Source.WEATHER; ++ case BLOCKS -> Sound.Source.BLOCK; ++ case HOSTILE -> Sound.Source.HOSTILE; ++ case NEUTRAL -> Sound.Source.NEUTRAL; ++ case PLAYERS -> Sound.Source.PLAYER; ++ case AMBIENT -> Sound.Source.AMBIENT; ++ case VOICE -> Sound.Source.VOICE; ++ }; ++ } ++ ++ public static Optional asVanillaSound(final Key key) { ++ return BuiltInRegistries.SOUND_EVENT.getOptional(asVanilla(key)); ++ } ++ ++ public static Optional> asSoundHolder(final net.minecraft.resources.ResourceKey key) { ++ return BuiltInRegistries.SOUND_EVENT.get(key); ++ } ++ ++ public static Optional> asVanillaSoundHolder(final Key key) { ++ return asSoundHolder(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.SOUND_EVENT, asVanilla(key))); ++ } ++ ++ // Parchment end ++ ++ + } diff --git a/parchment-server/paper-patches/files/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java.patch b/parchment-server/paper-patches/files/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java.patch new file mode 100644 index 0000000..27787cb --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java.patch @@ -0,0 +1,10 @@ +--- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java ++++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +@@ -306,6 +_,7 @@ + } + + public boolean disablePlayerCrits = false; ++ public boolean tickTimeSinceSleep = true; // Parchment + public boolean nerfPigmenFromNetherPortals = false; + @Comment("Prevents merging items that are not on the same y level, preventing potential visual artifacts.") + public boolean onlyMergeItemsHorizontally = false; diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch new file mode 100644 index 0000000..72ee61e --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch @@ -0,0 +1,19 @@ +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -2472,4 +_,16 @@ + return this.adventure$pointers; + } + // Paper end ++ ++ // Parchment start ++ @Override ++ public ItemStack smeltItem(ItemStack toSmelt, gg.projecteden.parchment.inventory.RecipeType recipeType) { ++ var optional = world.recipeAccess().getRecipeFor(gg.projecteden.parchment.inventory.CraftRecipeType.asCookingRecipe(recipeType), new net.minecraft.world.item.crafting.SingleRecipeInput(CraftItemStack.asNMSCopy(toSmelt)), world).map(recipe -> recipe.value()).orElse(null); ++ if (optional == null) { ++ return null; ++ } ++ return optional.assemble(new net.minecraft.world.item.crafting.SingleRecipeInput(CraftItemStack.asNMSCopy(toSmelt)), world.registryAccess()).asBukkitCopy(); ++ } ++ // Parchment end ++ + } diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/Main.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/Main.java.patch new file mode 100644 index 0000000..675bcb0 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/Main.java.patch @@ -0,0 +1,11 @@ +--- a/src/main/java/org/bukkit/craftbukkit/Main.java ++++ b/src/main/java/org/bukkit/craftbukkit/Main.java +@@ -267,7 +_,7 @@ + if (buildDate.before(deadline.getTime())) { + // Paper start - This is some stupid bullshit + System.err.println("*** Warning, you've not updated in a while! ***"); +- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads/paper ***"); // Paper ++ System.err.println("*** Please download a new build as per instructions from https://github.com/ProjectEdenGG/Parchment ***"); // Paper + //System.err.println("*** Server will start in 20 seconds ***"); + //Thread.sleep(TimeUnit.SECONDS.toMillis(20)); + // Paper end diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java.patch new file mode 100644 index 0000000..2951253 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java.patch @@ -0,0 +1,29 @@ +--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java ++++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +@@ -500,6 +_,11 @@ + + @Override + public boolean breakNaturally(ItemStack item, boolean triggerEffect, boolean dropExperience) { ++ return this.breakNaturally(null, item, triggerEffect, dropExperience); ++ } ++ ++ @Override ++ public boolean breakNaturally(Player player, ItemStack item, boolean triggerEffect, boolean dropExperience) { + // Paper end + // Order matters here, need to drop before setting to air so skulls can get their data + net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); +@@ -509,8 +_,12 @@ + + // Modelled off EntityHuman#hasBlock + if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) { +- net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper - Properly handle xp dropping +- // Paper start - improve Block#breanNaturally ++ List itemEntities = net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); ++ ++ if (player != null) { ++ new org.bukkit.event.block.BlockDropItemEvent(this, this.getState(), player, itemEntities.stream().map(i -> (org.bukkit.entity.Item) CraftEntity.getEntity((org.bukkit.craftbukkit.CraftServer) Bukkit.getServer(), i)).toList()).callEvent(); ++ } ++ + if (triggerEffect) { + if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) { + this.world.levelEvent(net.minecraft.world.level.block.LevelEvent.SOUND_EXTINGUISH_FIRE, this.position, 0); diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch new file mode 100644 index 0000000..84d3561 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch @@ -0,0 +1,12 @@ +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -1332,4 +_,9 @@ + } + } + // Paper end - broadcast hurt animation ++ ++ public gg.projecteden.parchment.entity.EntityData getStoredEntityData() { ++ return this.entity.getStoredEntityData(); ++ } ++ + } diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java.patch new file mode 100644 index 0000000..7e0f011 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java.patch @@ -0,0 +1,20 @@ +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java +@@ -66,4 +_,17 @@ + public String toString() { + return "CraftHanging"; + } ++ ++ // Parchment start ++ @Override ++ public boolean canTick() { ++ return this.getHandle().tick; ++ } ++ ++ @Override ++ public void setCanTick(boolean tick) { ++ this.getHandle().tick = tick; ++ } ++ // Parchment end ++ + } diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch new file mode 100644 index 0000000..70be676 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch @@ -0,0 +1,52 @@ +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -219,6 +_,7 @@ + public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API + private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit + private long lastSaveTime; // Paper - getLastPlayed replacement API ++ private boolean bypassesInsomnia = false; // Parchment - Insomnia api + + public CraftPlayer(CraftServer server, ServerPlayer entity) { + super(server, entity); +@@ -3541,4 +_,41 @@ + this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundEntityEventPacket(((CraftEntity) target).getHandle(), effect.getData())); + } + // Paper end - entity effect API ++ ++ // Parchment start ++ @Override ++ public Set getHiddenEntities(Plugin plugin) { ++ return invertedVisibilityEntities.entrySet().stream() ++ .filter(entry -> entry.getValue().contains(CraftPlayer.getPluginWeakReference(plugin))) ++ .map(Map.Entry::getKey) ++ .collect(java.util.stream.Collectors.toSet()); ++ } ++ ++ @Override ++ public boolean isInsomniac() { ++ return net.minecraft.world.entity.EntitySelector.IS_INSOMNIAC.test(this.getHandle()); ++ } ++ ++ @Override ++ public void setBypassInsomnia(boolean val) { ++ this.bypassesInsomnia = val; ++ } ++ ++ @Override ++ public boolean doesBypassInsomnia() { ++ return this.bypassesInsomnia; ++ } ++ ++ @Override ++ public void setTimeSinceLastRest(int ticks) { ++ this.getHandle().getStats().setValue(this.getHandle(), net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST), net.minecraft.util.Mth.clamp(ticks, 1, Integer.MAX_VALUE)); ++ } ++ ++ @Override ++ public int getTimeSinceLastRest() { ++ return net.minecraft.util.Mth.clamp(this.getHandle().getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE); ++ } ++ ++ // Parchment end ++ + } diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java.patch new file mode 100644 index 0000000..44a3696 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java.patch @@ -0,0 +1,69 @@ +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -1198,7 +_,7 @@ + } + + private static EntityDamageEvent callEntityDamageEvent(Block damager, BlockState damagerState, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) { +- EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagerState, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions); ++ EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagerState, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, bukkitDamageSource.getDamageLocation()); + return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled); + } + +@@ -2271,4 +_,57 @@ + return event; + } + // Paper end - add EntityFertilizeEggEvent ++ ++ // Parchment start ++ private static net.minecraft.network.protocol.@org.jetbrains.annotations.NotNull Packet handleSoundEvent(gg.projecteden.parchment.event.sound.SoundEvent event, CraftPlayer recipient) { ++ net.kyori.adventure.sound.Sound sound = event.calculateSound(recipient); ++ ResourceLocation name = io.papermc.paper.adventure.PaperAdventure.asVanilla(sound.name()); ++ gg.projecteden.parchment.event.sound.SoundEvent.Emitter emitter = event.calculateEmitter(recipient); ++ net.minecraft.sounds.SoundSource source = io.papermc.paper.adventure.PaperAdventure.asVanilla(sound.source()); ++ float volume = sound.volume(); ++ float pitch = sound.pitch(); ++ long seed = sound.seed().orElse(0L); // TODO: random source? ++ net.minecraft.resources.ResourceKey soundKey = net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.SOUND_EVENT, name); ++ net.minecraft.core.Holder.Reference soundEvent = io.papermc.paper.adventure.PaperAdventure.asVanillaSoundHolder(sound.name()) // TODO: calculate event distance? ++ .orElseGet(() -> net.minecraft.core.Holder.Reference.create(net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT, soundKey, net.minecraft.sounds.SoundEvent.createFixedRangeEvent(name, (float) event.calculateDistance()))); ++ if (emitter instanceof gg.projecteden.parchment.event.sound.SoundEvent.EntityEmitter entityEmitter) ++ return new net.minecraft.network.protocol.game.ClientboundSoundEntityPacket(soundEvent, source, ((CraftEntity) entityEmitter.entity()).getHandle(), volume, pitch, seed); ++ else if (emitter instanceof gg.projecteden.parchment.event.sound.SoundEvent.LocationEmitter locationEmitter) { ++ org.bukkit.Location loc = locationEmitter.getLocation(); ++ return new net.minecraft.network.protocol.game.ClientboundSoundPacket(soundEvent, source, loc.getX(), loc.getY(), loc.getZ(), volume, pitch, seed); ++ } ++ throw new IllegalArgumentException("Unknown emitter type: " + emitter.getClass().getName()); ++ } ++ ++ public static void playSoundEvent(gg.projecteden.parchment.event.sound.SoundEvent event) { ++ org.apache.commons.lang3.Validate.notNull(event, "event"); ++ io.papermc.paper.util.MCUtil.ASYNC_EXECUTOR.execute(() -> { ++ if (!event.callEvent()) ++ return; ++ try { ++ for (Player _player : event.calculateRecipients()) { ++ CraftPlayer player = (CraftPlayer) _player; ++ player.getHandle().connection.send(handleSoundEvent(event, player)); ++ } ++ } catch (Throwable e) { ++ org.slf4j.LoggerFactory.getLogger("SoundEvent").error("Error playing sound event", e); ++ } ++ }); ++ } ++ ++ public static List callBlockDropResourcesEvent(LevelAccessor world, BlockPos pos, List items) { ++ List bukkitItems = new ArrayList<>(items.size()); ++ for (ItemStack item : items) { ++ bukkitItems.add(CraftItemStack.asBukkitCopy(item)); ++ } ++ gg.projecteden.parchment.event.block.BlockDropResourcesEvent event = new gg.projecteden.parchment.event.block.BlockDropResourcesEvent(CraftBlock.at(world, pos), bukkitItems); ++ event.callEvent(); ++ items = new ArrayList<>(bukkitItems.size()); ++ for (org.bukkit.inventory.ItemStack item : bukkitItems) { ++ items.add(CraftItemStack.asNMSCopy(item)); ++ } ++ return items; ++ } ++ // Parchment end ++ + } diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java.patch new file mode 100644 index 0000000..6c3bda5 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java.patch @@ -0,0 +1,35 @@ +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +@@ -761,11 +_,12 @@ + this.setMaxDamage(maxDamage); + } + ++ CompoundTag internalTag = null; + String internal = SerializableMeta.getString(map, "internal", true); + if (internal != null) { + ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(internal)); + try { +- CompoundTag internalTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); ++ internalTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); + this.deserializeInternal(internalTag, map); + } catch (IOException ex) { + Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); +@@ -829,6 +_,18 @@ + this.customTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); + } catch (IOException ex) { + Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); ++ } ++ } ++ ++ if (internalTag != null) { ++ if (this.customTag == null) { ++ this.customTag = new CompoundTag(); ++ } ++ for (String key: internalTag.getAllKeys()) { ++ if (this.customTag.contains(key)) { ++ continue; ++ } ++ this.customTag.put(key, internalTag.get(key)); + } + } + } diff --git a/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/util/Versioning.java.patch b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/util/Versioning.java.patch new file mode 100644 index 0000000..f8f2c82 --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/util/Versioning.java.patch @@ -0,0 +1,11 @@ +--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +@@ -11,7 +_,7 @@ + public static String getBukkitVersion() { + String result = "Unknown-Version"; + +- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties"); ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gg.projecteden.parchment/parchment-api/pom.properties"); + Properties properties = new Properties(); + + if (stream != null) { diff --git a/parchment-server/paper-patches/files/src/main/java/org/spigotmc/WatchdogThread.java.patch b/parchment-server/paper-patches/files/src/main/java/org/spigotmc/WatchdogThread.java.patch new file mode 100644 index 0000000..126490d --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/java/org/spigotmc/WatchdogThread.java.patch @@ -0,0 +1,11 @@ +--- a/src/main/java/org/spigotmc/WatchdogThread.java ++++ b/src/main/java/org/spigotmc/WatchdogThread.java +@@ -84,7 +_,7 @@ + logger.log(Level.SEVERE, "\t If this is the case, consider increasing timeout-time in spigot.yml but note that this will replace the crash with LARGE lag spikes"); + logger.log(Level.SEVERE, "If you are unsure or still think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues"); + logger.log(Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports"); +- logger.log(Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion()); ++ logger.log(Level.SEVERE, "Parchment version: " + Bukkit.getServer().getVersion()); + + if (net.minecraft.world.level.Level.lastPhysicsProblem != null) { + logger.log(Level.SEVERE, "------------------------------"); diff --git a/parchment-server/paper-patches/files/src/main/resources/data/.paperassetsroot.patch b/parchment-server/paper-patches/files/src/main/resources/data/.paperassetsroot.patch new file mode 100644 index 0000000..b41d58b --- /dev/null +++ b/parchment-server/paper-patches/files/src/main/resources/data/.paperassetsroot.patch @@ -0,0 +1,3 @@ +--- a/src/main/resources/data/.paperassetsroot ++++ b/src/main/resources/data/.paperassetsroot +@@ -1,0 +_,0 @@