diff --git a/patches/server/0010-Fakeplayer-support.patch b/patches/server/0010-Fakeplayer-support.patch index 2cf065c..ee77412 100644 --- a/patches/server/0010-Fakeplayer-support.patch +++ b/patches/server/0010-Fakeplayer-support.patch @@ -1638,10 +1638,10 @@ index 0000000000000000000000000000000000000000..4f5e6e5c1b9d8bd38c98e97fd31b3833 +} diff --git a/src/main/java/org/leavesmc/leaves/bot/BotList.java b/src/main/java/org/leavesmc/leaves/bot/BotList.java new file mode 100644 -index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256391085c0 +index 0000000000000000000000000000000000000000..3eac675dccfa992d0aad4ebb84fcf6357761be2e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/BotList.java -@@ -0,0 +1,340 @@ +@@ -0,0 +1,297 @@ +package org.leavesmc.leaves.bot; + +import com.google.common.collect.Maps; @@ -1659,7 +1659,6 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; +import org.bukkit.Bukkit; +import org.bukkit.Location; @@ -1675,7 +1674,6 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 +import org.leavesmc.leaves.event.bot.BotSpawnLocationEvent; +import org.slf4j.Logger; + -+import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; @@ -1762,7 +1760,10 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + } + + public ServerBot placeNewBot(ServerBot bot, ServerLevel world, Location location, @Nullable CompoundTag nbt) { ++ Optional optional = Optional.ofNullable(nbt); ++ + bot.isRealPlayer = true; ++ bot.loginTime = System.currentTimeMillis(); + bot.connection = new ServerBotPacketListenerImpl(this.server, bot); + bot.setServerLevel(world); + @@ -1771,18 +1772,21 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + location = event.getSpawnLocation(); + + bot.spawnIn(world); -+ bot.gameMode.setLevel((ServerLevel) bot.level()); ++ bot.gameMode.setLevel(bot.serverLevel()); + + bot.setPosRaw(location.getX(), location.getY(), location.getZ()); + bot.setRot(location.getYaw(), location.getPitch()); + ++ bot.connection.teleport(bot.getX(), bot.getY(), bot.getZ(), bot.getYRot(), bot.getXRot()); ++ + this.bots.add(bot); + this.botsByName.put(bot.getScoreboardName().toLowerCase(Locale.ROOT), bot); + this.botsByUUID.put(bot.getUUID(), bot); + + bot.supressTrackerForLogin = true; + world.addNewPlayer(bot); -+ this.mountSavedVehicle(bot, world, nbt); ++ bot.loadAndSpawnEnderpearls(optional); ++ bot.loadAndSpawnParentVehicle(optional); + + BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitEntity(), PaperAdventure.asAdventure(Component.translatable("multiplayer.player.joined", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW))); + this.server.server.getPluginManager().callEvent(event1); @@ -1794,59 +1798,12 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + + bot.renderAll(); + bot.supressTrackerForLogin = false; ++ + bot.serverLevel().getChunkSource().chunkMap.addEntity(bot); + BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.serverLevel().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ()); + return bot; + } + -+ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, @Nullable CompoundTag nbt) { -+ Optional optional = Optional.ofNullable(nbt); -+ if (optional.isPresent() && optional.get().contains("RootVehicle", 10)) { -+ CompoundTag nbttagcompound = optional.get().getCompound("RootVehicle"); -+ Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver1, (entity1) -> { -+ return !worldserver1.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; -+ }); -+ -+ if (entity != null) { -+ UUID uuid; -+ -+ if (nbttagcompound.hasUUID("Attach")) { -+ uuid = nbttagcompound.getUUID("Attach"); -+ } else { -+ uuid = null; -+ } -+ -+ Iterator iterator; -+ Entity entity1; -+ -+ if (entity.getUUID().equals(uuid)) { -+ player.startRiding(entity, true); -+ } else { -+ iterator = entity.getIndirectPassengers().iterator(); -+ -+ while (iterator.hasNext()) { -+ entity1 = iterator.next(); -+ if (entity1.getUUID().equals(uuid)) { -+ player.startRiding(entity1, true); -+ break; -+ } -+ } -+ } -+ -+ if (!player.isPassenger()) { -+ BotList.LOGGER.warn("Couldn't reattach entity to fakeplayer"); -+ entity.discard(); -+ iterator = entity.getIndirectPassengers().iterator(); -+ -+ while (iterator.hasNext()) { -+ entity1 = iterator.next(); -+ entity1.discard(); -+ } -+ } -+ } -+ } -+ } -+ + public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved) { + return this.removeBot(bot, reason, remover, saved, this.dataStorage); + } diff --git a/patches/server/0036-Renewable-Elytra.patch b/patches/server/0036-Renewable-Elytra.patch index b140dc8..ac9f33a 100644 --- a/patches/server/0036-Renewable-Elytra.patch +++ b/patches/server/0036-Renewable-Elytra.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Renewable Elytra This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 150fd890ac65097b5434fd88e8d2b24a89dca79a..defde4529f2db132669ee4c1b36030fb39a32912 100644 +index 150fd890ac65097b5434fd88e8d2b24a89dca79a..25bbbfe8ccb8437880d6c27f9a859ed005f30faf 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java @@ -233,6 +233,20 @@ public class Phantom extends FlyingMob implements Enemy { @@ -15,13 +15,13 @@ index 150fd890ac65097b5434fd88e8d2b24a89dca79a..defde4529f2db132669ee4c1b36030fb + // Leaves start - renewable elytra + @Override -+ protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { -+ super.dropFromLootTable(source, causedByPlayer); ++ protected void dropFromLootTable(ServerLevel level, DamageSource source, boolean causedByPlayer) { ++ super.dropFromLootTable(level, source, causedByPlayer); + if (org.leavesmc.leaves.LeavesConfig.renewableElytra > 0.0D) { + if (source.getEntity() instanceof Shulker && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.renewableElytra) { + net.minecraft.world.item.ItemStack item = new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ELYTRA); + item.setDamageValue(432); -+ this.spawnAtLocation(item); ++ this.spawnAtLocation(level, item); + } + } + } diff --git a/patches/server/0044-Fix-update-suppression-crash.patch b/patches/server/0044-Fix-update-suppression-crash.patch index deb7e05..0c3afd3 100644 --- a/patches/server/0044-Fix-update-suppression-crash.patch +++ b/patches/server/0044-Fix-update-suppression-crash.patch @@ -39,7 +39,7 @@ index 8913b80ff4c593369b01fe75b67a11335a852439..3c2db9fa853ade7e429738f9896ad31e CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world"); diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index 155c7240b1112729333e6968122568c707d8f66b..2ae2f899183e3043b524712f0944bb9e894d74ab 100644 +index 155c7240b1112729333e6968122568c707d8f66b..96a3f7f46e6afbb6bf2247b14ec787afc8be2523 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java @@ -239,7 +239,17 @@ public class ShulkerBoxBlock extends BaseEntityBlock { @@ -52,7 +52,7 @@ index 155c7240b1112729333e6968122568c707d8f66b..2ae2f899183e3043b524712f0944bb9e + try { + return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); + } catch (ClassCastException ex) { -+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(null, pos); ++ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, this); + } + } else { + return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); @@ -62,7 +62,7 @@ index 155c7240b1112729333e6968122568c707d8f66b..2ae2f899183e3043b524712f0944bb9e @Override diff --git a/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java -index be8f34dd222e43b2db7f05e5e5839df8446e1b02..f54ddc20a5510864bff8eda6cf100f4ccade3dcd 100644 +index be8f34dd222e43b2db7f05e5e5839df8446e1b02..778d123f6fe4eb29becc42db8deafbfa8b9486be 100644 --- a/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java +++ b/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java @@ -70,9 +70,17 @@ public interface NeighborUpdater { @@ -71,13 +71,13 @@ index be8f34dd222e43b2db7f05e5e5839df8446e1b02..f54ddc20a5510864bff8eda6cf100f4c } catch (StackOverflowError ex) { + // Leaves start - fix update suppression crash + if (org.leavesmc.leaves.LeavesConfig.updateSuppressionCrashFix) { -+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, sourcePos); ++ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, sourceBlock); + } world.lastPhysicsProblem = new BlockPos(pos); // Spigot End } catch (Throwable throwable) { + if (org.leavesmc.leaves.LeavesConfig.updateSuppressionCrashFix) { -+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, sourcePos); ++ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, sourceBlock); + } + // Leaves end - fix update suppression crash CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours"); @@ -85,20 +85,21 @@ index be8f34dd222e43b2db7f05e5e5839df8446e1b02..f54ddc20a5510864bff8eda6cf100f4c diff --git a/src/main/java/org/leavesmc/leaves/util/UpdateSuppressionException.java b/src/main/java/org/leavesmc/leaves/util/UpdateSuppressionException.java new file mode 100644 -index 0000000000000000000000000000000000000000..77fd58a309b5d3c45f963c4bd1f47d7fc212898e +index 0000000000000000000000000000000000000000..150a0813b775a863d8c5c744f299dd248a600a47 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/UpdateSuppressionException.java -@@ -0,0 +1,33 @@ +@@ -0,0 +1,32 @@ +package org.leavesmc.leaves.util; + +import net.minecraft.core.BlockPos; ++import net.minecraft.world.level.block.Block; + +public class UpdateSuppressionException extends RuntimeException { + + private final BlockPos pos; -+ private final BlockPos source; ++ private final Block source; + -+ public UpdateSuppressionException(BlockPos pos, BlockPos source) { ++ public UpdateSuppressionException(BlockPos pos, Block source) { + super("Update suppression"); + this.pos = pos; + this.source = source; @@ -108,17 +109,15 @@ index 0000000000000000000000000000000000000000..77fd58a309b5d3c45f963c4bd1f47d7f + return pos; + } + -+ public BlockPos getSource() { ++ public Block getSource() { + return source; + } + + public String getMessage() { + if (pos != null) { -+ return "An update suppression processed, form [x:%d,y:%d,z:%d] to [x:%d,y:%d,z:%d]" -+ .formatted(source.getX(), source.getY(), source.getZ(), pos.getX(), pos.getY(), pos.getZ()); ++ return "An update suppression processed, form [%s] to [x:%d,y:%d,z:%d]".formatted(source.getName(), pos.getX(), pos.getY(), pos.getZ()); + } else { -+ return "An update suppression processed, form [x:%d,y:%d,z:%d]" -+ .formatted(source.getX(), source.getY(), source.getZ()); ++ return "An update suppression processed, form [%s]".formatted(source.getName()); + } + } +} diff --git a/patches/server/0057-Shave-snow-layers.patch b/patches/server/0057-Shave-snow-layers.patch index be2ef96..c60626a 100644 --- a/patches/server/0057-Shave-snow-layers.patch +++ b/patches/server/0057-Shave-snow-layers.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Shave snow layers diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index 55c18f182166f4905d623d6f5e909eefd5ed2483..d41d353a08d4834b3280e20f95416158996fd810 100644 +index 55c18f182166f4905d623d6f5e909eefd5ed2483..1a3a4fab67db34c6ca022465f474de3c84167fa7 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java @@ -44,6 +44,26 @@ public class ShovelItem extends DiggerItem { @@ -16,7 +16,7 @@ index 55c18f182166f4905d623d6f5e909eefd5ed2483..d41d353a08d4834b3280e20f95416158 + if (org.leavesmc.leaves.LeavesConfig.shaveSnowLayers && blockState.is(Blocks.SNOW)) { + int layers = blockState.getValue(net.minecraft.world.level.block.SnowLayerBlock.LAYERS); + ItemStack tool = context.getItemInHand(); -+ boolean hasSilkTouch = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(level.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getHolder(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH).get(), tool) > 0; ++ boolean hasSilkTouch = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(level.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getOrThrow(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH), tool) > 0; + BlockState shavedBlockState = layers > 1 ? blockState.setValue(net.minecraft.world.level.block.SnowLayerBlock.LAYERS, layers - 1) : Blocks.AIR.defaultBlockState(); + + level.setBlock(blockPos, shavedBlockState, Block.UPDATE_ALL_IMMEDIATE); diff --git a/patches/server/0075-Reduce-array-allocations.patch b/patches/server/0075-Reduce-array-allocations.patch index ac4bc40..b032c2e 100644 --- a/patches/server/0075-Reduce-array-allocations.patch +++ b/patches/server/0075-Reduce-array-allocations.patch @@ -382,23 +382,6 @@ index 91a2619dc11eef5d9ac7450caa43330bac3bbaaa..107a46185ad3db21736c211c603b14ee private static final int[] SLOTS_FOR_DOWN = new int[]{2, 1}; private static final int[] SLOTS_FOR_SIDES = new int[]{1}; public static final int DATA_LIT_DURATION = 1; -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java b/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java -index ae86c45c1d49c7646c721991910592091e7333f8..f3dce7156d518193fe27a69f5792800b72742632 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java -@@ -7,8 +7,10 @@ import org.bukkit.inventory.EquipmentSlot; - - public class CraftEquipmentSlot { - -- private static final net.minecraft.world.entity.EquipmentSlot[] slots = new net.minecraft.world.entity.EquipmentSlot[EquipmentSlot.values().length]; -- private static final EquipmentSlot[] enums = new EquipmentSlot[net.minecraft.world.entity.EquipmentSlot.values().length]; -+ // Leaves start - reduce array allocations -+ private static final net.minecraft.world.entity.EquipmentSlot[] slots = net.minecraft.world.entity.EquipmentSlot.VALUES; -+ private static final EquipmentSlot[] enums = new EquipmentSlot[net.minecraft.world.entity.EquipmentSlot.VALUES.length]; -+ // Leaves end - reduce array allocations - - static { - set(EquipmentSlot.HAND, net.minecraft.world.entity.EquipmentSlot.MAINHAND); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java index fdcc414f4fa246082ad0732133c870d915ae3084..556247696cde0d31cbb70907648d2970acf81153 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java diff --git a/patches/server/0089-Replay-Mod-API.patch b/patches/server/0089-Replay-Mod-API.patch index 98b60b6..aabd09f 100644 --- a/patches/server/0089-Replay-Mod-API.patch +++ b/patches/server/0089-Replay-Mod-API.patch @@ -169,7 +169,7 @@ index 4864eea883feade58ddb7a340f00f216315f4ace..fd2039e21382dfc8d9994930e55a6e94 } // Leaves end - skip diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d469fe8e2 100644 +index 86b0690bdecd139f30b02299754e14cf395fcea0..aabb5a3338d67fe6f9ffd80a6cab1a2fd6232f9c 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -125,6 +125,7 @@ import org.bukkit.event.player.PlayerSpawnChangeEvent; @@ -188,7 +188,7 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d // CraftBukkit start private CraftServer cserver; -@@ -183,6 +185,118 @@ public abstract class PlayerList { +@@ -183,6 +185,119 @@ public abstract class PlayerList { } abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor @@ -216,8 +216,10 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d + player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); -+ playerconnection.send(new ClientboundSetCarriedItemPacket(player.getInventory().selected)); -+ playerconnection.send(new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getRecipes())); ++ playerconnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected)); ++ RecipeManager craftingmanager = this.server.getRecipeManager(); ++ playerconnection.send(new ClientboundUpdateRecipesPacket(craftingmanager.getSynchronizedItemProperties(), craftingmanager.getSynchronizedStonecutterRecipes())); ++ + this.sendPlayerPermissionLevel(player); + player.getStats().markAllDirty(); + player.getRecipeBook().sendInitialRecipeBook(player); @@ -238,7 +240,6 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d + player.supressTrackerForLogin = true; + worldserver1.addNewPlayer(player); + this.server.getCustomBossEvents().onPlayerConnect(player); -+ mountSavedVehicle(player, worldserver1, Optional.empty()); + CraftPlayer bukkitPlayer = player.getBukkitEntity(); + + player.containerMenu.transferTo(player.containerMenu, bukkitPlayer); @@ -287,18 +288,18 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d + } + + worldserver1 = player.serverLevel(); -+ Iterator iterator = player.getActiveEffects().iterator(); ++ Iterator iterator = player.getActiveEffects().iterator(); + while (iterator.hasNext()) { -+ MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); ++ MobEffectInstance mobeffect = iterator.next(); + playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect, false)); + } + + if (player.isDeadOrDying()) { -+ net.minecraft.core.Holder plains = worldserver1.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME) -+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); ++ net.minecraft.core.Holder plains = worldserver1.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME) ++ .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); + player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( + new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains), -+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, false) ++ worldserver1.getLightEngine(), null, null, false) + ); + } + } @@ -307,7 +308,7 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed -@@ -331,6 +445,7 @@ public abstract class PlayerList { +@@ -331,6 +446,7 @@ public abstract class PlayerList { // entityplayer.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below this.players.add(player); @@ -315,7 +316,7 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot this.playersByUUID.put(player.getUUID(), player); // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below -@@ -401,6 +516,12 @@ public abstract class PlayerList { +@@ -401,6 +517,12 @@ public abstract class PlayerList { continue; } @@ -328,7 +329,7 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join } // Paper start - Use single player info update packet on join -@@ -551,6 +672,43 @@ public abstract class PlayerList { +@@ -551,6 +673,43 @@ public abstract class PlayerList { } @@ -372,7 +373,7 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component // Paper start - Fix kick event leave message not being sent return this.remove(entityplayer, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); -@@ -633,6 +791,7 @@ public abstract class PlayerList { +@@ -633,6 +792,7 @@ public abstract class PlayerList { entityplayer.retireScheduler(); // Paper - Folia schedulers entityplayer.getAdvancements().stopListening(); this.players.remove(entityplayer); @@ -380,7 +381,7 @@ index 86b0690bdecd139f30b02299754e14cf395fcea0..2dfb6dd33a1a20df22ea3928cde2508d this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot this.server.getCustomBossEvents().onPlayerDisconnect(entityplayer); UUID uuid = entityplayer.getUUID(); -@@ -727,7 +886,7 @@ public abstract class PlayerList { +@@ -727,7 +887,7 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; diff --git a/patches/server/0090-Leaves-I18n.patch b/patches/server/0090-Leaves-I18n.patch index 9ef5d3d..c0cadfe 100644 --- a/patches/server/0090-Leaves-I18n.patch +++ b/patches/server/0090-Leaves-I18n.patch @@ -5,28 +5,30 @@ Subject: [PATCH] Leaves I18n diff --git a/src/main/java/net/minecraft/locale/Language.java b/src/main/java/net/minecraft/locale/Language.java -index 93bf8a8adbf9082982fa01fc999d14d11afe0168..a5ecd14ebc36cc88b1f9ac930e8cdb4448547f2b 100644 +index 93bf8a8adbf9082982fa01fc999d14d11afe0168..f2ed44f4cf7ac490424ae84d21b3a4644f52acfd 100644 --- a/src/main/java/net/minecraft/locale/Language.java +++ b/src/main/java/net/minecraft/locale/Language.java -@@ -31,6 +31,41 @@ public abstract class Language { +@@ -31,6 +31,42 @@ public abstract class Language { public static final String DEFAULT = "en_us"; private static volatile Language instance = loadDefault(); + // Leaves start - i18n + public static void loadI18N(String lang) { -+ ImmutableMap.Builder builder = ImmutableMap.builder(); -+ BiConsumer biConsumer = builder::put; ++ DeprecatedTranslationsInfo deprecatedTranslationsInfo = DeprecatedTranslationsInfo.loadFromDefaultResource(); ++ Map map = new HashMap<>(); ++ BiConsumer biConsumer = map::put; + parseTranslations(biConsumer, "/assets/minecraft/lang/" + lang + ".json"); -+ final Map map = builder.build(); ++ deprecatedTranslationsInfo.applyToMap(map); ++ final Map map2 = Map.copyOf(map); + Language language = new Language() { + @Override + public String getOrDefault(String key, String fallback) { -+ return map.getOrDefault(key, fallback); ++ return map2.getOrDefault(key, fallback); + } + + @Override + public boolean has(String key) { -+ return map.containsKey(key); ++ return map2.containsKey(key); + } + + @Override @@ -36,11 +38,10 @@ index 93bf8a8adbf9082982fa01fc999d14d11afe0168..a5ecd14ebc36cc88b1f9ac930e8cdb44 + + @Override + public FormattedCharSequence getVisualOrder(FormattedText text) { -+ return (visitor) -> { -+ return text.visit((style, string) -> { -+ return StringDecomposer.iterateFormatted(string, style, visitor) ? Optional.empty() : FormattedText.STOP_ITERATION; -+ }, Style.EMPTY).isPresent(); -+ }; ++ return visitor -> text.visit( ++ (style, string) -> StringDecomposer.iterateFormatted(string, style, visitor) ? Optional.empty() : FormattedText.STOP_ITERATION, ++ Style.EMPTY ++ ).isPresent(); + } + }; + inject(language); diff --git a/patches/server/0098-CCE-update-suppression.patch b/patches/server/0098-CCE-update-suppression.patch index 33d67d5..a3fc93f 100644 --- a/patches/server/0098-CCE-update-suppression.patch +++ b/patches/server/0098-CCE-update-suppression.patch @@ -5,7 +5,7 @@ Subject: [PATCH] CCE update suppression diff --git a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -index 2ae2f899183e3043b524712f0944bb9e894d74ab..aa7f993654de91f2af5d52fa41ab5d77aece47e1 100644 +index 96a3f7f46e6afbb6bf2247b14ec787afc8be2523..ed903a9d79d1535a7786133242fbdc6f41a4ba71 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java @@ -239,17 +239,21 @@ public class ShulkerBoxBlock extends BaseEntityBlock { @@ -21,7 +21,7 @@ index 2ae2f899183e3043b524712f0944bb9e894d74ab..aa7f993654de91f2af5d52fa41ab5d77 + AbstractContainerMenu.getRedstoneSignalFromContainer((net.minecraft.world.Container) world.getBlockEntity(pos)) : + AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); } catch (ClassCastException ex) { - throw new org.leavesmc.leaves.util.UpdateSuppressionException(null, pos); + throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, this); } } else { - return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); diff --git a/patches/server/0101-Armor-stand-cant-kill-by-mob-projectile.patch b/patches/server/0101-Armor-stand-cant-kill-by-mob-projectile.patch index e8e3f46..bf9d9dd 100644 --- a/patches/server/0101-Armor-stand-cant-kill-by-mob-projectile.patch +++ b/patches/server/0101-Armor-stand-cant-kill-by-mob-projectile.patch @@ -5,9 +5,18 @@ Subject: [PATCH] Armor stand cant kill by mob projectile diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index dbaa552bed4d09e8b87475732dc911c95893ff89..a73ce65ed27b5cde99694210007b926a8b7112f0 100644 +index dbaa552bed4d09e8b87475732dc911c95893ff89..499e783a98c2f40fa9c08a5d38153779b87573b8 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +@@ -399,7 +399,7 @@ public class ArmorStand extends LivingEntity { + } else { + // Leaves start - stick can change ArmorStand arm status + if (org.leavesmc.leaves.LeavesConfig.stickChangeArmorStandArmStatus && itemstack.is(Items.STICK) && player.isShiftKeyDown()) { +- setShowArms(!isShowArms()); ++ setShowArms(!showArms()); + } + // Leaves end - stick can change ArmorStand arm status + @@ -532,6 +532,14 @@ public class ArmorStand extends LivingEntity { boolean flag = source.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); boolean flag1 = source.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); diff --git a/patches/server/0110-Renewable-sponges.patch b/patches/server/0110-Renewable-sponges.patch index 626fc0e..5f1db3f 100644 --- a/patches/server/0110-Renewable-sponges.patch +++ b/patches/server/0110-Renewable-sponges.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Renewable sponges diff --git a/src/main/java/net/minecraft/world/entity/monster/Guardian.java b/src/main/java/net/minecraft/world/entity/monster/Guardian.java -index 951f46684623582980901c1ebc1870aa5bcf25a1..77514f0e212ad2dfe4994658ac46b85376701de0 100644 +index 951f46684623582980901c1ebc1870aa5bcf25a1..d0eb523b37205f1e79aa32d171239d79dde520b1 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java @@ -342,6 +342,28 @@ public class Guardian extends Monster { @@ -18,7 +18,7 @@ index 951f46684623582980901c1ebc1870aa5bcf25a1..77514f0e212ad2dfe4994658ac46b853 + if (org.leavesmc.leaves.LeavesConfig.renewableSponges && !this.isRemoved() && !(this instanceof ElderGuardian)) { + ElderGuardian elderGuardian = new ElderGuardian(EntityType.ELDER_GUARDIAN ,this.level()); + elderGuardian.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); -+ elderGuardian.finalizeSpawn(world ,this.level().getCurrentDifficultyAt(elderGuardian.blockPosition()), MobSpawnType.CONVERSION, null); ++ elderGuardian.finalizeSpawn(world ,this.level().getCurrentDifficultyAt(elderGuardian.blockPosition()), EntitySpawnReason.CONVERSION, null); + elderGuardian.setNoAi(this.isNoAi()); + + if (this.hasCustomName()) { diff --git a/patches/server/0111-Renewable-coral.patch b/patches/server/0111-Renewable-coral.patch index ca749c8..a9c3bb1 100644 --- a/patches/server/0111-Renewable-coral.patch +++ b/patches/server/0111-Renewable-coral.patch @@ -70,7 +70,7 @@ index 7bc5ff8eb1174834dcc27363af4a5cef19017b3d..790686428b01127d0f94e044f0ec4bff BlockPos blockPos = pos.above(); diff --git a/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java b/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java new file mode 100644 -index 0000000000000000000000000000000000000000..f1cad30bd4c937b137305e790e1d372a123170a6 +index 0000000000000000000000000000000000000000..ec5aa65df54e2467d594a1885dbda850cee5a886 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java @@ -0,0 +1,72 @@ @@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..f1cad30bd4c937b137305e790e1d372a + + MapColor color = blockUnder.getMapColor(worldIn, pos); + BlockState properBlock = blockUnder; -+ HolderSet.Named coralBlocks = worldIn.registryAccess().registryOrThrow(Registries.BLOCK).getTag(BlockTags.CORAL_BLOCKS).orElseThrow(); ++ HolderSet.Named coralBlocks = worldIn.registryAccess().lookupOrThrow(Registries.BLOCK).getOrThrow(BlockTags.CORAL_BLOCKS); + for (Holder block : coralBlocks) { + properBlock = block.value().defaultBlockState(); + if (properBlock.getMapColor(worldIn, pos) == color) { diff --git a/patches/server/0112-Fast-resume.patch b/patches/server/0112-Fast-resume.patch index 6085d1c..659d4be 100644 --- a/patches/server/0112-Fast-resume.patch +++ b/patches/server/0112-Fast-resume.patch @@ -80,7 +80,7 @@ index fbebe8a51f33311bc744283c6db1f233a3d5bdcc..6d9b1779cac9979350c8fdc3cf921b51 if (this.hasStopped) return; diff --git a/src/main/java/org/leavesmc/leaves/util/TicketHelper.java b/src/main/java/org/leavesmc/leaves/util/TicketHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..36e9da7e68de086bc8572138eb14d0e00dc56879 +index 0000000000000000000000000000000000000000..42ac9e4ab4c9995aaa0a3732b4bc84e19ffa11ea --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/TicketHelper.java @@ -0,0 +1,175 @@ @@ -171,7 +171,7 @@ index 0000000000000000000000000000000000000000..36e9da7e68de086bc8572138eb14d0e0 + + for (JsonElement ticketElement : chunkJson.get("tickets").getAsJsonArray()) { + Ticket ticket = tickFormJson((JsonObject) ticketElement); -+ chunkDistanceManager.getChunkHolderManager().addTicketAtLevelCustom(ticket, chunkKey, true); ++ chunkDistanceManager.moonrise$getChunkHolderManager().addTicketAtLevelCustom(ticket, chunkKey, true); + } + } + } @@ -184,7 +184,7 @@ index 0000000000000000000000000000000000000000..36e9da7e68de086bc8572138eb14d0e0 + JsonArray levelArray = new JsonArray(); + DistanceManager chunkDistanceManager = level.getChunkSource().chunkMap.distanceManager; + -+ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { ++ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.moonrise$getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { + long chunkKey = chunkTickets.getLongKey(); + JsonArray ticketArray = new JsonArray(); + SortedArraySet> tickets = chunkTickets.getValue(); diff --git a/patches/server/0116-Bytebuf-API.patch b/patches/server/0116-Bytebuf-API.patch index 0645353..427f16b 100644 --- a/patches/server/0116-Bytebuf-API.patch +++ b/patches/server/0116-Bytebuf-API.patch @@ -18,10 +18,10 @@ index 5941800692ed06e17925ec6526ea38793a65de12..f77b2e12fb43039cf16a8511c9820859 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 2dfb6dd33a1a20df22ea3928cde2508d469fe8e2..cc8e4b788bc40b9faeaea5c9c61170b42a0ccf3b 100644 +index aabb5a3338d67fe6f9ffd80a6cab1a2fd6232f9c..a9dbffac24f1cfecf6eed683a66d4191251d40f9 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -470,6 +470,12 @@ public abstract class PlayerList { +@@ -471,6 +471,12 @@ public abstract class PlayerList { return; } diff --git a/patches/server/0126-Revert-raid-changes.patch b/patches/server/0126-Revert-raid-changes.patch index 5679101..f8cd57b 100644 --- a/patches/server/0126-Revert-raid-changes.patch +++ b/patches/server/0126-Revert-raid-changes.patch @@ -21,7 +21,7 @@ index e33e8db5f24437081d2026e66c13256aa3893a15..90060d6782e1169f540addcfdca00d14 if (raid == null || raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel()) { serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier)); diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index 18e4c53cb5c65647c3633ab41305a593fdc67c02..73406fee7cf7cdf371e6b098e9f9ad9390806536 100644 +index 18e4c53cb5c65647c3633ab41305a593fdc67c02..5b607d7a2ebefd9faed994f46810a5e5c436a73e 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -17,8 +17,11 @@ import net.minecraft.network.syncher.EntityDataSerializers; @@ -50,43 +50,45 @@ index 18e4c53cb5c65647c3633ab41305a593fdc67c02..73406fee7cf7cdf371e6b098e9f9ad93 import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.pathfinder.Path; -@@ -134,6 +140,43 @@ public abstract class Raider extends PatrollingMonster { +@@ -134,6 +140,45 @@ public abstract class Raider extends PatrollingMonster { raid.removeFromRaid(this, false); } + + // Leaves start - Revert raid changes -+ if (org.leavesmc.leaves.LeavesConfig.giveBadOmenWhenKillPatrolLeader && this.isPatrolLeader() && raid == null && ((ServerLevel) this.level()).getRaidAt(this.blockPosition()) == null) { -+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -+ Player entityhuman = null; ++ if (this.level() instanceof ServerLevel serverLevel) { ++ if (org.leavesmc.leaves.LeavesConfig.giveBadOmenWhenKillPatrolLeader && this.isPatrolLeader() && raid == null && serverLevel.getRaidAt(this.blockPosition()) == null) { ++ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); ++ Player entityhuman = null; + -+ if (entity instanceof Player) { -+ entityhuman = (Player) entity; -+ } else if (entity instanceof Wolf) { -+ Wolf entitywolf = (Wolf) entity; -+ LivingEntity entityliving = entitywolf.getOwner(); ++ if (entity instanceof Player) { ++ entityhuman = (Player) entity; ++ } else if (entity instanceof Wolf) { ++ Wolf entitywolf = (Wolf) entity; ++ LivingEntity entityliving = entitywolf.getOwner(); + -+ if (entitywolf.isTame() && entityliving instanceof Player) { -+ entityhuman = (Player) entityliving; ++ if (entitywolf.isTame() && entityliving instanceof Player) { ++ entityhuman = (Player) entityliving; ++ } + } -+ } + -+ if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN))) && entityhuman != null) { -+ MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); -+ int i = 1; ++ if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getOminousBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN))) && entityhuman != null) { ++ MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); ++ int i = 1; + -+ if (mobeffect != null) { -+ i += mobeffect.getAmplifier(); -+ entityhuman.removeEffectNoUpdate(MobEffects.BAD_OMEN); -+ } else { -+ --i; -+ } ++ if (mobeffect != null) { ++ i += mobeffect.getAmplifier(); ++ entityhuman.removeEffectNoUpdate(MobEffects.BAD_OMEN); ++ } else { ++ --i; ++ } + -+ i = Mth.clamp(i, 0, 4); -+ MobEffectInstance mobeffect1 = new MobEffectInstance(MobEffects.BAD_OMEN, 120000, i, false, false, true); ++ i = Mth.clamp(i, 0, 4); ++ MobEffectInstance mobeffect1 = new MobEffectInstance(MobEffects.BAD_OMEN, 120000, i, false, false, true); + -+ if (!this.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) { -+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit ++ if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) { ++ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit ++ } + } + } + }