More more more more work
This commit is contained in:
24
patches/server/API-for-an-entity-s-scoreboard-name.patch
Normal file
24
patches/server/API-for-an-entity-s-scoreboard-name.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 9 Jul 2023 11:55:02 -0700
|
||||
Subject: [PATCH] API for an entity's scoreboard name
|
||||
|
||||
Was obtainable through different methods, but you had to use different
|
||||
methods depending on the implementation of Entity you were working with.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return !this.getHandle().level().noCollision(this.getHandle(), aabb);
|
||||
}
|
||||
// Paper end - Collision API
|
||||
+
|
||||
+ // Paper start - entity scoreboard name
|
||||
+ @Override
|
||||
+ public String getScoreboardEntryName() {
|
||||
+ return this.getHandle().getScoreboardName();
|
||||
+ }
|
||||
+ // Paper end - entity scoreboard name
|
||||
}
|
||||
113
patches/server/API-for-updating-recipes-on-clients.patch
Normal file
113
patches/server/API-for-updating-recipes-on-clients.patch
Normal file
@@ -0,0 +1,113 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 21 Aug 2021 17:25:38 -0700
|
||||
Subject: [PATCH] API for updating recipes on clients
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void reloadResources() {
|
||||
+ // Paper start - API for updating recipes on clients
|
||||
+ this.reloadAdvancementData();
|
||||
+ this.reloadTagData();
|
||||
+ this.reloadRecipes();
|
||||
+ }
|
||||
+ public void reloadAdvancementData() {
|
||||
+ // Paper end - API for updating recipes on clients
|
||||
// CraftBukkit start
|
||||
/*Iterator iterator = this.advancements.values().iterator();
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - API for updating recipes on clients
|
||||
+ }
|
||||
+ public void reloadTagData() {
|
||||
this.broadcastAll(new ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(this.registries)));
|
||||
// CraftBukkit start
|
||||
- this.reloadRecipes();
|
||||
+ // this.reloadRecipes(); // Paper - do not reload recipes just because tag data was reloaded
|
||||
+ // Paper end - API for updating recipes on clients
|
||||
}
|
||||
|
||||
public void reloadRecipes() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
ReloadCommand.reload(this.console);
|
||||
}
|
||||
|
||||
+ // Paper start - API for updating recipes on clients
|
||||
+ @Override
|
||||
+ public void updateResources() {
|
||||
+ this.playerList.reloadResources();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void updateRecipes() {
|
||||
+ this.playerList.reloadRecipes();
|
||||
+ }
|
||||
+ // Paper end - API for updating recipes on clients
|
||||
+
|
||||
private void loadIcon() {
|
||||
this.icon = new CraftIconCache(null);
|
||||
try {
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public boolean addRecipe(Recipe recipe) {
|
||||
+ // Paper start - API for updating recipes on clients
|
||||
+ return this.addRecipe(recipe, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean addRecipe(Recipe recipe, boolean resendRecipes) {
|
||||
+ // Paper end - API for updating recipes on clients
|
||||
CraftRecipe toAdd;
|
||||
if (recipe instanceof CraftRecipe) {
|
||||
toAdd = (CraftRecipe) recipe;
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
}
|
||||
toAdd.addToCraftingManager();
|
||||
+ // Paper start - API for updating recipes on clients
|
||||
+ if (true || resendRecipes) { // Always needs to be resent now... TODO
|
||||
+ this.playerList.reloadRecipes();
|
||||
+ }
|
||||
+ // Paper end - API for updating recipes on clients
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public boolean removeRecipe(NamespacedKey recipeKey) {
|
||||
+ // Paper start - API for updating recipes on clients
|
||||
+ return this.removeRecipe(recipeKey, false);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean removeRecipe(NamespacedKey recipeKey, boolean resendRecipes) {
|
||||
+ // Paper end - API for updating recipes on clients
|
||||
Preconditions.checkArgument(recipeKey != null, "recipeKey == null");
|
||||
|
||||
- return this.getServer().getRecipeManager().removeRecipe(CraftRecipe.toMinecraft(recipeKey));
|
||||
+ // Paper start - resend recipes on successful removal
|
||||
+ final ResourceKey<net.minecraft.world.item.crafting.Recipe<?>> minecraftKey = CraftRecipe.toMinecraft(recipeKey);
|
||||
+ final boolean removed = this.getServer().getRecipeManager().removeRecipe(minecraftKey);
|
||||
+ if (removed/* && resendRecipes*/) { // TODO Always need to resend them rn - deprecate this method?
|
||||
+ this.playerList.reloadRecipes();
|
||||
+ }
|
||||
+ return removed;
|
||||
+ // Paper end - resend recipes on successful removal
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Villim <jan.villim@student.tuke.sk>
|
||||
Date: Sat, 22 Jan 2022 17:56:19 +0100
|
||||
Subject: [PATCH] Ability to control player's insomnia and phantoms
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
@@ -0,0 +0,0 @@ public final class EntitySelector {
|
||||
};
|
||||
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith);
|
||||
public static final Predicate<Entity> CAN_BE_PICKED = EntitySelector.NO_SPECTATORS.and(Entity::isPickable);
|
||||
- public static Predicate<Player> IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - Add phantom creative and insomniac controls
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ public static Predicate<Player> IS_INSOMNIAC = (player) -> {
|
||||
+ net.minecraft.server.level.ServerPlayer serverPlayer = (net.minecraft.server.level.ServerPlayer) player;
|
||||
+ int playerInsomniaTicks = serverPlayer.level().paperConfig().entities.behavior.playerInsomniaStartTicks;
|
||||
+
|
||||
+ if (playerInsomniaTicks <= 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return net.minecraft.util.Mth.clamp(serverPlayer.getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= playerInsomniaTicks;
|
||||
+ };
|
||||
+ // Paper end - Ability to control player's insomnia and phantoms
|
||||
|
||||
private EntitySelector() {}
|
||||
// Paper start - Affects Spawning API
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -0,0 +0,0 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
} else if (!world.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) {
|
||||
return 0;
|
||||
} else {
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ if (world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds <= 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // Paper end - Ability to control player's insomnia and phantoms
|
||||
RandomSource randomsource = world.random;
|
||||
|
||||
--this.nextTick;
|
||||
if (this.nextTick > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
- this.nextTick += (60 + randomsource.nextInt(60)) * 20;
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ int spawnAttemptMinSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMinSeconds;
|
||||
+ int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds;
|
||||
+ this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20;
|
||||
+ // Paper end - Ability to control player's insomnia and phantoms
|
||||
if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
|
||||
boolean flag2 = true;
|
||||
|
||||
- if (randomsource.nextInt(j) >= 72000) {
|
||||
+ if (randomsource.nextInt(j) >= world.paperConfig().entities.behavior.playerInsomniaStartTicks) { // Paper - Ability to control player's insomnia and phantoms
|
||||
BlockPos blockposition1 = blockposition.above(20 + randomsource.nextInt(15)).east(-10 + randomsource.nextInt(21)).south(-10 + randomsource.nextInt(21));
|
||||
BlockState iblockdata = world.getBlockState(blockposition1);
|
||||
FluidState fluid = world.getFluidState(blockposition1);
|
||||
@@ -0,0 +1,157 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 12 Sep 2018 18:53:55 +0300
|
||||
Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - Add an API for can-place-on/can-break adventure mode predicates
|
||||
+ @Override
|
||||
+ public Set<Material> getCanDestroy() {
|
||||
+ return !this.hasDestroyableKeys() ? Collections.emptySet() : convertToLegacyMaterial(this.canBreakPredicates);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanDestroy(final Set<Material> canDestroy) {
|
||||
+ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null set!");
|
||||
+ this.canBreakPredicates = convertFromLegacyMaterial(canDestroy);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Set<Material> getCanPlaceOn() {
|
||||
+ return !this.hasPlaceableKeys() ? Collections.emptySet() : convertToLegacyMaterial(this.canPlaceOnPredicates);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanPlaceOn(final Set<Material> canPlaceOn) {
|
||||
+ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null set!");
|
||||
+ this.canPlaceOnPredicates = convertFromLegacyMaterial(canPlaceOn);
|
||||
+ }
|
||||
+
|
||||
+ private static List<net.minecraft.advancements.critereon.BlockPredicate> convertFromLegacyMaterial(final Collection<Material> materials) {
|
||||
+ final net.minecraft.core.Registry<net.minecraft.world.level.block.Block> blockRegistry = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BLOCK);
|
||||
+ return materials.stream().map(m -> {
|
||||
+ return net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(blockRegistry, CraftBlockType.bukkitToMinecraft(m)).build();
|
||||
+ }).toList();
|
||||
+ }
|
||||
+
|
||||
+ private static Set<Material> convertToLegacyMaterial(final List<net.minecraft.advancements.critereon.BlockPredicate> predicates) {
|
||||
+ return predicates.stream()
|
||||
+ .flatMap(p -> p.blocks().map(net.minecraft.core.HolderSet::stream).orElse(java.util.stream.Stream.empty()))
|
||||
+ .map(holder -> CraftBlockType.minecraftToBukkit(holder.value()))
|
||||
+ .collect(java.util.stream.Collectors.toSet());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Set<com.destroystokyo.paper.Namespaced> getDestroyableKeys() {
|
||||
+ return !this.hasDestroyableKeys() ? Collections.emptySet() : convertToLegacyNamespaced(this.canBreakPredicates);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setDestroyableKeys(final Collection<com.destroystokyo.paper.Namespaced> canDestroy) {
|
||||
+ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null collection!");
|
||||
+ Preconditions.checkArgument(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!");
|
||||
+ this.canBreakPredicates = convertFromLegacyNamespaced(canDestroy);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Set<com.destroystokyo.paper.Namespaced> getPlaceableKeys() {
|
||||
+ return !this.hasPlaceableKeys() ? Collections.emptySet() : convertToLegacyNamespaced(this.canPlaceOnPredicates);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPlaceableKeys(final Collection<com.destroystokyo.paper.Namespaced> canPlaceOn) {
|
||||
+ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null collection!");
|
||||
+ Preconditions.checkArgument(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!");
|
||||
+ this.canPlaceOnPredicates = convertFromLegacyNamespaced(canPlaceOn);
|
||||
+ }
|
||||
+
|
||||
+ private static List<net.minecraft.advancements.critereon.BlockPredicate> convertFromLegacyNamespaced(final Collection<com.destroystokyo.paper.Namespaced> namespaceds) {
|
||||
+ final List<net.minecraft.advancements.critereon.BlockPredicate> predicates = new ArrayList<>();
|
||||
+ final net.minecraft.core.Registry<net.minecraft.world.level.block.Block> blockRegistry = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BLOCK);
|
||||
+ for (final com.destroystokyo.paper.Namespaced namespaced : namespaceds) {
|
||||
+ if (namespaced instanceof final org.bukkit.NamespacedKey key) {
|
||||
+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(blockRegistry, CraftBlockType.bukkitToMinecraft(Objects.requireNonNull(org.bukkit.Registry.MATERIAL.get(key)))).build());
|
||||
+ } else if (namespaced instanceof final com.destroystokyo.paper.NamespacedTag tag) {
|
||||
+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(blockRegistry, net.minecraft.tags.TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(tag.getNamespace(), tag.getKey()))).build());
|
||||
+ }
|
||||
+ }
|
||||
+ return predicates;
|
||||
+ }
|
||||
+
|
||||
+ private static Set<com.destroystokyo.paper.Namespaced> convertToLegacyNamespaced(final Collection<net.minecraft.advancements.critereon.BlockPredicate> predicates) {
|
||||
+ final Set<com.destroystokyo.paper.Namespaced> namespaceds = Sets.newHashSet();
|
||||
+ for (final net.minecraft.advancements.critereon.BlockPredicate predicate : predicates) {
|
||||
+ if (predicate.blocks().isEmpty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ final net.minecraft.core.HolderSet<net.minecraft.world.level.block.Block> holders = predicate.blocks().get();
|
||||
+ if (holders instanceof final net.minecraft.core.HolderSet.Named<net.minecraft.world.level.block.Block> named) {
|
||||
+ namespaceds.add(new com.destroystokyo.paper.NamespacedTag(named.key().location().getNamespace(), named.key().location().getPath()));
|
||||
+ } else {
|
||||
+ holders.forEach(h -> {
|
||||
+ h.unwrapKey().ifPresent(key -> {
|
||||
+ namespaceds.add(new org.bukkit.NamespacedKey(key.location().getNamespace(), key.location().getPath()));
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+ return namespaceds;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasPlaceableKeys() {
|
||||
+ return this.canPlaceOnPredicates != null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasDestroyableKeys() {
|
||||
+ return this.canBreakPredicates != null;
|
||||
+ }
|
||||
+
|
||||
+ // not a fan of this
|
||||
+ private static boolean ofAcceptableType(final Collection<com.destroystokyo.paper.Namespaced> namespacedResources) {
|
||||
+ for (com.destroystokyo.paper.Namespaced resource : namespacedResources) {
|
||||
+ if (!(resource instanceof org.bukkit.NamespacedKey || resource instanceof com.destroystokyo.paper.NamespacedTag)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Add an API for can-place-on/can-break adventure mode predicates
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
@@ -0,0 +0,0 @@ public class MaterialRerouting {
|
||||
return ItemStack.of(material, amount);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start - methods added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1015)
|
||||
+ public static Set<Material> getCanDestroy(final ItemMeta meta) {
|
||||
+ return meta.getCanDestroy();
|
||||
+ }
|
||||
+
|
||||
+ public static void setCanDestroy(final ItemMeta meta, final Set<Material> materials) {
|
||||
+ meta.setCanDestroy(materials);
|
||||
+ }
|
||||
+
|
||||
+ public static Set<Material> getCanPlaceOn(final ItemMeta meta) {
|
||||
+ return meta.getCanPlaceOn();
|
||||
+ }
|
||||
+
|
||||
+ public static void setCanPlaceOn(final ItemMeta meta, final Set<Material> materials) {
|
||||
+ meta.setCanPlaceOn(materials);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TrollyLoki <trollyloki@gmail.com>
|
||||
Date: Wed, 11 Oct 2023 00:45:53 -0400
|
||||
Subject: [PATCH] Add API to get the collision shape of a block before it's
|
||||
placed
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockData implements BlockData {
|
||||
return this.state.isFaceSturdy(EmptyBlockGetter.INSTANCE, BlockPos.ZERO, CraftBlock.blockFaceToNotch(face), CraftBlockSupport.toNMS(support));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.util.VoxelShape getCollisionShape(Location location) {
|
||||
+ Preconditions.checkArgument(location != null, "location must not be null");
|
||||
+
|
||||
+ CraftWorld world = (CraftWorld) location.getWorld();
|
||||
+ Preconditions.checkArgument(world != null, "location must not have a null world");
|
||||
+
|
||||
+ BlockPos position = CraftLocation.toBlockPosition(location);
|
||||
+ net.minecraft.world.phys.shapes.VoxelShape shape = this.state.getCollisionShape(world.getHandle(), position);
|
||||
+ return new org.bukkit.craftbukkit.util.CraftVoxelShape(shape);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Color getMapColor() {
|
||||
return Color.fromRGB(this.state.getMapColor(null, null).col);
|
||||
28
patches/server/Add-BlockBreakProgressUpdateEvent.patch
Normal file
28
patches/server/Add-BlockBreakProgressUpdateEvent.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Badbird5907 <50347938+Badbird5907@users.noreply.github.com>
|
||||
Date: Mon, 4 Mar 2024 22:18:28 -0500
|
||||
Subject: [PATCH] Add BlockBreakProgressUpdateEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof Player) entityhuman = (Player) entity;
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - Add BlockBreakProgressUpdateEvent
|
||||
+ // If a plugin is using this method to send destroy packets for a client-side only entity id, no block progress occurred on the server.
|
||||
+ // Hence, do not call the event.
|
||||
+ if (entity != null) {
|
||||
+ float progressFloat = Mth.clamp(progress, 0, 10) / 10.0f;
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(this, pos);
|
||||
+ new io.papermc.paper.event.block.BlockBreakProgressUpdateEvent(bukkitBlock, progressFloat, entity.getBukkitEntity())
|
||||
+ .callEvent();
|
||||
+ }
|
||||
+ // Paper end - Add BlockBreakProgressUpdateEvent
|
||||
+
|
||||
while (iterator.hasNext()) {
|
||||
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
||||
|
||||
39
patches/server/Add-BlockFace-to-BlockDamageEvent.patch
Normal file
39
patches/server/Add-BlockFace-to-BlockDamageEvent.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: aerulion <aerulion@gmail.com>
|
||||
Date: Mon, 21 Aug 2023 04:36:07 +0200
|
||||
Subject: [PATCH] Add BlockFace to BlockDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
return;
|
||||
}
|
||||
- org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, pos, this.player.getInventory().getSelected(), f >= 1.0f);
|
||||
+ org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, pos, direction, this.player.getInventory().getSelected(), f >= 1.0f); // Paper - Add BlockFace to BlockDamageEvent
|
||||
|
||||
if (blockEvent.isCancelled()) {
|
||||
// Let the client know the block still exists
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
/**
|
||||
* BlockDamageEvent
|
||||
*/
|
||||
- public static BlockDamageEvent callBlockDamageEvent(ServerPlayer who, BlockPos pos, ItemStack itemstack, boolean instaBreak) {
|
||||
+ public static BlockDamageEvent callBlockDamageEvent(ServerPlayer who, BlockPos pos, Direction direction, ItemStack itemstack, boolean instaBreak) { // Paper - Add BlockFace to BlockDamageEvent
|
||||
Player player = who.getBukkitEntity();
|
||||
CraftItemStack itemInHand = CraftItemStack.asCraftMirror(itemstack);
|
||||
|
||||
Block blockClicked = CraftBlock.at(who.level(), pos);
|
||||
|
||||
- BlockDamageEvent event = new BlockDamageEvent(player, blockClicked, itemInHand, instaBreak);
|
||||
+ BlockDamageEvent event = new BlockDamageEvent(player, blockClicked, CraftBlock.notchToBlockFace(direction), itemInHand, instaBreak); // Paper - Add BlockFace to BlockDamageEvent
|
||||
player.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
return event;
|
||||
70
patches/server/Add-BlockLockCheckEvent.patch
Normal file
70
patches/server/Add-BlockLockCheckEvent.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 21 May 2022 20:59:45 -0700
|
||||
Subject: [PATCH] Add BlockLockCheckEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
|
||||
protected abstract Component getDefaultName();
|
||||
|
||||
public boolean canOpen(Player player) {
|
||||
- return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName());
|
||||
+ return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName(), this); // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add BlockLockCheckEvent
|
||||
public static boolean canUnlock(Player player, LockCode lock, Component containerName) {
|
||||
+ // Paper start - Add BlockLockCheckEvent
|
||||
+ return canUnlock(player, lock, containerName, null);
|
||||
+ }
|
||||
+ public static boolean canUnlock(Player player, LockCode lock, Component containerName, @Nullable BlockEntity blockEntity) {
|
||||
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != null && blockEntity.getLevel().getBlockEntity(blockEntity.getBlockPos()) == blockEntity) {
|
||||
+ final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(blockEntity.getLevel(), blockEntity.getBlockPos());
|
||||
+ net.kyori.adventure.text.Component lockedMessage = net.kyori.adventure.text.Component.translatable("container.isLocked", io.papermc.paper.adventure.PaperAdventure.asAdventure(containerName));
|
||||
+ net.kyori.adventure.sound.Sound lockedSound = net.kyori.adventure.sound.Sound.sound(org.bukkit.Sound.BLOCK_CHEST_LOCKED, net.kyori.adventure.sound.Sound.Source.BLOCK, 1.0F, 1.0F);
|
||||
+ final io.papermc.paper.event.block.BlockLockCheckEvent event = new io.papermc.paper.event.block.BlockLockCheckEvent(block, serverPlayer.getBukkitEntity(), lockedMessage, lockedSound);
|
||||
+ event.callEvent();
|
||||
+ if (event.getResult() == org.bukkit.event.Event.Result.ALLOW) {
|
||||
+ return true;
|
||||
+ } else if (event.getResult() == org.bukkit.event.Event.Result.DENY || (!player.isSpectator() && !lock.unlocksWith(event.isUsingCustomKeyItemStack() ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getKeyItem()) : player.getMainHandItem()))) {
|
||||
+ if (event.getLockedMessage() != null) {
|
||||
+ event.getPlayer().sendActionBar(event.getLockedMessage());
|
||||
+ }
|
||||
+ if (event.getLockedSound() != null) {
|
||||
+ event.getPlayer().playSound(event.getLockedSound());
|
||||
+ }
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ } else { // logic below is replaced by logic above
|
||||
+ // Paper end - Add BlockLockCheckEvent
|
||||
if (!player.isSpectator() && !lock.unlocksWith(player.getMainHandItem())) {
|
||||
- player.displayClientMessage(Component.translatable("container.isLocked", containerName), true);
|
||||
+ player.displayClientMessage(Component.translatable("container.isLocked", containerName), true); // Paper - diff on change
|
||||
player.playNotifySound(SoundEvents.CHEST_LOCKED, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
+ } // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
protected abstract NonNullList<ItemStack> getItems();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
|
||||
- return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName()) ? new BeaconMenu(syncId, playerInventory, this.dataAccess, ContainerLevelAccess.create(this.level, this.getBlockPos())) : null;
|
||||
+ return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName(), this) ? new BeaconMenu(syncId, playerInventory, this.dataAccess, ContainerLevelAccess.create(this.level, this.getBlockPos())) : null; // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
43
patches/server/Add-CartographyItemEvent.patch
Normal file
43
patches/server/Add-CartographyItemEvent.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Janet Blackquill <uhhadd@gmail.com>
|
||||
Date: Sun, 7 Apr 2024 16:52:42 -0400
|
||||
Subject: [PATCH] Add CartographyItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - cartography item event
|
||||
+ if (packet.getSlotNum() == net.minecraft.world.inventory.CartographyTableMenu.RESULT_SLOT && top instanceof org.bukkit.inventory.CartographyInventory cartographyInventory) {
|
||||
+ org.bukkit.inventory.ItemStack result = cartographyInventory.getResult();
|
||||
+ if (result != null && !result.isEmpty()) {
|
||||
+ if (click == ClickType.NUMBER_KEY) {
|
||||
+ event = new io.papermc.paper.event.player.CartographyItemEvent(inventory, type, packet.getSlotNum(), click, action, packet.getButtonNum());
|
||||
+ } else {
|
||||
+ event = new io.papermc.paper.event.player.CartographyItemEvent(inventory, type, packet.getSlotNum(), click, action);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - cartography item event
|
||||
+
|
||||
event.setCancelled(cancelled);
|
||||
AbstractContainerMenu oldContainer = this.player.containerMenu; // SPIGOT-1224
|
||||
this.cserver.getPluginManager().callEvent(event);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
@@ -0,0 +0,0 @@ public class CartographyTableMenu extends AbstractContainerMenu {
|
||||
this.resultContainer = new ResultContainer(this.createBlockHolder(context)) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
- CartographyTableMenu.this.slotsChanged(this);
|
||||
+ // CartographyTableMenu.this.slotsChanged(this); // Paper - Add CatographyItemEvent - do not recompute results if the result slot changes - allows to set the result slot via api
|
||||
super.setChanged();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Noah van der Aa <ndvdaa@gmail.com>
|
||||
Date: Sun, 8 Aug 2021 19:56:02 +0200
|
||||
Subject: [PATCH] Add CompostItemEvent and EntityCompostItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
|
||||
@@ -0,0 +0,0 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
int i = (Integer) iblockdata.getValue(ComposterBlock.LEVEL);
|
||||
float f = ComposterBlock.COMPOSTABLES.getFloat(itemstack.getItem());
|
||||
|
||||
- if ((i != 0 || f <= 0.0F) && rand >= (double) f) {
|
||||
+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent
|
||||
+ boolean willRaiseLevel = !((i != 0 || f <= 0.0F) && rand >= (double) f);
|
||||
+ final io.papermc.paper.event.block.CompostItemEvent event;
|
||||
+ if (entity == null) {
|
||||
+ event = new io.papermc.paper.event.block.CompostItemEvent(org.bukkit.craftbukkit.block.CraftBlock.at(generatoraccess, blockposition), itemstack.getBukkitStack(), willRaiseLevel);
|
||||
+ } else {
|
||||
+ event = new io.papermc.paper.event.entity.EntityCompostItemEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(generatoraccess, blockposition), itemstack.getBukkitStack(), willRaiseLevel);
|
||||
+ }
|
||||
+ if (!event.callEvent()) { // check for cancellation of entity event (non entity event can't be cancelled cause of hoppers)
|
||||
+ return null;
|
||||
+ }
|
||||
+ willRaiseLevel = event.willRaiseLevel();
|
||||
+
|
||||
+ if (!willRaiseLevel) {
|
||||
+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent
|
||||
return iblockdata;
|
||||
} else {
|
||||
int j = i + 1;
|
||||
@@ -0,0 +0,0 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
|
||||
if (!itemstack.isEmpty()) {
|
||||
this.changed = true;
|
||||
BlockState iblockdata = ComposterBlock.addItem((Entity) null, this.state, this.level, this.pos, itemstack);
|
||||
+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent
|
||||
+ if (iblockdata == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent
|
||||
|
||||
this.level.levelEvent(1500, this.pos, iblockdata != this.state ? 1 : 0);
|
||||
this.removeItemNoUpdate(0);
|
||||
65
patches/server/Add-Entity-Body-Yaw-API.patch
Normal file
65
patches/server/Add-Entity-Body-Yaw-API.patch
Normal file
@@ -0,0 +1,65 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TheTuso <piotrekpasztor@gmail.com>
|
||||
Date: Thu, 2 Feb 2023 16:40:41 +0100
|
||||
Subject: [PATCH] Add Entity Body Yaw API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
// Paper end - entity powdered snow API
|
||||
|
||||
+ // Paper start - entity body yaw API
|
||||
+ @Override
|
||||
+ public double getX() {
|
||||
+ return this.entity.getX();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getY() {
|
||||
+ return this.entity.getY();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getZ() {
|
||||
+ return this.entity.getZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getPitch() {
|
||||
+ return this.entity.getXRot();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getYaw() {
|
||||
+ return this.entity.getBukkitYaw();
|
||||
+ }
|
||||
+ // Paper end - entity body yaw API
|
||||
+
|
||||
// Paper start - missing entity api
|
||||
@Override
|
||||
public boolean isInvisible() { // Paper - moved up from LivingEntity
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
this.getHandle().frictionState = state;
|
||||
}
|
||||
// Paper end - friction API
|
||||
+
|
||||
+ // Paper start - body yaw API
|
||||
+ @Override
|
||||
+ public float getBodyYaw() {
|
||||
+ return this.getHandle().getVisualRotationYInDegrees();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setBodyYaw(final float bodyYaw) {
|
||||
+ this.getHandle().setYBodyRot(bodyYaw);
|
||||
+ }
|
||||
+ // Paper end - body yaw API
|
||||
}
|
||||
103
patches/server/Add-EntityFertilizeEggEvent.patch
Normal file
103
patches/server/Add-EntityFertilizeEggEvent.patch
Normal file
@@ -0,0 +1,103 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Fri, 24 Jun 2022 12:39:34 +0200
|
||||
Subject: [PATCH] Add EntityFertilizeEggEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
if (entityplayer == null && this.partner.getLoveCause() != null) {
|
||||
entityplayer = this.partner.getLoveCause();
|
||||
}
|
||||
+ // Paper start - Add EntityFertilizeEggEvent event
|
||||
+ io.papermc.paper.event.entity.EntityFertilizeEggEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this.animal, this.partner);
|
||||
+ if (event.isCancelled()) return;
|
||||
+ // Paper end - Add EntityFertilizeEggEvent event
|
||||
|
||||
if (entityplayer != null) {
|
||||
entityplayer.awardStat(Stats.ANIMALS_BRED);
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
RandomSource randomsource = this.animal.getRandom();
|
||||
|
||||
if (getServerLevel((Level) this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper;
|
||||
+ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper - Add EntityFertilizeEggEvent event
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
@@ -0,0 +0,0 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
|
||||
|
||||
@Override
|
||||
public void spawnChildFromBreeding(ServerLevel world, Animal other) {
|
||||
- this.finalizeSpawnChildFromBreeding(world, other, null);
|
||||
+ // Paper start - Add EntityFertilizeEggEvent event
|
||||
+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other);
|
||||
+ if (result.isCancelled()) return;
|
||||
+
|
||||
+ this.finalizeSpawnChildFromBreeding(world, other, null, result.getExperience()); // Paper - use craftbukkit call that takes experience amount
|
||||
+ // Paper end - Add EntityFertilizeEggEvent event
|
||||
this.getBrain().setMemory(MemoryModuleType.IS_PREGNANT, Unit.INSTANCE);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
@@ -0,0 +0,0 @@ public class Sniffer extends Animal {
|
||||
|
||||
@Override
|
||||
public void spawnChildFromBreeding(ServerLevel world, Animal other) {
|
||||
+ // Paper start - Add EntityFertilizeEggEvent event
|
||||
+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent result = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityFertilizeEggEvent(this, other);
|
||||
+ if (result.isCancelled()) return;
|
||||
+ // Paper end - Add EntityFertilizeEggEvent event
|
||||
+
|
||||
ItemStack itemstack = new ItemStack(Items.SNIFFER_EGG);
|
||||
ItemEntity entityitem = new ItemEntity(world, this.position().x(), this.position().y(), this.position().z(), itemstack);
|
||||
|
||||
entityitem.setDefaultPickUpDelay();
|
||||
- this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null);
|
||||
+ this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null, result.getExperience()); // Paper - Add EntityFertilizeEggEvent event
|
||||
if (this.spawnAtLocation(world, entityitem) != null) { // Paper - Call EntityDropItemEvent
|
||||
this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F);
|
||||
} // Paper - Call EntityDropItemEvent
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event.callEvent();
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start - add EntityFertilizeEggEvent
|
||||
+ /**
|
||||
+ * Calls the {@link io.papermc.paper.event.entity.EntityFertilizeEggEvent}.
|
||||
+ * If the event is cancelled, this method also resets the love on both the {@code breeding} and {@code other} entity.
|
||||
+ *
|
||||
+ * @param breeding the entity on which #spawnChildFromBreeding was called.
|
||||
+ * @param other the partner of the entity.
|
||||
+ * @return the event after it was called. The instance may be used to retrieve the experience of the event.
|
||||
+ */
|
||||
+ public static io.papermc.paper.event.entity.EntityFertilizeEggEvent callEntityFertilizeEggEvent(Animal breeding, Animal other) {
|
||||
+ ServerPlayer serverPlayer = breeding.getLoveCause();
|
||||
+ if (serverPlayer == null) serverPlayer = other.getLoveCause();
|
||||
+ final int experience = breeding.getRandom().nextInt(7) + 1; // From Animal#spawnChildFromBreeding(ServerLevel, Animal)
|
||||
+
|
||||
+ final io.papermc.paper.event.entity.EntityFertilizeEggEvent event = new io.papermc.paper.event.entity.EntityFertilizeEggEvent((LivingEntity) breeding.getBukkitEntity(), (LivingEntity) other.getBukkitEntity(), serverPlayer == null ? null : serverPlayer.getBukkitEntity(), breeding.breedItem == null ? null : CraftItemStack.asCraftMirror(breeding.breedItem).clone(), experience);
|
||||
+ if (!event.callEvent()) {
|
||||
+ breeding.resetLove();
|
||||
+ other.resetLove(); // stop the pathfinding to avoid infinite loop
|
||||
+ }
|
||||
+
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end - add EntityFertilizeEggEvent
|
||||
}
|
||||
25
patches/server/Add-EntityPortalReadyEvent.patch
Normal file
25
patches/server/Add-EntityPortalReadyEvent.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 12 May 2021 04:30:42 -0700
|
||||
Subject: [PATCH] Add EntityPortalReadyEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block implements Portal {
|
||||
// CraftBukkit start
|
||||
ResourceKey<Level> resourcekey = world.getTypeKey() == LevelStem.NETHER ? Level.OVERWORLD : Level.NETHER;
|
||||
ServerLevel worldserver1 = world.getServer().getLevel(resourcekey);
|
||||
+ // Paper start - Add EntityPortalReadyEvent
|
||||
+ io.papermc.paper.event.entity.EntityPortalReadyEvent portalReadyEvent = new io.papermc.paper.event.entity.EntityPortalReadyEvent(entity.getBukkitEntity(), worldserver1 == null ? null : worldserver1.getWorld(), org.bukkit.PortalType.NETHER);
|
||||
+ if (!portalReadyEvent.callEvent()) {
|
||||
+ entity.portalProcess = null;
|
||||
+ return null;
|
||||
+ }
|
||||
+ worldserver1 = portalReadyEvent.getTargetWorld() == null ? null : ((org.bukkit.craftbukkit.CraftWorld) portalReadyEvent.getTargetWorld()).getHandle();
|
||||
+ // Paper end - Add EntityPortalReadyEvent
|
||||
|
||||
if (worldserver1 == null) {
|
||||
return new TeleportTransition(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // always fire event in case plugins wish to change it
|
||||
100
patches/server/Add-EntityToggleSitEvent.patch
Normal file
100
patches/server/Add-EntityToggleSitEvent.patch
Normal file
@@ -0,0 +1,100 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: KyGuy2002 <IEatBeans#1165>
|
||||
Date: Fri, 11 Mar 2022 15:33:10 +0000
|
||||
Subject: [PATCH] Add EntityToggleSitEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
|
||||
@@ -0,0 +0,0 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity {
|
||||
}
|
||||
|
||||
this.orderedToSit = nbt.getBoolean("Sitting");
|
||||
- this.setInSittingPose(this.orderedToSit);
|
||||
+ this.setInSittingPose(this.orderedToSit, false); // Paper - Add EntityToggleSitEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity {
|
||||
}
|
||||
|
||||
public void setInSittingPose(boolean inSittingPose) {
|
||||
+ // Paper start - Add EntityToggleSitEvent
|
||||
+ this.setInSittingPose(inSittingPose, true);
|
||||
+ }
|
||||
+ public void setInSittingPose(boolean inSittingPose, boolean callEvent) {
|
||||
+ if (callEvent && !new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), inSittingPose).callEvent()) return;
|
||||
+ // Paper end - Add EntityToggleSitEvent
|
||||
byte b0 = (Byte) this.entityData.get(TamableAnimal.DATA_FLAGS_ID);
|
||||
|
||||
if (inSittingPose) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -0,0 +0,0 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
|
||||
|
||||
this.setSleeping(nbt.getBoolean("Sleeping"));
|
||||
this.setVariant(Fox.Variant.byName(nbt.getString("Type")));
|
||||
- this.setSitting(nbt.getBoolean("Sitting"));
|
||||
+ this.setSitting(nbt.getBoolean("Sitting"), false); // Paper - Add EntityToggleSitEvent
|
||||
this.setIsCrouching(nbt.getBoolean("Crouching"));
|
||||
if (this.level() instanceof ServerLevel) {
|
||||
this.setTargetGoals();
|
||||
@@ -0,0 +0,0 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
|
||||
}
|
||||
|
||||
public void setSitting(boolean sitting) {
|
||||
+ // Paper start - Add EntityToggleSitEvent
|
||||
+ this.setSitting(sitting, true);
|
||||
+ }
|
||||
+ public void setSitting(boolean sitting, boolean fireEvent) {
|
||||
+ if (fireEvent && !new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), sitting).callEvent()) return;
|
||||
+ // Paper end - Add EntityToggleSitEvent
|
||||
this.setFlag(1, sitting);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
@@ -0,0 +0,0 @@ public class Panda extends Animal {
|
||||
}
|
||||
|
||||
public void sit(boolean sitting) {
|
||||
+ if (!new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), sitting).callEvent()) return; // Paper - Add EntityToggleSitEvent
|
||||
this.setFlag(8, sitting);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
|
||||
@@ -0,0 +0,0 @@ public class Camel extends AbstractHorse {
|
||||
}
|
||||
|
||||
public void sitDown() {
|
||||
- if (!this.isCamelSitting()) {
|
||||
+ if (!this.isCamelSitting() && new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), true).callEvent()) { // Paper - Add EntityToggleSitEvent
|
||||
this.makeSound(SoundEvents.CAMEL_SIT);
|
||||
this.setPose(Pose.SITTING);
|
||||
this.gameEvent(GameEvent.ENTITY_ACTION);
|
||||
@@ -0,0 +0,0 @@ public class Camel extends AbstractHorse {
|
||||
}
|
||||
|
||||
public void standUp() {
|
||||
- if (this.isCamelSitting()) {
|
||||
+ if (this.isCamelSitting() && new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), false).callEvent()) { // Paper - Add EntityToggleSitEvent
|
||||
this.makeSound(SoundEvents.CAMEL_STAND);
|
||||
this.setPose(Pose.STANDING);
|
||||
this.gameEvent(GameEvent.ENTITY_ACTION);
|
||||
@@ -0,0 +0,0 @@ public class Camel extends AbstractHorse {
|
||||
}
|
||||
|
||||
public void standUpInstantly() {
|
||||
+ if (this.isCamelSitting() && !new io.papermc.paper.event.entity.EntityToggleSitEvent(this.getBukkitEntity(), false).callEvent()) return; // Paper - Add EntityToggleSitEvent
|
||||
this.setPose(Pose.STANDING);
|
||||
this.gameEvent(GameEvent.ENTITY_ACTION);
|
||||
this.resetLastPoseChangeTickToFullStand(this.level().getGameTime());
|
||||
208
patches/server/Add-FluidState-API.patch
Normal file
208
patches/server/Add-FluidState-API.patch
Normal file
@@ -0,0 +1,208 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: vicisacat <victor.branchu@gmail.com>
|
||||
Date: Fri, 17 Nov 2023 20:22:43 +0100
|
||||
Subject: [PATCH] Add FluidState API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/PaperFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.block.fluid;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import io.papermc.paper.block.fluid.type.PaperFallingFluidData;
|
||||
+import io.papermc.paper.block.fluid.type.PaperFlowingFluidData;
|
||||
+import io.papermc.paper.util.MCUtil;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.function.Function;
|
||||
+import net.minecraft.world.level.material.FluidState;
|
||||
+import net.minecraft.world.level.material.LavaFluid;
|
||||
+import net.minecraft.world.level.material.WaterFluid;
|
||||
+import org.bukkit.Fluid;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.craftbukkit.CraftFluid;
|
||||
+import org.bukkit.craftbukkit.CraftWorld;
|
||||
+import org.bukkit.craftbukkit.util.CraftVector;
|
||||
+import org.bukkit.util.Vector;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class PaperFluidData implements FluidData {
|
||||
+
|
||||
+ private final FluidState state;
|
||||
+
|
||||
+ protected PaperFluidData(final FluidState state) {
|
||||
+ this.state = state;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Provides the internal server representation of this fluid data.
|
||||
+ * @return the fluid state.
|
||||
+ */
|
||||
+ public FluidState getState() {
|
||||
+ return this.state;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final @NotNull Fluid getFluidType() {
|
||||
+ return CraftFluid.minecraftToBukkit(this.state.getType());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull PaperFluidData clone() {
|
||||
+ try {
|
||||
+ return (PaperFluidData) super.clone();
|
||||
+ } catch (final CloneNotSupportedException ex) {
|
||||
+ throw new AssertionError("Clone not supported", ex);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Vector computeFlowDirection(final Location location) {
|
||||
+ Preconditions.checkArgument(location.getWorld() != null, "Cannot compute flow direction on world-less location");
|
||||
+ return CraftVector.toBukkit(this.state.getFlow(
|
||||
+ ((CraftWorld) location.getWorld()).getHandle(),
|
||||
+ MCUtil.toBlockPosition(location)
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getLevel() {
|
||||
+ return this.state.getAmount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float computeHeight(@NotNull final Location location) {
|
||||
+ Preconditions.checkArgument(location.getWorld() != null, "Cannot compute height on world-less location");
|
||||
+ return this.state.getHeight(((CraftWorld) location.getWorld()).getHandle(), MCUtil.toBlockPos(location));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSource() {
|
||||
+ return this.state.isSource();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return this.state.hashCode();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(final Object obj) {
|
||||
+ return obj instanceof final PaperFluidData paperFluidData && this.state.equals(paperFluidData.state);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "PaperFluidData{" + this.state + "}";
|
||||
+ }
|
||||
+
|
||||
+ /* Registry */
|
||||
+ private static final Map<Class<? extends net.minecraft.world.level.material.Fluid>, Function<FluidState, PaperFluidData>> MAP = new HashMap<>();
|
||||
+ static {
|
||||
+ //<editor-fold desc="PaperFluidData Registration" defaultstate="collapsed">
|
||||
+ register(LavaFluid.Source.class, PaperFallingFluidData::new);
|
||||
+ register(WaterFluid.Source.class, PaperFallingFluidData::new);
|
||||
+ register(LavaFluid.Flowing.class, PaperFlowingFluidData::new);
|
||||
+ register(WaterFluid.Flowing.class, PaperFlowingFluidData::new);
|
||||
+ //</editor-fold>
|
||||
+ }
|
||||
+
|
||||
+ static void register(final Class<? extends net.minecraft.world.level.material.Fluid> fluid, final Function<FluidState, PaperFluidData> creator) {
|
||||
+ Preconditions.checkState(MAP.put(fluid, creator) == null, "Duplicate mapping %s->%s", fluid, creator);
|
||||
+ MAP.put(fluid, creator);
|
||||
+ }
|
||||
+
|
||||
+ public static PaperFluidData createData(final FluidState state) {
|
||||
+ return MAP.getOrDefault(state.getType().getClass(), PaperFluidData::new).apply(state);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/block/fluid/package-info.java b/src/main/java/io/papermc/paper/block/fluid/package-info.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/package-info.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+package io.papermc.paper.block.fluid;
|
||||
+
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
diff --git a/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/type/PaperFallingFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+
|
||||
+package io.papermc.paper.block.fluid.type;
|
||||
+
|
||||
+import io.papermc.paper.block.fluid.PaperFluidData;
|
||||
+import net.minecraft.world.level.material.FlowingFluid;
|
||||
+import net.minecraft.world.level.material.FluidState;
|
||||
+
|
||||
+public class PaperFallingFluidData extends PaperFluidData implements FallingFluidData {
|
||||
+
|
||||
+ public PaperFallingFluidData(final FluidState state) {
|
||||
+ super(state);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isFalling() {
|
||||
+ return this.getState().getValue(FlowingFluid.FALLING);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/block/fluid/type/PaperFlowingFluidData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.block.fluid.type;
|
||||
+
|
||||
+import net.minecraft.world.level.material.FluidState;
|
||||
+
|
||||
+public class PaperFlowingFluidData extends PaperFallingFluidData implements FlowingFluidData {
|
||||
+
|
||||
+ public PaperFlowingFluidData(final FluidState state) {
|
||||
+ super(state);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
return CraftBlock.at(this.getHandle(), new BlockPos(x, y, z)).getState();
|
||||
}
|
||||
|
||||
+ // Paper start - FluidState API
|
||||
+ @Override
|
||||
+ public io.papermc.paper.block.fluid.FluidData getFluidData(final int x, final int y, final int z) {
|
||||
+ return io.papermc.paper.block.fluid.PaperFluidData.createData(getHandle().getFluidState(new BlockPos(x, y, z)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public BlockData getBlockData(Location location) {
|
||||
return this.getBlockData(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
|
||||
return centerChunkZ;
|
||||
}
|
||||
// Paper end - Add more LimitedRegion API
|
||||
+ // Paper start - Fluid API
|
||||
+ @Override
|
||||
+ public io.papermc.paper.block.fluid.FluidData getFluidData(int x, int y, int z) {
|
||||
+ Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
|
||||
+ return super.getFluidData(x, y, z);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
23
patches/server/Add-ItemType-getItemRarity.patch
Normal file
23
patches/server/Add-ItemType-getItemRarity.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 9 Jul 2024 18:37:37 -0700
|
||||
Subject: [PATCH] Add ItemType#getItemRarity
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java
|
||||
@@ -0,0 +0,0 @@ public class CraftItemType<M extends ItemMeta> implements ItemType.Typed<M>, Han
|
||||
return this.item.getDescriptionId();
|
||||
}
|
||||
// Paper end - add Translatable
|
||||
+
|
||||
+ // Paper start - expand ItemRarity API
|
||||
+ @Override
|
||||
+ public org.bukkit.inventory.ItemRarity getItemRarity() {
|
||||
+ final net.minecraft.world.item.Rarity rarity = this.item.components().get(DataComponents.RARITY);
|
||||
+ return rarity == null ? null : org.bukkit.inventory.ItemRarity.valueOf(rarity.name());
|
||||
+ }
|
||||
+ // Paper end - expand ItemRarity API
|
||||
}
|
||||
785
patches/server/Add-Lifecycle-Event-system.patch
Normal file
785
patches/server/Add-Lifecycle-Event-system.patch
Normal file
@@ -0,0 +1,785 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 18 Jul 2023 17:49:38 -0700
|
||||
Subject: [PATCH] Add Lifecycle Event system
|
||||
|
||||
This event system is separate from Bukkit's event system and is
|
||||
meant for managing resources across reloads and from points in the
|
||||
PluginBootstrap.
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java b/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/bootstrap/PluginBootstrapContextImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package io.papermc.paper.plugin.bootstrap;
|
||||
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEventManager;
|
||||
import io.papermc.paper.plugin.provider.PluginProvider;
|
||||
import java.nio.file.Path;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
@@ -0,0 +0,0 @@ public final class PluginBootstrapContextImpl implements BootstrapContext {
|
||||
private final Path dataFolder;
|
||||
private final ComponentLogger logger;
|
||||
private final Path pluginSource;
|
||||
+ // Paper start - lifecycle events
|
||||
+ private boolean allowsLifecycleRegistration = true;
|
||||
+ private final PaperLifecycleEventManager<BootstrapContext> lifecycleEventManager = new PaperLifecycleEventManager<>(this, () -> this.allowsLifecycleRegistration); // Paper - lifecycle events
|
||||
+ // Paper end - lifecycle events
|
||||
|
||||
public PluginBootstrapContextImpl(PluginMeta config, Path dataFolder, ComponentLogger logger, Path pluginSource) {
|
||||
this.config = config;
|
||||
@@ -0,0 +0,0 @@ public final class PluginBootstrapContextImpl implements BootstrapContext {
|
||||
public @NotNull Path getPluginSource() {
|
||||
return this.pluginSource;
|
||||
}
|
||||
+
|
||||
+ // Paper start - lifecycle event system
|
||||
+ @Override
|
||||
+ public @NotNull PluginMeta getPluginMeta() {
|
||||
+ return this.config;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public LifecycleEventManager<BootstrapContext> getLifecycleManager() {
|
||||
+ return this.lifecycleEventManager;
|
||||
+ }
|
||||
+
|
||||
+ public void lockLifecycleEventRegistration() {
|
||||
+ this.allowsLifecycleRegistration = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.PaperRegistrar;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEventImpl;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.OwnerAwareLifecycleEvent;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class LifecycleEventRunner {
|
||||
+
|
||||
+ public static final LifecycleEventRunner INSTANCE = new LifecycleEventRunner();
|
||||
+
|
||||
+ private final List<LifecycleEventType<?, ?, ?>> lifecycleEventTypes = new ArrayList<>();
|
||||
+ private boolean blockPluginReloading = false;
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner> void checkRegisteredHandler(final O owner, final AbstractLifecycleEventType<O, ?, ?> eventType) {
|
||||
+ /*
|
||||
+ Lifecycle event handlers for reloadable events that are registered from the BootstrapContext prevent
|
||||
+ the server from reloading plugins. This is because reloading plugins requires disabling all the plugins,
|
||||
+ running the reload logic (which would include places where these events should fire) and then re-enabling plugins.
|
||||
+ */
|
||||
+ if (eventType.blocksReloading(owner)) {
|
||||
+ this.blockPluginReloading = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean blocksPluginReloading() {
|
||||
+ return this.blockPluginReloading;
|
||||
+ }
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner, E extends LifecycleEvent, ET extends LifecycleEventType<O, E, ?>> void addEventType(final ET eventType) {
|
||||
+ this.lifecycleEventTypes.add(eventType);
|
||||
+ }
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner, E extends PaperLifecycleEvent> void callEvent(final LifecycleEventType<O, ? super E, ?> eventType, final E event) {
|
||||
+ this.callEvent(eventType, event, $ -> true);
|
||||
+ }
|
||||
+
|
||||
+ public <O extends LifecycleEventOwner, E extends PaperLifecycleEvent> void callEvent(final LifecycleEventType<O, ? super E, ?> eventType, final E event, final Predicate<? super O> ownerPredicate) {
|
||||
+ final AbstractLifecycleEventType<O, ? super E, ?> lifecycleEventType = (AbstractLifecycleEventType<O, ? super E, ?>) eventType;
|
||||
+ lifecycleEventType.forEachHandler(event, registeredHandler -> {
|
||||
+ try {
|
||||
+ if (event instanceof final OwnerAwareLifecycleEvent<?> ownerAwareEvent) {
|
||||
+ ownerAwareGenericHelper(ownerAwareEvent, registeredHandler.owner());
|
||||
+ }
|
||||
+ registeredHandler.lifecycleEventHandler().run(event);
|
||||
+ } catch (final Throwable ex) {
|
||||
+ throw new RuntimeException("Could not run '%s' lifecycle event handler from %s".formatted(lifecycleEventType.name(), registeredHandler.owner().getPluginMeta().getDisplayName()), ex);
|
||||
+ } finally {
|
||||
+ if (event instanceof final OwnerAwareLifecycleEvent<?> ownerAwareEvent) {
|
||||
+ ownerAwareEvent.setOwner(null);
|
||||
+ }
|
||||
+ }
|
||||
+ }, handler -> ownerPredicate.test(handler.owner()));
|
||||
+ event.invalidate();
|
||||
+ }
|
||||
+
|
||||
+ private static <O extends LifecycleEventOwner> void ownerAwareGenericHelper(final OwnerAwareLifecycleEvent<O> event, final LifecycleEventOwner possibleOwner) {
|
||||
+ final @Nullable O owner = event.castOwner(possibleOwner);
|
||||
+ if (owner != null) {
|
||||
+ event.setOwner(owner);
|
||||
+ } else {
|
||||
+ throw new IllegalStateException("Found invalid owner " + possibleOwner + " for event " + event);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void unregisterAllEventHandlersFor(final Plugin plugin) {
|
||||
+ for (final LifecycleEventType<?, ?, ?> lifecycleEventType : this.lifecycleEventTypes) {
|
||||
+ this.removeEventHandlersOwnedBy(lifecycleEventType, plugin);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private <O extends LifecycleEventOwner> void removeEventHandlersOwnedBy(final LifecycleEventType<O, ?, ?> eventType, final Plugin possibleOwner) {
|
||||
+ final AbstractLifecycleEventType<O, ?, ?> lifecycleEventType = (AbstractLifecycleEventType<O, ?, ?>) eventType;
|
||||
+ lifecycleEventType.removeMatching(registeredHandler -> registeredHandler.owner().getPluginMeta().getName().equals(possibleOwner.getPluginMeta().getName()));
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public <O extends LifecycleEventOwner, R extends PaperRegistrar<? super O>> void callStaticRegistrarEvent(final LifecycleEventType<O, ? extends RegistrarEvent<? super R>, ?> lifecycleEventType, final R registrar, final Class<? extends O> ownerClass) {
|
||||
+ this.callEvent((LifecycleEventType<O, RegistrarEvent<? super R>, ?>) lifecycleEventType, new RegistrarEventImpl<>(registrar, ownerClass), ownerClass::isInstance);
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public <O extends LifecycleEventOwner, R extends PaperRegistrar<? super O>> void callReloadableRegistrarEvent(final LifecycleEventType<O, ? extends ReloadableRegistrarEvent<? super R>, ?> lifecycleEventType, final R registrar, final Class<? extends O> ownerClass, final ReloadableRegistrarEvent.Cause cause) {
|
||||
+ this.callEvent((LifecycleEventType<O, ReloadableRegistrarEvent<? super R>, ?>) lifecycleEventType, new RegistrarEventImpl.ReloadableImpl<>(registrar, ownerClass, cause), ownerClass::isInstance);
|
||||
+ }
|
||||
+
|
||||
+ private LifecycleEventRunner() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+public interface PaperLifecycleEvent extends LifecycleEvent {
|
||||
+
|
||||
+ // called after all handlers have been run. Can be
|
||||
+ // used to invalid various contexts to plugins can't
|
||||
+ // try to re-use them by storing them from the event
|
||||
+ default void invalidate() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEventManager.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEventManager.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/PaperLifecycleEventManager.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.AbstractLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration;
|
||||
+import java.util.function.BooleanSupplier;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class PaperLifecycleEventManager<O extends LifecycleEventOwner> implements LifecycleEventManager<O> {
|
||||
+
|
||||
+ private final O owner;
|
||||
+ public final BooleanSupplier registrationCheck;
|
||||
+
|
||||
+ public PaperLifecycleEventManager(final O owner, final BooleanSupplier registrationCheck) {
|
||||
+ this.owner = owner;
|
||||
+ this.registrationCheck = registrationCheck;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void registerEventHandler(final LifecycleEventHandlerConfiguration<? super O> handlerConfiguration) {
|
||||
+ Preconditions.checkState(this.registrationCheck.getAsBoolean(), "Cannot register lifecycle event handlers");
|
||||
+ ((AbstractLifecycleEventHandlerConfiguration<? super O, ?>) handlerConfiguration).registerFrom(this.owner);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/AbstractLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/AbstractLifecycleEventHandlerConfiguration.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/AbstractLifecycleEventHandlerConfiguration.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public abstract class AbstractLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner, E extends LifecycleEvent> implements LifecycleEventHandlerConfiguration<O> {
|
||||
+
|
||||
+ private final LifecycleEventHandler<? super E> handler;
|
||||
+ private final AbstractLifecycleEventType<O, E, ?> type;
|
||||
+
|
||||
+ protected AbstractLifecycleEventHandlerConfiguration(final LifecycleEventHandler<? super E> handler, final AbstractLifecycleEventType<O, E, ?> type) {
|
||||
+ this.handler = handler;
|
||||
+ this.type = type;
|
||||
+ }
|
||||
+
|
||||
+ public final void registerFrom(final O owner) {
|
||||
+ this.type.tryRegister(owner, this);
|
||||
+ }
|
||||
+
|
||||
+ public LifecycleEventHandler<? super E> handler() {
|
||||
+ return this.handler;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfigurationImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfigurationImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfigurationImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class MonitorLifecycleEventHandlerConfigurationImpl<O extends LifecycleEventOwner, E extends LifecycleEvent> extends AbstractLifecycleEventHandlerConfiguration<O, E> implements MonitorLifecycleEventHandlerConfiguration<O> {
|
||||
+
|
||||
+ private boolean monitor = false;
|
||||
+
|
||||
+ public MonitorLifecycleEventHandlerConfigurationImpl(final LifecycleEventHandler<? super E> handler, final AbstractLifecycleEventType<O, E, ?> eventType) {
|
||||
+ super(handler, eventType);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isMonitor() {
|
||||
+ return this.monitor;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MonitorLifecycleEventHandlerConfiguration<O> monitor() {
|
||||
+ this.monitor = true;
|
||||
+ return this;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfigurationImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfigurationImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfigurationImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.handler.configuration;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
+import java.util.OptionalInt;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class PrioritizedLifecycleEventHandlerConfigurationImpl<O extends LifecycleEventOwner, E extends LifecycleEvent>
|
||||
+ extends AbstractLifecycleEventHandlerConfiguration<O, E>
|
||||
+ implements PrioritizedLifecycleEventHandlerConfiguration<O> {
|
||||
+
|
||||
+ private static final OptionalInt DEFAULT_PRIORITY = OptionalInt.of(0);
|
||||
+ private static final OptionalInt MONITOR_PRIORITY = OptionalInt.empty();
|
||||
+
|
||||
+ private OptionalInt priority = DEFAULT_PRIORITY;
|
||||
+
|
||||
+ public PrioritizedLifecycleEventHandlerConfigurationImpl(final LifecycleEventHandler<? super E> handler, final AbstractLifecycleEventType<O, E, ?> eventType) {
|
||||
+ super(handler, eventType);
|
||||
+ }
|
||||
+
|
||||
+ public OptionalInt priority() {
|
||||
+ return this.priority;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfiguration<O> priority(final int priority) {
|
||||
+ this.priority = OptionalInt.of(priority);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfiguration<O> monitor() {
|
||||
+ this.priority = MONITOR_PRIORITY;
|
||||
+ return this;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/PaperRegistrar.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/PaperRegistrar.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/PaperRegistrar.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.registrar;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public interface PaperRegistrar<O extends LifecycleEventOwner> extends Registrar {
|
||||
+
|
||||
+ void setCurrentContext(@Nullable O owner);
|
||||
+
|
||||
+ default void invalidate() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEventImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEventImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEventImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.registrar;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.types.OwnerAwareLifecycleEvent;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class RegistrarEventImpl<R extends PaperRegistrar<? super O>, O extends LifecycleEventOwner> implements PaperLifecycleEvent, OwnerAwareLifecycleEvent<O>, RegistrarEvent<R> {
|
||||
+
|
||||
+ private final R registrar;
|
||||
+ private final Class<? extends O> ownerClass;
|
||||
+
|
||||
+ public RegistrarEventImpl(final R registrar, final Class<? extends O> ownerClass) {
|
||||
+ this.registrar = registrar;
|
||||
+ this.ownerClass = ownerClass;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public R registrar() {
|
||||
+ return this.registrar;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final void setOwner(final @Nullable O owner) {
|
||||
+ this.registrar.setCurrentContext(owner);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final @Nullable O castOwner(final LifecycleEventOwner owner) {
|
||||
+ return this.ownerClass.isInstance(owner) ? this.ownerClass.cast(owner) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void invalidate() {
|
||||
+ this.registrar.invalidate();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "RegistrarEventImpl{" +
|
||||
+ "registrar=" + this.registrar +
|
||||
+ ", ownerClass=" + this.ownerClass +
|
||||
+ '}';
|
||||
+ }
|
||||
+
|
||||
+ public static class ReloadableImpl<R extends PaperRegistrar<? super O>, O extends LifecycleEventOwner> extends RegistrarEventImpl<R, O> implements ReloadableRegistrarEvent<R> {
|
||||
+
|
||||
+ private final ReloadableRegistrarEvent.Cause cause;
|
||||
+
|
||||
+ public ReloadableImpl(final R registrar, final Class<? extends O> ownerClass, final Cause cause) {
|
||||
+ super(registrar, ownerClass);
|
||||
+ this.cause = cause;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Cause cause() {
|
||||
+ return this.cause;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "ReloadableImpl{" +
|
||||
+ "cause=" + this.cause +
|
||||
+ "} " + super.toString();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/AbstractLifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/AbstractLifecycleEventType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/AbstractLifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.types;
|
||||
+
|
||||
+import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.AbstractLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration;
|
||||
+import java.util.function.Consumer;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public abstract class AbstractLifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent, C extends LifecycleEventHandlerConfiguration<O>> implements LifecycleEventType<O, E, C> {
|
||||
+
|
||||
+ private final String name;
|
||||
+ private final Class<? extends O> ownerType;
|
||||
+
|
||||
+ protected AbstractLifecycleEventType(final String name, final Class<? extends O> ownerType) {
|
||||
+ this.name = name;
|
||||
+ this.ownerType = ownerType;
|
||||
+ LifecycleEventRunner.INSTANCE.addEventType(this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String name() {
|
||||
+ return this.name;
|
||||
+ }
|
||||
+
|
||||
+ private void verifyOwner(final O owner) {
|
||||
+ if (!this.ownerType.isInstance(owner)) {
|
||||
+ throw new IllegalArgumentException("You cannot register the lifecycle event '" + this.name + "' on " + owner);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean blocksReloading(final O eventOwner) {
|
||||
+ return eventOwner instanceof BootstrapContext;
|
||||
+ }
|
||||
+
|
||||
+ public abstract boolean hasHandlers();
|
||||
+
|
||||
+ public abstract void forEachHandler(E event, Consumer<RegisteredHandler<O, E>> consumer, Predicate<RegisteredHandler<O, E>> predicate);
|
||||
+
|
||||
+ public abstract void removeMatching(Predicate<RegisteredHandler<O, E>> predicate);
|
||||
+
|
||||
+ protected abstract void register(O owner, AbstractLifecycleEventHandlerConfiguration<O, E> config);
|
||||
+
|
||||
+ public final void tryRegister(final O owner, final AbstractLifecycleEventHandlerConfiguration<O, E> config) {
|
||||
+ this.verifyOwner(owner);
|
||||
+ LifecycleEventRunner.INSTANCE.checkRegisteredHandler(owner, this);
|
||||
+ this.register(owner, config);
|
||||
+ }
|
||||
+
|
||||
+ public record RegisteredHandler<O extends LifecycleEventOwner, E extends LifecycleEvent>(O owner, AbstractLifecycleEventHandlerConfiguration<O, E> config) {
|
||||
+
|
||||
+ public LifecycleEventHandler<? super E> lifecycleEventHandler() {
|
||||
+ return this.config().handler();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.types;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class LifecycleEventTypeProviderImpl implements LifecycleEventTypeProvider {
|
||||
+
|
||||
+ public static LifecycleEventTypeProviderImpl instance() {
|
||||
+ return (LifecycleEventTypeProviderImpl) LifecycleEventTypeProvider.provider();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Monitorable<O, E> monitor(final String name, final Class<? extends O> ownerType) {
|
||||
+ return new MonitorableLifecycleEventType<>(name, ownerType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <O extends LifecycleEventOwner, E extends LifecycleEvent> LifecycleEventType.Prioritizable<O, E> prioritized(final String name, final Class<? extends O> ownerType) {
|
||||
+ return new PrioritizableLifecycleEventType.Simple<>(name, ownerType);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/MonitorableLifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/MonitorableLifecycleEventType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/MonitorableLifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.types;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.AbstractLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfigurationImpl;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.function.Consumer;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class MonitorableLifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent> extends AbstractLifecycleEventType<O, E, MonitorLifecycleEventHandlerConfiguration<O>> implements LifecycleEventType.Monitorable<O, E> {
|
||||
+
|
||||
+ final List<RegisteredHandler<O, E>> handlers = new ArrayList<>();
|
||||
+ int nonMonitorIdx = 0;
|
||||
+
|
||||
+ public MonitorableLifecycleEventType(final String name, final Class<? extends O> ownerType) {
|
||||
+ super(name, ownerType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasHandlers() {
|
||||
+ return !this.handlers.isEmpty();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MonitorLifecycleEventHandlerConfigurationImpl<O, E> newHandler(final LifecycleEventHandler<? super E> handler) {
|
||||
+ return new MonitorLifecycleEventHandlerConfigurationImpl<>(handler, this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void register(final O owner, final AbstractLifecycleEventHandlerConfiguration<O, E> config) {
|
||||
+ if (!(config instanceof final MonitorLifecycleEventHandlerConfigurationImpl<?,?> monitor)) {
|
||||
+ throw new IllegalArgumentException("Configuration must be a MonitorLifecycleEventHandlerConfiguration");
|
||||
+ }
|
||||
+ final RegisteredHandler<O, E> registeredHandler = new RegisteredHandler<>(owner, config);
|
||||
+ if (!monitor.isMonitor()) {
|
||||
+ this.handlers.add(this.nonMonitorIdx, registeredHandler);
|
||||
+ this.nonMonitorIdx++;
|
||||
+ } else {
|
||||
+ this.handlers.add(registeredHandler);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void forEachHandler(final E event, final Consumer<RegisteredHandler<O, E>> consumer, final Predicate<RegisteredHandler<O, E>> predicate) {
|
||||
+ for (final RegisteredHandler<O, E> handler : this.handlers) {
|
||||
+ if (predicate.test(handler)) {
|
||||
+ consumer.accept(handler);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeMatching(final Predicate<RegisteredHandler<O, E>> predicate) {
|
||||
+ this.handlers.removeIf(predicate);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/OwnerAwareLifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/OwnerAwareLifecycleEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/OwnerAwareLifecycleEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.types;
|
||||
+
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public interface OwnerAwareLifecycleEvent<O extends LifecycleEventOwner> extends LifecycleEvent {
|
||||
+
|
||||
+ void setOwner(@Nullable O owner);
|
||||
+
|
||||
+ @Nullable O castOwner(LifecycleEventOwner owner);
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PrioritizableLifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PrioritizableLifecycleEventType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PrioritizableLifecycleEventType.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.plugin.lifecycle.event.types;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.AbstractLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration;
|
||||
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfigurationImpl;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Comparator;
|
||||
+import java.util.List;
|
||||
+import java.util.function.Consumer;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public abstract class PrioritizableLifecycleEventType<
|
||||
+ O extends LifecycleEventOwner,
|
||||
+ E extends LifecycleEvent,
|
||||
+ C extends PrioritizedLifecycleEventHandlerConfiguration<O>
|
||||
+> extends AbstractLifecycleEventType<O, E, C> {
|
||||
+
|
||||
+ private static final Comparator<RegisteredHandler<?, ?>> COMPARATOR = Comparator.comparing(handler -> ((PrioritizedLifecycleEventHandlerConfigurationImpl<?, ?>) handler.config()).priority(), (o1, o2) -> {
|
||||
+ if (o1.equals(o2)) {
|
||||
+ return 0;
|
||||
+ } else if (o1.isEmpty()) {
|
||||
+ return 1;
|
||||
+ } else if (o2.isEmpty()) {
|
||||
+ return -1;
|
||||
+ } else {
|
||||
+ return Integer.compare(o1.getAsInt(), o2.getAsInt());
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ private final List<RegisteredHandler<O, E>> handlers = new ArrayList<>();
|
||||
+
|
||||
+ public PrioritizableLifecycleEventType(final String name, final Class<? extends O> ownerType) {
|
||||
+ super(name, ownerType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasHandlers() {
|
||||
+ return !this.handlers.isEmpty();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void register(final O owner, final AbstractLifecycleEventHandlerConfiguration<O, E> config) {
|
||||
+ Preconditions.checkArgument(config instanceof PrioritizedLifecycleEventHandlerConfigurationImpl<?, ?>, "Configuration must be a PrioritizedLifecycleEventHandlerConfiguration");
|
||||
+ this.handlers.add(new RegisteredHandler<>(owner, config));
|
||||
+ this.handlers.sort(COMPARATOR);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void forEachHandler(final E event, final Consumer<RegisteredHandler<O, E>> consumer, final Predicate<RegisteredHandler<O, E>> predicate) {
|
||||
+ for (final RegisteredHandler<O, E> handler : this.handlers) {
|
||||
+ if (predicate.test(handler)) {
|
||||
+ consumer.accept(handler);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeMatching(final Predicate<RegisteredHandler<O, E>> predicate) {
|
||||
+ this.handlers.removeIf(predicate);
|
||||
+ }
|
||||
+
|
||||
+ public static class Simple<O extends LifecycleEventOwner, E extends LifecycleEvent> extends PrioritizableLifecycleEventType<O, E, PrioritizedLifecycleEventHandlerConfiguration<O>> implements LifecycleEventType.Prioritizable<O, E> {
|
||||
+ public Simple(final String name, final Class<? extends O> ownerType) {
|
||||
+ super(name, ownerType);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PrioritizedLifecycleEventHandlerConfiguration<O> newHandler(final LifecycleEventHandler<? super E> handler) {
|
||||
+ return new PrioritizedLifecycleEventHandlerConfigurationImpl<>(handler, this);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java
|
||||
@@ -0,0 +0,0 @@ class PaperPluginInstanceManager {
|
||||
+ pluginName + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
+ // Paper start - lifecycle event system
|
||||
+ try {
|
||||
+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.unregisterAllEventHandlersFor(plugin);
|
||||
+ } catch (Throwable ex) {
|
||||
+ this.handlePluginException("Error occurred (in the plugin loader) while unregistering lifecycle event handlers for "
|
||||
+ + pluginName + " (Is it up to date?)", ex, plugin);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
try {
|
||||
this.server.getMessenger().unregisterIncomingPluginChannel(plugin);
|
||||
this.server.getMessenger().unregisterOutgoingPluginChannel(plugin);
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java b/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/storage/BootstrapProviderStorage.java
|
||||
@@ -0,0 +0,0 @@ public class BootstrapProviderStorage extends SimpleProviderStorage<PluginBootst
|
||||
@Override
|
||||
public boolean load(PluginProvider<PluginBootstrap> provider, PluginBootstrap provided) {
|
||||
try {
|
||||
- BootstrapContext context = PluginBootstrapContextImpl.create(provider, PluginInitializerManager.instance().pluginDirectoryPath());
|
||||
+ PluginBootstrapContextImpl context = PluginBootstrapContextImpl.create(provider, PluginInitializerManager.instance().pluginDirectoryPath()); // Paper - lifecycle events
|
||||
provided.bootstrap(context);
|
||||
+ context.lockLifecycleEventRegistration(); // Paper - lifecycle events
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
+ // Paper start - lifecycle events
|
||||
+ if (io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.blocksPluginReloading()) {
|
||||
+ throw new IllegalStateException("A lifecycle event handler has been registered which makes reloading plugins not possible");
|
||||
+ }
|
||||
+ // Paper end - lifecycle events
|
||||
org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
||||
this.reloadCount++;
|
||||
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
}
|
||||
// Paper end - spawn egg color visibility
|
||||
|
||||
+ // Paper start - lifecycle event API
|
||||
+ @Override
|
||||
+ public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck) {
|
||||
+ return new io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEventManager<>(plugin, registrationCheck);
|
||||
+ }
|
||||
+ // Paper end - lifecycle event API
|
||||
+
|
||||
/**
|
||||
* This helper class represents the different NBT Tags.
|
||||
* <p>
|
||||
diff --git a/src/main/resources/META-INF/services/io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProvider b/src/main/resources/META-INF/services/io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProvider
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/resources/META-INF/services/io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProvider
|
||||
@@ -0,0 +1 @@
|
||||
+io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventTypeProviderImpl
|
||||
diff --git a/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java b/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java
|
||||
+++ b/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java
|
||||
@@ -0,0 +0,0 @@ public class PaperTestPlugin extends PluginBase {
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
+
|
||||
+ // Paper start - lifecycle events
|
||||
+ @Override
|
||||
+ public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+ // Paper end - lifecycle events
|
||||
}
|
||||
186
patches/server/Add-Listing-API-for-Player.patch
Normal file
186
patches/server/Add-Listing-API-for-Player.patch
Normal file
@@ -0,0 +1,186 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Corey Shupe <coreyshupe101@gmail.com>
|
||||
Date: Wed, 11 Jan 2023 16:40:39 -0500
|
||||
Subject: [PATCH] Add Listing API for Player
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
@@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke
|
||||
this.actions = EnumSet.of(action);
|
||||
this.entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry(player));
|
||||
}
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ public ClientboundPlayerInfoUpdatePacket(EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions, List<ClientboundPlayerInfoUpdatePacket.Entry> entries) {
|
||||
+ this.actions = actions;
|
||||
+ this.entries = entries;
|
||||
+ }
|
||||
+
|
||||
+ public ClientboundPlayerInfoUpdatePacket(EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions, ClientboundPlayerInfoUpdatePacket.Entry entry) {
|
||||
+ this.actions = actions;
|
||||
+ this.entries = List.of(entry);
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
|
||||
public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection<ServerPlayer> players) {
|
||||
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(
|
||||
@@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke
|
||||
return new ClientboundPlayerInfoUpdatePacket(enumSet, players);
|
||||
}
|
||||
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(Collection<ServerPlayer> players, ServerPlayer forPlayer) {
|
||||
+ final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
|
||||
+ final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = new java.util.ArrayList<>(players.size());
|
||||
+ final org.bukkit.craftbukkit.entity.CraftPlayer bukkitEntity = forPlayer.getBukkitEntity();
|
||||
+ for (final ServerPlayer player : players) {
|
||||
+ entries.add(new ClientboundPlayerInfoUpdatePacket.Entry(player, bukkitEntity.isListed(player.getBukkitEntity())));
|
||||
+ }
|
||||
+ return new ClientboundPlayerInfoUpdatePacket(enumSet, entries);
|
||||
+ }
|
||||
+
|
||||
+ public static ClientboundPlayerInfoUpdatePacket createSinglePlayerInitializing(ServerPlayer player, boolean listed) {
|
||||
+ final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
|
||||
+ final List<ClientboundPlayerInfoUpdatePacket.Entry> entries = List.of(new Entry(player, listed));
|
||||
+ return new ClientboundPlayerInfoUpdatePacket(enumSet, entries);
|
||||
+ }
|
||||
+
|
||||
+ public static ClientboundPlayerInfoUpdatePacket updateListed(UUID playerInfoId, boolean listed) {
|
||||
+ EnumSet<ClientboundPlayerInfoUpdatePacket.Action> enumSet = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED);
|
||||
+ return new ClientboundPlayerInfoUpdatePacket(enumSet, new ClientboundPlayerInfoUpdatePacket.Entry(playerInfoId, listed));
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
private ClientboundPlayerInfoUpdatePacket(RegistryFriendlyByteBuf buf) {
|
||||
this.actions = buf.readEnumSet(ClientboundPlayerInfoUpdatePacket.Action.class);
|
||||
this.entries = buf.readList(buf2 -> {
|
||||
@@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke
|
||||
@Nullable RemoteChatSession.Data chatSession
|
||||
) {
|
||||
Entry(ServerPlayer player) {
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ this(player, true);
|
||||
+ }
|
||||
+ Entry(ServerPlayer player, boolean listed) {
|
||||
this(
|
||||
+ // Paper end - Add Listing API for Player
|
||||
player.getUUID(),
|
||||
player.getGameProfile(),
|
||||
- true,
|
||||
+ listed, // Paper - Add Listing API for Player
|
||||
player.connection.latency(),
|
||||
player.gameMode.getGameModeForPlayer(),
|
||||
player.getTabListDisplayName(),
|
||||
@@ -0,0 +0,0 @@ public class ClientboundPlayerInfoUpdatePacket implements Packet<ClientGamePacke
|
||||
Optionull.map(player.getChatSession(), RemoteChatSession::asData)
|
||||
);
|
||||
}
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ Entry(UUID profileId, boolean listed) {
|
||||
+ this(profileId, null, listed, 0, GameType.DEFAULT_MODE, null, 0, null);
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
}
|
||||
|
||||
static class EntryBuilder {
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
// CraftBukkit end
|
||||
|
||||
// CraftBukkit start - sendAll above replaced with this loop
|
||||
- ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player));
|
||||
+ ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player
|
||||
|
||||
final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
|
||||
|
||||
if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) {
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) {
|
||||
+ // Paper end - Add Listing API for Player
|
||||
entityplayer1.connection.send(packet);
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ } else {
|
||||
+ entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false));
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
}
|
||||
|
||||
if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
}
|
||||
// Paper start - Use single player info update packet on join
|
||||
if (!onlinePlayers.isEmpty()) {
|
||||
- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers));
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player)); // Paper - Add Listing API for Player
|
||||
}
|
||||
// Paper end - Use single player info update packet on join
|
||||
player.sentListPacket = true;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private final ConversationTracker conversationTracker = new ConversationTracker();
|
||||
private final Set<String> channels = new HashSet<String>();
|
||||
private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new HashMap<>();
|
||||
+ private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
||||
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
||||
private int hash = 0;
|
||||
private double health = 20;
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
otherPlayer.setUUID(uuidOverride);
|
||||
}
|
||||
// Paper end
|
||||
- this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(otherPlayer)));
|
||||
+ this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(otherPlayer), this.getHandle())); // Paper - Add Listing API for Player
|
||||
if (original != null) otherPlayer.setUUID(original); // Paper - uuid override
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it
|
||||
}
|
||||
|
||||
+ // Paper start - Add Listing API for Player
|
||||
+ @Override
|
||||
+ public boolean isListed(Player other) {
|
||||
+ return !this.unlistedEntities.contains(other.getUniqueId());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean unlistPlayer(@NotNull Player other) {
|
||||
+ Preconditions.checkNotNull(other, "hidden entity cannot be null");
|
||||
+ if (this.getHandle().connection == null) return false;
|
||||
+ if (!this.canSee(other)) return false;
|
||||
+
|
||||
+ if (unlistedEntities.add(other.getUniqueId())) {
|
||||
+ this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.updateListed(other.getUniqueId(), false));
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean listPlayer(@NotNull Player other) {
|
||||
+ Preconditions.checkNotNull(other, "hidden entity cannot be null");
|
||||
+ if (this.getHandle().connection == null) return false;
|
||||
+ if (!this.canSee(other)) throw new IllegalStateException("Player cannot see other player");
|
||||
+
|
||||
+ if (this.unlistedEntities.remove(other.getUniqueId())) {
|
||||
+ this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.updateListed(other.getUniqueId(), true));
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add Listing API for Player
|
||||
+
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
22
patches/server/Add-Mob-Experience-reward-API.patch
Normal file
22
patches/server/Add-Mob-Experience-reward-API.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: GodOfPro <1387ilia@gmail.com>
|
||||
Date: Tue, 11 Apr 2023 16:31:39 +0430
|
||||
Subject: [PATCH] Add Mob Experience reward API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
this.getHandle().setAggressive(aggressive);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getPossibleExperienceReward() {
|
||||
+ return getHandle().getExperienceReward((net.minecraft.server.level.ServerLevel) this.getHandle().level(), null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
46
patches/server/Add-Moving-Piston-API.patch
Normal file
46
patches/server/Add-Moving-Piston-API.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 4 Dec 2021 13:29:36 -0500
|
||||
Subject: [PATCH] Add Moving Piston API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftMovingPiston.java b/src/main/java/org/bukkit/craftbukkit/block/CraftMovingPiston.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftMovingPiston.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftMovingPiston.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
-public class CraftMovingPiston extends CraftBlockEntityState<PistonMovingBlockEntity> {
|
||||
+public class CraftMovingPiston extends CraftBlockEntityState<PistonMovingBlockEntity> implements io.papermc.paper.block.MovingPiston { // Paper - Add Moving Piston API
|
||||
|
||||
public CraftMovingPiston(World world, PistonMovingBlockEntity tileEntity) {
|
||||
super(world, tileEntity);
|
||||
@@ -0,0 +0,0 @@ public class CraftMovingPiston extends CraftBlockEntityState<PistonMovingBlockEn
|
||||
public CraftMovingPiston copy(Location location) {
|
||||
return new CraftMovingPiston(this, location);
|
||||
}
|
||||
+
|
||||
+ // Paper start - Add Moving Piston API
|
||||
+ @Override
|
||||
+ public org.bukkit.block.data.BlockData getMovingBlock() {
|
||||
+ return org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(this.getTileEntity().getMovedState());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.block.BlockFace getDirection() {
|
||||
+ return org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(this.getTileEntity().getDirection());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isExtending() {
|
||||
+ return this.getTileEntity().isExtending();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isPistonHead() {
|
||||
+ return this.getTileEntity().isSourcePiston();
|
||||
+ }
|
||||
+ // Paper end - Add Moving Piston API
|
||||
}
|
||||
28
patches/server/Add-NamespacedKey-biome-methods.patch
Normal file
28
patches/server/Add-NamespacedKey-biome-methods.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
|
||||
Date: Sun, 14 Aug 2022 12:23:11 -0400
|
||||
Subject: [PATCH] Add NamespacedKey biome methods
|
||||
|
||||
Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
var supplier = net.minecraft.world.entity.ai.attributes.DefaultAttributes.getSupplier((net.minecraft.world.entity.EntityType<? extends net.minecraft.world.entity.LivingEntity>) net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getValue(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
|
||||
return new io.papermc.paper.attribute.UnmodifiableAttributeMap(supplier);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.NamespacedKey getBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z) {
|
||||
+ return accessor.getBiome(x, y, z).getKey();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z, org.bukkit.NamespacedKey biomeKey) {
|
||||
+ accessor.setBiome(x, y, z, org.bukkit.Registry.BIOME.getOrThrow(biomeKey));
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
/**
|
||||
57
patches/server/Add-Player-Warden-Warning-API.patch
Normal file
57
patches/server/Add-Player-Warden-Warning-API.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: dawon <dawon@dawon.eu>
|
||||
Date: Sat, 15 Oct 2022 00:46:57 +0200
|
||||
Subject: [PATCH] Add Player Warden Warning API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.level.ServerPlayer wardenSpawnTracker
|
||||
public net.minecraft.world.entity.monster.warden.WardenSpawnTracker ticksSinceLastWarning
|
||||
public net.minecraft.world.entity.monster.warden.WardenSpawnTracker cooldownTicks
|
||||
public net.minecraft.world.entity.monster.warden.WardenSpawnTracker increaseWarningLevel()V
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public void showElderGuardian(boolean silent) {
|
||||
if (getHandle().connection != null) getHandle().connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, silent ? 0F : 1F));
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getWardenWarningCooldown() {
|
||||
+ return this.getHandle().wardenSpawnTracker.cooldownTicks;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWardenWarningCooldown(int cooldown) {
|
||||
+ this.getHandle().wardenSpawnTracker.cooldownTicks = Math.max(cooldown, 0);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getWardenTimeSinceLastWarning() {
|
||||
+ return this.getHandle().wardenSpawnTracker.ticksSinceLastWarning;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWardenTimeSinceLastWarning(int time) {
|
||||
+ this.getHandle().wardenSpawnTracker.ticksSinceLastWarning = time;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getWardenWarningLevel() {
|
||||
+ return this.getHandle().wardenSpawnTracker.getWarningLevel();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWardenWarningLevel(int warningLevel) {
|
||||
+ this.getHandle().wardenSpawnTracker.setWarningLevel(warningLevel);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void increaseWardenWarningLevel() {
|
||||
+ this.getHandle().wardenSpawnTracker.increaseWarningLevel();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
public Player.Spigot spigot()
|
||||
26
patches/server/Add-Player-getFishHook.patch
Normal file
26
patches/server/Add-Player-getFishHook.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: u9g <git@u9g.dev>
|
||||
Date: Tue, 14 Jun 2022 19:36:10 -0400
|
||||
Subject: [PATCH] Add Player#getFishHook
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
return new Location(worldServer.getWorld(), bed.getX(), bed.getY(), bed.getZ());
|
||||
}
|
||||
// Paper end
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.FishHook getFishHook() {
|
||||
+ if (getHandle().fishing == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return (org.bukkit.entity.FishHook) getHandle().fishing.getBukkitEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean sleep(Location location, boolean force) {
|
||||
Preconditions.checkArgument(location != null, "Location cannot be null");
|
||||
65
patches/server/Add-PlayerInventorySlotChangeEvent.patch
Normal file
65
patches/server/Add-PlayerInventorySlotChangeEvent.patch
Normal file
@@ -0,0 +1,65 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Zacek <dawon@dawon.eu>
|
||||
Date: Sun, 24 Apr 2022 22:56:59 +0200
|
||||
Subject: [PATCH] Add PlayerInventorySlotChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
|
||||
}
|
||||
}
|
||||
+ // Paper start - Add PlayerInventorySlotChangeEvent
|
||||
+ @Override
|
||||
+ public void slotChanged(AbstractContainerMenu handler, int slotId, ItemStack oldStack, ItemStack stack) {
|
||||
+ Slot slot = handler.getSlot(slotId);
|
||||
+ if (!(slot instanceof ResultSlot)) {
|
||||
+ if (slot.container == ServerPlayer.this.getInventory()) {
|
||||
+ if (io.papermc.paper.event.player.PlayerInventorySlotChangeEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
+ CriteriaTriggers.INVENTORY_CHANGED.trigger(ServerPlayer.this, ServerPlayer.this.getInventory(), stack);
|
||||
+ return;
|
||||
+ }
|
||||
+ io.papermc.paper.event.player.PlayerInventorySlotChangeEvent event = new io.papermc.paper.event.player.PlayerInventorySlotChangeEvent(ServerPlayer.this.getBukkitEntity(), slotId, CraftItemStack.asBukkitCopy(oldStack), CraftItemStack.asBukkitCopy(stack));
|
||||
+ event.callEvent();
|
||||
+ if (event.shouldTriggerAdvancements()) {
|
||||
+ CriteriaTriggers.INVENTORY_CHANGED.trigger(ServerPlayer.this, ServerPlayer.this.getInventory(), stack);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add PlayerInventorySlotChangeEvent
|
||||
|
||||
@Override
|
||||
public void dataChanged(AbstractContainerMenu handler, int property, int value) {}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
while (iterator.hasNext()) {
|
||||
ContainerListener icrafting = (ContainerListener) iterator.next();
|
||||
|
||||
- icrafting.slotChanged(this, slot, itemstack2);
|
||||
+ icrafting.slotChanged(this, slot, itemstack1, itemstack2); // Paper - Add PlayerInventorySlotChangeEvent
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ContainerListener.java b/src/main/java/net/minecraft/world/inventory/ContainerListener.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ContainerListener.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ContainerListener.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.item.ItemStack;
|
||||
public interface ContainerListener {
|
||||
void slotChanged(AbstractContainerMenu handler, int slotId, ItemStack stack);
|
||||
|
||||
+ // Paper start - Add PlayerInventorySlotChangeEvent
|
||||
+ default void slotChanged(AbstractContainerMenu handler, int slotId, ItemStack oldStack, ItemStack stack) {
|
||||
+ slotChanged(handler, slotId, stack);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerInventorySlotChangeEvent
|
||||
+
|
||||
void dataChanged(AbstractContainerMenu handler, int property, int value);
|
||||
}
|
||||
68
patches/server/Add-PlayerPickItemEvent.patch
Normal file
68
patches/server/Add-PlayerPickItemEvent.patch
Normal file
@@ -0,0 +1,68 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: RodneyMKay <36546810+RodneyMKay@users.noreply.github.com>
|
||||
Date: Wed, 8 Sep 2021 21:34:01 +0200
|
||||
Subject: [PATCH] Add PlayerPickItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
if (stack.isItemEnabled(this.player.level().enabledFeatures())) {
|
||||
Inventory playerinventory = this.player.getInventory();
|
||||
int i = playerinventory.findSlotMatchingItem(stack);
|
||||
+ // Paper start - Add PlayerPickItemEvent
|
||||
+ final int sourceSlot = i;
|
||||
+ final int targetSlot = Inventory.isHotbarSlot(sourceSlot) ? sourceSlot : playerinventory.getSuitableHotbarSlot();
|
||||
+ final Player bukkitPlayer = this.player.getBukkitEntity();
|
||||
+ final io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Add PlayerPickItemEvent
|
||||
|
||||
if (i != -1) {
|
||||
if (Inventory.isHotbarSlot(i)) {
|
||||
- playerinventory.selected = i;
|
||||
+ playerinventory.selected = event.getTargetSlot(); // Paper - Add target slot
|
||||
} else {
|
||||
- playerinventory.pickSlot(i);
|
||||
+ playerinventory.pickSlot(i, event.getTargetSlot()); // Paper - Add target slot
|
||||
}
|
||||
} else if (this.player.hasInfiniteMaterials()) {
|
||||
- playerinventory.addAndPickItem(stack);
|
||||
+ playerinventory.addAndPickItem(stack, event.getTargetSlot()); // Paper - Add target slot
|
||||
}
|
||||
|
||||
this.player.connection.send(new ClientboundSetHeldSlotPacket(playerinventory.selected));
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -0,0 +0,0 @@ public class Inventory implements Container, Nameable {
|
||||
return -1;
|
||||
}
|
||||
|
||||
- public void addAndPickItem(ItemStack stack) {
|
||||
- this.selected = this.getSuitableHotbarSlot();
|
||||
+ // Paper start - Add PlayerPickItemEvent
|
||||
+ public void addAndPickItem(ItemStack stack, final int targetSlot) {
|
||||
+ this.selected = targetSlot;
|
||||
+ // Paper end - Add PlayerPickItemEvent
|
||||
if (!((ItemStack) this.items.get(this.selected)).isEmpty()) {
|
||||
int i = this.getFreeSlot();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Inventory implements Container, Nameable {
|
||||
this.items.set(this.selected, stack);
|
||||
}
|
||||
|
||||
- public void pickSlot(int slot) {
|
||||
- this.selected = this.getSuitableHotbarSlot();
|
||||
+ // Paper start - Add PlayerPickItemEvent
|
||||
+ public void pickSlot(int slot, final int targetSlot) {
|
||||
+ this.selected = targetSlot;
|
||||
+ // Paper end - Add PlayerPickItemEvent
|
||||
ItemStack itemstack = (ItemStack) this.items.get(this.selected);
|
||||
|
||||
this.items.set(this.selected, (ItemStack) this.items.get(slot));
|
||||
53
patches/server/Add-PlayerShieldDisableEvent.patch
Normal file
53
patches/server/Add-PlayerShieldDisableEvent.patch
Normal file
@@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cryptite <cryptite@gmail.com>
|
||||
Date: Mon, 1 May 2023 16:22:43 -0500
|
||||
Subject: [PATCH] Add PlayerShieldDisableEvent
|
||||
|
||||
Called whenever a players shield is disabled. This is mainly caused by
|
||||
attacking players or monsters that carry axes.
|
||||
|
||||
The event, while similar to the PlayerItemCooldownEvent, offers other
|
||||
behaviour and can hence not be implemented as a childtype of said event.
|
||||
Specifically, cancelling the event prevents the game events from being
|
||||
sent to the player.
|
||||
|
||||
Plugins listening to just the PlayerItemCooldownEvent may not want said
|
||||
sideeffects, meaning the disable event cannot share a handlerlist with
|
||||
the cooldown event
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
ItemStack itemstack = this.getItemBlockingWith();
|
||||
|
||||
if (attacker.canDisableShield() && itemstack != null) {
|
||||
- this.disableShield(itemstack);
|
||||
+ this.disableShield(itemstack, attacker); // Paper - Add PlayerShieldDisableEvent
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
this.attack(target);
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerShieldDisableEvent
|
||||
public void disableShield(ItemStack shield) {
|
||||
- this.getCooldowns().addCooldown(shield, 100);
|
||||
+ // Paper start - Add PlayerShieldDisableEvent
|
||||
+ this.disableShield(shield, null);
|
||||
+ }
|
||||
+ public void disableShield(ItemStack shield, @Nullable LivingEntity attacker) {
|
||||
+ final org.bukkit.entity.Entity finalAttacker = attacker != null ? attacker.getBukkitEntity() : null;
|
||||
+ if (finalAttacker != null) {
|
||||
+ final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) getBukkitEntity(), finalAttacker, 100);
|
||||
+ if (!shieldDisableEvent.callEvent()) return;
|
||||
+ this.getCooldowns().addCooldown(shield, shieldDisableEvent.getCooldown());
|
||||
+ } else {
|
||||
+ this.getCooldowns().addCooldown(shield, 100);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerShieldDisableEvent
|
||||
this.stopUsingItem();
|
||||
this.level().broadcastEntityEvent(this, (byte) 30);
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 2 Jul 2020 16:12:10 -0700
|
||||
Subject: [PATCH] Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
|
||||
Co-authored-by: Alexander <protonull@protonmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
|
||||
@Override
|
||||
public void overrideXp(int experience) {}
|
||||
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+ @Override
|
||||
+ public void processTrade(MerchantOffer recipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent
|
||||
+ if (event == null || event.willIncreaseTradeUses()) {
|
||||
+ recipe.increaseUses();
|
||||
+ }
|
||||
+ if (event == null || event.isRewardingExp()) {
|
||||
+ this.rewardTradeXp(recipe);
|
||||
+ }
|
||||
+ this.notifyTrade(recipe);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+
|
||||
@Override
|
||||
public void notifyTrade(MerchantOffer offer) {
|
||||
- offer.increaseUses();
|
||||
+ // offer.increaseUses(); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
this.ambientSoundTime = -this.getAmbientSoundInterval();
|
||||
- this.rewardTradeXp(offer);
|
||||
+ // this.rewardTradeXp(offer); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
if (this.tradingPlayer instanceof ServerPlayer) {
|
||||
CriteriaTriggers.TRADE.trigger((ServerPlayer) this.tradingPlayer, this, offer.getResult());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
public abstract boolean stillValid(Player player);
|
||||
|
||||
protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+ return this.moveItemStackTo(stack, startIndex, endIndex, fromLast, false);
|
||||
+ }
|
||||
+ protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast, boolean isCheck) {
|
||||
+ if (isCheck) {
|
||||
+ stack = stack.copy();
|
||||
+ }
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
boolean flag1 = false;
|
||||
int k = startIndex;
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
|
||||
slot = (Slot) this.slots.get(k);
|
||||
itemstack1 = slot.getItem();
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent; clone if only a check
|
||||
+ if (isCheck) {
|
||||
+ itemstack1 = itemstack1.copy();
|
||||
+ }
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(stack, itemstack1)) {
|
||||
l = itemstack1.getCount() + stack.getCount();
|
||||
int i1 = slot.getMaxStackSize(itemstack1);
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
if (l <= i1) {
|
||||
stack.setCount(0);
|
||||
itemstack1.setCount(l);
|
||||
+ if (!isCheck) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
slot.setChanged();
|
||||
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
flag1 = true;
|
||||
} else if (itemstack1.getCount() < i1) {
|
||||
stack.shrink(i1 - itemstack1.getCount());
|
||||
itemstack1.setCount(i1);
|
||||
+ if (!isCheck) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
slot.setChanged();
|
||||
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
|
||||
slot = (Slot) this.slots.get(k);
|
||||
itemstack1 = slot.getItem();
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+ if (isCheck) {
|
||||
+ itemstack1 = itemstack1.copy();
|
||||
+ }
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
if (itemstack1.isEmpty() && slot.mayPlace(stack)) {
|
||||
l = slot.getMaxStackSize(stack);
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+ if (isCheck) {
|
||||
+ stack.shrink(Math.min(stack.getCount(), l));
|
||||
+ } else {
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
slot.setByPlayer(stack.split(Math.min(stack.getCount(), l)));
|
||||
slot.setChanged();
|
||||
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
flag1 = true;
|
||||
break;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java
|
||||
@@ -0,0 +0,0 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
|
||||
itemstack = itemstack1.copy();
|
||||
if (slot == 2) {
|
||||
- if (!this.moveItemStackTo(itemstack1, 3, 39, true)) {
|
||||
+ if (!this.moveItemStackTo(itemstack1, 3, 39, true, true)) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
- slot1.onQuickCraft(itemstack1, itemstack);
|
||||
- this.playTradeSound();
|
||||
+ // slot1.onQuickCraft(itemstack1, itemstack); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; moved to after the non-check moveItemStackTo call
|
||||
+ // this.playTradeSound();
|
||||
} else if (slot != 0 && slot != 1) {
|
||||
if (slot >= 3 && slot < 30) {
|
||||
if (!this.moveItemStackTo(itemstack1, 30, 39, false)) {
|
||||
@@ -0,0 +0,0 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
+ if (slot != 2) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; moved down for slot 2
|
||||
if (itemstack1.isEmpty()) {
|
||||
slot1.setByPlayer(ItemStack.EMPTY);
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
}
|
||||
|
||||
slot1.onTake(player, itemstack1);
|
||||
+ } // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent; handle slot 2
|
||||
+ if (slot == 2) { // is merchant result slot
|
||||
+ slot1.onTake(player, itemstack1);
|
||||
+ if (itemstack1.isEmpty()) {
|
||||
+ slot1.set(ItemStack.EMPTY);
|
||||
+ return ItemStack.EMPTY;
|
||||
+ }
|
||||
+
|
||||
+ this.moveItemStackTo(itemstack1, 3, 39, true, false); // This should always succeed because it's checked above
|
||||
+
|
||||
+ slot1.onQuickCraft(itemstack1, itemstack);
|
||||
+ this.playTradeSound();
|
||||
+ slot1.set(ItemStack.EMPTY); // itemstack1 should ALWAYS be empty
|
||||
+ }
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java
|
||||
@@ -0,0 +0,0 @@ public class MerchantResultSlot extends Slot {
|
||||
|
||||
@Override
|
||||
public void onTake(Player player, ItemStack stack) {
|
||||
- this.checkTakeAchievements(stack);
|
||||
+ // this.checkTakeAchievements(stack); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; move to after event is called and not cancelled
|
||||
MerchantOffer merchantOffer = this.slots.getActiveOffer();
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+ io.papermc.paper.event.player.PlayerPurchaseEvent event = null;
|
||||
+ if (merchantOffer != null && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
|
||||
+ if (this.merchant instanceof net.minecraft.world.entity.npc.AbstractVillager abstractVillager) {
|
||||
+ event = new io.papermc.paper.event.player.PlayerTradeEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.AbstractVillager) abstractVillager.getBukkitEntity(), merchantOffer.asBukkit(), true, true);
|
||||
+ } else if (this.merchant instanceof org.bukkit.craftbukkit.inventory.CraftMerchantCustom.MinecraftMerchant) {
|
||||
+ event = new io.papermc.paper.event.player.PlayerPurchaseEvent(serverPlayer.getBukkitEntity(), merchantOffer.asBukkit(), false, true);
|
||||
+ }
|
||||
+ if (event != null) {
|
||||
+ if (!event.callEvent()) {
|
||||
+ stack.setCount(0);
|
||||
+ event.getPlayer().updateInventory();
|
||||
+ return;
|
||||
+ }
|
||||
+ merchantOffer = org.bukkit.craftbukkit.inventory.CraftMerchantRecipe.fromBukkit(event.getTrade()).toMinecraft();
|
||||
+ }
|
||||
+ }
|
||||
+ this.checkTakeAchievements(stack);
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
if (merchantOffer != null) {
|
||||
ItemStack itemStack = this.slots.getItem(0);
|
||||
ItemStack itemStack2 = this.slots.getItem(1);
|
||||
if (merchantOffer.take(itemStack, itemStack2) || merchantOffer.take(itemStack2, itemStack)) {
|
||||
- this.merchant.notifyTrade(merchantOffer);
|
||||
+ this.merchant.processTrade(merchantOffer, event); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
player.awardStat(Stats.TRADED_WITH_VILLAGER);
|
||||
this.slots.setItem(0, itemStack);
|
||||
this.slots.setItem(1, itemStack2);
|
||||
diff --git a/src/main/java/net/minecraft/world/item/trading/Merchant.java b/src/main/java/net/minecraft/world/item/trading/Merchant.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/trading/Merchant.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/trading/Merchant.java
|
||||
@@ -0,0 +0,0 @@ public interface Merchant {
|
||||
|
||||
void overrideOffers(MerchantOffers offers);
|
||||
|
||||
+ default void processTrade(MerchantOffer merchantRecipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { this.notifyTrade(merchantRecipe); } // Paper
|
||||
void notifyTrade(MerchantOffer offer);
|
||||
|
||||
void notifyTradeUpdated(ItemStack stack);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java
|
||||
@@ -0,0 +0,0 @@ public class CraftMerchantCustom implements CraftMerchant {
|
||||
return this.trades;
|
||||
}
|
||||
|
||||
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
+ @Override
|
||||
+ public void processTrade(MerchantOffer merchantRecipe, @javax.annotation.Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent
|
||||
+ /** Based on {@link net.minecraft.world.entity.npc.AbstractVillager#processTrade(MerchantOffer, io.papermc.paper.event.player.PlayerPurchaseEvent)} */
|
||||
+ if (getTradingPlayer() instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ if (event == null || event.willIncreaseTradeUses()) {
|
||||
+ merchantRecipe.increaseUses();
|
||||
+ }
|
||||
+ if (event == null || event.isRewardingExp()) {
|
||||
+ this.tradingPlayer.level().addFreshEntity(new net.minecraft.world.entity.ExperienceOrb(this.tradingPlayer.level(), this.tradingPlayer.getX(), this.tradingPlayer.getY(), this.tradingPlayer.getZ(), merchantRecipe.getXp(), org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.tradingPlayer, null));
|
||||
+ }
|
||||
+ }
|
||||
+ this.notifyTrade(merchantRecipe);
|
||||
+ }
|
||||
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
|
||||
@Override
|
||||
public void notifyTrade(MerchantOffer offer) {
|
||||
// increase recipe's uses
|
||||
- offer.increaseUses();
|
||||
+ // offer.increaseUses(); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; handled above in processTrade
|
||||
}
|
||||
|
||||
@Override
|
||||
30
patches/server/Add-PrePlayerAttackEntityEvent.patch
Normal file
30
patches/server/Add-PrePlayerAttackEntityEvent.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 18 Sep 2022 13:10:18 -0400
|
||||
Subject: [PATCH] Add PrePlayerAttackEntityEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
public void attack(Entity target) {
|
||||
- if (target.isAttackable()) {
|
||||
- if (!target.skipAttackInteraction(this)) {
|
||||
+ // Paper start - PlayerAttackEntityEvent
|
||||
+ boolean willAttack = target.isAttackable() && !target.skipAttackInteraction(this); // Vanilla logic
|
||||
+ io.papermc.paper.event.player.PrePlayerAttackEntityEvent playerAttackEntityEvent = new io.papermc.paper.event.player.PrePlayerAttackEntityEvent(
|
||||
+ (org.bukkit.entity.Player) this.getBukkitEntity(),
|
||||
+ target.getBukkitEntity(),
|
||||
+ willAttack
|
||||
+ );
|
||||
+
|
||||
+ if (playerAttackEntityEvent.callEvent() && willAttack) { // Logic moved to willAttack local variable.
|
||||
+ {
|
||||
+ // Paper end - PlayerAttackEntityEvent
|
||||
float f = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE);
|
||||
ItemStack itemstack = this.getWeaponItem();
|
||||
DamageSource damagesource = (DamageSource) Optional.ofNullable(itemstack.getItem().getDamageSource(this)).orElse(this.damageSources().playerAttack(this));
|
||||
135
patches/server/Add-Shearable-API.patch
Normal file
135
patches/server/Add-Shearable-API.patch
Normal file
@@ -0,0 +1,135 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 17 Oct 2021 15:39:48 -0400
|
||||
Subject: [PATCH] Add Shearable API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/entity/PaperShearable.java b/src/main/java/io/papermc/paper/entity/PaperShearable.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/entity/PaperShearable.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.kyori.adventure.sound.Sound;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.world.entity.Shearable;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.Items;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface PaperShearable extends io.papermc.paper.entity.Shearable {
|
||||
+
|
||||
+ Shearable getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean readyToBeSheared() {
|
||||
+ return this.getHandle().readyForShearing();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void shear(@NotNull Sound.Source source) {
|
||||
+ if (!(this.getHandle().level() instanceof final ServerLevel serverLevel)) return;
|
||||
+ this.getHandle().shear(serverLevel, PaperAdventure.asVanilla(source), new ItemStack(Items.SHEARS));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
@@ -0,0 +0,0 @@ public interface Shearable {
|
||||
void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears);
|
||||
|
||||
boolean readyForShearing();
|
||||
+ net.minecraft.world.level.Level level(); // Shearable API - expose default level needed for shearing.
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Bogged;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
|
||||
-public class CraftBogged extends CraftAbstractSkeleton implements Bogged {
|
||||
+public class CraftBogged extends CraftAbstractSkeleton implements Bogged, io.papermc.paper.entity.PaperShearable { // Paper - Shear API
|
||||
|
||||
public CraftBogged(CraftServer server, net.minecraft.world.entity.monster.Bogged entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
-public class CraftMushroomCow extends CraftCow implements MushroomCow {
|
||||
+public class CraftMushroomCow extends CraftCow implements MushroomCow, io.papermc.paper.entity.PaperShearable { // Paper
|
||||
public CraftMushroomCow(CraftServer server, net.minecraft.world.entity.animal.MushroomCow entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.DyeColor;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Sheep;
|
||||
|
||||
-public class CraftSheep extends CraftAnimals implements Sheep {
|
||||
+public class CraftSheep extends CraftAnimals implements Sheep, io.papermc.paper.entity.PaperShearable { // Paper
|
||||
public CraftSheep(CraftServer server, net.minecraft.world.entity.animal.Sheep entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.animal.SnowGolem;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Snowman;
|
||||
|
||||
-public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem> { // Paper
|
||||
+public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem>, io.papermc.paper.entity.PaperShearable { // Paper
|
||||
public CraftSnowman(CraftServer server, SnowGolem entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/entity/ShearableTest.java b/src/test/java/io/papermc/paper/entity/ShearableTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/entity/ShearableTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import com.destroystokyo.paper.entity.ai.MobGoalHelper;
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import java.util.List;
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
+import net.minecraft.world.entity.Shearable;
|
||||
+import org.bukkit.support.environment.Normal;
|
||||
+import org.junit.jupiter.api.Assertions;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+@Normal
|
||||
+class ShearableTest {
|
||||
+
|
||||
+ static List<Class<Shearable>> nmsShearables() {
|
||||
+ try (final ScanResult result = new ClassGraph().enableClassInfo().whitelistPackages("net.minecraft.world.entity").scan()) {
|
||||
+ return result.getClassesImplementing(Shearable.class.getName()).loadClasses(Shearable.class);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ @ParameterizedTest
|
||||
+ @MethodSource("nmsShearables")
|
||||
+ void ensureImplementsShearable(final Class<? extends Shearable> shearableNmsClass) {
|
||||
+ final Class<? extends org.bukkit.entity.Mob> bukkitClass = MobGoalHelper.toBukkitClass((Class<? extends Mob>) shearableNmsClass);
|
||||
+ Assertions.assertTrue(io.papermc.paper.entity.Shearable.class.isAssignableFrom(bukkitClass), bukkitClass.getName() + " does not implement Shearable");
|
||||
+ }
|
||||
+}
|
||||
22
patches/server/Add-ShulkerDuplicateEvent.patch
Normal file
22
patches/server/Add-ShulkerDuplicateEvent.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chase Henderson <henderson.chase@gmail.com>
|
||||
Date: Fri, 5 Jan 2024 03:50:10 -0500
|
||||
Subject: [PATCH] Add ShulkerDuplicateEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
@@ -0,0 +0,0 @@ public class Shulker extends AbstractGolem implements VariantHolder<Optional<Dye
|
||||
if (entityshulker != null) {
|
||||
entityshulker.setVariant(this.getVariant());
|
||||
entityshulker.moveTo(vec3d);
|
||||
+ // Paper start - Shulker duplicate event
|
||||
+ if (!new io.papermc.paper.event.entity.ShulkerDuplicateEvent((org.bukkit.entity.Shulker) entityshulker.getBukkitEntity(), (org.bukkit.entity.Shulker) this.getBukkitEntity()).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Shulker duplicate event
|
||||
this.level().addFreshEntity(entityshulker, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - the mysteries of life
|
||||
}
|
||||
|
||||
29
patches/server/Add-Sneaking-API-for-Entities.patch
Normal file
29
patches/server/Add-Sneaking-API-for-Entities.patch
Normal file
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: dawon <dawon@dawon.eu>
|
||||
Date: Wed, 19 Oct 2022 23:31:53 +0200
|
||||
Subject: [PATCH] Add Sneaking API for Entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return Pose.values()[this.getHandle().getPose().ordinal()];
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setSneaking(boolean sneak) {
|
||||
+ this.getHandle().setShiftKeyDown(sneak);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSneaking() {
|
||||
+ return this.getHandle().isShiftKeyDown();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public SpawnCategory getSpawnCategory() {
|
||||
return CraftSpawnCategory.toBukkit(this.getHandle().getType().getCategory());
|
||||
26
patches/server/Add-Structure-check-API.patch
Normal file
26
patches/server/Add-Structure-check-API.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 27 Mar 2023 10:20:00 -0700
|
||||
Subject: [PATCH] Add Structure check API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
};
|
||||
}
|
||||
// Paper end
|
||||
+ // Paper start - structure check API
|
||||
+ @Override
|
||||
+ public boolean hasStructureAt(final io.papermc.paper.math.Position position, final Structure structure) {
|
||||
+ return this.world.structureManager().getStructureWithPieceAt(
|
||||
+ io.papermc.paper.util.MCUtil.toBlockPos(position),
|
||||
+ CraftStructure.bukkitToMinecraft(structure)
|
||||
+ ).isValid();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
private static final Random rand = new Random();
|
||||
|
||||
142
patches/server/Add-UUID-attribute-modifier-API.patch
Normal file
142
patches/server/Add-UUID-attribute-modifier-API.patch
Normal file
@@ -0,0 +1,142 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
|
||||
Date: Thu, 9 Nov 2023 20:34:44 -0500
|
||||
Subject: [PATCH] Add UUID attribute modifier API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
|
||||
|
||||
+import java.util.UUID;
|
||||
import java.util.Collection;
|
||||
|
||||
public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
@@ -0,0 +0,0 @@ public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void removeModifier(UUID uuid) {
|
||||
+ throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void addModifier(AttributeModifier modifier) {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/AttributeMappings.java b/src/main/java/org/bukkit/craftbukkit/attribute/AttributeMappings.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/AttributeMappings.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package org.bukkit.craftbukkit.attribute;
|
||||
+
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.UUID;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+final class AttributeMappings {
|
||||
+ private static final Map<UUID, NamespacedKey> ATTRIBUTE_MODIFIER_IDS = new HashMap<>();
|
||||
+
|
||||
+ static {
|
||||
+ add(-4483571535397864886L, -5989644940537681742L, "armor.body");
|
||||
+ add(8144722948526719024L, -7778190119041365872L, "effect.slowness");
|
||||
+ add(6967552254039378640L, -9116175396973475259L, "enchantment.aqua_affinity");
|
||||
+ add(5279725409867744698L, -5150363631200102632L, "attacking");
|
||||
+ add(148071211714102867L, -7685811609035173472L, "attacking");
|
||||
+ add(6196088217904236654L, -7493791321850887290L, "effect.minining_fatigue");
|
||||
+ add(-5084161844451524480L, -8859020046251006329L, "enchantment.soul_speed");
|
||||
+ add(-7907339078496465106L, -8112074600724210224L, "enchantment.swift_sneak");
|
||||
+ add(6688265815086220243L, -6545541163342161890L, "drinking");
|
||||
+ add(8315164243412860989L, -6631520853640075966L, "creative_mode_block_range");
|
||||
+ add(4389663563256579765L, -4827163546944004714L, "enchantment.efficiency");
|
||||
+ add(6732612758648800940L, -5145707699103688244L, "effect.health_boost");
|
||||
+ add(9079981369298536661L, -6728494925450710401L, "covered");
|
||||
+ add(-1521481167610687786L, -8630419745734927691L, "effect.absorption");
|
||||
+ add(-7473408062188862076L, -5872005994337939597L, "creative_mode_entity_range");
|
||||
+ add(-3721396875562958315L, -5317020504214661337L, "effect.unluck");
|
||||
+ add(-2861585646493481178L, -6113244764726669811L, "armor.leggings");
|
||||
+ add(6718535547217657911L, -5386630269401489641L, "enchantment.sweeping_edge");
|
||||
+ add(-7949229004988660584L, -7828611303000832459L, "effect.speed");
|
||||
+ add(-8650171790042118250L, -5749650997644763080L, "enchantment.soul_speed");
|
||||
+ add(551224288813600377L, -8734740027710371860L, "enchantment.respiration");
|
||||
+ add(-7046399332347654691L, -6723081531683397260L, "suffocating");
|
||||
+ add(7361814797886573596L, -8641397326606817395L, "sprinting");
|
||||
+ add(-6972338111383059132L, -8978659762232839026L, "armor.chestplate");
|
||||
+ add(-5371971015925809039L, -6062243582569928137L, "enchantment.fire_protection");
|
||||
+ add(7245570952092733273L, -8449101711440750679L, "effect.strength");
|
||||
+ add(-422425648963762075L, -5756800103171642205L, "base_attack_speed");
|
||||
+ add(-4607081316629330256L, -7008565754814018370L, "effect.jump_boost");
|
||||
+ add(271280981090454338L, -8746077033958322898L, "effect.luck");
|
||||
+ add(2211131075215181206L, -5513857709499300658L, "powder_snow");
|
||||
+ add(-8908768238899017377L, -8313820693701227669L, "armor.boots");
|
||||
+ add(-5797418877589107702L, -6181652684028920077L, "effect.haste");
|
||||
+ add(3086076556416732775L, -5150312587563650736L, "armor.helmet");
|
||||
+ add(-5082757096938257406L, -4891139119377885130L, "baby");
|
||||
+ add(2478452629826324956L, -7247530463494186011L, "effect.weakness");
|
||||
+ add(4659420831966187055L, -5191473055587376048L, "enchantment.blast_protection");
|
||||
+ add(7301951777949303281L, -6753860660653972126L, "evil");
|
||||
+ add(8533189226688352746L, -8254757081029716377L, "baby");
|
||||
+ add(1286946037536540352L, -5768092872487507967L, "enchantment.depth_strider");
|
||||
+ add(-3801225194067177672L, -6586624321849018929L, "base_attack_damage");
|
||||
+ }
|
||||
+
|
||||
+ public static @NotNull NamespacedKey uuidToKey(final UUID uuid) {
|
||||
+ final NamespacedKey key = ATTRIBUTE_MODIFIER_IDS.get(uuid);
|
||||
+ if (key != null) {
|
||||
+ return key;
|
||||
+ } else {
|
||||
+ return NamespacedKey.minecraft(uuid.toString());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void add(final long msb, final long lsb, final String id) {
|
||||
+ final UUID uuid = new UUID(msb, lsb);
|
||||
+ ATTRIBUTE_MODIFIER_IDS.put(uuid, NamespacedKey.minecraft(id));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
@@ -0,0 +0,0 @@ public class CraftAttributeInstance implements AttributeInstance {
|
||||
return result;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public AttributeModifier getModifier(final net.kyori.adventure.key.Key key) {
|
||||
+ Preconditions.checkArgument(key != null, "Key cannot be null");
|
||||
+ net.minecraft.world.entity.ai.attributes.AttributeModifier modifier = this.handle.getModifier(io.papermc.paper.adventure.PaperAdventure.asVanilla(key));
|
||||
+ return modifier == null ? null : CraftAttributeInstance.convert(modifier);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeModifier(final net.kyori.adventure.key.Key key) {
|
||||
+ Preconditions.checkArgument(key != null, "Key cannot be null");
|
||||
+ this.handle.removeModifier(io.papermc.paper.adventure.PaperAdventure.asVanilla(key));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public AttributeModifier getModifier(java.util.UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ return this.getModifier(AttributeMappings.uuidToKey(uuid));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeModifier(java.util.UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ this.removeModifier(AttributeMappings.uuidToKey(uuid));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addModifier(AttributeModifier modifier) {
|
||||
Preconditions.checkArgument(modifier != null, "modifier");
|
||||
242
patches/server/Add-Velocity-IP-Forwarding-Support.patch
Normal file
242
patches/server/Add-Velocity-IP-Forwarding-Support.patch
Normal file
@@ -0,0 +1,242 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Steinborn <git@steinborn.me>
|
||||
Date: Mon, 8 Oct 2018 14:36:14 -0400
|
||||
Subject: [PATCH] Add Velocity IP Forwarding Support
|
||||
|
||||
While Velocity supports BungeeCord-style IP forwarding, it is not secure. Users
|
||||
have a lot of problems setting up firewalls or setting up plugins like IPWhitelist.
|
||||
Further, the BungeeCord IP forwarding protocol still retains essentially its original
|
||||
form, when there is brand new support for custom login plugin messages in 1.13.
|
||||
|
||||
Velocity's modern IP forwarding uses an HMAC-SHA256 code to ensure authenticity
|
||||
of messages, is packed into a binary format that is smaller than BungeeCord's
|
||||
forwarding, and is integrated into the Minecraft login process by using the 1.13
|
||||
login plugin message packet.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/proxy/VelocityProxy.java b/src/main/java/com/destroystokyo/paper/proxy/VelocityProxy.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/proxy/VelocityProxy.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.proxy;
|
||||
+
|
||||
+import io.papermc.paper.configuration.GlobalConfiguration;
|
||||
+import com.google.common.net.InetAddresses;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
+import com.mojang.authlib.properties.Property;
|
||||
+import java.net.InetAddress;
|
||||
+import java.security.InvalidKeyException;
|
||||
+import java.security.MessageDigest;
|
||||
+import java.security.NoSuchAlgorithmException;
|
||||
+import java.util.UUID;
|
||||
+import javax.crypto.Mac;
|
||||
+import javax.crypto.spec.SecretKeySpec;
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.login.custom.CustomQueryPayload;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.world.entity.player.ProfilePublicKey;
|
||||
+
|
||||
+/**
|
||||
+ * While Velocity supports BungeeCord-style IP forwarding, it is not secure. Users
|
||||
+ * have a lot of problems setting up firewalls or setting up plugins like IPWhitelist.
|
||||
+ * Further, the BungeeCord IP forwarding protocol still retains essentially its original
|
||||
+ * form, when there is brand-new support for custom login plugin messages in 1.13.
|
||||
+ * <p>
|
||||
+ * Velocity's modern IP forwarding uses an HMAC-SHA256 code to ensure authenticity
|
||||
+ * of messages, is packed into a binary format that is smaller than BungeeCord's
|
||||
+ * forwarding, and is integrated into the Minecraft login process by using the 1.13
|
||||
+ * login plugin message packet.
|
||||
+ */
|
||||
+public class VelocityProxy {
|
||||
+ private static final int SUPPORTED_FORWARDING_VERSION = 1;
|
||||
+ public static final int MODERN_FORWARDING_WITH_KEY = 2;
|
||||
+ public static final int MODERN_FORWARDING_WITH_KEY_V2 = 3;
|
||||
+ public static final int MODERN_LAZY_SESSION = 4;
|
||||
+ public static final byte MAX_SUPPORTED_FORWARDING_VERSION = MODERN_LAZY_SESSION;
|
||||
+ public static final ResourceLocation PLAYER_INFO_CHANNEL = ResourceLocation.fromNamespaceAndPath("velocity", "player_info");
|
||||
+
|
||||
+ public static boolean checkIntegrity(final FriendlyByteBuf buf) {
|
||||
+ final byte[] signature = new byte[32];
|
||||
+ buf.readBytes(signature);
|
||||
+
|
||||
+ final byte[] data = new byte[buf.readableBytes()];
|
||||
+ buf.getBytes(buf.readerIndex(), data);
|
||||
+
|
||||
+ try {
|
||||
+ final Mac mac = Mac.getInstance("HmacSHA256");
|
||||
+ mac.init(new SecretKeySpec(GlobalConfiguration.get().proxies.velocity.secret.getBytes(java.nio.charset.StandardCharsets.UTF_8), "HmacSHA256"));
|
||||
+ final byte[] mySignature = mac.doFinal(data);
|
||||
+ if (!MessageDigest.isEqual(signature, mySignature)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ } catch (final InvalidKeyException | NoSuchAlgorithmException e) {
|
||||
+ throw new AssertionError(e);
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public static InetAddress readAddress(final FriendlyByteBuf buf) {
|
||||
+ return InetAddresses.forString(buf.readUtf(Short.MAX_VALUE));
|
||||
+ }
|
||||
+
|
||||
+ public static GameProfile createProfile(final FriendlyByteBuf buf) {
|
||||
+ final GameProfile profile = new GameProfile(buf.readUUID(), buf.readUtf(16));
|
||||
+ readProperties(buf, profile);
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ private static void readProperties(final FriendlyByteBuf buf, final GameProfile profile) {
|
||||
+ final int properties = buf.readVarInt();
|
||||
+ for (int i1 = 0; i1 < properties; i1++) {
|
||||
+ final String name = buf.readUtf(Short.MAX_VALUE);
|
||||
+ final String value = buf.readUtf(Short.MAX_VALUE);
|
||||
+ final String signature = buf.readBoolean() ? buf.readUtf(Short.MAX_VALUE) : null;
|
||||
+ profile.getProperties().put(name, new Property(name, value, signature));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static ProfilePublicKey.Data readForwardedKey(FriendlyByteBuf buf) {
|
||||
+ return new ProfilePublicKey.Data(buf);
|
||||
+ }
|
||||
+
|
||||
+ public static UUID readSignerUuidOrElse(FriendlyByteBuf buf, UUID orElse) {
|
||||
+ return buf.readBoolean() ? buf.readUUID() : orElse;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
+ boolean usingProxy = org.spigotmc.SpigotConfig.bungee || io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled;
|
||||
+ String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
|
||||
+ String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";
|
||||
+ // Paper end - Add Velocity IP Forwarding Support
|
||||
if (!this.usesAuthentication()) {
|
||||
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
|
||||
DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
|
||||
// Spigot start
|
||||
- if (org.spigotmc.SpigotConfig.bungee) {
|
||||
- DedicatedServer.LOGGER.warn("Whilst this makes it possible to use BungeeCord, unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose.");
|
||||
- DedicatedServer.LOGGER.warn("Please see http://www.spigotmc.org/wiki/firewall-guide/ for further information.");
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
+ if (usingProxy) {
|
||||
+ DedicatedServer.LOGGER.warn("Whilst this makes it possible to use " + proxyFlavor + ", unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose.");
|
||||
+ DedicatedServer.LOGGER.warn("Please see " + proxyLink + " for further information.");
|
||||
+ // Paper end - Add Velocity IP Forwarding Support
|
||||
} else {
|
||||
DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose.");
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
private final boolean transferred;
|
||||
private ServerPlayer player; // CraftBukkit
|
||||
public boolean iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation = false; // Paper - username validation overriding
|
||||
+ private int velocityLoginMessageId = -1; // Paper - Add Velocity IP Forwarding Support
|
||||
|
||||
public ServerLoginPacketListenerImpl(MinecraftServer server, Connection connection, boolean transferred) {
|
||||
this.state = ServerLoginPacketListenerImpl.State.HELLO;
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
this.state = ServerLoginPacketListenerImpl.State.KEY;
|
||||
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge, true));
|
||||
} else {
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) {
|
||||
+ this.velocityLoginMessageId = java.util.concurrent.ThreadLocalRandom.current().nextInt();
|
||||
+ net.minecraft.network.FriendlyByteBuf buf = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.buffer());
|
||||
+ buf.writeByte(com.destroystokyo.paper.proxy.VelocityProxy.MAX_SUPPORTED_FORWARDING_VERSION);
|
||||
+ net.minecraft.network.protocol.login.ClientboundCustomQueryPacket packet1 = new net.minecraft.network.protocol.login.ClientboundCustomQueryPacket(this.velocityLoginMessageId, new net.minecraft.network.protocol.login.ClientboundCustomQueryPacket.PlayerInfoChannelPayload(com.destroystokyo.paper.proxy.VelocityProxy.PLAYER_INFO_CHANNEL, buf));
|
||||
+ this.connection.send(packet1);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Add Velocity IP Forwarding Support
|
||||
// CraftBukkit start
|
||||
// Paper start - Cache authenticator threads
|
||||
authenticatorPool.execute(new Runnable() {
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
// CraftBukkit start
|
||||
private GameProfile callPlayerPreLoginEvents(GameProfile gameprofile) throws Exception { // Paper - Add more fields to AsyncPlayerPreLoginEvent
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
+ if (ServerLoginPacketListenerImpl.this.velocityLoginMessageId == -1 && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) {
|
||||
+ disconnect("This server requires you to connect with Velocity.");
|
||||
+ return gameprofile;
|
||||
+ }
|
||||
+ // Paper end - Add Velocity IP Forwarding Support
|
||||
String playerName = gameprofile.getName();
|
||||
java.net.InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
|
||||
java.util.UUID uniqueId = gameprofile.getId();
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
@Override
|
||||
public void handleCustomQueryPacket(ServerboundCustomQueryAnswerPacket packet) {
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled && packet.transactionId() == this.velocityLoginMessageId) {
|
||||
+ ServerboundCustomQueryAnswerPacket.QueryAnswerPayload payload = (ServerboundCustomQueryAnswerPacket.QueryAnswerPayload)packet.payload();
|
||||
+ if (payload == null) {
|
||||
+ this.disconnect("This server requires you to connect with Velocity.");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.network.FriendlyByteBuf buf = payload.buffer;
|
||||
+
|
||||
+ if (!com.destroystokyo.paper.proxy.VelocityProxy.checkIntegrity(buf)) {
|
||||
+ this.disconnect("Unable to verify player details");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ int version = buf.readVarInt();
|
||||
+ if (version > com.destroystokyo.paper.proxy.VelocityProxy.MAX_SUPPORTED_FORWARDING_VERSION) {
|
||||
+ throw new IllegalStateException("Unsupported forwarding version " + version + ", wanted upto " + com.destroystokyo.paper.proxy.VelocityProxy.MAX_SUPPORTED_FORWARDING_VERSION);
|
||||
+ }
|
||||
+
|
||||
+ java.net.SocketAddress listening = this.connection.getRemoteAddress();
|
||||
+ int port = 0;
|
||||
+ if (listening instanceof java.net.InetSocketAddress) {
|
||||
+ port = ((java.net.InetSocketAddress) listening).getPort();
|
||||
+ }
|
||||
+ this.connection.address = new java.net.InetSocketAddress(com.destroystokyo.paper.proxy.VelocityProxy.readAddress(buf), port);
|
||||
+
|
||||
+ this.authenticatedProfile = com.destroystokyo.paper.proxy.VelocityProxy.createProfile(buf);
|
||||
+
|
||||
+ //TODO Update handling for lazy sessions, might not even have to do anything?
|
||||
+
|
||||
+ // Proceed with login
|
||||
+ authenticatorPool.execute(() -> {
|
||||
+ try {
|
||||
+ final GameProfile gameprofile = this.callPlayerPreLoginEvents(this.authenticatedProfile);
|
||||
+ ServerLoginPacketListenerImpl.LOGGER.info("UUID of player {} is {}", gameprofile.getName(), gameprofile.getId());
|
||||
+ ServerLoginPacketListenerImpl.this.startClientVerification(gameprofile);
|
||||
+ } catch (Exception ex) {
|
||||
+ disconnect("Failed to verify username!");
|
||||
+ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + this.authenticatedProfile.getName(), ex);
|
||||
+ }
|
||||
+ });
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Add Velocity IP Forwarding Support
|
||||
this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
@Override
|
||||
public long getConnectionThrottle() {
|
||||
// Spigot Start - Automatically set connection throttle for bungee configurations
|
||||
- if (org.spigotmc.SpigotConfig.bungee) {
|
||||
+ if (org.spigotmc.SpigotConfig.bungee || io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) { // Paper - Add Velocity IP Forwarding Support
|
||||
return -1;
|
||||
} else {
|
||||
return this.configuration.getInt("settings.connection-throttle");
|
||||
39
patches/server/Add-WardenAngerChangeEvent.patch
Normal file
39
patches/server/Add-WardenAngerChangeEvent.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: nopjar <code.nopjar@gmail.com>
|
||||
Date: Sun, 12 Jun 2022 02:26:04 +0200
|
||||
Subject: [PATCH] Add WardenAngerChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java
|
||||
@@ -0,0 +0,0 @@ public class AngerManagement {
|
||||
|
||||
public int increaseAnger(Entity entity, int amount) {
|
||||
boolean bl = !this.angerBySuspect.containsKey(entity);
|
||||
- int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount));
|
||||
+ int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount)); // Paper - diff on change (Warden#increaseAngerAt WardenAngerChangeEvent)
|
||||
if (bl) {
|
||||
int j = this.angerByUuid.removeInt(entity.getUUID());
|
||||
i += j;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
|
||||
@@ -0,0 +0,0 @@ public class Warden extends Monster implements VibrationSystem {
|
||||
@VisibleForTesting
|
||||
public void increaseAngerAt(@Nullable Entity entity, int amount, boolean listening) {
|
||||
if (!this.isNoAi() && this.canTargetEntity(entity)) {
|
||||
+ // Paper start - Add WardenAngerChangeEvent
|
||||
+ int activeAnger = this.angerManagement.getActiveAnger(entity);
|
||||
+ io.papermc.paper.event.entity.WardenAngerChangeEvent event = new io.papermc.paper.event.entity.WardenAngerChangeEvent((org.bukkit.entity.Warden) this.getBukkitEntity(), entity.getBukkitEntity(), activeAnger, Math.min(150, activeAnger + amount));
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ amount = event.getNewAnger() - activeAnger;
|
||||
+ // Paper end - Add WardenAngerChangeEvent
|
||||
WardenAi.setDigCooldown(this);
|
||||
boolean flag1 = !(this.getTarget() instanceof Player);
|
||||
int j = this.angerManagement.increaseAnger(entity, amount);
|
||||
71
patches/server/Add-and-fix-missing-BlockFadeEvents.patch
Normal file
71
patches/server/Add-and-fix-missing-BlockFadeEvents.patch
Normal file
@@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Thu, 21 Jul 2022 12:07:54 -0400
|
||||
Subject: [PATCH] Add and fix missing BlockFadeEvents
|
||||
|
||||
Beyond calling the BlockFadeEvent in more places, this patch also aims
|
||||
to pass the proper replacement state to the event, specifically for
|
||||
potentially waterlogged block states fading.
|
||||
|
||||
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
|
||||
@@ -0,0 +0,0 @@ public class FrogspawnBlock extends Block {
|
||||
}
|
||||
|
||||
private void hatchFrogspawn(ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ // Paper start - Call BlockFadeEvent
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockFadeEvent
|
||||
this.destroyBlock(world, pos);
|
||||
world.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
this.spawnTadpoles(world, pos, random);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java
|
||||
@@ -0,0 +0,0 @@ public class ScaffoldingBlock extends Block implements SimpleWaterloggedBlock {
|
||||
int i = ScaffoldingBlock.getDistance(world, pos);
|
||||
BlockState iblockdata1 = (BlockState) ((BlockState) state.setValue(ScaffoldingBlock.DISTANCE, i)).setValue(ScaffoldingBlock.BOTTOM, this.isBottom(world, pos, i));
|
||||
|
||||
- if ((Integer) iblockdata1.getValue(ScaffoldingBlock.DISTANCE) == 7 && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { // CraftBukkit - BlockFadeEvent
|
||||
+ if ((Integer) iblockdata1.getValue(ScaffoldingBlock.DISTANCE) == 7 && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, iblockdata1.getFluidState().createLegacyBlock()).isCancelled()) { // CraftBukkit - BlockFadeEvent // Paper - fix wrong block state
|
||||
if ((Integer) state.getValue(ScaffoldingBlock.DISTANCE) == 7) {
|
||||
FallingBlockEntity.fall(world, pos, iblockdata1);
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
@@ -0,0 +0,0 @@ public class SnifferEggBlock extends Block {
|
||||
return this.getHatchLevel(state) == 2;
|
||||
}
|
||||
|
||||
+ // Paper start - Call BlockFadeEvent
|
||||
+ private void rescheduleTick(ServerLevel world, BlockPos pos) {
|
||||
+ int baseDelay = hatchBoost(world, pos) ? BOOSTED_HATCH_TIME_TICKS : REGULAR_HATCH_TIME_TICKS;
|
||||
+ world.scheduleTick(pos, this, (baseDelay / 3) + world.random.nextInt(RANDOM_HATCH_OFFSET_TICKS));
|
||||
+ // reschedule to avoid being stuck here and behave like the other calls (see #onPlace)
|
||||
+ }
|
||||
+ // Paper end - Call BlockFadeEvent
|
||||
+
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
if (!this.isReadyToHatch(state)) {
|
||||
world.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
|
||||
world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2);
|
||||
} else {
|
||||
+ // Paper start - Call BlockFadeEvent
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, state.getFluidState().createLegacyBlock()).isCancelled()) {
|
||||
+ this.rescheduleTick(world, pos);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Call BlockFadeEvent
|
||||
world.playSound(null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
|
||||
world.destroyBlock(pos, false);
|
||||
Sniffer sniffer = EntityType.SNIFFER.create(world, EntitySpawnReason.BREEDING);
|
||||
26
patches/server/Add-api-for-spawn-egg-texture-colors.patch
Normal file
26
patches/server/Add-api-for-spawn-egg-texture-colors.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Luis <luisc99@icloud.com>
|
||||
Date: Thu, 11 Jan 2024 19:58:23 +0100
|
||||
Subject: [PATCH] Add api for spawn egg texture colors
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - spawn egg color visibility
|
||||
+ @Override
|
||||
+ public org.bukkit.Color getSpawnEggLayerColor(final EntityType entityType, final int layer) {
|
||||
+ final net.minecraft.world.entity.EntityType<?> nmsType = org.bukkit.craftbukkit.entity.CraftEntityType.bukkitToMinecraft(entityType);
|
||||
+ final net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType);
|
||||
+ return eggItem == null ? null : org.bukkit.Color.fromRGB(eggItem.getColor(layer));
|
||||
+ }
|
||||
+ // Paper end - spawn egg color visibility
|
||||
+
|
||||
/**
|
||||
* This helper class represents the different NBT Tags.
|
||||
* <p>
|
||||
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 2 Dec 2020 21:03:02 -0800
|
||||
Subject: [PATCH] Add config for mobs immune to default effects
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -0,0 +0,0 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
|
||||
@Override
|
||||
public boolean canBeAffected(MobEffectInstance effect) {
|
||||
- return effect.is(MobEffects.WITHER) ? false : super.canBeAffected(effect);
|
||||
+ return effect.is(MobEffects.WITHER) && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.wither ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
|
||||
}
|
||||
|
||||
private class WitherDoNothingGoal extends Goal {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -0,0 +0,0 @@ public class Spider extends Monster {
|
||||
|
||||
@Override
|
||||
public boolean canBeAffected(MobEffectInstance effect) {
|
||||
- return effect.is(MobEffects.POISON) ? false : super.canBeAffected(effect);
|
||||
+ return effect.is(MobEffects.POISON) && this.level().paperConfig().entities.mobEffects.spidersImmuneToPoisonEffect ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
|
||||
}
|
||||
|
||||
public boolean isClimbing() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
@@ -0,0 +0,0 @@ public class WitherSkeleton extends AbstractSkeleton {
|
||||
|
||||
@Override
|
||||
public boolean canBeAffected(MobEffectInstance effect) {
|
||||
- return effect.is(MobEffects.WITHER) ? false : super.canBeAffected(effect);
|
||||
+ return effect.is(MobEffects.WITHER) && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.witherSkeleton ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 27 Oct 2022 15:35:47 +0200
|
||||
Subject: [PATCH] Add config option for spider worldborder climbing
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -0,0 +0,0 @@ public class Spider extends Monster {
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!this.level().isClientSide) {
|
||||
- this.setClimbing(this.horizontalCollision);
|
||||
+ this.setClimbing(this.horizontalCollision && (this.level().paperConfig().entities.behavior.allowSpiderWorldBorderClimbing || !(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(this.level().getWorldBorder(), this.getBoundingBox().inflate(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) && this.level().getWorldBorder().isInsideCloseToBorder(this, this.getBoundingBox())))); // Paper - Add config option for spider worldborder climbing (Inflate by +EPSILON as collision will just barely place us outside border)
|
||||
}
|
||||
|
||||
}
|
||||
403
patches/server/Add-drops-to-shear-events.patch
Normal file
403
patches/server/Add-drops-to-shear-events.patch
Normal file
@@ -0,0 +1,403 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 18 May 2021 12:32:02 -0700
|
||||
Subject: [PATCH] Add drops to shear events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
|
||||
@@ -0,0 +0,0 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
|
||||
if (entityliving instanceof Shearable ishearable) {
|
||||
if (ishearable.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) {
|
||||
+ // Paper start - Add drops to shear events
|
||||
+ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops(worldserver, itemstack));
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Paper end - Add drops to shear events
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
- ishearable.shear(worldserver, SoundSource.BLOCKS, itemstack);
|
||||
+ ishearable.shear(worldserver, SoundSource.BLOCKS, itemstack, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events
|
||||
worldserver.gameEvent((Entity) null, (Holder) GameEvent.SHEAR, blockposition);
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Shearable.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public interface Shearable {
|
||||
+ default void shear(ServerLevel world, SoundSource soundCategory, ItemStack shears, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(world, soundCategory, shears); } // Paper - Add drops to shear events
|
||||
void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears);
|
||||
|
||||
boolean readyForShearing();
|
||||
net.minecraft.world.level.Level level(); // Shearable API - expose default level needed for shearing.
|
||||
+
|
||||
+ // Paper start - custom shear drops; ensure all implementing entities override this
|
||||
+ default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
|
||||
+ return java.util.Collections.emptyList();
|
||||
+ }
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
||||
// CraftBukkit start
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.event.entity.EntityDropItemEvent;
|
||||
import org.bukkit.event.entity.EntityTransformEvent;
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.shear(worldserver, SoundSource.PLAYERS, itemstack);
|
||||
+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
|
||||
|
||||
@Override
|
||||
public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
|
||||
+ final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (ignored, stack) -> {
|
||||
+ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1));
|
||||
+ });
|
||||
+ return drops;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
|
||||
+ // Paper end - custom shear drops
|
||||
world.playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), (entitycow) -> {
|
||||
world.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D);
|
||||
- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (worldserver1, itemstack1) -> {
|
||||
- for (int i = 0; i < itemstack1.getCount(); ++i) {
|
||||
- // CraftBukkit start
|
||||
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), itemstack1.copyWithCount(1));
|
||||
- EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
|
||||
- Bukkit.getPluginManager().callEvent(event);
|
||||
- if (event.isCancelled()) {
|
||||
- continue;
|
||||
- }
|
||||
- worldserver1.addFreshEntity(entityitem);
|
||||
- // CraftBukkit end
|
||||
- }
|
||||
-
|
||||
+ // Paper start - custom shear drops; moved drop generation to separate method
|
||||
+ drops.forEach(drop -> {
|
||||
+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
|
||||
+ this.spawnAtLocation(world, entityitem);
|
||||
+ // Paper end - custom shear drops; moved drop generation to separate method
|
||||
});
|
||||
}, EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
|
||||
@@ -0,0 +0,0 @@ public class Sheep extends Animal implements Shearable {
|
||||
|
||||
if (this.readyForShearing()) {
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.shear(worldserver, SoundSource.PLAYERS, itemstack);
|
||||
+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
@@ -0,0 +0,0 @@ public class Sheep extends Animal implements Shearable {
|
||||
|
||||
@Override
|
||||
public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
|
||||
+ final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SHEEP, shears, (ignored, stack) -> {
|
||||
+ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1));
|
||||
+ });
|
||||
+ return drops;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
|
||||
+ final ServerLevel worldserver1 = world; // Named for lambda consumption
|
||||
+ // Paper end - custom shear drops
|
||||
world.playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SHEEP, shears, (worldserver1, itemstack1) -> {
|
||||
- for (int i = 0; i < itemstack1.getCount(); ++i) {
|
||||
+ drops.forEach(itemstack1 -> { // Paper - custom drops - loop in generated default drops
|
||||
+ if (true) { // Paper - custom drops - loop in generated default drops
|
||||
this.forceDrops = true; // CraftBukkit
|
||||
- ItemEntity entityitem = this.spawnAtLocation(worldserver1, itemstack1.copyWithCount(1), 1.0F);
|
||||
+ ItemEntity entityitem = this.spawnAtLocation(worldserver1, itemstack1, 1.0F); // Paper - custom drops - copy already done above
|
||||
this.forceDrops = false; // CraftBukkit
|
||||
|
||||
if (entityitem != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
|
||||
@@ -0,0 +0,0 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.shear(worldserver, SoundSource.PLAYERS, itemstack);
|
||||
+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
||||
|
||||
@Override
|
||||
public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
|
||||
+ final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (ignored, stack) -> {
|
||||
+ drops.add(stack);
|
||||
+ });
|
||||
+ return drops;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
|
||||
+ final ServerLevel worldserver1 = world; // Named for lambda consumption
|
||||
+ // Paper end - custom shear drops
|
||||
world.playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
this.setPumpkin(false);
|
||||
- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (worldserver1, itemstack1) -> {
|
||||
+ drops.forEach(itemstack1 -> { // Paper - custom shear drops
|
||||
this.forceDrops = true; // CraftBukkit
|
||||
this.spawnAtLocation(worldserver1, itemstack1, this.getEyeHeight());
|
||||
this.forceDrops = false; // CraftBukkit
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
|
||||
public class Bogged extends AbstractSkeleton implements Shearable {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
|
||||
- this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients
|
||||
- return InteractionResult.PASS;
|
||||
+ // Paper start - custom shear drops
|
||||
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
|
||||
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
|
||||
+ if (event != null) {
|
||||
+ if (event.isCancelled()) {
|
||||
+ // this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients // Paper - no longer needed
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
||||
+ // Paper end - custom shear drops
|
||||
}
|
||||
// CraftBukkit end
|
||||
- this.shear(worldserver, SoundSource.PLAYERS, itemstack);
|
||||
+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
|
||||
this.gameEvent(GameEvent.SHEAR, player);
|
||||
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
||||
|
||||
@Override
|
||||
public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
|
||||
+ final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
||||
+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.BOGGED_SHEAR, shears, (ignored, stack) -> {
|
||||
+ drops.add(stack);
|
||||
+ });
|
||||
+ return drops;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
|
||||
+ // Paper end - custom shear drops
|
||||
world.playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
|
||||
- this.spawnShearedMushrooms(world, shears);
|
||||
+ this.spawnShearedMushrooms(world, shears, drops); // Paper - custom shear drops
|
||||
this.setSheared(true);
|
||||
}
|
||||
|
||||
- private void spawnShearedMushrooms(ServerLevel world, ItemStack shears) {
|
||||
+ // Paper start - custom shear drops
|
||||
+ private void spawnShearedMushrooms(ServerLevel world, ItemStack shears, java.util.List<ItemStack> drops) {
|
||||
+ final ServerLevel worldserver1 = world; // Named for lambda consumption
|
||||
this.forceDrops = true; // Paper - Add missing forceDrop toggles
|
||||
- this.dropFromShearingLootTable(world, BuiltInLootTables.BOGGED_SHEAR, shears, (worldserver1, itemstack1) -> {
|
||||
+ drops.forEach(itemstack1 -> {
|
||||
+ // Paper end - custom shear drops
|
||||
this.spawnAtLocation(worldserver1, itemstack1, this.getBbHeight());
|
||||
});
|
||||
this.forceDrops = false; // Paper - Add missing forceDrop toggles
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
player.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
|
||||
- public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is) {
|
||||
- BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is);
|
||||
+ public static BlockShearEntityEvent callBlockShearEntityEvent(Entity animal, org.bukkit.block.Block dispenser, CraftItemStack is, List<ItemStack> drops) { // Paper - custom shear drops
|
||||
+ BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, animal.getBukkitEntity(), is, Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops
|
||||
Bukkit.getPluginManager().callEvent(bse);
|
||||
return bse;
|
||||
}
|
||||
|
||||
- public static boolean handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand) {
|
||||
+ public static PlayerShearEntityEvent handlePlayerShearEntityEvent(net.minecraft.world.entity.player.Player player, Entity sheared, ItemStack shears, InteractionHand hand, List<ItemStack> drops) { // Paper - custom shear drops
|
||||
if (!(player instanceof ServerPlayer)) {
|
||||
- return true;
|
||||
+ return null; // Paper - custom shear drops
|
||||
}
|
||||
|
||||
- PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
|
||||
+ PlayerShearEntityEvent event = new PlayerShearEntityEvent((Player) player.getBukkitEntity(), sheared.getBukkitEntity(), CraftItemStack.asCraftMirror(shears), (hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND), Lists.transform(drops, CraftItemStack::asCraftMirror)); // Paper - custom shear drops
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
- return !event.isCancelled();
|
||||
+ return event; // Paper - custom shear drops
|
||||
}
|
||||
|
||||
public static Cancellable handleStatisticsIncrease(net.minecraft.world.entity.player.Player entityHuman, net.minecraft.stats.Stat<?> statistic, int current, int newValue) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
return stack;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static java.util.List<net.minecraft.world.item.ItemStack> asNMSCopy(java.util.List<? extends ItemStack> originals) {
|
||||
+ final java.util.List<net.minecraft.world.item.ItemStack> items = new java.util.ArrayList<>(originals.size());
|
||||
+ for (final ItemStack original : originals) {
|
||||
+ items.add(asNMSCopy(original));
|
||||
+ }
|
||||
+ return items;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static net.minecraft.world.item.ItemStack copyNMSStack(net.minecraft.world.item.ItemStack original, int amount) {
|
||||
net.minecraft.world.item.ItemStack stack = original.copy();
|
||||
stack.setCount(amount);
|
||||
diff --git a/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/entity/ShearableDropsTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.entity;
|
||||
+
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ClassInfo;
|
||||
+import io.github.classgraph.MethodInfoList;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import java.util.ArrayList;
|
||||
+import net.minecraft.world.entity.Shearable;
|
||||
+import org.bukkit.support.environment.Normal;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+
|
||||
+@Normal
|
||||
+class ShearableDropsTest {
|
||||
+
|
||||
+ static Iterable<ClassInfo> parameters() {
|
||||
+ try (ScanResult scanResult = new ClassGraph()
|
||||
+ .enableClassInfo()
|
||||
+ .enableMethodInfo()
|
||||
+ .whitelistPackages("net.minecraft")
|
||||
+ .scan()
|
||||
+ ) {
|
||||
+ return new ArrayList<>(scanResult.getClassesImplementing(Shearable.class.getName()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest
|
||||
+ @MethodSource("parameters")
|
||||
+ void checkShearableDropOverrides(final ClassInfo classInfo) {
|
||||
+ final MethodInfoList generateDefaultDrops = classInfo.getDeclaredMethodInfo("generateDefaultDrops");
|
||||
+ assertEquals(1, generateDefaultDrops.size(), classInfo.getName() + " doesn't implement Shearable#generateDefaultDrops");
|
||||
+ }
|
||||
+}
|
||||
23
patches/server/Add-entity-knockback-API.patch
Normal file
23
patches/server/Add-entity-knockback-API.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MelnCat <melncatuwu@gmail.com>
|
||||
Date: Sun, 16 Oct 2022 12:10:17 -0700
|
||||
Subject: [PATCH] Add entity knockback API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
throw new UnsupportedOperationException("Cannot set the hurt direction on a non player");
|
||||
}
|
||||
// Paper end - hurt direction API
|
||||
+
|
||||
+ // Paper start - knockback API
|
||||
+ @Override
|
||||
+ public void knockback(final double strength, final double directionX, final double directionZ) {
|
||||
+ Preconditions.checkArgument(strength > 0, "Knockback strength must be > 0");
|
||||
+ this.getHandle().knockback(strength, directionX, directionZ);
|
||||
+ };
|
||||
+ // Paper end - knockback API
|
||||
}
|
||||
47
patches/server/Add-even-more-Enchantment-API.patch
Normal file
47
patches/server/Add-even-more-Enchantment-API.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 19 Jul 2024 08:42:45 -0700
|
||||
Subject: [PATCH] Add even more Enchantment API
|
||||
|
||||
In a separate patch because RegistryKeySet is used
|
||||
and the previous "more enchant api" patch is before that.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
|
||||
}
|
||||
// Paper end - more Enchantment API
|
||||
|
||||
+ // Paper start - even more Enchantment API
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.Component description() {
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.handle.value().description());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.registry.set.RegistryKeySet<org.bukkit.inventory.ItemType> getSupportedItems() {
|
||||
+ return io.papermc.paper.registry.set.PaperRegistrySets.convertToApi(io.papermc.paper.registry.RegistryKey.ITEM, this.handle.value().getSupportedItems());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.registry.set.RegistryKeySet<org.bukkit.inventory.ItemType> getPrimaryItems() {
|
||||
+ final java.util.Optional<net.minecraft.core.HolderSet<net.minecraft.world.item.Item>> primaryItems = this.handle.value().definition().primaryItems();
|
||||
+ return primaryItems.map(holders -> io.papermc.paper.registry.set.PaperRegistrySets.convertToApi(io.papermc.paper.registry.RegistryKey.ITEM, holders)).orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getWeight() {
|
||||
+ return this.handle.value().getWeight();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.registry.set.RegistryKeySet<org.bukkit.enchantments.Enchantment> getExclusiveWith() {
|
||||
+ return io.papermc.paper.registry.set.PaperRegistrySets.convertToApi(io.papermc.paper.registry.RegistryKey.ENCHANTMENT, this.handle.value().exclusiveSet());
|
||||
+ }
|
||||
+ // Paper end - even more Enchantment API
|
||||
+
|
||||
@Override
|
||||
public String getTranslationKey() {
|
||||
return Util.makeDescriptionId("enchantment", this.handle.unwrapKey().get().location());
|
||||
93
patches/server/Add-event-for-player-editing-sign.patch
Normal file
93
patches/server/Add-event-for-player-editing-sign.patch
Normal file
@@ -0,0 +1,93 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: by77er <by77er@gmail.com>
|
||||
Date: Mon, 12 Jun 2023 12:56:46 -0400
|
||||
Subject: [PATCH] Add event for player editing sign
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
try {
|
||||
if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) {
|
||||
if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) {
|
||||
- blocksign.openTextEdit(entityhuman, tileentitysign, true, org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE); // Craftbukkit
|
||||
+ blocksign.openTextEdit(entityhuman, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Craftbukkit // Paper - Add PlayerOpenSignEvent
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SignBlock.java b/src/main/java/net/minecraft/world/level/block/SignBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SignBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SignBlock.java
|
||||
@@ -0,0 +0,0 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo
|
||||
} else if (flag1) {
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
} else if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag)) {
|
||||
- this.openTextEdit(player, tileentitysign, flag, org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT); // CraftBukkit
|
||||
+ this.openTextEdit(player, tileentitysign, flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
} else {
|
||||
return InteractionResult.PASS;
|
||||
@@ -0,0 +0,0 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo
|
||||
return blockpropertywood;
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerOpenSignEvent
|
||||
public void openTextEdit(Player player, SignBlockEntity blockEntity, boolean front) {
|
||||
- // Craftbukkit start
|
||||
- this.openTextEdit(player, blockEntity, front, org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN);
|
||||
- }
|
||||
-
|
||||
- public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, org.bukkit.event.player.PlayerSignOpenEvent.Cause cause) {
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, cause)) {
|
||||
+ // Paper start - Add PlayerOpenSignEvent
|
||||
+ this.openTextEdit(player, blockEntity, front, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN);
|
||||
+ }
|
||||
+ public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) {
|
||||
+ org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) entityhuman.getBukkitEntity();
|
||||
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(tileentitysign.getLevel(), tileentitysign.getBlockPos());
|
||||
+ org.bukkit.craftbukkit.block.CraftSign<?> bukkitSign = (org.bukkit.craftbukkit.block.CraftSign<?>) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(bukkitBlock);
|
||||
+ io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent(
|
||||
+ bukkitPlayer,
|
||||
+ bukkitSign,
|
||||
+ flag ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK,
|
||||
+ cause);
|
||||
+ if (!event.callEvent()) return;
|
||||
+ if (org.bukkit.event.player.PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ final org.bukkit.event.player.PlayerSignOpenEvent.Cause legacyCause = switch (cause) {
|
||||
+ case PLACE -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE;
|
||||
+ case PLUGIN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLUGIN;
|
||||
+ case INTERACT -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT;
|
||||
+ case UNKNOWN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN;
|
||||
+ };
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, legacyCause)) {
|
||||
+ // Paper end - Add PlayerOpenSignEvent
|
||||
return;
|
||||
}
|
||||
- // Craftbukkit end
|
||||
+ } // Paper - Add PlayerOpenSignEvent
|
||||
tileentitysign.setAllowedPlayerEditor(entityhuman.getUUID());
|
||||
entityhuman.openTextEdit(tileentitysign, flag);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSign<T extends SignBlockEntity> extends CraftBlockEntityState<
|
||||
Preconditions.checkArgument(sign.isPlaced(), "Sign must be placed");
|
||||
Preconditions.checkArgument(sign.getWorld() == player.getWorld(), "Sign must be in same world as Player");
|
||||
|
||||
+ // Paper start - Add PlayerOpenSignEvent
|
||||
+ io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent((Player) player, sign, side, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLUGIN);
|
||||
+ if (!event.callEvent()) return;
|
||||
+ if (PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ // Paper end - Add PlayerOpenSignEvent
|
||||
if (!CraftEventFactory.callPlayerSignOpenEvent(player, sign, side, PlayerSignOpenEvent.Cause.PLUGIN)) {
|
||||
return;
|
||||
}
|
||||
+ } // Paper - Add PlayerOpenSignEvent
|
||||
|
||||
SignBlockEntity handle = ((CraftSign<?>) sign).getTileEntity();
|
||||
handle.setAllowedPlayerEditor(player.getUniqueId());
|
||||
73
patches/server/Add-experience-points-API.patch
Normal file
73
patches/server/Add-experience-points-API.patch
Normal file
@@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Planz <lukas.planz@web.de>
|
||||
Date: Tue, 5 Sep 2023 20:34:20 +0200
|
||||
Subject: [PATCH] Add experience points API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
public int getXpNeededForNextLevel() {
|
||||
- return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
|
||||
+ return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); // Paper - diff on change; calculateTotalExperiencePoints
|
||||
}
|
||||
// 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) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
Preconditions.checkArgument(exp >= 0, "Total experience points must not be negative (%s)", exp);
|
||||
this.getHandle().totalExperience = exp;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int calculateTotalExperiencePoints() {
|
||||
+ return calculateTotalExperiencePoints(this.getLevel()) + Math.round(this.getExperiencePointsNeededForNextLevel() * getExp());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setExperienceLevelAndProgress(final int totalExperience) {
|
||||
+ Preconditions.checkArgument(totalExperience >= 0, "Total experience points must not be negative (%s)", totalExperience);
|
||||
+ int level = calculateLevelsForExperiencePoints(totalExperience);
|
||||
+ int remainingPoints = totalExperience - calculateTotalExperiencePoints(level);
|
||||
+
|
||||
+ this.getHandle().experienceLevel = level;
|
||||
+ this.getHandle().experienceProgress = (float) remainingPoints / this.getExperiencePointsNeededForNextLevel();
|
||||
+ this.getHandle().lastSentExp = -1;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getExperiencePointsNeededForNextLevel() {
|
||||
+ return this.getHandle().getXpNeededForNextLevel();
|
||||
+ }
|
||||
+
|
||||
+ // See https://minecraft.wiki/w/Experience#Leveling_up for reference
|
||||
+ private int calculateTotalExperiencePoints(int level) {
|
||||
+ if (level <= 16) {
|
||||
+ return (int) (Math.pow(level, 2) + 6 * level);
|
||||
+ } else if (level <= 31) {
|
||||
+ return (int) (2.5 * Math.pow(level, 2) - 40.5 * level + 360.0);
|
||||
+ } else {
|
||||
+ return (int) (4.5 * Math.pow(level, 2) - 162.5 * level + 2220.0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private int calculateLevelsForExperiencePoints(int points) {
|
||||
+ if (points <= 352) { // Level 0-16
|
||||
+ return (int) Math.floor(Math.sqrt(points + 9) - 3);
|
||||
+ } else if (points <= 1507) { // Level 17-31
|
||||
+ return (int) Math.floor(8.1 + Math.sqrt(0.4 * (points - (7839.0 / 40.0))));
|
||||
+ } else { // 32+
|
||||
+ return (int) Math.floor((325.0 / 18.0) + Math.sqrt((2.0 / 9.0) * (points - (54215.0 / 72.0))));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public void sendExperienceChange(float progress) {
|
||||
34
patches/server/Add-fire-tick-delay-option.patch
Normal file
34
patches/server/Add-fire-tick-delay-option.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: VytskaLT <VytskaLT@protonmail.com>
|
||||
Date: Wed, 22 Jun 2022 14:34:28 +0300
|
||||
Subject: [PATCH] Add fire-tick-delay option
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock {
|
||||
|
||||
@Override
|
||||
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
- world.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(world.random));
|
||||
+ world.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(world)); // Paper - Add fire-tick-delay option
|
||||
if (world.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) {
|
||||
if (!state.canSurvive(world, pos)) {
|
||||
this.fireExtinguished(world, pos); // CraftBukkit - invalid place location
|
||||
@@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock {
|
||||
protected void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, UseOnContext context) {
|
||||
super.onPlace(iblockdata, world, blockposition, iblockdata1, flag, context);
|
||||
// CraftBukkit end
|
||||
- world.scheduleTick(blockposition, (Block) this, FireBlock.getFireTickDelay(world.random));
|
||||
+ world.scheduleTick(blockposition, (Block) this, FireBlock.getFireTickDelay(world)); // Paper - Add fire-tick-delay option
|
||||
}
|
||||
|
||||
- private static int getFireTickDelay(RandomSource random) {
|
||||
- return 30 + random.nextInt(10);
|
||||
+ private static int getFireTickDelay(Level world) { // Paper - Add fire-tick-delay option
|
||||
+ return world.paperConfig().environment.fireTickDelay + world.random.nextInt(10); // Paper - Add fire-tick-delay option
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Sat, 10 Feb 2024 10:03:48 +0100
|
||||
Subject: [PATCH] Add getChunkSnapshot includeLightData parameter
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot getChunkSnapshot(boolean includeMaxBlockY, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
+ // Paper start - Add getChunkSnapshot includeLightData parameter
|
||||
+ return getChunkSnapshot(includeMaxBlockY, includeBiome, includeBiomeTempRain, true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ChunkSnapshot getChunkSnapshot(boolean includeMaxBlockY, boolean includeBiome, boolean includeBiomeTempRain, boolean includeLightData) {
|
||||
+ // Paper end - Add getChunkSnapshot includeLightData parameter
|
||||
ChunkAccess chunk = this.getHandle(ChunkStatus.FULL);
|
||||
|
||||
LevelChunkSection[] cs = chunk.getSections();
|
||||
PalettedContainer[] sectionBlockIDs = new PalettedContainer[cs.length];
|
||||
- byte[][] sectionSkyLights = new byte[cs.length][];
|
||||
- byte[][] sectionEmitLights = new byte[cs.length][];
|
||||
+ // Paper start - Add getChunkSnapshot includeLightData parameter
|
||||
+ byte[][] sectionSkyLights = includeLightData ? new byte[cs.length][] : null;
|
||||
+ byte[][] sectionEmitLights = includeLightData ? new byte[cs.length][] : null;
|
||||
+ // Paper end - Add getChunkSnapshot includeLightData parameter
|
||||
boolean[] sectionEmpty = new boolean[cs.length];
|
||||
PalettedContainerRO<Holder<net.minecraft.world.level.biome.Biome>>[] biome = (includeBiome || includeBiomeTempRain) ? new PalettedContainer[cs.length] : null;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
}
|
||||
// Paper end - Fix ChunkSnapshot#isSectionEmpty(int)
|
||||
|
||||
+ if (includeLightData) { // Paper - Add getChunkSnapshot includeLightData parameter
|
||||
LevelLightEngine lightengine = this.worldServer.getLightEngine();
|
||||
DataLayer skyLightArray = lightengine.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(this.x, chunk.getSectionYFromSectionIndex(i), this.z)); // SPIGOT-7498: Convert section index
|
||||
if (skyLightArray == null) {
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
sectionEmitLights[i] = new byte[2048];
|
||||
System.arraycopy(emitLightArray.getData(), 0, sectionEmitLights[i], 0, 2048);
|
||||
}
|
||||
+ } // Paper - Add getChunkSnapshot includeLightData parameter
|
||||
|
||||
if (biome != null) {
|
||||
biome[i] = ((PalettedContainer<Holder<net.minecraft.world.level.biome.Biome>>) cs[i].getBiomes()).copy(); // Paper - Perf: use copy instead of round tripping with codecs
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
|
||||
@@ -0,0 +0,0 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
|
||||
|
||||
@Override
|
||||
public final int getBlockSkyLight(int x, int y, int z) {
|
||||
+ Preconditions.checkState(this.skylight != null, "ChunkSnapshot created without light data. Please call getSnapshot with includeLightData=true"); // Paper - Add getChunkSnapshot includeLightData parameter
|
||||
this.validateChunkCoordinates(x, y, z);
|
||||
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
@@ -0,0 +0,0 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
|
||||
|
||||
@Override
|
||||
public final int getBlockEmittedLight(int x, int y, int z) {
|
||||
+ Preconditions.checkState(this.emitlight != null, "ChunkSnapshot created without light data. Please call getSnapshot with includeLightData=true"); // Paper - Add getChunkSnapshot includeLightData parameter
|
||||
this.validateChunkCoordinates(x, y, z);
|
||||
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
37
patches/server/Add-getDrops-to-BlockState.patch
Normal file
37
patches/server/Add-getDrops-to-BlockState.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MelnCat <melncatuwu@gmail.com>
|
||||
Date: Fri, 12 Aug 2022 23:24:37 -0700
|
||||
Subject: [PATCH] Add getDrops to BlockState
|
||||
|
||||
Originally added isPreferredTool to BlockData but
|
||||
upstream added that.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockState implements BlockState {
|
||||
public boolean isCollidable() {
|
||||
return this.data.getBlock().hasCollision;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Collection<org.bukkit.inventory.ItemStack> getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) {
|
||||
+ this.requirePlaced();
|
||||
+ net.minecraft.world.item.ItemStack nms = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item);
|
||||
+
|
||||
+ // Modelled off EntityHuman#hasBlock
|
||||
+ if (item == null || !data.requiresCorrectToolForDrops() || nms.isCorrectToolForDrops(data)) {
|
||||
+ return net.minecraft.world.level.block.Block.getDrops(
|
||||
+ data,
|
||||
+ world.getHandle(),
|
||||
+ position,
|
||||
+ world.getHandle().getBlockEntity(position), entity == null ? null :
|
||||
+ ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle(), nms
|
||||
+ ).stream().map(org.bukkit.craftbukkit.inventory.CraftItemStack::asBukkitCopy).toList();
|
||||
+ } else {
|
||||
+ return java.util.Collections.emptyList();
|
||||
+ }
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Mon, 3 Jul 2023 01:55:32 +0200
|
||||
Subject: [PATCH] Add hand to fish event for all player interactions
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -0,0 +0,0 @@ public class FishingHook extends Projectile {
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {}
|
||||
|
||||
+ // Paper start - Add hand parameter to PlayerFishEvent
|
||||
+ @Deprecated
|
||||
+ @io.papermc.paper.annotation.DoNotUse
|
||||
public int retrieve(ItemStack usedItem) {
|
||||
+ return this.retrieve(net.minecraft.world.InteractionHand.MAIN_HAND, usedItem);
|
||||
+ }
|
||||
+
|
||||
+ public int retrieve(net.minecraft.world.InteractionHand hand, ItemStack usedItem) {
|
||||
+ // Paper end - Add hand parameter to PlayerFishEvent
|
||||
net.minecraft.world.entity.player.Player entityhuman = this.getPlayerOwner();
|
||||
|
||||
if (!this.level().isClientSide && entityhuman != null && !this.shouldStopFishing(entityhuman)) {
|
||||
@@ -0,0 +0,0 @@ public class FishingHook extends Projectile {
|
||||
|
||||
if (this.hookedIn != null) {
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_ENTITY);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), this.hookedIn.getBukkitEntity(), (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.CAUGHT_ENTITY); // Paper - Add hand parameter to PlayerFishEvent
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
@@ -0,0 +0,0 @@ public class FishingHook extends Projectile {
|
||||
}
|
||||
// Paper end
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem may be null
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem may be null // Paper - Add hand parameter to PlayerFishEvent
|
||||
playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1);
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
@@ -0,0 +0,0 @@ public class FishingHook extends Projectile {
|
||||
|
||||
if (this.onGround()) {
|
||||
// CraftBukkit start
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.IN_GROUND);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.IN_GROUND); // Paper - Add hand parameter to PlayerFishEvent
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
@@ -0,0 +0,0 @@ public class FishingHook extends Projectile {
|
||||
}
|
||||
// CraftBukkit start
|
||||
if (i == 0) {
|
||||
- PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.REEL_IN);
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.REEL_IN); // Paper - Add hand parameter to PlayerFishEvent
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent);
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
return 0;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FishingRodItem.java b/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FishingRodItem.java
|
||||
@@ -0,0 +0,0 @@ public class FishingRodItem extends Item {
|
||||
|
||||
if (user.fishing != null) {
|
||||
if (!world.isClientSide) {
|
||||
- int i = user.fishing.retrieve(itemstack);
|
||||
+ int i = user.fishing.retrieve(hand, itemstack); // Paper - Add hand parameter to PlayerFishEvent
|
||||
|
||||
itemstack.hurtAndBreak(i, user, LivingEntity.getSlotForHand(hand));
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 17 Jun 2023 13:17:25 -0700
|
||||
Subject: [PATCH] Add method to remove all active potion effects
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return effects;
|
||||
}
|
||||
|
||||
+ // Paper start - LivingEntity#clearActivePotionEffects();
|
||||
+ @Override
|
||||
+ public boolean clearActivePotionEffects() {
|
||||
+ return this.getHandle().removeAllEffects(EntityPotionEffectEvent.Cause.PLUGIN);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile) {
|
||||
return this.launchProjectile(projectile, null);
|
||||
314
patches/server/Add-missing-InventoryHolders-to-inventories.patch
Normal file
314
patches/server/Add-missing-InventoryHolders-to-inventories.patch
Normal file
@@ -0,0 +1,314 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 24 Jan 2022 00:09:02 -0800
|
||||
Subject: [PATCH] Add missing InventoryHolders to inventories
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/Container.java
|
||||
+++ b/src/main/java/net/minecraft/world/Container.java
|
||||
@@ -0,0 +0,0 @@ public interface Container extends Clearable {
|
||||
|
||||
java.util.List<org.bukkit.entity.HumanEntity> getViewers();
|
||||
|
||||
- org.bukkit.inventory.InventoryHolder getOwner();
|
||||
+ org.bukkit.inventory.@org.jetbrains.annotations.Nullable InventoryHolder getOwner(); // Paper - annotation
|
||||
|
||||
void setMaxStackSize(int size);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/SimpleContainer.java b/src/main/java/net/minecraft/world/SimpleContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/SimpleContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/SimpleContainer.java
|
||||
@@ -0,0 +0,0 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
// CraftBukkit start - add fields and methods
|
||||
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
private int maxStack = MAX_STACK;
|
||||
- protected org.bukkit.inventory.InventoryHolder bukkitOwner;
|
||||
+ protected @Nullable org.bukkit.inventory.InventoryHolder bukkitOwner; // Paper - annotation
|
||||
|
||||
public List<ItemStack> getContents() {
|
||||
return this.items;
|
||||
@@ -0,0 +0,0 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.InventoryHolder getOwner() {
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ if (this.bukkitOwner == null && this.bukkitOwnerCreator != null) {
|
||||
+ this.bukkitOwner = this.bukkitOwnerCreator.get();
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
return this.bukkitOwner;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
|
||||
public SimpleContainer(int size) {
|
||||
this(size, null);
|
||||
}
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ private @Nullable java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> bukkitOwnerCreator;
|
||||
+ public SimpleContainer(java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> bukkitOwnerCreator, int size) {
|
||||
+ this(size);
|
||||
+ this.bukkitOwnerCreator = bukkitOwnerCreator;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
public SimpleContainer(int i, org.bukkit.inventory.InventoryHolder owner) {
|
||||
this.bukkitOwner = owner;
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
this.stateId = this.stateId + 1 & 32767;
|
||||
return this.stateId;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ // The reason this is a supplier, is that the createHolder method uses the bukkit InventoryView#getTopInventory to get the inventory in question
|
||||
+ // and that can't be obtained safely until the AbstractContainerMenu has been fully constructed. Using a supplier lazily
|
||||
+ // initializes the InventoryHolder safely.
|
||||
+ protected final Supplier<org.bukkit.inventory.BlockInventoryHolder> createBlockHolder(final ContainerLevelAccess context) {
|
||||
+ //noinspection ConstantValue
|
||||
+ Preconditions.checkArgument(context != null, "context was null");
|
||||
+ return () -> context.createBlockHolder(this);
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
||||
@@ -0,0 +0,0 @@ public class BeaconMenu extends AbstractContainerMenu {
|
||||
public BeaconMenu(int syncId, Container inventory, ContainerData propertyDelegate, ContainerLevelAccess context) {
|
||||
super(MenuType.BEACON, syncId);
|
||||
this.player = (Inventory) inventory; // CraftBukkit - TODO: check this
|
||||
- this.beacon = new SimpleContainer(1) { // CraftBukkit - decompile error
|
||||
+ this.beacon = new SimpleContainer(this.createBlockHolder(context), 1) { // CraftBukkit - decompile error // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
return stack.is(ItemTags.BEACON_PAYMENT_ITEMS);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
||||
@@ -0,0 +0,0 @@ public class CartographyTableMenu extends AbstractContainerMenu {
|
||||
|
||||
public CartographyTableMenu(int syncId, Inventory inventory, final ContainerLevelAccess context) {
|
||||
super(MenuType.CARTOGRAPHY_TABLE, syncId);
|
||||
- this.container = new SimpleContainer(2) {
|
||||
+ this.container = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
CartographyTableMenu.this.slotsChanged(this);
|
||||
@@ -0,0 +0,0 @@ public class CartographyTableMenu extends AbstractContainerMenu {
|
||||
}
|
||||
// CraftBukkit end
|
||||
};
|
||||
- this.resultContainer = new ResultContainer() {
|
||||
+ this.resultContainer = new ResultContainer(this.createBlockHolder(context)) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
CartographyTableMenu.this.slotsChanged(this);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java b/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java
|
||||
@@ -0,0 +0,0 @@ public interface ContainerLevelAccess {
|
||||
return new org.bukkit.Location(this.getWorld().getWorld(), this.getPosition().getX(), this.getPosition().getY(), this.getPosition().getZ());
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ default boolean isBlock() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ default org.bukkit.inventory.@org.jetbrains.annotations.Nullable BlockInventoryHolder createBlockHolder(AbstractContainerMenu menu) {
|
||||
+ if (!this.isBlock()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(this, menu.getBukkitView().getTopInventory());
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
ContainerLevelAccess NULL = new ContainerLevelAccess() {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public interface ContainerLevelAccess {
|
||||
return pos;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ @Override
|
||||
+ public boolean isBlock() {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> evaluate(BiFunction<Level, BlockPos, T> getter) {
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
@@ -0,0 +0,0 @@ public class EnchantmentMenu extends AbstractContainerMenu {
|
||||
|
||||
public EnchantmentMenu(int syncId, Inventory playerInventory, ContainerLevelAccess context) {
|
||||
super(MenuType.ENCHANTMENT, syncId);
|
||||
- this.enchantSlots = new SimpleContainer(2) {
|
||||
+ this.enchantSlots = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -0,0 +0,0 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
|
||||
public GrindstoneMenu(int syncId, Inventory playerInventory, final ContainerLevelAccess context) {
|
||||
super(MenuType.GRINDSTONE, syncId);
|
||||
- this.resultSlots = new ResultContainer();
|
||||
- this.repairSlots = new SimpleContainer(2) {
|
||||
+ this.resultSlots = new ResultContainer(this.createBlockHolder(context)); // Paper - Add missing InventoryHolders
|
||||
+ this.repairSlots = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
protected final ContainerLevelAccess access;
|
||||
protected final Player player;
|
||||
protected final Container inputSlots;
|
||||
- protected final ResultContainer resultSlots = new ResultContainer() {
|
||||
- @Override
|
||||
- public void setChanged() {
|
||||
- ItemCombinerMenu.this.slotsChanged(this);
|
||||
- }
|
||||
- };
|
||||
+ protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init
|
||||
private final int resultSlotIndex;
|
||||
|
||||
protected boolean mayPickup(Player player, boolean present) {
|
||||
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
public ItemCombinerMenu(@Nullable MenuType<?> type, int syncId, Inventory playerInventory, ContainerLevelAccess context, ItemCombinerMenuSlotDefinition forgingSlotsManager) {
|
||||
super(type, syncId);
|
||||
this.access = context;
|
||||
+ // Paper start - Add missing InventoryHolders; delay field init
|
||||
+ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)) {
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ ItemCombinerMenu.this.slotsChanged(this);
|
||||
+ }
|
||||
+ };
|
||||
+ // Paper end - Add missing InventoryHolders; delay field init
|
||||
this.player = playerInventory.player;
|
||||
this.inputSlots = this.createContainer(forgingSlotsManager.getNumOfInputSlots());
|
||||
this.resultSlotIndex = forgingSlotsManager.getResultSlotIndex();
|
||||
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
public abstract void createResult();
|
||||
|
||||
private SimpleContainer createContainer(int size) {
|
||||
- return new SimpleContainer(size) {
|
||||
+ return new SimpleContainer(this.createBlockHolder(this.access), size) {
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/LoomMenu.java b/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/LoomMenu.java
|
||||
@@ -0,0 +0,0 @@ public class LoomMenu extends AbstractContainerMenu {
|
||||
this.selectablePatterns = List.of();
|
||||
this.slotUpdateListener = () -> {
|
||||
};
|
||||
- this.inputContainer = new SimpleContainer(3) {
|
||||
+ this.inputContainer = new SimpleContainer(this.createBlockHolder(context), 3) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
@@ -0,0 +0,0 @@ public class LoomMenu extends AbstractContainerMenu {
|
||||
}
|
||||
// CraftBukkit end
|
||||
};
|
||||
- this.outputContainer = new SimpleContainer(1) {
|
||||
+ this.outputContainer = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ResultContainer.java b/src/main/java/net/minecraft/world/inventory/ResultContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ResultContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ResultContainer.java
|
||||
@@ -0,0 +0,0 @@ public class ResultContainer implements Container, RecipeCraftingHolder {
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.InventoryHolder getOwner() {
|
||||
- return null; // Result slots don't get an owner
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ if (this.holder == null && this.holderCreator != null) {
|
||||
+ this.holder = this.holderCreator.get();
|
||||
+ }
|
||||
+ return this.holder; // Result slots don't get an owner
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
}
|
||||
|
||||
// Don't need a transaction; the InventoryCrafting keeps track of it for us
|
||||
@@ -0,0 +0,0 @@ public class ResultContainer implements Container, RecipeCraftingHolder {
|
||||
return null;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ private @Nullable java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> holderCreator;
|
||||
+ private @Nullable org.bukkit.inventory.InventoryHolder holder;
|
||||
+ public ResultContainer(java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> holderCreator) {
|
||||
+ this();
|
||||
+ this.holderCreator = holderCreator;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
public ResultContainer() {
|
||||
this.itemStacks = NonNullList.withSize(1, ItemStack.EMPTY);
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
||||
@@ -0,0 +0,0 @@ public class StonecutterMenu extends AbstractContainerMenu {
|
||||
this.input = ItemStack.EMPTY;
|
||||
this.slotUpdateListener = () -> {
|
||||
};
|
||||
- this.container = new SimpleContainer(1) {
|
||||
+ this.container = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders
|
||||
@Override
|
||||
public void setChanged() {
|
||||
super.setChanged();
|
||||
@@ -0,0 +0,0 @@ public class StonecutterMenu extends AbstractContainerMenu {
|
||||
}
|
||||
// CraftBukkit end
|
||||
};
|
||||
- this.resultContainer = new ResultContainer();
|
||||
+ this.resultContainer = new ResultContainer(this.createBlockHolder(context)); // Paper - Add missing InventoryHolders
|
||||
this.access = context;
|
||||
this.level = playerInventory.player.level();
|
||||
this.inputSlot = this.addSlot(new Slot(this.container, 0, 20, 33));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockInventoryHolder implements BlockInventoryHolder {
|
||||
this.block = CraftBlock.at(world, pos);
|
||||
this.inventory = new CraftInventory(inv);
|
||||
}
|
||||
+ // Paper start - Add missing InventoryHolders
|
||||
+ public CraftBlockInventoryHolder(net.minecraft.world.inventory.ContainerLevelAccess levelAccess, Inventory inventory) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(levelAccess.isBlock());
|
||||
+ this.block = CraftBlock.at(levelAccess.getWorld(), levelAccess.getPosition());
|
||||
+ this.inventory = inventory;
|
||||
+ }
|
||||
+ // Paper end - Add missing InventoryHolders
|
||||
|
||||
@Override
|
||||
public Block getBlock() {
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NonSwag <mrminecraft00@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 20:25:05 +0100
|
||||
Subject: [PATCH] Add missing SpigotConfig logCommands check
|
||||
|
||||
Co-authored-by: david <mrminecraft00@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
private void performUnsignedChatCommand(String command) {
|
||||
// CraftBukkit start
|
||||
String command1 = "/" + command;
|
||||
+ if (org.spigotmc.SpigotConfig.logCommands) { // Paper - Add missing SpigotConfig logCommands check
|
||||
ServerGamePacketListenerImpl.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command1);
|
||||
+ }
|
||||
|
||||
PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command1, new LazyPlayerSet(this.server));
|
||||
this.cserver.getPluginManager().callEvent(event);
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
private void performSignedChatCommand(ServerboundChatCommandSignedPacket packet, LastSeenMessages lastSeenMessages) {
|
||||
// CraftBukkit start
|
||||
String command = "/" + packet.command();
|
||||
+ if (org.spigotmc.SpigotConfig.logCommands) { // Paper - Add missing SpigotConfig logCommands check
|
||||
ServerGamePacketListenerImpl.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command);
|
||||
+ } // Paper - Add missing SpigotConfig logCommands check
|
||||
|
||||
PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command, new LazyPlayerSet(this.server));
|
||||
this.cserver.getPluginManager().callEvent(event);
|
||||
26
patches/server/Add-missing-fishing-event-state.patch
Normal file
26
patches/server/Add-missing-fishing-event-state.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Wed, 1 May 2024 07:44:50 +0300
|
||||
Subject: [PATCH] Add missing fishing event state
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -0,0 +0,0 @@ public class FishingHook extends Projectile {
|
||||
this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle);
|
||||
this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime);
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing fishing event state
|
||||
+ if (this.getPlayerOwner() != null) {
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.LURED);
|
||||
+ if (!playerFishEvent.callEvent()) {
|
||||
+ this.timeUntilHooked = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing fishing event state
|
||||
}
|
||||
} else {
|
||||
// CraftBukkit start - logic to modify fishing wait time
|
||||
@@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 12 Jun 2022 13:25:52 -0400
|
||||
Subject: [PATCH] Add missing important BlockStateListPopulator methods
|
||||
|
||||
Without these methods it causes exceptions due to these being used by certain feature generators.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java
|
||||
@@ -0,0 +0,0 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
|
||||
|
||||
@Override
|
||||
public boolean isFluidAtPosition(BlockPos pos, Predicate<FluidState> state) {
|
||||
- return this.world.isFluidAtPosition(pos, state);
|
||||
+ return state.test(this.getFluidState(pos)); // Paper - fix
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
|
||||
public RandomSource getRandom() {
|
||||
return this.world.getRandom();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public <T extends BlockEntity> java.util.Optional<T> getBlockEntity(BlockPos pos, net.minecraft.world.level.block.entity.BlockEntityType<T> type) {
|
||||
+ BlockEntity tileentity = this.getBlockEntity(pos);
|
||||
+
|
||||
+ return tileentity != null && tileentity.getType() == type ? (java.util.Optional<T>) java.util.Optional.of(tileentity) : java.util.Optional.empty();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public BlockPos getHeightmapPos(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, BlockPos pos) {
|
||||
+ return world.getHeightmapPos(heightmap, pos);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getHeight(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, int x, int z) {
|
||||
+ return world.getHeight(heightmap, x, z);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getRawBrightness(BlockPos pos, int ambientDarkness) {
|
||||
+ return world.getRawBrightness(pos, ambientDarkness);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getBrightness(net.minecraft.world.level.LightLayer type, BlockPos pos) {
|
||||
+ return world.getBrightness(type, pos);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
|
||||
@@ -0,0 +0,0 @@ public class DummyGeneratorAccess implements WorldGenLevel {
|
||||
public boolean destroyBlock(BlockPos pos, boolean drop, Entity breakingEntity, int maxUpdateDepth) {
|
||||
return false; // SPIGOT-6515
|
||||
}
|
||||
+
|
||||
+ // Paper start - add more methods
|
||||
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay) {}
|
||||
+
|
||||
+ @Override
|
||||
+ public void scheduleTick(BlockPos pos, Block block, int delay, net.minecraft.world.ticks.TickPriority priority) {}
|
||||
+
|
||||
+ @Override
|
||||
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay, net.minecraft.world.ticks.TickPriority priority) {}
|
||||
+ // Paper end - add more methods
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 23 Sep 2023 01:49:39 -0400
|
||||
Subject: [PATCH] Add missing logs for log-ips config option
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper
|
||||
|
||||
if (i == 0) {
|
||||
- LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}", socketaddress);
|
||||
+ LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socketaddress: "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
|
||||
// Paper start - Call PaperServerListPingEvent and use results
|
||||
event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketaddress, 39, null);
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
// LegacyQueryHandler.LOGGER.debug("Ping: (1.6) from {}", socketaddress);
|
||||
// Paper end
|
||||
} else {
|
||||
- LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}", socketaddress);
|
||||
+ LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socketaddress: "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
}
|
||||
|
||||
if (s == null) {
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
buf.release();
|
||||
this.buf = null;
|
||||
|
||||
- LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
|
||||
+ LOGGER.debug("Ping: (1.6) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? ctx.channel().remoteAddress(): "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
|
||||
java.net.InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
|
||||
com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(
|
||||
@@ -0,0 +1,103 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: leguan <longboard.noah@gmail.com>
|
||||
Date: Sun, 10 Mar 2024 20:10:41 +0100
|
||||
Subject: [PATCH] Add onboarding message for initial server start
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/configuration/Configurations.java
|
||||
+++ b/src/main/java/io/papermc/paper/configuration/Configurations.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Configurations<G, W> {
|
||||
if (Files.notExists(configFile)) {
|
||||
node = CommentedConfigurationNode.root(loader.defaultOptions());
|
||||
node.node(Configuration.VERSION_FIELD).raw(this.globalConfigVersion());
|
||||
+ GlobalConfiguration.isFirstStart = true;
|
||||
} else {
|
||||
node = loader.load();
|
||||
this.verifyGlobalConfigVersion(node);
|
||||
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
|
||||
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
|
||||
@@ -0,0 +0,0 @@ public class GlobalConfiguration extends ConfigurationPart {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
static final int CURRENT_VERSION = 29; // (when you change the version, change the comment, so it conflicts on rebases): <insert changes here>
|
||||
private static GlobalConfiguration instance;
|
||||
+ public static boolean isFirstStart = false;
|
||||
public static GlobalConfiguration get() {
|
||||
return instance;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
long tickSection = Util.getNanos();
|
||||
long currentTime;
|
||||
// Paper end - further improve server tick loop
|
||||
+ // Paper start - Add onboarding message for initial server start
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.isFirstStart) {
|
||||
+ LOGGER.info("*************************************************************************************");
|
||||
+ LOGGER.info("This is the first time you're starting this server.");
|
||||
+ LOGGER.info("It's recommended you read our 'Getting Started' documentation for guidance.");
|
||||
+ LOGGER.info("View this and more helpful information here: https://docs.papermc.io/paper/next-steps");
|
||||
+ LOGGER.info("*************************************************************************************");
|
||||
+ }
|
||||
+ // Paper end - Add onboarding message for initial server start
|
||||
+
|
||||
while (this.running) {
|
||||
long i;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
+++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
@@ -0,0 +0,0 @@ public class MinecraftServerGui extends JComponent {
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
try {
|
||||
+ this.add(this.buildOnboardingPanel(), "North"); // Paper - Add onboarding message for initial server start
|
||||
this.add(this.buildChatPanel(), "Center");
|
||||
this.add(this.buildInfoPanel(), "West");
|
||||
} catch (Exception exception) {
|
||||
@@ -0,0 +0,0 @@ public class MinecraftServerGui extends JComponent {
|
||||
return jpanel;
|
||||
}
|
||||
|
||||
+ // Paper start - Add onboarding message for initial server start
|
||||
+ private JComponent buildOnboardingPanel() {
|
||||
+ String onboardingLink = "https://docs.papermc.io/paper/next-steps";
|
||||
+ JPanel jPanel = new JPanel();
|
||||
+
|
||||
+ javax.swing.JLabel jLabel = new javax.swing.JLabel("If you need help setting up your server you can visit:");
|
||||
+ jLabel.setFont(MinecraftServerGui.MONOSPACED);
|
||||
+
|
||||
+ javax.swing.JLabel link = new javax.swing.JLabel("<html><u> " + onboardingLink + "</u></html>");
|
||||
+ link.setFont(MinecraftServerGui.MONOSPACED);
|
||||
+ link.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
|
||||
+ link.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
+ @Override
|
||||
+ public void mouseClicked(final java.awt.event.MouseEvent e) {
|
||||
+ try {
|
||||
+ java.awt.Desktop.getDesktop().browse(java.net.URI.create(onboardingLink));
|
||||
+ } catch (java.io.IOException exception) {
|
||||
+ LOGGER.error("Unable to find a default browser. Please manually visit the website: " + onboardingLink, exception);
|
||||
+ } catch (UnsupportedOperationException exception) {
|
||||
+ LOGGER.error("This platform does not support the BROWSE action. Please manually visit the website: " + onboardingLink, exception);
|
||||
+ } catch (SecurityException exception) {
|
||||
+ LOGGER.error("This action has been denied by the security manager. Please manually visit the website: " + onboardingLink, exception);
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ jPanel.add(jLabel);
|
||||
+ jPanel.add(link);
|
||||
+
|
||||
+ return jPanel;
|
||||
+ }
|
||||
+ // Paper end - Add onboarding message for initial server start
|
||||
+
|
||||
private JComponent buildPlayerPanel() {
|
||||
JList<?> jlist = new PlayerListComponent(this.server);
|
||||
JScrollPane jscrollpane = new JScrollPane(jlist, 22, 30);
|
||||
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 12 Jun 2022 11:47:24 -0700
|
||||
Subject: [PATCH] Add option for strict advancement dimension checks
|
||||
|
||||
Craftbukkit attempts to translate worlds that use the
|
||||
same generation as the Overworld, The Nether, or The End
|
||||
to use those dimensions when checking the `changed_dimension`
|
||||
criteria trigger, or whether to trigger the `NETHER_TRAVEL`
|
||||
distance trigger. This adds a config option to ignore that
|
||||
and use the exact dimension key of the worlds involved.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java b/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java
|
||||
@@ -0,0 +0,0 @@ public record LocationPredicate(
|
||||
public boolean matches(ServerLevel world, double x, double y, double z) {
|
||||
if (this.position.isPresent() && !this.position.get().matches(x, y, z)) {
|
||||
return false;
|
||||
- } else if (this.dimension.isPresent() && this.dimension.get() != world.dimension()) {
|
||||
+ } else if (this.dimension.isPresent() && this.dimension.get() != (io.papermc.paper.configuration.GlobalConfiguration.get().misc.strictAdvancementDimensionCheck ? world.dimension() : org.bukkit.craftbukkit.util.CraftDimensionUtil.getMainDimensionKey(world))) { // Paper - Add option for strict advancement dimension checks
|
||||
return false;
|
||||
} else {
|
||||
BlockPos blockPos = BlockPos.containing(x, y, z);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
ResourceKey<Level> maindimensionkey = CraftDimensionUtil.getMainDimensionKey(origin);
|
||||
ResourceKey<Level> maindimensionkey1 = CraftDimensionUtil.getMainDimensionKey(this.level());
|
||||
|
||||
+ // Paper start - Add option for strict advancement dimension checks
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.strictAdvancementDimensionCheck) {
|
||||
+ maindimensionkey = resourcekey;
|
||||
+ maindimensionkey1 = resourcekey1;
|
||||
+ }
|
||||
+ // Paper end - Add option for strict advancement dimension checks
|
||||
CriteriaTriggers.CHANGED_DIMENSION.trigger(this, maindimensionkey, maindimensionkey1);
|
||||
if (maindimensionkey != resourcekey || maindimensionkey1 != resourcekey1) {
|
||||
CriteriaTriggers.CHANGED_DIMENSION.trigger(this, resourcekey, resourcekey1);
|
||||
179
patches/server/Add-option-to-disable-block-updates.patch
Normal file
179
patches/server/Add-option-to-disable-block-updates.patch
Normal file
@@ -0,0 +1,179 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Boy <sivertpaulsen2@gmail.com>
|
||||
Date: Sun, 18 Jun 2023 17:45:33 +0200
|
||||
Subject: [PATCH] Add option to disable block updates
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates
|
||||
return getStateWithConnections(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState());
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
BlockState neighborState,
|
||||
RandomSource random
|
||||
) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return state; // Paper - add option to disable block updates
|
||||
if (!state.canSurvive(world, pos)) {
|
||||
tickView.scheduleTick(pos, this, 1);
|
||||
return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random);
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return; // Paper - add option to disable block updates
|
||||
if (!state.canSurvive(world, pos)) {
|
||||
world.destroyBlock(pos, true);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ChorusPlantBlock extends PipeBlock {
|
||||
|
||||
@Override
|
||||
protected boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return true; // Paper - add option to disable block updates
|
||||
BlockState blockState = world.getBlockState(pos.below());
|
||||
boolean bl = !world.getBlockState(pos.above()).isAir() && !blockState.isAir();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/HugeMushroomBlock.java
|
||||
@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates
|
||||
BlockGetter blockGetter = ctx.getLevel();
|
||||
BlockPos blockPos = ctx.getClickedPos();
|
||||
return this.defaultBlockState()
|
||||
@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block {
|
||||
BlockState neighborState,
|
||||
RandomSource random
|
||||
) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
|
||||
return neighborState.is(this)
|
||||
? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false))
|
||||
: super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random);
|
||||
@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected BlockState rotate(BlockState state, Rotation rotation) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
|
||||
return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH))
|
||||
.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH))
|
||||
.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST))
|
||||
@@ -0,0 +0,0 @@ public class HugeMushroomBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected BlockState mirror(BlockState state, Mirror mirror) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
|
||||
return state.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.NORTH)), state.getValue(NORTH))
|
||||
.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.SOUTH)), state.getValue(SOUTH))
|
||||
.setValue(PROPERTY_BY_DIRECTION.get(mirror.mirror(Direction.EAST)), state.getValue(EAST))
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
@@ -0,0 +0,0 @@ public class NoteBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return this.defaultBlockState(); // Paper - place without considering instrument
|
||||
return this.setInstrument(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) {
|
||||
+ 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 ? this.setInstrument(world, pos, state) : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random);
|
||||
@@ -0,0 +0,0 @@ public class NoteBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating
|
||||
boolean flag1 = world.hasNeighborSignal(pos);
|
||||
|
||||
if (flag1 != (Boolean) state.getValue(NoteBlock.POWERED)) {
|
||||
@@ -0,0 +0,0 @@ public class NoteBlock extends Block {
|
||||
@Override
|
||||
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
|
||||
if (!world.isClientSide) {
|
||||
- state = (BlockState) state.cycle(NoteBlock.NOTE);
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = (BlockState) state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating
|
||||
world.setBlock(pos, state, 3);
|
||||
this.playNote(player, state, world, pos);
|
||||
player.awardStat(Stats.TUNE_NOTEBLOCK);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return this.defaultBlockState(); // Paper - place tripwire without updating
|
||||
Level world = ctx.getLevel();
|
||||
BlockPos blockposition = ctx.getClickedPos();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating
|
||||
return direction.getAxis().isHorizontal() ? (BlockState) state.setValue((Property) TripWireBlock.PROPERTY_BY_DIRECTION.get(direction), this.shouldConnectTo(neighborState, direction)) : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
if (!oldState.is(state.getBlock())) {
|
||||
this.updateSource(world, pos, state);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
if (!moved && !state.is(newState.getBlock())) {
|
||||
this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
public BlockState playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent disarming tripwires
|
||||
if (!world.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) {
|
||||
world.setBlock(pos, (BlockState) state.setValue(TripWireBlock.DISARMED, true), 4);
|
||||
world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos);
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
}
|
||||
|
||||
private void updateSource(Level world, BlockPos pos, BlockState state) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
|
||||
Direction[] aenumdirection = new Direction[]{Direction.SOUTH, Direction.WEST};
|
||||
int i = aenumdirection.length;
|
||||
int j = 0;
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
+ 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
if (!world.isClientSide) {
|
||||
if (!(Boolean) state.getValue(TripWireBlock.POWERED)) {
|
||||
@@ -0,0 +0,0 @@ public class TripWireBlock extends Block {
|
||||
|
||||
@Override
|
||||
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwire pressed check
|
||||
if ((Boolean) world.getBlockState(pos).getValue(TripWireBlock.POWERED)) {
|
||||
this.checkPressed(world, pos);
|
||||
}
|
||||
197
patches/server/Add-paper-dumplisteners-command.patch
Normal file
197
patches/server/Add-paper-dumplisteners-command.patch
Normal file
@@ -0,0 +1,197 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Tue, 25 Oct 2022 21:15:37 +0200
|
||||
Subject: [PATCH] Add /paper dumplisteners command
|
||||
|
||||
Co-authored-by: TwoLeggedCat <80929284+TwoLeggedCat@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
@@ -0,0 +0,0 @@ public final class PaperCommand extends Command {
|
||||
commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand());
|
||||
commands.put(Set.of("dumpitem"), new DumpItemCommand());
|
||||
commands.put(Set.of("mobcaps", "playermobcaps"), new MobcapsCommand());
|
||||
+ commands.put(Set.of("dumplisteners"), new DumpListenersCommand());
|
||||
|
||||
return commands.entrySet().stream()
|
||||
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
|
||||
diff --git a/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java b/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.command.subcommands;
|
||||
+
|
||||
+import com.destroystokyo.paper.util.SneakyThrow;
|
||||
+import io.papermc.paper.command.PaperSubcommand;
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.io.PrintWriter;
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.reflect.Field;
|
||||
+import java.time.LocalDateTime;
|
||||
+import java.time.format.DateTimeFormatter;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collections;
|
||||
+import java.util.List;
|
||||
+import java.util.Locale;
|
||||
+import java.util.Set;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+import org.bukkit.plugin.RegisteredListener;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+import static net.kyori.adventure.text.Component.newline;
|
||||
+import static net.kyori.adventure.text.Component.space;
|
||||
+import static net.kyori.adventure.text.Component.text;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class DumpListenersCommand implements PaperSubcommand {
|
||||
+ private static final MethodHandle EVENT_TYPES_HANDLE;
|
||||
+
|
||||
+ static {
|
||||
+ try {
|
||||
+ final Field eventTypesField = HandlerList.class.getDeclaredField("EVENT_TYPES");
|
||||
+ eventTypesField.setAccessible(true);
|
||||
+ EVENT_TYPES_HANDLE = MethodHandles.lookup().unreflectGetter(eventTypesField);
|
||||
+ } catch (final ReflectiveOperationException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
+ if (args.length >= 1 && args[0].equals("tofile")) {
|
||||
+ this.dumpToFile(sender);
|
||||
+ return true;
|
||||
+ }
|
||||
+ this.doDumpListeners(sender, args);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ private void dumpToFile(final CommandSender sender) {
|
||||
+ final File file = new File("debug/listeners-"
|
||||
+ + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt");
|
||||
+ file.getParentFile().mkdirs();
|
||||
+ try (final PrintWriter writer = new PrintWriter(file)) {
|
||||
+ for (final String eventClass : eventClassNames()) {
|
||||
+ final HandlerList handlers;
|
||||
+ try {
|
||||
+ handlers = (HandlerList) findClass(eventClass).getMethod("getHandlerList").invoke(null);
|
||||
+ } catch (final ReflectiveOperationException e) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (handlers.getRegisteredListeners().length != 0) {
|
||||
+ writer.println(eventClass);
|
||||
+ }
|
||||
+ for (final RegisteredListener registeredListener : handlers.getRegisteredListeners()) {
|
||||
+ writer.println(" - " + registeredListener);
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (final IOException ex) {
|
||||
+ throw new RuntimeException(ex);
|
||||
+ }
|
||||
+ sender.sendMessage(text("Dumped listeners to " + file, GREEN));
|
||||
+ }
|
||||
+
|
||||
+ private void doDumpListeners(final CommandSender sender, final String[] args) {
|
||||
+ if (args.length == 0) {
|
||||
+ sender.sendMessage(text("Usage: /paper dumplisteners tofile|<className>", RED));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ final HandlerList handlers = (HandlerList) findClass(args[0]).getMethod("getHandlerList").invoke(null);
|
||||
+
|
||||
+ if (handlers.getRegisteredListeners().length == 0) {
|
||||
+ sender.sendMessage(text(args[0] + " does not have any registered listeners."));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ sender.sendMessage(text("Listeners for " + args[0] + ":"));
|
||||
+
|
||||
+ for (final RegisteredListener listener : handlers.getRegisteredListeners()) {
|
||||
+ final Component hoverText = text("Priority: " + listener.getPriority().name() + " (" + listener.getPriority().getSlot() + ")", WHITE)
|
||||
+ .append(newline())
|
||||
+ .append(text("Listener: " + listener.getListener()))
|
||||
+ .append(newline())
|
||||
+ .append(text("Executor: " + listener.getExecutor()))
|
||||
+ .append(newline())
|
||||
+ .append(text("Ignoring cancelled: " + listener.isIgnoringCancelled()));
|
||||
+
|
||||
+ sender.sendMessage(text(listener.getPlugin().getName(), GREEN)
|
||||
+ .append(space())
|
||||
+ .append(text("(" + listener.getListener().getClass().getName() + ")", GRAY).hoverEvent(hoverText)));
|
||||
+ }
|
||||
+
|
||||
+ sender.sendMessage(text("Total listeners: " + handlers.getRegisteredListeners().length));
|
||||
+
|
||||
+ } catch (final ClassNotFoundException e) {
|
||||
+ sender.sendMessage(text("Unable to find a class named '" + args[0] + "'. Make sure to use the fully qualified name.", RED));
|
||||
+ } catch (final NoSuchMethodException e) {
|
||||
+ sender.sendMessage(text("Class '" + args[0] + "' does not have a valid getHandlerList method.", RED));
|
||||
+ } catch (final ReflectiveOperationException e) {
|
||||
+ sender.sendMessage(text("Something went wrong, see the console for more details.", RED));
|
||||
+ MinecraftServer.LOGGER.warn("Error occurred while dumping listeners for class " + args[0], e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
+ return switch (args.length) {
|
||||
+ case 0 -> suggestions();
|
||||
+ case 1 -> suggestions().stream()
|
||||
+ .filter(clazz -> clazz.toLowerCase(Locale.ROOT).contains(args[0].toLowerCase(Locale.ROOT)))
|
||||
+ .toList();
|
||||
+ default -> Collections.emptyList();
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ private static List<String> suggestions() {
|
||||
+ final List<String> ret = new ArrayList<>();
|
||||
+ ret.add("tofile");
|
||||
+ ret.addAll(eventClassNames());
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ private static Set<String> eventClassNames() {
|
||||
+ try {
|
||||
+ return (Set<String>) EVENT_TYPES_HANDLE.invokeExact();
|
||||
+ } catch (final Throwable e) {
|
||||
+ SneakyThrow.sneaky(e);
|
||||
+ return Collections.emptySet(); // Unreachable
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static Class<?> findClass(final String className) throws ClassNotFoundException {
|
||||
+ try {
|
||||
+ return Class.forName(className);
|
||||
+ } catch (final ClassNotFoundException ignore) {
|
||||
+ for (final Plugin plugin : Bukkit.getServer().getPluginManager().getPlugins()) {
|
||||
+ if (!plugin.isEnabled()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ return Class.forName(className, false, plugin.getClass().getClassLoader());
|
||||
+ } catch (final ClassNotFoundException ignore0) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ throw new ClassNotFoundException(className);
|
||||
+ }
|
||||
+}
|
||||
30
patches/server/Add-player-idle-duration-API.patch
Normal file
30
patches/server/Add-player-idle-duration-API.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Sat, 14 Oct 2023 03:11:11 +0200
|
||||
Subject: [PATCH] Add player idle duration API
|
||||
|
||||
Implements API for getting and resetting a player's idle duration.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Duration getIdleDuration() {
|
||||
+ return Duration.ofMillis(net.minecraft.Util.getMillis() - this.getHandle().getLastActionTime());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetIdleDuration() {
|
||||
+ this.getHandle().resetLastActionTime();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public Player.Spigot spigot()
|
||||
{
|
||||
return this.spigot;
|
||||
64
patches/server/Add-plugin-info-at-startup.patch
Normal file
64
patches/server/Add-plugin-info-at-startup.patch
Normal file
@@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Thu, 18 Jul 2024 18:44:28 -0700
|
||||
Subject: [PATCH] Add plugin info at startup
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
|
||||
@@ -0,0 +0,0 @@ import io.papermc.paper.plugin.entrypoint.Entrypoint;
|
||||
import io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler;
|
||||
import io.papermc.paper.plugin.provider.PluginProvider;
|
||||
import io.papermc.paper.plugin.provider.type.paper.PaperPluginParent;
|
||||
+import io.papermc.paper.plugin.provider.type.spigot.SpigotPluginProvider;
|
||||
import io.papermc.paper.pluginremap.PluginRemapper;
|
||||
+import java.util.Set;
|
||||
+import java.util.TreeSet;
|
||||
import java.util.function.Function;
|
||||
import joptsimple.OptionSet;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
@@ -0,0 +0,0 @@ public class PluginInitializerManager {
|
||||
}
|
||||
|
||||
public static void load(OptionSet optionSet) throws Exception {
|
||||
+ LOGGER.info("Initializing plugins...");
|
||||
// We have to load the bukkit configuration inorder to get the update folder location.
|
||||
io.papermc.paper.plugin.PluginInitializerManager pluginSystem = io.papermc.paper.plugin.PluginInitializerManager.init(optionSet);
|
||||
if (pluginSystem.pluginRemapper != null) pluginSystem.pluginRemapper.loadingPlugins();
|
||||
@@ -0,0 +0,0 @@ public class PluginInitializerManager {
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.List<Path> files = ((java.util.List<File>) optionSet.valuesOf("add-plugin")).stream().map(File::toPath).toList();
|
||||
io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(io.papermc.paper.plugin.provider.source.PluginFlagProviderSource.INSTANCE, files);
|
||||
+
|
||||
+ final Set<String> paperPluginNames = new TreeSet<>();
|
||||
+ final Set<String> legacyPluginNames = new TreeSet<>();
|
||||
+ LaunchEntryPointHandler.INSTANCE.getStorage().forEach((entrypoint, providerStorage) -> {
|
||||
+ providerStorage.getRegisteredProviders().forEach(provider -> {
|
||||
+ if (provider instanceof final SpigotPluginProvider legacy) {
|
||||
+ legacyPluginNames.add(String.format("%s (%s)", legacy.getMeta().getName(), legacy.getMeta().getVersion()));
|
||||
+ } else if (provider instanceof final PaperPluginParent.PaperServerPluginProvider paper) {
|
||||
+ paperPluginNames.add(String.format("%s (%s)", provider.getMeta().getName(), provider.getMeta().getVersion()));
|
||||
+ }
|
||||
+ });
|
||||
+ });
|
||||
+ final int total = paperPluginNames.size() + legacyPluginNames.size();
|
||||
+ LOGGER.info("Initialized {} plugin{}", total, total == 1 ? "" : "s");
|
||||
+ if (!paperPluginNames.isEmpty()) {
|
||||
+ if (LOGGER.isDebugEnabled()) {
|
||||
+ LOGGER.info("Paper plugins ({}):\n - {}", paperPluginNames.size(), String.join("\n - ", paperPluginNames));
|
||||
+ } else {
|
||||
+ LOGGER.info("Paper plugins ({}):\n - {}", paperPluginNames.size(), String.join(", ", paperPluginNames));
|
||||
+ }
|
||||
+ }
|
||||
+ if (!legacyPluginNames.isEmpty()) {
|
||||
+ if (LOGGER.isDebugEnabled()) {
|
||||
+ LOGGER.info("Bukkit plugins ({}):\n - {}", legacyPluginNames.size(), String.join("\n - ", legacyPluginNames));
|
||||
+ } else {
|
||||
+ LOGGER.info("Bukkit plugins ({}):\n - {}", legacyPluginNames.size(), String.join(", ", legacyPluginNames));
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
// This will be the end of me...
|
||||
116
patches/server/Add-predicate-for-blocks-when-raytracing.patch
Normal file
116
patches/server/Add-predicate-for-blocks-when-raytracing.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
|
||||
Date: Wed, 6 Sep 2023 19:24:16 -0400
|
||||
Subject: [PATCH] Add predicate for blocks when raytracing
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
|
||||
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
||||
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return clip(raytrace1, blockposition, null);
|
||||
+ }
|
||||
+
|
||||
+ default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
// Paper start - Prevent raytrace from loading chunks
|
||||
BlockState iblockdata = this.getBlockStateIfLoaded(blockposition);
|
||||
if (iblockdata == null) {
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
return BlockHitResult.miss(raytrace1.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo()));
|
||||
}
|
||||
// Paper end - Prevent raytrace from loading chunks
|
||||
- if (iblockdata.isAir()) return null; // Paper - Perf: optimise air cases
|
||||
+ if (iblockdata.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockposition)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate
|
||||
FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again
|
||||
Vec3 vec3d = raytrace1.getFrom();
|
||||
Vec3 vec3d1 = raytrace1.getTo();
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
// CraftBukkit end
|
||||
|
||||
default BlockHitResult clip(ClipContext context) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return clip(context, (java.util.function.Predicate<org.bukkit.block.Block>) null);
|
||||
+ }
|
||||
+
|
||||
+ default BlockHitResult clip(ClipContext context, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
return (BlockHitResult) BlockGetter.traverseBlocks(context.getFrom(), context.getTo(), context, (raytrace1, blockposition) -> {
|
||||
- return this.clip(raytrace1, blockposition); // CraftBukkit - moved into separate method
|
||||
+ return this.clip(raytrace1, blockposition, canCollide); // CraftBukkit - moved into separate method // Paper - Add predicate for blocks when raytracing
|
||||
}, (raytrace1) -> {
|
||||
Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo());
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return rayTraceEntities((io.papermc.paper.math.Position) start, direction, maxDistance, raySize, filter);
|
||||
+ }
|
||||
+
|
||||
+ public RayTraceResult rayTraceEntities(io.papermc.paper.math.Position start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
|
||||
Preconditions.checkArgument(start != null, "Location start cannot be null");
|
||||
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
|
||||
- start.checkFinite();
|
||||
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
|
||||
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
|
||||
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
|
||||
direction.checkFinite();
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) {
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RayTraceResult rayTraceBlocks(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, Predicate<? super Block> canCollide) {
|
||||
Preconditions.checkArgument(start != null, "Location start cannot be null");
|
||||
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
|
||||
- start.checkFinite();
|
||||
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
|
||||
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
|
||||
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
|
||||
direction.checkFinite();
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
}
|
||||
|
||||
Vector dir = direction.clone().normalize().multiply(maxDistance);
|
||||
- Vec3 startPos = CraftLocation.toVec3D(start);
|
||||
+ Vec3 startPos = io.papermc.paper.util.MCUtil.toVec3(start); // Paper - Add predicate for blocks when raytracing
|
||||
Vec3 endPos = startPos.add(dir.getX(), dir.getY(), dir.getZ());
|
||||
- HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()));
|
||||
+ HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()), canCollide); // Paper - Add predicate for blocks when raytracing
|
||||
|
||||
return CraftRayTraceResult.fromNMS(this, nmsHitResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter) {
|
||||
- RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks);
|
||||
+ // Paper start - Add predicate for blocks when raytracing
|
||||
+ return this.rayTrace(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, raySize, filter, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RayTraceResult rayTrace(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter, Predicate<? super Block> canCollide) {
|
||||
+ RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, canCollide);
|
||||
+ // Paper end - Add predicate for blocks when raytracing
|
||||
Vector startVec = null;
|
||||
double blockHitDistance = maxDistance;
|
||||
|
||||
575
patches/server/Add-registry-entry-and-builders.patch
Normal file
575
patches/server/Add-registry-entry-and-builders.patch
Normal file
@@ -0,0 +1,575 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <git@lynxplay.dev>
|
||||
Date: Thu, 13 Jun 2024 23:45:32 +0200
|
||||
Subject: [PATCH] Add registry entry and builders
|
||||
|
||||
Feature patch
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/registry/PaperRegistries.java
|
||||
+++ b/src/main/java/io/papermc/paper/registry/PaperRegistries.java
|
||||
@@ -0,0 +0,0 @@ package io.papermc.paper.registry;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry;
|
||||
+import io.papermc.paper.registry.data.PaperGameEventRegistryEntry;
|
||||
+import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import java.util.Collections;
|
||||
@@ -0,0 +0,0 @@ public final class PaperRegistries {
|
||||
static {
|
||||
REGISTRY_ENTRIES = List.of(
|
||||
// built-ins
|
||||
- entry(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new),
|
||||
+ writable(Registries.GAME_EVENT, RegistryKey.GAME_EVENT, GameEvent.class, CraftGameEvent::new, PaperGameEventRegistryEntry.PaperBuilder::new),
|
||||
entry(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, StructureType.class, CraftStructureType::new),
|
||||
entry(Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, PotionEffectType.class, CraftPotionEffectType::new),
|
||||
entry(Registries.BLOCK, RegistryKey.BLOCK, BlockType.class, CraftBlockType::new),
|
||||
@@ -0,0 +0,0 @@ public final class PaperRegistries {
|
||||
entry(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN, TrimPattern.class, CraftTrimPattern::new).delayed(),
|
||||
entry(Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE, DamageType.class, CraftDamageType::new).delayed(),
|
||||
entry(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT, Wolf.Variant.class, CraftWolf.CraftVariant::new).delayed(),
|
||||
- entry(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(),
|
||||
+ writable(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, Enchantment.class, CraftEnchantment::new, PaperEnchantmentRegistryEntry.PaperBuilder::new).withSerializationUpdater(FieldRename.ENCHANTMENT_RENAME).delayed(),
|
||||
entry(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG, JukeboxSong.class, CraftJukeboxSong::new).delayed(),
|
||||
entry(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN, PatternType.class, CraftPatternType::new).delayed(),
|
||||
- entry(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new).delayed(),
|
||||
+ writable(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, Art.class, CraftArt::new, PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(),
|
||||
entry(Registries.INSTRUMENT, RegistryKey.INSTRUMENT, MusicInstrument.class, CraftMusicInstrument::new).delayed(),
|
||||
|
||||
// api-only
|
||||
diff --git a/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.registry.data;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import com.google.common.collect.Iterables;
|
||||
+import com.google.common.collect.Lists;
|
||||
+import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
+import io.papermc.paper.registry.RegistryKey;
|
||||
+import io.papermc.paper.registry.TypedKey;
|
||||
+import io.papermc.paper.registry.data.util.Checks;
|
||||
+import io.papermc.paper.registry.data.util.Conversions;
|
||||
+import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
+import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
+import java.util.Collections;
|
||||
+import java.util.List;
|
||||
+import java.util.Optional;
|
||||
+import java.util.OptionalInt;
|
||||
+import net.minecraft.core.HolderSet;
|
||||
+import net.minecraft.core.component.DataComponentMap;
|
||||
+import net.minecraft.core.registries.Registries;
|
||||
+import net.minecraft.network.chat.Component;
|
||||
+import net.minecraft.world.entity.EquipmentSlotGroup;
|
||||
+import net.minecraft.world.item.Item;
|
||||
+import net.minecraft.world.item.enchantment.Enchantment;
|
||||
+import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
+import org.bukkit.inventory.ItemType;
|
||||
+import org.jetbrains.annotations.Range;
|
||||
+import org.jspecify.annotations.Nullable;
|
||||
+
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asArgument;
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asArgumentMin;
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asConfigured;
|
||||
+
|
||||
+public class PaperEnchantmentRegistryEntry implements EnchantmentRegistryEntry {
|
||||
+
|
||||
+ // Top level
|
||||
+ protected @Nullable Component description;
|
||||
+
|
||||
+ // Definition
|
||||
+ protected @Nullable HolderSet<Item> supportedItems;
|
||||
+ protected @Nullable HolderSet<Item> primaryItems;
|
||||
+ protected OptionalInt weight = OptionalInt.empty();
|
||||
+ protected OptionalInt maxLevel = OptionalInt.empty();
|
||||
+ protected Enchantment.@Nullable Cost minimumCost;
|
||||
+ protected Enchantment.@Nullable Cost maximumCost;
|
||||
+ protected OptionalInt anvilCost = OptionalInt.empty();
|
||||
+ protected @Nullable List<EquipmentSlotGroup> activeSlots;
|
||||
+
|
||||
+ // Exclusive
|
||||
+ protected HolderSet<Enchantment> exclusiveWith = HolderSet.empty(); // Paper added default to empty.
|
||||
+
|
||||
+ // Effects
|
||||
+ protected DataComponentMap effects;
|
||||
+
|
||||
+ protected final Conversions conversions;
|
||||
+
|
||||
+ public PaperEnchantmentRegistryEntry(
|
||||
+ final Conversions conversions,
|
||||
+ final TypedKey<org.bukkit.enchantments.Enchantment> ignoredKey,
|
||||
+ final @Nullable Enchantment internal
|
||||
+ ) {
|
||||
+ this.conversions = conversions;
|
||||
+ if (internal == null) {
|
||||
+ this.effects = DataComponentMap.EMPTY;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // top level
|
||||
+ this.description = internal.description();
|
||||
+
|
||||
+ // definition
|
||||
+ final Enchantment.EnchantmentDefinition definition = internal.definition();
|
||||
+ this.supportedItems = definition.supportedItems();
|
||||
+ this.primaryItems = definition.primaryItems().orElse(null);
|
||||
+ this.weight = OptionalInt.of(definition.weight());
|
||||
+ this.maxLevel = OptionalInt.of(definition.maxLevel());
|
||||
+ this.minimumCost = definition.minCost();
|
||||
+ this.maximumCost = definition.maxCost();
|
||||
+ this.anvilCost = OptionalInt.of(definition.anvilCost());
|
||||
+ this.activeSlots = definition.slots();
|
||||
+
|
||||
+ // exclusive
|
||||
+ this.exclusiveWith = internal.exclusiveSet();
|
||||
+
|
||||
+ // effects
|
||||
+ this.effects = internal.effects();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.Component description() {
|
||||
+ return this.conversions.asAdventure(asConfigured(this.description, "description"));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RegistryKeySet<ItemType> supportedItems() {
|
||||
+ return PaperRegistrySets.convertToApi(RegistryKey.ITEM, asConfigured(this.supportedItems, "supportedItems"));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Nullable RegistryKeySet<ItemType> primaryItems() {
|
||||
+ return this.primaryItems == null ? null : PaperRegistrySets.convertToApi(RegistryKey.ITEM, this.primaryItems);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Range(from = 1, to = 1024) int weight() {
|
||||
+ return asConfigured(this.weight, "weight");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Range(from = 1, to = 255) int maxLevel() {
|
||||
+ return asConfigured(this.maxLevel, "maxLevel");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public EnchantmentCost minimumCost() {
|
||||
+ final Enchantment.Cost cost = asConfigured(this.minimumCost, "minimumCost");
|
||||
+ return EnchantmentRegistryEntry.EnchantmentCost.of(cost.base(), cost.perLevelAboveFirst());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public EnchantmentCost maximumCost() {
|
||||
+ final Enchantment.Cost cost = asConfigured(this.maximumCost, "maximumCost");
|
||||
+ return EnchantmentRegistryEntry.EnchantmentCost.of(cost.base(), cost.perLevelAboveFirst());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Range(from = 0, to = Integer.MAX_VALUE) int anvilCost() {
|
||||
+ return asConfigured(this.anvilCost, "anvilCost");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<org.bukkit.inventory.EquipmentSlotGroup> activeSlots() {
|
||||
+ return Collections.unmodifiableList(Lists.transform(asConfigured(this.activeSlots, "activeSlots"), CraftEquipmentSlot::getSlot));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RegistryKeySet<org.bukkit.enchantments.Enchantment> exclusiveWith() {
|
||||
+ return PaperRegistrySets.convertToApi(RegistryKey.ENCHANTMENT, this.exclusiveWith);
|
||||
+ }
|
||||
+
|
||||
+ public static final class PaperBuilder extends PaperEnchantmentRegistryEntry implements EnchantmentRegistryEntry.Builder,
|
||||
+ PaperRegistryBuilder<Enchantment, org.bukkit.enchantments.Enchantment> {
|
||||
+
|
||||
+ public PaperBuilder(final Conversions conversions, final TypedKey<org.bukkit.enchantments.Enchantment> key, final @Nullable Enchantment internal) {
|
||||
+ super(conversions, key, internal);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder description(final net.kyori.adventure.text.Component description) {
|
||||
+ this.description = this.conversions.asVanilla(asArgument(description, "description"));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder supportedItems(final RegistryKeySet<ItemType> supportedItems) {
|
||||
+ this.supportedItems = PaperRegistrySets.convertToNms(Registries.ITEM, this.conversions.lookup(), asArgument(supportedItems, "supportedItems"));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder primaryItems(final @Nullable RegistryKeySet<ItemType> primaryItems) {
|
||||
+ this.primaryItems = primaryItems == null ? null : PaperRegistrySets.convertToNms(Registries.ITEM, this.conversions.lookup(), primaryItems);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder weight(final @Range(from = 1, to = 1024) int weight) {
|
||||
+ this.weight = OptionalInt.of(Checks.asArgumentRange(weight, "weight", 1, 1024));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder maxLevel(final @Range(from = 1, to = 255) int maxLevel) {
|
||||
+ this.maxLevel = OptionalInt.of(Checks.asArgumentRange(maxLevel, "maxLevel", 1, 255));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder minimumCost(final EnchantmentCost minimumCost) {
|
||||
+ final EnchantmentCost validCost = asArgument(minimumCost, "minimumCost");
|
||||
+ this.minimumCost = Enchantment.dynamicCost(validCost.baseCost(), validCost.additionalPerLevelCost());
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder maximumCost(final EnchantmentCost maximumCost) {
|
||||
+ final EnchantmentCost validCost = asArgument(maximumCost, "maximumCost");
|
||||
+ this.maximumCost = Enchantment.dynamicCost(validCost.baseCost(), validCost.additionalPerLevelCost());
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder anvilCost(final @Range(from = 0, to = Integer.MAX_VALUE) int anvilCost) {
|
||||
+ Preconditions.checkArgument(anvilCost >= 0, "anvilCost must be non-negative");
|
||||
+ this.anvilCost = OptionalInt.of(asArgumentMin(anvilCost, "anvilCost", 0));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder activeSlots(final Iterable<org.bukkit.inventory.EquipmentSlotGroup> activeSlots) {
|
||||
+ this.activeSlots = Lists.newArrayList(Iterables.transform(asArgument(activeSlots, "activeSlots"), CraftEquipmentSlot::getNMSGroup));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder exclusiveWith(final RegistryKeySet<org.bukkit.enchantments.Enchantment> exclusiveWith) {
|
||||
+ this.exclusiveWith = PaperRegistrySets.convertToNms(Registries.ENCHANTMENT, this.conversions.lookup(), asArgument(exclusiveWith, "exclusiveWith"));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Enchantment build() {
|
||||
+ final Enchantment.EnchantmentDefinition def = new Enchantment.EnchantmentDefinition(
|
||||
+ asConfigured(this.supportedItems, "supportedItems"),
|
||||
+ Optional.ofNullable(this.primaryItems),
|
||||
+ this.weight(),
|
||||
+ this.maxLevel(),
|
||||
+ asConfigured(this.minimumCost, "minimumCost"),
|
||||
+ asConfigured(this.maximumCost, "maximumCost"),
|
||||
+ this.anvilCost(),
|
||||
+ Collections.unmodifiableList(asConfigured(this.activeSlots, "activeSlots"))
|
||||
+ );
|
||||
+ return new Enchantment(
|
||||
+ asConfigured(this.description, "description"),
|
||||
+ def,
|
||||
+ this.exclusiveWith,
|
||||
+ this.effects
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/registry/data/PaperGameEventRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperGameEventRegistryEntry.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/registry/data/PaperGameEventRegistryEntry.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.registry.data;
|
||||
+
|
||||
+import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
+import io.papermc.paper.registry.data.util.Conversions;
|
||||
+import java.util.OptionalInt;
|
||||
+import net.minecraft.world.level.gameevent.GameEvent;
|
||||
+import org.jetbrains.annotations.Range;
|
||||
+import org.jspecify.annotations.Nullable;
|
||||
+
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asArgumentMin;
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asConfigured;
|
||||
+
|
||||
+public class PaperGameEventRegistryEntry implements GameEventRegistryEntry {
|
||||
+
|
||||
+ protected OptionalInt range = OptionalInt.empty();
|
||||
+
|
||||
+ public PaperGameEventRegistryEntry(
|
||||
+ final Conversions ignoredConversions,
|
||||
+ final io.papermc.paper.registry.TypedKey<org.bukkit.GameEvent> ignoredKey,
|
||||
+ final @Nullable GameEvent internal
|
||||
+ ) {
|
||||
+ if (internal == null) return;
|
||||
+
|
||||
+ this.range = OptionalInt.of(internal.notificationRadius());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Range(from = 0, to = Integer.MAX_VALUE) int range() {
|
||||
+ return asConfigured(this.range, "range");
|
||||
+ }
|
||||
+
|
||||
+ public static final class PaperBuilder extends PaperGameEventRegistryEntry implements GameEventRegistryEntry.Builder,
|
||||
+ PaperRegistryBuilder<GameEvent, org.bukkit.GameEvent> {
|
||||
+
|
||||
+ public PaperBuilder(
|
||||
+ final Conversions conversions,
|
||||
+ final io.papermc.paper.registry.TypedKey<org.bukkit.GameEvent> key,
|
||||
+ final @Nullable GameEvent internal
|
||||
+ ) {
|
||||
+ super(conversions, key, internal);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GameEventRegistryEntry.Builder range(final @Range(from = 0, to = Integer.MAX_VALUE) int range) {
|
||||
+ this.range = OptionalInt.of(asArgumentMin(range, "range", 0));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GameEvent build() {
|
||||
+ return new GameEvent(this.range());
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/registry/data/PaperPaintingVariantRegistryEntry.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.registry.data;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
+import io.papermc.paper.registry.TypedKey;
|
||||
+import io.papermc.paper.registry.data.util.Conversions;
|
||||
+import java.util.Optional;
|
||||
+import java.util.OptionalInt;
|
||||
+import net.kyori.adventure.key.Key;
|
||||
+import net.minecraft.network.chat.Component;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.world.entity.decoration.PaintingVariant;
|
||||
+import org.bukkit.Art;
|
||||
+import org.jetbrains.annotations.Range;
|
||||
+import org.jspecify.annotations.NullMarked;
|
||||
+import org.jspecify.annotations.Nullable;
|
||||
+
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asArgument;
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asArgumentRange;
|
||||
+import static io.papermc.paper.registry.data.util.Checks.asConfigured;
|
||||
+
|
||||
+@NullMarked
|
||||
+public class PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry {
|
||||
+
|
||||
+ protected OptionalInt width = OptionalInt.empty();
|
||||
+ protected OptionalInt height = OptionalInt.empty();
|
||||
+ protected @Nullable Component title;
|
||||
+ protected @Nullable Component author;
|
||||
+ protected @Nullable ResourceLocation assetId;
|
||||
+
|
||||
+ protected final Conversions conversions;
|
||||
+
|
||||
+ public PaperPaintingVariantRegistryEntry(
|
||||
+ final Conversions conversions,
|
||||
+ final TypedKey<Art> ignoredKey,
|
||||
+ final @Nullable PaintingVariant internal
|
||||
+ ) {
|
||||
+ this.conversions = conversions;
|
||||
+ if (internal == null) return;
|
||||
+
|
||||
+ this.width = OptionalInt.of(internal.width());
|
||||
+ this.height = OptionalInt.of(internal.height());
|
||||
+ this.title = internal.title().orElse(null);
|
||||
+ this.author = internal.author().orElse(null);
|
||||
+ this.assetId = internal.assetId();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Range(from = 1, to = 16) int width() {
|
||||
+ return asConfigured(this.width, "width");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Range(from = 1, to = 16) int height() {
|
||||
+ return asConfigured(this.height, "height");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.@Nullable Component title() {
|
||||
+ return this.title == null ? null : this.conversions.asAdventure(this.title);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.@Nullable Component author() {
|
||||
+ return this.author == null ? null : this.conversions.asAdventure(this.author);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Key assetId() {
|
||||
+ return PaperAdventure.asAdventure(asConfigured(this.assetId, "assetId"));
|
||||
+ }
|
||||
+
|
||||
+ public static final class PaperBuilder extends PaperPaintingVariantRegistryEntry implements PaintingVariantRegistryEntry.Builder, PaperRegistryBuilder<PaintingVariant, Art> {
|
||||
+
|
||||
+ public PaperBuilder(final Conversions conversions, final TypedKey<Art> key, final @Nullable PaintingVariant internal) {
|
||||
+ super(conversions, key, internal);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder width(final @Range(from = 1, to = 16) int width) {
|
||||
+ this.width = OptionalInt.of(asArgumentRange(width, "width", 1, 16));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder height(final @Range(from = 1, to = 16) int height) {
|
||||
+ this.height = OptionalInt.of(asArgumentRange(height, "height", 1, 16));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder title(final net.kyori.adventure.text.@Nullable Component title) {
|
||||
+ this.title = this.conversions.asVanilla(title);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder author(final net.kyori.adventure.text.@Nullable Component author) {
|
||||
+ this.author = this.conversions.asVanilla(author);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Builder assetId(final Key assetId) {
|
||||
+ this.assetId = PaperAdventure.asVanilla(asArgument(assetId, "assetId"));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PaintingVariant build() {
|
||||
+ return new PaintingVariant(
|
||||
+ this.width(),
|
||||
+ this.height(),
|
||||
+ asConfigured(this.assetId, "assetId"),
|
||||
+ Optional.ofNullable(this.title),
|
||||
+ Optional.ofNullable(this.author)
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/registry/data/package-info.java b/src/main/java/io/papermc/paper/registry/data/package-info.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/registry/data/package-info.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+@NullMarked
|
||||
+package io.papermc.paper.registry.data;
|
||||
+
|
||||
+import org.jspecify.annotations.NullMarked;
|
||||
diff --git a/src/main/java/io/papermc/paper/registry/data/util/Checks.java b/src/main/java/io/papermc/paper/registry/data/util/Checks.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/registry/data/util/Checks.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.registry.data.util;
|
||||
+
|
||||
+import java.util.OptionalInt;
|
||||
+import org.jspecify.annotations.Nullable;
|
||||
+
|
||||
+public final class Checks {
|
||||
+
|
||||
+ public static <T> T asConfigured(final @Nullable T value, final String field) {
|
||||
+ if (value == null) {
|
||||
+ throw new IllegalStateException(field + " has not been configured");
|
||||
+ }
|
||||
+ return value;
|
||||
+ }
|
||||
+
|
||||
+ public static int asConfigured(final OptionalInt value, final String field) {
|
||||
+ if (value.isEmpty()) {
|
||||
+ throw new IllegalStateException(field + " has not been configured");
|
||||
+ }
|
||||
+ return value.getAsInt();
|
||||
+ }
|
||||
+
|
||||
+ public static <T> T asArgument(final @Nullable T value, final String field) {
|
||||
+ if (value == null) {
|
||||
+ throw new IllegalArgumentException("argument " + field + " cannot be null");
|
||||
+ }
|
||||
+ return value;
|
||||
+ }
|
||||
+
|
||||
+ public static int asArgumentRange(final int value, final String field, final int min, final int max) {
|
||||
+ if (value < min || value > max) {
|
||||
+ throw new IllegalArgumentException("argument " + field + " must be [" + min + ", " + max + "]");
|
||||
+ }
|
||||
+ return value;
|
||||
+ }
|
||||
+
|
||||
+ public static int asArgumentMin(final int value, final String field, final int min) {
|
||||
+ if (value < min) {
|
||||
+ throw new IllegalArgumentException("argument " + field + " must be [" + min + ",+inf)");
|
||||
+ }
|
||||
+ return value;
|
||||
+ }
|
||||
+
|
||||
+ private Checks() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEvent.java b/src/main/java/net/minecraft/world/level/gameevent/GameEvent.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEvent.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEvent.java
|
||||
@@ -0,0 +0,0 @@ public record GameEvent(int notificationRadius) {
|
||||
}
|
||||
|
||||
private static Holder.Reference<GameEvent> register(String id, int range) {
|
||||
- return Registry.registerForHolder(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(id), new GameEvent(range));
|
||||
+ return io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerForHolderWithListeners(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(id), new GameEvent(range)); // Paper - run with listeners
|
||||
}
|
||||
|
||||
public static record Context(@Nullable Entity sourceEntity, @Nullable BlockState affectedState) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftGameEvent.java b/src/main/java/org/bukkit/craftbukkit/CraftGameEvent.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftGameEvent.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftGameEvent.java
|
||||
@@ -0,0 +0,0 @@ public class CraftGameEvent extends GameEvent implements Handleable<net.minecraf
|
||||
}
|
||||
|
||||
private final NamespacedKey key;
|
||||
+ private final net.minecraft.resources.ResourceKey<net.minecraft.world.level.gameevent.GameEvent> handleKey; // Paper
|
||||
private final net.minecraft.world.level.gameevent.GameEvent handle;
|
||||
|
||||
public CraftGameEvent(NamespacedKey key, net.minecraft.world.level.gameevent.GameEvent handle) {
|
||||
this.key = key;
|
||||
+ this.handleKey = net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.GAME_EVENT, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(key)); // Paper
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftGameEvent extends GameEvent implements Handleable<net.minecraf
|
||||
return this.handle;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getRange() {
|
||||
+ return this.handle.notificationRadius();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getVibrationLevel() {
|
||||
+ return net.minecraft.world.level.gameevent.vibrations.VibrationSystem.getGameEventFrequency(this.handleKey);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@NotNull
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
21
patches/server/Add-skipping-world-symlink-scan.patch
Normal file
21
patches/server/Add-skipping-world-symlink-scan.patch
Normal file
@@ -0,0 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: mja00 <me@mja00.dev>
|
||||
Date: Mon, 12 Aug 2024 06:27:15 -0400
|
||||
Subject: [PATCH] Add skipping world symlink scan
|
||||
|
||||
In worlds that are extremely large (greater than 1TB), it can take an insanely long time to walk the entire world for symlinks.
|
||||
This patch adds a system property to disable the symlink scan, which can be used to speed up world loading.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/LevelStorageSource.java
|
||||
@@ -0,0 +0,0 @@ public class LevelStorageSource {
|
||||
|
||||
public LevelStorageSource.LevelStorageAccess validateAndCreateAccess(String s, ResourceKey<LevelStem> dimensionType) throws IOException, ContentValidationException { // CraftBukkit
|
||||
Path path = this.getLevelPath(s);
|
||||
- List<ForbiddenSymlinkInfo> list = this.worldDirValidator.validateDirectory(path, true);
|
||||
+ List<ForbiddenSymlinkInfo> list = Boolean.getBoolean("paper.disableWorldSymlinkValidation") ? List.of() : this.worldDirValidator.validateDirectory(path, true); // Paper - add skipping of symlinks scan
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
throw new ContentValidationException(path, list);
|
||||
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Mon, 11 Sep 2023 12:01:57 +1000
|
||||
Subject: [PATCH] Add slot sanity checks in container clicks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
break;
|
||||
case SWAP:
|
||||
if ((packet.getButtonNum() >= 0 && packet.getButtonNum() < 9) || packet.getButtonNum() == 40) {
|
||||
+ // Paper start - Add slot sanity checks to container clicks
|
||||
+ if (packet.getSlotNum() < 0) {
|
||||
+ action = InventoryAction.NOTHING;
|
||||
+ break;
|
||||
+ }
|
||||
+ // Paper end - Add slot sanity checks to container clicks
|
||||
click = (packet.getButtonNum() == 40) ? ClickType.SWAP_OFFHAND : ClickType.NUMBER_KEY;
|
||||
Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum());
|
||||
if (clickedSlot.mayPickup(this.player)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
this.resetQuickCraft();
|
||||
}
|
||||
} else if (this.quickcraftStatus == 1) {
|
||||
+ if (slotIndex < 0) return; // Paper - Add slot sanity checks to container clicks
|
||||
slot = (Slot) this.slots.get(slotIndex);
|
||||
itemstack = this.getCarried();
|
||||
if (AbstractContainerMenu.canItemQuickReplace(slot, itemstack, true) && slot.mayPlace(itemstack) && (this.quickcraftType == 2 || itemstack.getCount() > this.quickcraftSlots.size()) && this.canDragTo(slot)) {
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
int j2;
|
||||
|
||||
if (actionType == ClickType.SWAP && (button >= 0 && button < 9 || button == 40)) {
|
||||
+ if (slotIndex < 0) return; // Paper - Add slot sanity checks to container clicks
|
||||
ItemStack itemstack4 = playerinventory.getItem(button);
|
||||
|
||||
slot = (Slot) this.slots.get(slotIndex);
|
||||
42
patches/server/Add-source-block-to-BlockPhysicsEvent.patch
Normal file
42
patches/server/Add-source-block-to-BlockPhysicsEvent.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sun, 7 Aug 2022 22:16:36 +0200
|
||||
Subject: [PATCH] Add source block to BlockPhysicsEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
||||
@@ -0,0 +0,0 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
|
||||
orientation = this.orientation.withFront(direction);
|
||||
}
|
||||
|
||||
- NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, orientation, false);
|
||||
+ NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, orientation, false, this.sourcePos); // Paper - Add source block to BlockPhysicsEvent
|
||||
if (this.idx < NeighborUpdater.UPDATE_ORDER.length && NeighborUpdater.UPDATE_ORDER[this.idx] == this.skipDirection) {
|
||||
this.idx++;
|
||||
}
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
@@ -0,0 +0,0 @@ public interface NeighborUpdater {
|
||||
}
|
||||
|
||||
static void executeUpdate(Level world, BlockState state, BlockPos pos, Block sourceBlock, @Nullable Orientation orientation, boolean notify) {
|
||||
+ // Paper start - Add source block to BlockPhysicsEvent
|
||||
+ executeUpdate(world, state, pos, sourceBlock, orientation, notify, pos);
|
||||
+ }
|
||||
+
|
||||
+ static void executeUpdate(Level world, BlockState state, BlockPos pos, Block sourceBlock, @Nullable Orientation orientation, boolean notify, BlockPos sourcePos) {
|
||||
+ // Paper end - Add source block to BlockPhysicsEvent
|
||||
try {
|
||||
// CraftBukkit start
|
||||
CraftWorld cworld = ((ServerLevel) world).getWorld();
|
||||
if (cworld != null) {
|
||||
- BlockPhysicsEvent event = new BlockPhysicsEvent(CraftBlock.at(world, pos), CraftBlockData.fromData(state));
|
||||
+ BlockPhysicsEvent event = new BlockPhysicsEvent(CraftBlock.at(world, pos), CraftBlockData.fromData(state), CraftBlock.at(world, sourcePos)); // Paper - Add source block to BlockPhysicsEvent
|
||||
((ServerLevel) world).getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
120
patches/server/Add-titleOverride-to-InventoryOpenEvent.patch
Normal file
120
patches/server/Add-titleOverride-to-InventoryOpenEvent.patch
Normal file
@@ -0,0 +1,120 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 4 Mar 2022 12:45:03 -0800
|
||||
Subject: [PATCH] Add titleOverride to InventoryOpenEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
this.nextContainerCounter();
|
||||
AbstractContainerMenu container = factory.createMenu(this.containerCounter, this.getInventory(), this);
|
||||
|
||||
+ Component title = null; // Paper - Add titleOverride to InventoryOpenEvent
|
||||
// CraftBukkit start - Inventory open hook
|
||||
if (container != null) {
|
||||
container.setTitle(factory.getDisplayName());
|
||||
|
||||
boolean cancelled = false;
|
||||
- container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(this, container, cancelled);
|
||||
+ container = result.getSecond();
|
||||
+ title = PaperAdventure.asVanilla(result.getFirst());
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (container == null && !cancelled) { // Let pre-cancelled events fall through
|
||||
// SPIGOT-5263 - close chest if cancelled
|
||||
if (factory instanceof Container) {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
} else {
|
||||
// CraftBukkit start
|
||||
this.containerMenu = container;
|
||||
- if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper - Prevent opening inventories when frozen
|
||||
+ if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), Objects.requireNonNullElseGet(title, container::getTitle))); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
// CraftBukkit end
|
||||
this.initMenu(container);
|
||||
return OptionalInt.of(this.containerCounter);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
Preconditions.checkArgument(windowType != null, "Unknown windowType");
|
||||
AbstractContainerMenu container = new CraftContainer(inventory, player, player.nextContainerCounter());
|
||||
|
||||
- container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(player, container);
|
||||
+ container = result.getSecond();
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (container == null) return;
|
||||
|
||||
//String title = container.getBukkitView().getTitle(); // Paper - comment
|
||||
net.kyori.adventure.text.Component adventure$title = container.getBukkitView().title(); // Paper
|
||||
if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().getTitle()); // Paper
|
||||
+ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
|
||||
//player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
|
||||
if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
}
|
||||
|
||||
// Trigger an INVENTORY_OPEN event
|
||||
- container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ final com.mojang.datafixers.util.Pair<net.kyori.adventure.text.Component, AbstractContainerMenu> result = CraftEventFactory.callInventoryOpenEventWithTitle(player, container);
|
||||
+ container = result.getSecond();
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
//String title = inventory.getTitle(); // Paper - comment
|
||||
net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper
|
||||
if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper
|
||||
+ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
//player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
|
||||
if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen
|
||||
player.containerMenu = container;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container) {
|
||||
- return CraftEventFactory.callInventoryOpenEvent(player, container, false);
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ return callInventoryOpenEventWithTitle(player, container).getSecond();
|
||||
+ }
|
||||
+ public static com.mojang.datafixers.util.Pair<net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component, @org.jetbrains.annotations.Nullable AbstractContainerMenu> callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container) {
|
||||
+ return CraftEventFactory.callInventoryOpenEventWithTitle(player, container, false);
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - use method that acknowledges title overrides
|
||||
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
+ // Paper start - Add titleOverride to InventoryOpenEvent
|
||||
+ return callInventoryOpenEventWithTitle(player, container, cancelled).getSecond();
|
||||
+ }
|
||||
+ public static com.mojang.datafixers.util.Pair<net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component, @org.jetbrains.annotations.Nullable AbstractContainerMenu> callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
+ // Paper end - Add titleOverride to InventoryOpenEvent
|
||||
if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open
|
||||
player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
|
||||
if (event.isCancelled()) {
|
||||
container.transferTo(player.containerMenu, craftPlayer);
|
||||
- return null;
|
||||
+ return com.mojang.datafixers.util.Pair.of(null, null); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
}
|
||||
|
||||
- return container;
|
||||
+ return com.mojang.datafixers.util.Pair.of(event.titleOverride(), container); // Paper - Add titleOverride to InventoryOpenEvent
|
||||
}
|
||||
|
||||
public static ItemStack callPreCraftEvent(CraftingContainer matrix, Container resultInventory, ItemStack result, InventoryView lastCraftView, boolean isRepair) {
|
||||
41
patches/server/Add-transient-modifier-API.patch
Normal file
41
patches/server/Add-transient-modifier-API.patch
Normal file
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Malfrador <malfrador@gmail.com>
|
||||
Date: Wed, 31 May 2023 23:30:00 +0200
|
||||
Subject: [PATCH] Add transient modifier API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
@@ -0,0 +0,0 @@ public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void addTransientModifier(AttributeModifier modifier) {
|
||||
+ throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void removeModifier(AttributeModifier modifier) {
|
||||
throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
|
||||
@@ -0,0 +0,0 @@ public class CraftAttributeInstance implements AttributeInstance {
|
||||
this.handle.addPermanentModifier(CraftAttributeInstance.convert(modifier));
|
||||
}
|
||||
|
||||
+ // Paper start - Transient modifier API
|
||||
+ @Override
|
||||
+ public void addTransientModifier(AttributeModifier modifier) {
|
||||
+ Preconditions.checkArgument(modifier != null, "modifier");
|
||||
+ this.handle.addTransientModifier(CraftAttributeInstance.convert(modifier));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void removeModifier(AttributeModifier modifier) {
|
||||
Preconditions.checkArgument(modifier != null, "modifier");
|
||||
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 20 Jul 2021 21:35:47 -0700
|
||||
Subject: [PATCH] Add various missing EntityDropItemEvent calls
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
|
||||
|
||||
entityitem.setDefaultPickUpDelay();
|
||||
+ // Paper start - Call EntityDropItemEvent
|
||||
+ return this.spawnAtLocation(world, entityitem);
|
||||
+ }
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public ItemEntity spawnAtLocation(ServerLevel world, ItemEntity entityitem) {
|
||||
+ {
|
||||
+ // Paper end - Call EntityDropItemEvent
|
||||
// CraftBukkit start
|
||||
EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
|
||||
@@ -0,0 +0,0 @@ public class Dolphin extends AgeableWaterCreature {
|
||||
float f2 = 0.02F * Dolphin.this.random.nextFloat();
|
||||
|
||||
entityitem.setDeltaMovement((double) (0.3F * -Mth.sin(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.cos(f1) * f2), (double) (0.3F * Mth.sin(Dolphin.this.getXRot() * 0.017453292F) * 1.5F), (double) (0.3F * Mth.cos(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.sin(f1) * f2));
|
||||
- Dolphin.this.level().addFreshEntity(entityitem);
|
||||
+ Dolphin.this.spawnAtLocation(getServerLevel(Dolphin.this), entityitem); // Paper - Call EntityDropItemEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -0,0 +0,0 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
|
||||
entityitem.setPickUpDelay(40);
|
||||
entityitem.setThrower(this);
|
||||
this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F);
|
||||
- this.level().addFreshEntity(entityitem);
|
||||
+ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem); // Paper - Call EntityDropItemEvent
|
||||
}
|
||||
}
|
||||
|
||||
private void dropItemStack(ItemStack stack) {
|
||||
ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), stack);
|
||||
|
||||
- this.level().addFreshEntity(entityitem);
|
||||
+ this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem); // Paper - Call EntityDropItemEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
@@ -0,0 +0,0 @@ public class Goat extends Animal {
|
||||
double d2 = (double) Mth.randomBetween(this.random, -0.2F, 0.2F);
|
||||
ItemEntity entityitem = new ItemEntity(this.level(), vec3d.x(), vec3d.y(), vec3d.z(), itemstack, d0, d1, d2);
|
||||
|
||||
- this.level().addFreshEntity(entityitem);
|
||||
- return true;
|
||||
+ return this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), entityitem) != null; // Paper - Call EntityDropItemEvent
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
||||
@@ -0,0 +0,0 @@ public class Sniffer extends Animal {
|
||||
|
||||
entityitem.setDefaultPickUpDelay();
|
||||
this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null);
|
||||
+ if (this.spawnAtLocation(world, entityitem) != null) { // Paper - Call EntityDropItemEvent
|
||||
this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F);
|
||||
- world.addFreshEntity(entityitem);
|
||||
+ } // Paper - Call EntityDropItemEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemUtils.java b/src/main/java/net/minecraft/world/item/ItemUtils.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemUtils.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemUtils.java
|
||||
@@ -0,0 +0,0 @@ public class ItemUtils {
|
||||
public static void onContainerDestroyed(ItemEntity itemEntity, Iterable<ItemStack> contents) {
|
||||
Level level = itemEntity.level();
|
||||
if (!level.isClientSide) {
|
||||
- contents.forEach(stack -> level.addFreshEntity(new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack)));
|
||||
+ // Paper start - call EntityDropItemEvent
|
||||
+ contents.forEach(stack -> {
|
||||
+ ItemEntity droppedItem = new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack);
|
||||
+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(itemEntity.getBukkitEntity(), (org.bukkit.entity.Item) droppedItem.getBukkitEntity());
|
||||
+ if (event.callEvent()) {
|
||||
+ level.addFreshEntity(droppedItem);
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end - call EntityDropItemEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
34
patches/server/Add-whitelist-events.patch
Normal file
34
patches/server/Add-whitelist-events.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SageSphinx63920 <sage@sagesphinx63920.dev>
|
||||
Date: Sun, 14 May 2023 12:57:15 +0200
|
||||
Subject: [PATCH] Add whitelist events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/UserWhiteList.java b/src/main/java/net/minecraft/server/players/UserWhiteList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/UserWhiteList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/UserWhiteList.java
|
||||
@@ -0,0 +0,0 @@ public class UserWhiteList extends StoredUserList<GameProfile, UserWhiteListEntr
|
||||
protected String getKeyForUser(GameProfile gameProfile) {
|
||||
return gameProfile.getId().toString();
|
||||
}
|
||||
+ // Paper start - Add whitelist events
|
||||
+ @Override
|
||||
+ public void add(UserWhiteListEntry entry) {
|
||||
+ if (!new io.papermc.paper.event.server.WhitelistStateUpdateEvent(com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitCopy(entry.getUser()), io.papermc.paper.event.server.WhitelistStateUpdateEvent.WhitelistStatus.ADDED).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ super.add(entry);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void remove(GameProfile profile) {
|
||||
+ if (!new io.papermc.paper.event.server.WhitelistStateUpdateEvent(com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitCopy(profile), io.papermc.paper.event.server.WhitelistStateUpdateEvent.WhitelistStatus.REMOVED).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ super.remove(profile);
|
||||
+ }
|
||||
+ // Paper end - Add whitelist events
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: nostalfinals <yuu8583@proton.me>
|
||||
Date: Mon, 8 Apr 2024 23:24:38 +0800
|
||||
Subject: [PATCH] Added API to get player ha proxy address
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
this.stopReadingPackets = true;
|
||||
}
|
||||
// Paper end - packet limiter
|
||||
+ @Nullable public SocketAddress haProxyAddress; // Paper - Add API to get player's proxy address
|
||||
|
||||
public Connection(PacketFlow side) {
|
||||
this.receiving = side;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -0,0 +0,0 @@ public class ServerConnectionListener {
|
||||
|
||||
Connection connection = (Connection) channel.pipeline().get("packet_handler");
|
||||
connection.address = socketaddr;
|
||||
+
|
||||
+ // Paper start - Add API to get player's proxy address
|
||||
+ final String proxyAddress = message.destinationAddress();
|
||||
+ final int proxyPort = message.destinationPort();
|
||||
+
|
||||
+ connection.haProxyAddress = new java.net.InetSocketAddress(proxyAddress, proxyPort);
|
||||
+ // Paper end - Add API to get player's proxy address
|
||||
}
|
||||
} else {
|
||||
super.channelRead(ctx, msg);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getAddress() {
|
||||
- if (this.getHandle().connection.protocol() == null) return null;
|
||||
+ if (this.getHandle().connection == null) return null;
|
||||
|
||||
SocketAddress addr = this.getHandle().connection.getRemoteAddress();
|
||||
if (addr instanceof InetSocketAddress) {
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Add API to get player's proxy address
|
||||
+ @Override
|
||||
+ public @Nullable InetSocketAddress getHAProxyAddress() {
|
||||
+ if (this.getHandle().connection == null) return null;
|
||||
+
|
||||
+ return this.getHandle().connection.connection.haProxyAddress instanceof final InetSocketAddress inetSocketAddress ? inetSocketAddress : null;
|
||||
+ }
|
||||
+ // Paper end - Add API to get player's proxy address
|
||||
+
|
||||
public interface TransferCookieConnection {
|
||||
|
||||
boolean isTransferred();
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nex <nex@bits.team>
|
||||
Date: Thu, 24 Feb 2022 16:28:07 +0100
|
||||
Subject: [PATCH] Added byte array serialization/deserialization for
|
||||
PersistentDataContainers
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
this.customDataTags.clear();
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start - byte array serialization
|
||||
+ @Override
|
||||
+ public byte[] serializeToBytes() throws java.io.IOException {
|
||||
+ final net.minecraft.nbt.CompoundTag root = this.toTagCompound();
|
||||
+ final java.io.ByteArrayOutputStream byteArrayOutput = new java.io.ByteArrayOutputStream();
|
||||
+ try (final java.io.DataOutputStream dataOutput = new java.io.DataOutputStream(byteArrayOutput)) {
|
||||
+ net.minecraft.nbt.NbtIo.write(root, dataOutput);
|
||||
+ return byteArrayOutput.toByteArray();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void readFromBytes(final byte[] bytes, final boolean clear) throws java.io.IOException {
|
||||
+ if (clear) {
|
||||
+ this.clear();
|
||||
+ }
|
||||
+ try (final java.io.DataInputStream dataInput = new java.io.DataInputStream(new java.io.ByteArrayInputStream(bytes))) {
|
||||
+ final net.minecraft.nbt.CompoundTag compound = net.minecraft.nbt.NbtIo.read(dataInput);
|
||||
+ this.putAll(compound);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - byte array serialization
|
||||
}
|
||||
134
patches/server/Adopt-MaterialRerouting.patch
Normal file
134
patches/server/Adopt-MaterialRerouting.patch
Normal file
@@ -0,0 +1,134 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <git@lynxplay.dev>
|
||||
Date: Thu, 13 Jun 2024 11:02:36 +0200
|
||||
Subject: [PATCH] Adopt MaterialRerouting
|
||||
|
||||
Adopts the paper-api to the material rerouting infrastructure introduced
|
||||
by upstream.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
@@ -0,0 +0,0 @@ public class MaterialRerouting {
|
||||
public static void setBlocks(ToolComponent.ToolRule toolRule, Collection<Material> blocks) {
|
||||
toolRule.setBlocks(blocks.stream().map(MaterialRerouting::transformToBlockType).toList());
|
||||
}
|
||||
+
|
||||
+ // Paper start - register paper API specific material consumers in rerouting
|
||||
+ // A lot of these methods do *not* run through MaterialRerouting to avoid the overhead of a system that
|
||||
+ // currently is an effective noop.
|
||||
+ // The only downside is that upstream moved the handling of legacy materials into transformFromXType methods.
|
||||
+ // As such, methods introduced prior to 1.13 need to run through the transformation to make sure legacy material
|
||||
+ // constants still work.
|
||||
+
|
||||
+ // Utility method for constructing a set from an existing one after mapping each element.
|
||||
+ private static <I, O> Set<O> mapSet(final Set<I> input, final java.util.function.Function<I,O> mapper) {
|
||||
+ final Set<O> output = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(input.size());
|
||||
+ for (final I i : input) {
|
||||
+ output.add(mapper.apply(i));
|
||||
+ }
|
||||
+ return output;
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/4965)
|
||||
+ public static org.bukkit.Material getMinecartMaterial(org.bukkit.entity.Minecart minecart, @InjectPluginVersion ApiVersion version) {
|
||||
+ return minecart.getMinecartMaterial();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/4965)
|
||||
+ public static Material getBoatMaterial(Boat boat, @InjectPluginVersion ApiVersion version) {
|
||||
+ return boat.getBoatMaterial();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/3807)
|
||||
+ public static Material getType(io.papermc.paper.event.player.PlayerItemCooldownEvent event, @InjectPluginVersion ApiVersion version) {
|
||||
+ return event.getType();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/3850)
|
||||
+ public static Collection<Material> getInfiniburn(World world, @InjectPluginVersion ApiVersion version) {
|
||||
+ return world.getInfiniburn();
|
||||
+ }
|
||||
+
|
||||
+ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192)
|
||||
+ public static Set<Material> getTypes(
|
||||
+ final com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType slotType,
|
||||
+ @InjectPluginVersion final ApiVersion apiVersion
|
||||
+ ) {
|
||||
+ if (apiVersion.isNewerThanOrSameAs(ApiVersion.FLATTENING)) return slotType.getTypes();
|
||||
+ else return mapSet(slotType.getTypes(), MaterialRerouting::transformToItemType); // Needed as pre-flattening is hanled by transformToItemType
|
||||
+ }
|
||||
+
|
||||
+ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192)
|
||||
+ @RerouteStatic("com/destroystokyo/paper/event/player/PlayerArmorChangeEvent$SlotType")
|
||||
+ public static com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType getByMaterial(
|
||||
+ final Material material
|
||||
+ ) {
|
||||
+ return com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.getByMaterial(MaterialRerouting.transformToItemType(material));
|
||||
+ }
|
||||
+
|
||||
+ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192)
|
||||
+ @RerouteStatic("com/destroystokyo/paper/event/player/PlayerArmorChangeEvent$SlotType")
|
||||
+ public static boolean isEquipable(final Material material) {
|
||||
+ return com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.isEquipable(MaterialRerouting.transformToItemType(material));
|
||||
+ }
|
||||
+
|
||||
+ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1244)
|
||||
+ public static Material getMaterial(final com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState damageState) {
|
||||
+ return damageState.getMaterial();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1244)
|
||||
+ @RerouteStatic("com/destroystokyo/paper/event/block/AnvilDamagedEvent$DamageState")
|
||||
+ public static com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState getState(
|
||||
+ final Material material
|
||||
+ ) {
|
||||
+ return com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.getState(material);
|
||||
+ }
|
||||
+
|
||||
+ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/10290)
|
||||
+ public static ItemStack withType(final ItemStack itemStack, final Material material) {
|
||||
+ return itemStack.withType(material);
|
||||
+ }
|
||||
+ // Paper end - register paper API specific material consumers in rerouting
|
||||
}
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
@@ -0,0 +0,0 @@ public class MaterialReroutingTest {
|
||||
.filter(entry -> !entry.getName().endsWith("ItemType.class"))
|
||||
.filter(entry -> !entry.getName().endsWith("Registry.class"))
|
||||
.filter(entry -> !entry.getName().startsWith("org/bukkit/material"))
|
||||
+ // Paper start - types that cannot be translated to ItemType/BlockType
|
||||
+ .filter(entry -> !entry.getName().equals("com/destroystokyo/paper/MaterialSetTag.class"))
|
||||
+ // Paper end - types that cannot be translated to ItemType/BlockType
|
||||
.map(entry -> {
|
||||
try {
|
||||
return MaterialReroutingTest.jarFile.getInputStream(entry);
|
||||
@@ -0,0 +0,0 @@ public class MaterialReroutingTest {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
+ // Paper start - filter out more methods from rerouting test
|
||||
+ if (methodNode.name.startsWith("lambda$")) continue;
|
||||
+ if (isInternal(methodNode.invisibleAnnotations)) continue;
|
||||
+ // Paper end - filter out more methods from rerouting test
|
||||
|
||||
if (!Commodore.rerouteMethods(ApiVersion.CURRENT, MaterialReroutingTest.MATERIAL_METHOD_REROUTE, (methodNode.access & Opcodes.ACC_STATIC) != 0, classNode.name, methodNode.name, methodNode.desc, a -> { })) {
|
||||
missingReroute.add(methodNode.name + " " + methodNode.desc + " " + methodNode.signature);
|
||||
@@ -0,0 +0,0 @@ public class MaterialReroutingTest {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - filter out more methods from rerouting test
|
||||
+ private static boolean isInternal(final List<org.objectweb.asm.tree.AnnotationNode> annotationNodes) {
|
||||
+ return annotationNodes != null
|
||||
+ && annotationNodes.stream().anyMatch(a -> a.desc.equals("Lorg/jetbrains/annotations/ApiStatus$Internal;"));
|
||||
+ }
|
||||
+ // Paper end - filter out more methods from rerouting test
|
||||
+
|
||||
@AfterAll
|
||||
public static void clear() throws IOException {
|
||||
if (MaterialReroutingTest.jarFile != null) {
|
||||
@@ -0,0 +1,130 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Tue, 21 May 2024 13:18:15 -0700
|
||||
Subject: [PATCH] Allow Bukkit plugin to use Paper PluginLoader API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
|
||||
@@ -0,0 +0,0 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
|
||||
}
|
||||
|
||||
public PaperPluginClassLoader buildClassLoader(Logger logger, Path source, JarFile jarFile, PaperPluginMeta configuration) {
|
||||
- PaperLibraryStore paperLibraryStore = new PaperLibraryStore();
|
||||
- for (ClassPathLibrary library : this.libraries) {
|
||||
- library.register(paperLibraryStore);
|
||||
- }
|
||||
-
|
||||
- List<Path> paths = paperLibraryStore.getPaths();
|
||||
- if (PluginInitializerManager.instance().pluginRemapper != null) {
|
||||
- paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
|
||||
- }
|
||||
+ List<Path> paths = this.buildLibraryPaths(true);
|
||||
URL[] urls = new URL[paths.size()];
|
||||
for (int i = 0; i < paths.size(); i++) {
|
||||
Path path = paths.get(i);
|
||||
@@ -0,0 +0,0 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public List<Path> buildLibraryPaths(final boolean remap) {
|
||||
+ PaperLibraryStore paperLibraryStore = new PaperLibraryStore();
|
||||
+ for (ClassPathLibrary library : this.libraries) {
|
||||
+ library.register(paperLibraryStore);
|
||||
+ }
|
||||
+
|
||||
+ List<Path> paths = paperLibraryStore.getPaths();
|
||||
+ if (remap && PluginInitializerManager.instance().pluginRemapper != null) {
|
||||
+ paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
|
||||
+ }
|
||||
+ return paths;
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotPluginProvider implements PluginProvider<JavaPlugin>, Provide
|
||||
private final PluginDescriptionFile description;
|
||||
private final JarFile jarFile;
|
||||
private final Logger logger;
|
||||
+ private final List<Path> paperLibraryPaths;
|
||||
private final ComponentLogger componentLogger;
|
||||
private ProviderStatus status;
|
||||
private DependencyContext dependencyContext;
|
||||
|
||||
- SpigotPluginProvider(Path path, JarFile file, PluginDescriptionFile description) {
|
||||
+ SpigotPluginProvider(Path path, JarFile file, PluginDescriptionFile description, List<Path> paperLibraryPaths) {
|
||||
this.path = path;
|
||||
this.jarFile = file;
|
||||
this.description = description;
|
||||
this.logger = PaperPluginLogger.getLogger(description);
|
||||
+ this.paperLibraryPaths = paperLibraryPaths;
|
||||
this.componentLogger = ComponentLogger.logger(this.logger.getName());
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class SpigotPluginProvider implements PluginProvider<JavaPlugin>, Provide
|
||||
|
||||
final PluginClassLoader loader;
|
||||
try {
|
||||
- loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description), this.jarFile, this.dependencyContext); // Paper
|
||||
+ loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description, this.paperLibraryPaths), this.jarFile, this.dependencyContext); // Paper
|
||||
} catch (InvalidPluginException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package io.papermc.paper.plugin.provider.type.spigot;
|
||||
|
||||
+import com.destroystokyo.paper.utils.PaperPluginLogger;
|
||||
+import io.papermc.paper.plugin.bootstrap.PluginProviderContextImpl;
|
||||
import io.papermc.paper.plugin.entrypoint.classloader.BytecodeModifyingURLClassLoader;
|
||||
+import io.papermc.paper.plugin.entrypoint.classloader.PaperSimplePluginClassLoader;
|
||||
+import io.papermc.paper.plugin.loader.PaperClasspathBuilder;
|
||||
+import io.papermc.paper.plugin.loader.PluginLoader;
|
||||
import io.papermc.paper.plugin.provider.configuration.serializer.constraints.PluginConfigConstraints;
|
||||
import io.papermc.paper.plugin.provider.type.PluginTypeFactory;
|
||||
+import io.papermc.paper.plugin.provider.util.ProviderUtil;
|
||||
import io.papermc.paper.util.MappingEnvironment;
|
||||
+import java.util.List;
|
||||
+import java.util.logging.Logger;
|
||||
+import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.LibraryLoader;
|
||||
@@ -0,0 +0,0 @@ class SpigotPluginProviderFactory implements PluginTypeFactory<SpigotPluginProvi
|
||||
throw new InvalidDescriptionException("Restricted name, cannot use 0x20 (space character) in a plugin name.");
|
||||
}
|
||||
|
||||
- return new SpigotPluginProvider(source, file, configuration);
|
||||
+ final List<Path> paperLibraryPaths;
|
||||
+ if (configuration.getPaperPluginLoader() != null) {
|
||||
+ final Logger logger = PaperPluginLogger.getLogger(configuration);
|
||||
+ PaperClasspathBuilder builder = new PaperClasspathBuilder(PluginProviderContextImpl.create(
|
||||
+ configuration, ComponentLogger.logger(logger.getName()), source
|
||||
+ ));
|
||||
+
|
||||
+ try (
|
||||
+ PaperSimplePluginClassLoader simplePluginClassLoader = new PaperSimplePluginClassLoader(source, file, configuration, this.getClass().getClassLoader())
|
||||
+ ) {
|
||||
+ PluginLoader loader = ProviderUtil.loadClass(configuration.getPaperPluginLoader(), PluginLoader.class, simplePluginClassLoader);
|
||||
+ loader.classloader(builder);
|
||||
+ } catch (IOException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+
|
||||
+ paperLibraryPaths = builder.buildLibraryPaths(false);
|
||||
+ } else {
|
||||
+ paperLibraryPaths = null;
|
||||
+ }
|
||||
+
|
||||
+ return new SpigotPluginProvider(source, file, configuration, paperLibraryPaths);
|
||||
}
|
||||
|
||||
@Override
|
||||
204
patches/server/Allow-Saving-of-Oversized-Chunks.patch
Normal file
204
patches/server/Allow-Saving-of-Oversized-Chunks.patch
Normal file
@@ -0,0 +1,204 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Feb 2019 01:08:19 -0500
|
||||
Subject: [PATCH] Allow Saving of Oversized Chunks
|
||||
|
||||
The Minecraft World Region File format has a hard cap of 1MB per chunk.
|
||||
This is due to the fact that the header of the file format only allocates
|
||||
a single byte for sector count, meaning a maximum of 256 sectors, at 4k per sector.
|
||||
|
||||
This limit can be reached fairly easily with books, resulting in the chunk being unable
|
||||
to save to the world. Worse off, is that nothing printed when this occured, and silently
|
||||
performed a chunk rollback on next load.
|
||||
|
||||
This leads to security risk with duplication and is being actively exploited.
|
||||
|
||||
This patch catches the too large scenario, falls back and moves any large Entity
|
||||
or Tile Entity into a new compound, and this compound is saved into a different file.
|
||||
|
||||
On Chunk Load, we check for oversized status, and if so, we load the extra file and
|
||||
merge the Entities and Tile Entities from the oversized chunk back into the level to
|
||||
then be loaded as normal.
|
||||
|
||||
Once a chunk is returned back to normal size, the oversized flag will clear, and no
|
||||
extra data file will exist.
|
||||
|
||||
This fix maintains compatability with all existing Anvil Region Format tools as it
|
||||
does not alter the save format. They will just not know about the extra entities.
|
||||
|
||||
This fix also maintains compatability if someone switches server jars to one without
|
||||
this fix, as the data will remain in the oversized file. Once the server returns
|
||||
to a jar with this fix, the data will be restored.
|
||||
|
||||
Feature patch
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -0,0 +0,0 @@ import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
+import java.util.zip.InflaterInputStream; // Paper
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.profiling.jfr.JvmProfiler;
|
||||
+import net.minecraft.nbt.CompoundTag; // Paper
|
||||
+import net.minecraft.nbt.NbtIo; // Paper
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
this.usedSectors = new RegionBitmap();
|
||||
this.info = storageKey;
|
||||
this.path = path;
|
||||
+ initOversizedState(); // Paper
|
||||
this.version = compressionFormat;
|
||||
if (!Files.isDirectory(directory, new LinkOption[0])) {
|
||||
throw new IllegalArgumentException("Expected directory, got " + String.valueOf(directory.toAbsolutePath()));
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private final byte[] oversized = new byte[1024];
|
||||
+ private int oversizedCount;
|
||||
+
|
||||
+ private synchronized void initOversizedState() throws IOException {
|
||||
+ Path metaFile = getOversizedMetaFile();
|
||||
+ if (Files.exists(metaFile)) {
|
||||
+ final byte[] read = java.nio.file.Files.readAllBytes(metaFile);
|
||||
+ System.arraycopy(read, 0, oversized, 0, oversized.length);
|
||||
+ for (byte temp : oversized) {
|
||||
+ oversizedCount += temp;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static int getChunkIndex(int x, int z) {
|
||||
+ return (x & 31) + (z & 31) * 32;
|
||||
+ }
|
||||
+ synchronized boolean isOversized(int x, int z) {
|
||||
+ return this.oversized[getChunkIndex(x, z)] == 1;
|
||||
+ }
|
||||
+ synchronized void setOversized(int x, int z, boolean oversized) throws IOException {
|
||||
+ final int offset = getChunkIndex(x, z);
|
||||
+ boolean previous = this.oversized[offset] == 1;
|
||||
+ this.oversized[offset] = (byte) (oversized ? 1 : 0);
|
||||
+ if (!previous && oversized) {
|
||||
+ oversizedCount++;
|
||||
+ } else if (!oversized && previous) {
|
||||
+ oversizedCount--;
|
||||
+ }
|
||||
+ if (previous && !oversized) {
|
||||
+ Path oversizedFile = getOversizedFile(x, z);
|
||||
+ if (Files.exists(oversizedFile)) {
|
||||
+ Files.delete(oversizedFile);
|
||||
+ }
|
||||
+ }
|
||||
+ if (oversizedCount > 0) {
|
||||
+ if (previous != oversized) {
|
||||
+ writeOversizedMeta();
|
||||
+ }
|
||||
+ } else if (previous) {
|
||||
+ Path oversizedMetaFile = getOversizedMetaFile();
|
||||
+ if (Files.exists(oversizedMetaFile)) {
|
||||
+ Files.delete(oversizedMetaFile);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void writeOversizedMeta() throws IOException {
|
||||
+ java.nio.file.Files.write(getOversizedMetaFile(), oversized);
|
||||
+ }
|
||||
+
|
||||
+ private Path getOversizedMetaFile() {
|
||||
+ return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + ".oversized.nbt");
|
||||
+ }
|
||||
+
|
||||
+ private Path getOversizedFile(int x, int z) {
|
||||
+ return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt");
|
||||
+ }
|
||||
+
|
||||
+ synchronized CompoundTag getOversizedData(int x, int z) throws IOException {
|
||||
+ Path file = getOversizedFile(x, z);
|
||||
+ try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) {
|
||||
+ return NbtIo.read((java.io.DataInput) out);
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ // Paper end
|
||||
private class ChunkBuffer extends ByteArrayOutputStream {
|
||||
|
||||
private final ChunkPos pos;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private static void printOversizedLog(String msg, Path file, int x, int z) {
|
||||
+ org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
|
||||
+ }
|
||||
+
|
||||
+ private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
|
||||
+ synchronized (regionfile) {
|
||||
+ try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) {
|
||||
+ CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z);
|
||||
+ CompoundTag chunk = NbtIo.read((DataInput) datainputstream);
|
||||
+ if (oversizedData == null) {
|
||||
+ return chunk;
|
||||
+ }
|
||||
+ CompoundTag oversizedLevel = oversizedData.getCompound("Level");
|
||||
+
|
||||
+ mergeChunkList(chunk.getCompound("Level"), oversizedLevel, "Entities", "Entities");
|
||||
+ mergeChunkList(chunk.getCompound("Level"), oversizedLevel, "TileEntities", "TileEntities");
|
||||
+
|
||||
+ return chunk;
|
||||
+ } catch (Throwable throwable) {
|
||||
+ throwable.printStackTrace();
|
||||
+ throw throwable;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void mergeChunkList(CompoundTag level, CompoundTag oversizedLevel, String key, String oversizedKey) {
|
||||
+ net.minecraft.nbt.ListTag levelList = level.getList(key, net.minecraft.nbt.Tag.TAG_COMPOUND);
|
||||
+ net.minecraft.nbt.ListTag oversizedList = oversizedLevel.getList(oversizedKey, net.minecraft.nbt.Tag.TAG_COMPOUND);
|
||||
+
|
||||
+ if (!oversizedList.isEmpty()) {
|
||||
+ levelList.addAll(oversizedList);
|
||||
+ level.put(key, levelList);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
public CompoundTag read(ChunkPos pos) throws IOException {
|
||||
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
|
||||
@@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
// CraftBukkit end
|
||||
DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos);
|
||||
|
||||
+ // Paper start
|
||||
+ if (regionfile.isOversized(pos.x, pos.z)) {
|
||||
+ printOversizedLog("Loading Oversized Chunk!", regionfile.getPath(), pos.x, pos.z);
|
||||
+ return readOversizedChunk(regionfile, pos);
|
||||
+ }
|
||||
+ // Paper end
|
||||
CompoundTag nbttagcompound;
|
||||
label43:
|
||||
{
|
||||
@@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
|
||||
try {
|
||||
NbtIo.write(nbt, (DataOutput) dataoutputstream);
|
||||
+ regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone
|
||||
} catch (Throwable throwable) {
|
||||
if (dataoutputstream != null) {
|
||||
try {
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Scandurra <david.scandurra@check24.de>
|
||||
Date: Wed, 25 Oct 2023 20:36:25 +0200
|
||||
Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, ItemStack item) {
|
||||
- this.sendEquipmentChange(entity, Map.of(slot, item));
|
||||
+ this.sendEquipmentChange(entity, java.util.Collections.singletonMap(slot, item)); // Paper - replace Map.of to allow null values
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aeltumn <daniel@goossens.ch>
|
||||
Date: Mon, 28 Aug 2023 13:44:09 +0200
|
||||
Subject: [PATCH] Allow proper checking of empty item stacks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
}
|
||||
// Paper end - MC Utils
|
||||
|
||||
+ // Paper start - override isEmpty to use vanilla's impl
|
||||
+ @Override
|
||||
+ public boolean isEmpty() {
|
||||
+ return handle == null || handle.isEmpty();
|
||||
+ }
|
||||
+ // Paper end - override isEmpty to use vanilla's impl
|
||||
+
|
||||
public static net.minecraft.world.item.ItemStack asNMSCopy(ItemStack original) {
|
||||
if (original instanceof CraftItemStack) {
|
||||
CraftItemStack stack = (CraftItemStack) original;
|
||||
return stack.handle == null ? net.minecraft.world.item.ItemStack.EMPTY : stack.handle.copy();
|
||||
}
|
||||
- if (original == null || original.getType() == Material.AIR) {
|
||||
+ if (original == null || original.isEmpty()) { // Paper - override isEmpty to use vanilla's impl; use isEmpty
|
||||
return net.minecraft.world.item.ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
39
patches/server/Allow-trident-custom-damage.patch
Normal file
39
patches/server/Allow-trident-custom-damage.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Tue, 12 Jul 2022 18:01:14 +0200
|
||||
Subject: [PATCH] Allow trident custom damage
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
|
||||
@@ -0,0 +0,0 @@ public class ThrownTrident extends AbstractArrow {
|
||||
|
||||
public ThrownTrident(EntityType<? extends ThrownTrident> type, Level world) {
|
||||
super(type, world);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
}
|
||||
|
||||
public ThrownTrident(Level world, LivingEntity owner, ItemStack stack) {
|
||||
super(EntityType.TRIDENT, owner, world, stack, (ItemStack) null);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack));
|
||||
this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil());
|
||||
}
|
||||
|
||||
public ThrownTrident(Level world, double x, double y, double z, ItemStack stack) {
|
||||
super(EntityType.TRIDENT, x, y, z, world, stack, stack);
|
||||
+ this.setBaseDamage(net.minecraft.world.item.TridentItem.BASE_DAMAGE); // Paper - Allow trident custom damage
|
||||
this.entityData.set(ThrownTrident.ID_LOYALTY, this.getLoyaltyFromItem(stack));
|
||||
this.entityData.set(ThrownTrident.ID_FOIL, stack.hasFoil());
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ThrownTrident extends AbstractArrow {
|
||||
@Override
|
||||
protected void onHitEntity(EntityHitResult entityHitResult) {
|
||||
Entity entity = entityHitResult.getEntity();
|
||||
- float f = 8.0F;
|
||||
+ float f = (float) this.getBaseDamage(); // Paper - Allow trident custom damage
|
||||
Entity entity1 = this.getOwner();
|
||||
DamageSource damagesource = this.damageSources().trident(this, (Entity) (entity1 == null ? this : entity1));
|
||||
Level world = this.level();
|
||||
1664
patches/server/Anti-Xray.patch
Normal file
1664
patches/server/Anti-Xray.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 14 May 2023 00:47:28 -0400
|
||||
Subject: [PATCH] Avoid Lazy Initialization for Enum Fields
|
||||
|
||||
This patch is meant to get rid of any instances of lazy initialization that Minecraft introduces for enums.
|
||||
This has the possibility to create race condition issues, and generally don't make sense to be lazily done anyways.
|
||||
|
||||
diff --git a/src/main/java/com/mojang/math/OctahedralGroup.java b/src/main/java/com/mojang/math/OctahedralGroup.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/mojang/math/OctahedralGroup.java
|
||||
+++ b/src/main/java/com/mojang/math/OctahedralGroup.java
|
||||
@@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable {
|
||||
this.permutation = axisTransformation;
|
||||
this.transformation = new Matrix3f().scaling(flipX ? -1.0F : 1.0F, flipY ? -1.0F : 1.0F, flipZ ? -1.0F : 1.0F);
|
||||
this.transformation.mul(axisTransformation.transformation());
|
||||
+ this.initializeRotationDirections(); // Paper - Avoid Lazy Initialization for Enum Fields
|
||||
}
|
||||
|
||||
private BooleanList packInversions() {
|
||||
@@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
- public Direction rotate(Direction direction) {
|
||||
+ public void initializeRotationDirections() { // Paper - Avoid Lazy Initialization for Enum Fields
|
||||
if (this.rotatedDirections == null) {
|
||||
this.rotatedDirections = Maps.newEnumMap(Direction.class);
|
||||
Direction.Axis[] axiss = Direction.Axis.values();
|
||||
@@ -0,0 +0,0 @@ public enum OctahedralGroup implements StringRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Avoid Lazy Initialization for Enum Fields
|
||||
+ }
|
||||
+ public Direction rotate(Direction direction) {
|
||||
+ // Paper end - Avoid Lazy Initialization for Enum Fields
|
||||
return this.rotatedDirections.get(direction);
|
||||
}
|
||||
|
||||
179
patches/server/Bandaid-fix-for-Effect.patch
Normal file
179
patches/server/Bandaid-fix-for-Effect.patch
Normal file
@@ -0,0 +1,179 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 28 Jul 2023 15:02:44 -0700
|
||||
Subject: [PATCH] Bandaid fix for Effect
|
||||
|
||||
Effect or LevelEvent needs to be replaced
|
||||
but ideally after the enum PR has been merged
|
||||
upstream. Until then, this test and these fixes
|
||||
should address all the known issues with them
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEffect {
|
||||
public static <T> int getDataValue(Effect effect, T data) {
|
||||
int datavalue;
|
||||
switch (effect) {
|
||||
+ // Paper start - add missing effects
|
||||
+ case PARTICLES_SCULK_CHARGE:
|
||||
+ case TRIAL_SPAWNER_DETECT_PLAYER:
|
||||
+ case BEE_GROWTH:
|
||||
+ case TURTLE_EGG_PLACEMENT:
|
||||
+ case SMASH_ATTACK:
|
||||
+ case TRIAL_SPAWNER_DETECT_PLAYER_OMINOUS:
|
||||
+ // Paper end - add missing effects
|
||||
case VILLAGER_PLANT_GROW:
|
||||
datavalue = (Integer) data;
|
||||
break;
|
||||
@@ -0,0 +0,0 @@ public class CraftEffect {
|
||||
Preconditions.checkArgument(data == Material.AIR || ((Material) data).isRecord(), "Invalid record type for Material %s!", data);
|
||||
datavalue = Item.getId(CraftItemType.bukkitToMinecraft((Material) data));
|
||||
break;
|
||||
+ // Paper start - handle shoot white smoke event
|
||||
+ case SHOOT_WHITE_SMOKE:
|
||||
+ final BlockFace face = (BlockFace) data;
|
||||
+ Preconditions.checkArgument(face.isCartesian(), face + " isn't cartesian");
|
||||
+ datavalue = org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(face).get3DDataValue();
|
||||
+ break;
|
||||
+ // Paper end - handle shoot white smoke event
|
||||
case SMOKE:
|
||||
switch ((BlockFace) data) {
|
||||
case DOWN:
|
||||
@@ -0,0 +0,0 @@ public class CraftEffect {
|
||||
}
|
||||
break;
|
||||
case STEP_SOUND:
|
||||
+ if (data instanceof Material) { // Paper - support BlockData
|
||||
Preconditions.checkArgument(((Material) data).isBlock(), "Material %s is not a block!", data);
|
||||
datavalue = Block.getId(CraftBlockType.bukkitToMinecraft((Material) data).defaultBlockState());
|
||||
+ // Paper start - support BlockData
|
||||
+ break;
|
||||
+ }
|
||||
+ case PARTICLES_AND_SOUND_BRUSH_BLOCK_COMPLETE:
|
||||
+ datavalue = Block.getId(((org.bukkit.craftbukkit.block.data.CraftBlockData) data).getState());
|
||||
+ // Paper end
|
||||
break;
|
||||
case COMPOSTER_FILL_ATTEMPT:
|
||||
+ // Paper start - add missing effects
|
||||
+ case TRIAL_SPAWNER_SPAWN:
|
||||
+ case TRIAL_SPAWNER_SPAWN_MOB_AT:
|
||||
+ case VAULT_ACTIVATE:
|
||||
+ case VAULT_DEACTIVATE:
|
||||
+ case TRIAL_SPAWNER_BECOME_OMINOUS:
|
||||
+ case TRIAL_SPAWNER_SPAWN_ITEM:
|
||||
+ // Paper end - add missing effects
|
||||
datavalue = ((Boolean) data) ? 1 : 0;
|
||||
break;
|
||||
case BONE_MEAL_USE:
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public <T> void playEffect(Location loc, Effect effect, T data, int radius) {
|
||||
if (data != null) {
|
||||
Preconditions.checkArgument(effect.getData() != null, "Effect.%s does not have a valid Data", effect);
|
||||
- Preconditions.checkArgument(effect.getData().isAssignableFrom(data.getClass()), "%s data cannot be used for the %s effect", data.getClass().getName(), effect);
|
||||
+ Preconditions.checkArgument(effect.isApplicable(data), "%s data cannot be used for the %s effect", data.getClass().getName(), effect); // Paper
|
||||
} else {
|
||||
// Special case: the axis is optional for ELECTRIC_SPARK
|
||||
Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
Preconditions.checkArgument(effect != null, "Effect cannot be null");
|
||||
if (data != null) {
|
||||
Preconditions.checkArgument(effect.getData() != null, "Effect.%s does not have a valid Data", effect);
|
||||
- Preconditions.checkArgument(effect.getData().isAssignableFrom(data.getClass()), "%s data cannot be used for the %s effect", data.getClass().getName(), effect);
|
||||
+ Preconditions.checkArgument(effect.isApplicable(data), "%s data cannot be used for the %s effect", data.getClass().getName(), effect); // Paper
|
||||
} else {
|
||||
// Special case: the axis is optional for ELECTRIC_SPARK
|
||||
Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect);
|
||||
diff --git a/src/test/java/org/bukkit/EffectTest.java b/src/test/java/org/bukkit/EffectTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/org/bukkit/EffectTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package org.bukkit;
|
||||
+
|
||||
+import com.google.common.base.Joiner;
|
||||
+import java.lang.reflect.Field;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.List;
|
||||
+import java.util.Map;
|
||||
+import java.util.Set;
|
||||
+import net.minecraft.world.level.block.LevelEvent;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
+import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+import static org.junit.jupiter.api.Assertions.fail;
|
||||
+
|
||||
+public class EffectTest {
|
||||
+
|
||||
+ private static List<Integer> collectNmsLevelEvents() throws ReflectiveOperationException {
|
||||
+ final List<Integer> events = new ArrayList<>();
|
||||
+ for (final Field field : LevelEvent.class.getFields()) {
|
||||
+ if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()) && field.getType() == int.class) {
|
||||
+ events.add((int) field.get(null));
|
||||
+ }
|
||||
+ }
|
||||
+ return events;
|
||||
+ }
|
||||
+
|
||||
+ private static boolean isNotDeprecated(Effect effect) throws ReflectiveOperationException {
|
||||
+ return !Effect.class.getDeclaredField(effect.name()).isAnnotationPresent(Deprecated.class);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void checkAllApiExists() throws ReflectiveOperationException {
|
||||
+ Map<Integer, Effect> toId = new HashMap<>();
|
||||
+ for (final Effect effect : Effect.values()) {
|
||||
+ if (isNotDeprecated(effect)) {
|
||||
+ final Effect put = toId.put(effect.getId(), effect);
|
||||
+ assertNull(put, "duplicate API effect: " + put);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final Set<Integer> missingEvents = new HashSet<>();
|
||||
+ for (final Integer event : collectNmsLevelEvents()) {
|
||||
+ if (toId.get(event) == null) {
|
||||
+ missingEvents.add(event);
|
||||
+ }
|
||||
+ }
|
||||
+ if (!missingEvents.isEmpty()) {
|
||||
+ fail("Missing API Effects:\n" + Joiner.on("\n").join(missingEvents));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void checkNoExtraApi() throws ReflectiveOperationException {
|
||||
+ Map<Integer, Effect> toId = new HashMap<>();
|
||||
+ for (final Effect effect : Effect.values()) {
|
||||
+ if (isNotDeprecated(effect)) {
|
||||
+ final Effect put = toId.put(effect.getId(), effect);
|
||||
+ assertNull(put, "duplicate API effect: " + put);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final List<Integer> nmsEvents = collectNmsLevelEvents();
|
||||
+ final Set<Effect> extraApiEffects = new HashSet<>();
|
||||
+ for (final Map.Entry<Integer, Effect> entry : toId.entrySet()) {
|
||||
+ if (!nmsEvents.contains(entry.getKey())) {
|
||||
+ extraApiEffects.add(entry.getValue());
|
||||
+ }
|
||||
+ }
|
||||
+ if (!extraApiEffects.isEmpty()) {
|
||||
+ fail("Extra API Effects:\n" + Joiner.on("\n").join(extraApiEffects));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
63
patches/server/Block-Ticking-API.patch
Normal file
63
patches/server/Block-Ticking-API.patch
Normal file
@@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 26 Dec 2021 13:23:46 -0500
|
||||
Subject: [PATCH] Block Ticking API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
|
||||
return this.world.getBlockState(this.position);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public net.minecraft.world.level.material.FluidState getNMSFluid() {
|
||||
+ return this.world.getFluidState(this.position);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public BlockPos getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
|
||||
public boolean isValidTool(ItemStack itemStack) {
|
||||
return getDrops(itemStack).size() != 0;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void tick() {
|
||||
+ final ServerLevel level = this.world.getMinecraftWorld();
|
||||
+ this.getNMS().tick(level, this.position, level.random);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Override
|
||||
+ public void fluidTick() {
|
||||
+ this.getNMSFluid().tick(this.world.getMinecraftWorld(), this.position, this.getNMS());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void randomTick() {
|
||||
+ final ServerLevel level = this.world.getMinecraftWorld();
|
||||
+ this.getNMS().randomTick(level, this.position, level.random);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockData implements BlockData {
|
||||
return speed;
|
||||
}
|
||||
// Paper end - destroy speed API
|
||||
+
|
||||
+ // Paper start - Block tick API
|
||||
+ @Override
|
||||
+ public boolean isRandomlyTicked() {
|
||||
+ return this.state.isRandomlyTicking();
|
||||
+ }
|
||||
+ // Paper end - Block tick API
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 1 May 2023 18:31:26 -0700
|
||||
Subject: [PATCH] Break redstone on top of trap doors early
|
||||
|
||||
This logic hooks into the neighbour update which should be invoked
|
||||
as a result of redstone powering the trap door.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java
|
||||
@@ -0,0 +0,0 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
|
||||
flag1 = eventRedstone.getNewCurrent() > 0;
|
||||
}
|
||||
// CraftBukkit end
|
||||
- if ((Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1) {
|
||||
+ // Paper start - break redstone on trapdoors early
|
||||
+ boolean open = (Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1;
|
||||
+ // note: this must run before any state for this block/its neighborus are written to the world
|
||||
+ // we allow the redstone event to fire so that plugins can block
|
||||
+ if (flag1 && open) { // if we are now powered and it caused the trap door to open
|
||||
+ // in this case, first check for the redstone on top first
|
||||
+ BlockPos abovePos = pos.above();
|
||||
+ BlockState above = world.getBlockState(abovePos);
|
||||
+ if (above.getBlock() instanceof RedStoneWireBlock) {
|
||||
+ world.setBlock(abovePos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_NEIGHBORS);
|
||||
+ Block.popResource(world, abovePos, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.REDSTONE));
|
||||
+ // now check that this didn't change our state
|
||||
+ if (world.getBlockState(pos) != state) {
|
||||
+ // our state was changed, so we cannot propagate this update
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (open) {
|
||||
+ // Paper end - break redstone on trapdoors early
|
||||
state = (BlockState) state.setValue(TrapDoorBlock.OPEN, flag1);
|
||||
this.playSound((Player) null, world, pos, flag1);
|
||||
}
|
||||
2819
patches/server/Brigadier-based-command-API.patch
Normal file
2819
patches/server/Brigadier-based-command-API.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Sun, 29 Oct 2023 02:36:10 +0100
|
||||
Subject: [PATCH] Broadcast take item packets with collector as source
|
||||
|
||||
This fixes players (which can't view the collector) seeing item pickups with themselves as the target.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
public void take(Entity item, int count) {
|
||||
if (!item.isRemoved() && !this.level().isClientSide && (item instanceof ItemEntity || item instanceof AbstractArrow || item instanceof ExperienceOrb)) {
|
||||
- ((ServerLevel) this.level()).getChunkSource().broadcast(item, new ClientboundTakeItemEntityPacket(item.getId(), this.getId(), count));
|
||||
+ ((ServerLevel) this.level()).getChunkSource().broadcastAndSend(this, new ClientboundTakeItemEntityPacket(item.getId(), this.getId(), count)); // Paper - broadcast with collector as source
|
||||
}
|
||||
|
||||
}
|
||||
39
patches/server/Cache-map-ids-on-item-frames.patch
Normal file
39
patches/server/Cache-map-ids-on-item-frames.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Mon, 7 Aug 2023 12:58:28 +0200
|
||||
Subject: [PATCH] Cache map ids on item frames
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ServerEntity {
|
||||
ItemStack itemstack = entityitemframe.getItem();
|
||||
|
||||
if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable
|
||||
- MapId mapid = (MapId) itemstack.get(DataComponents.MAP_ID);
|
||||
+ MapId mapid = entityitemframe.cachedMapId; // Paper - Perf: Cache map ids on item frames
|
||||
MapItemSavedData worldmap = MapItem.getSavedData(mapid, this.level);
|
||||
|
||||
if (worldmap != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
@@ -0,0 +0,0 @@ public class ItemFrame extends HangingEntity {
|
||||
private static final float HEIGHT = 0.75F;
|
||||
public float dropChance;
|
||||
public boolean fixed;
|
||||
+ public @Nullable MapId cachedMapId; // Paper - Perf: Cache map ids on item frames
|
||||
|
||||
public ItemFrame(EntityType<? extends ItemFrame> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -0,0 +0,0 @@ public class ItemFrame extends HangingEntity {
|
||||
}
|
||||
|
||||
private void onItemChanged(ItemStack stack) {
|
||||
+ this.cachedMapId = stack.getComponents().get(net.minecraft.core.component.DataComponents.MAP_ID); // Paper - Perf: Cache map ids on item frames
|
||||
if (!stack.isEmpty() && stack.getFrame() != this) {
|
||||
stack.setEntityRepresentation(this);
|
||||
}
|
||||
39
patches/server/Call-BlockGrowEvent-for-missing-blocks.patch
Normal file
39
patches/server/Call-BlockGrowEvent-for-missing-blocks.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Fri, 9 Jun 2023 13:04:42 +0200
|
||||
Subject: [PATCH] Call BlockGrowEvent for missing blocks
|
||||
|
||||
Call the event for pitcher crops and sniffer egg
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/PitcherCropBlock.java
|
||||
@@ -0,0 +0,0 @@ public class PitcherCropBlock extends DoublePlantBlock implements BonemealableBl
|
||||
int i = Math.min(state.getValue(AGE) + amount, 4);
|
||||
if (this.canGrow(world, pos, state, i)) {
|
||||
BlockState blockState = state.setValue(AGE, Integer.valueOf(i));
|
||||
- world.setBlock(pos, blockState, 2);
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, blockState, 2)) return; // Paper
|
||||
if (isDouble(i)) {
|
||||
world.setBlock(pos.above(), blockState.setValue(HALF, DoubleBlockHalf.UPPER), 3);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
@@ -0,0 +0,0 @@ public class SnifferEggBlock extends Block {
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
if (!this.isReadyToHatch(state)) {
|
||||
+ // Paper start
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2)) {
|
||||
+ this.rescheduleTick(world, pos);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
world.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
|
||||
- world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2);
|
||||
} else {
|
||||
// Paper start - Call BlockFadeEvent
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, state.getFluidState().createLegacyBlock()).isCancelled()) {
|
||||
42
patches/server/Call-BlockRedstoneEvents-properly.patch
Normal file
42
patches/server/Call-BlockRedstoneEvents-properly.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
|
||||
Date: Wed, 13 Sep 2023 05:46:10 +0200
|
||||
Subject: [PATCH] Call BlockRedstoneEvents properly
|
||||
|
||||
Call BlockRedstoneEvents for lecterns.
|
||||
Fix previous power level for experimental redstone wire.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/LecternBlock.java b/src/main/java/net/minecraft/world/level/block/LecternBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java
|
||||
@@ -0,0 +0,0 @@ public class LecternBlock extends BaseEntityBlock {
|
||||
}
|
||||
|
||||
private static void changePowered(Level world, BlockPos pos, BlockState state, boolean powered) {
|
||||
+ // Paper start - Call BlockRedstoneEvent properly
|
||||
+ final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = powered ? 15 : 0;
|
||||
+ if (currentRedstoneLevel != targetRedstoneLevel) {
|
||||
+ final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, pos, currentRedstoneLevel, targetRedstoneLevel);
|
||||
+
|
||||
+ if (event.getNewCurrent() != targetRedstoneLevel) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Call BlockRedstoneEvent properly
|
||||
world.setBlock(pos, (BlockState) state.setValue(LecternBlock.POWERED, powered), 3);
|
||||
LecternBlock.updateBelow(world, pos, state);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/redstone/ExperimentalRedstoneWireEvaluator.java b/src/main/java/net/minecraft/world/level/redstone/ExperimentalRedstoneWireEvaluator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/redstone/ExperimentalRedstoneWireEvaluator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/redstone/ExperimentalRedstoneWireEvaluator.java
|
||||
@@ -0,0 +0,0 @@ public class ExperimentalRedstoneWireEvaluator extends RedstoneWireEvaluator {
|
||||
BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
|
||||
// CraftBukkit start
|
||||
- int oldPower = state.getValue(RedStoneWireBlock.POWER);
|
||||
+ int oldPower = iblockdata1.getValue(RedStoneWireBlock.POWER); // Paper - Call BlockRedstoneEvent properly; get the previous power from the right state
|
||||
if (oldPower != j) {
|
||||
BlockRedstoneEvent event = new BlockRedstoneEvent(CraftBlock.at(world, blockposition1), oldPower, j);
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
88
patches/server/Call-missing-BlockDispenseEvent.patch
Normal file
88
patches/server/Call-missing-BlockDispenseEvent.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sat, 29 Oct 2022 15:41:56 +0200
|
||||
Subject: [PATCH] Call missing BlockDispenseEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
|
||||
this.setSuccess(true);
|
||||
if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) {
|
||||
if ((Integer) iblockdata.getValue(RespawnAnchorBlock.CHARGE) != 4) {
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition, stack, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
RespawnAnchorBlock.charge((Entity) null, worldserver, blockposition, iblockdata);
|
||||
stack.shrink(1);
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
|
||||
Optional<BlockState> optional = HoneycombItem.getWaxed(iblockdata);
|
||||
|
||||
if (optional.isPresent()) {
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition, stack, this);
|
||||
+ if (result != null) {
|
||||
+ this.setSuccess(false);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
worldserver.setBlockAndUpdate(blockposition, (BlockState) optional.get());
|
||||
worldserver.levelEvent(3003, blockposition, 0);
|
||||
stack.shrink(1);
|
||||
@@ -0,0 +0,0 @@ public interface DispenseItemBehavior {
|
||||
if (!worldserver.getBlockState(blockposition1).is(BlockTags.CONVERTABLE_TO_MUD)) {
|
||||
return this.defaultDispenseItemBehavior.dispense(pointer, stack);
|
||||
} else {
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ ItemStack result = org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDispenseEvent(pointer, blockposition1, stack, this);
|
||||
+ if (result != null) {
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
if (!worldserver.isClientSide) {
|
||||
for (int k = 0; k < 5; ++k) {
|
||||
worldserver.sendParticles(ParticleTypes.SPLASH, (double) blockposition.getX() + worldserver.random.nextDouble(), (double) (blockposition.getY() + 1), (double) blockposition.getZ() + worldserver.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - Call missing BlockDispenseEvent
|
||||
+ @Nullable
|
||||
+ public static ItemStack handleBlockDispenseEvent(net.minecraft.core.dispenser.BlockSource pointer, BlockPos to, ItemStack itemStack, net.minecraft.core.dispenser.DispenseItemBehavior instance) {
|
||||
+ org.bukkit.block.Block bukkitBlock = CraftBlock.at(pointer.level(), pointer.pos());
|
||||
+ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack.copyWithCount(1));
|
||||
+
|
||||
+ org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), CraftVector.toBukkit(to));
|
||||
+ if (!net.minecraft.world.level.block.DispenserBlock.eventFired) {
|
||||
+ if (!event.callEvent()) {
|
||||
+ return itemStack;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem());
|
||||
+ net.minecraft.core.dispenser.DispenseItemBehavior itemBehavior = net.minecraft.world.level.block.DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem());
|
||||
+ if (itemBehavior != net.minecraft.core.dispenser.DispenseItemBehavior.NOOP && itemBehavior != instance) {
|
||||
+ itemBehavior.dispense(pointer, eventStack);
|
||||
+ return itemStack;
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end - Call missing BlockDispenseEvent
|
||||
+
|
||||
// Paper start - add EntityFertilizeEggEvent
|
||||
/**
|
||||
* Calls the {@link io.papermc.paper.event.entity.EntityFertilizeEggEvent}.
|
||||
69
patches/server/Check-distance-in-entity-interactions.patch
Normal file
69
patches/server/Check-distance-in-entity-interactions.patch
Normal file
@@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 2 Aug 2021 10:10:40 +0200
|
||||
Subject: [PATCH] Check distance in entity interactions
|
||||
|
||||
Feature patch
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/Util.java
|
||||
+++ b/src/main/java/net/minecraft/Util.java
|
||||
@@ -0,0 +0,0 @@ public class Util {
|
||||
.filter(fileSystemProvider -> fileSystemProvider.getScheme().equalsIgnoreCase("jar"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("No jar file system provider found"));
|
||||
+ public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Check distance in entity interactions
|
||||
private static Consumer<String> thePauser = message -> {
|
||||
};
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!source.is(DamageTypeTags.IS_PROJECTILE)) {
|
||||
Entity entity = source.getDirectEntity();
|
||||
|
||||
- if (entity instanceof LivingEntity) {
|
||||
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Check distance in entity interactions
|
||||
LivingEntity entityliving = (LivingEntity) entity;
|
||||
|
||||
this.blockUsingShield(entityliving);
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
d0 = source.getSourcePosition().x() - this.getX();
|
||||
d1 = source.getSourcePosition().z() - this.getZ();
|
||||
}
|
||||
+ // Paper start - Check distance in entity interactions; see for loop in knockback method
|
||||
+ if (Math.abs(d0) > 200) {
|
||||
+ d0 = Math.random() - Math.random();
|
||||
+ }
|
||||
+ if (Math.abs(d1) > 200) {
|
||||
+ d1 = Math.random() - Math.random();
|
||||
+ }
|
||||
+ // Paper end - Check distance in entity interactions
|
||||
|
||||
this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
|
||||
if (!flag) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
|
||||
Entity entity = damagesource.getDirectEntity();
|
||||
|
||||
- if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity) { // Paper - Fix shield disable inconsistency
|
||||
+ if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Fix shield disable inconsistency & Check distance in entity interactions
|
||||
this.blockUsingShield((LivingEntity) entity);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
|
||||
double d2 = (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D;
|
||||
|
||||
if (this.level().noCollision(this, this.getBoundingBox().move(0.0D, d2 - this.getY(), 0.0D))) {
|
||||
- this.setPos(this.getX(), d2, this.getZ());
|
||||
+ this.move(MoverType.SELF, new Vec3(0.0D, d2 - this.getY(), 0.0D)); // Paper - Check distance in entity interactions // TODO Still needed??
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
|
||||
this.lastYd = 0.0D;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Wed, 7 Aug 2024 14:33:25 +0200
|
||||
Subject: [PATCH] Check for block type in SculkSensorBlock#canActivate
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
@@ -0,0 +0,0 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg
|
||||
}
|
||||
|
||||
public static boolean canActivate(BlockState state) {
|
||||
- return SculkSensorBlock.getPhase(state) == SculkSensorPhase.INACTIVE;
|
||||
+ return state.getBlock() instanceof SculkSensorBlock && SculkSensorBlock.getPhase(state) == SculkSensorPhase.INACTIVE; // Paper - Check for a valid type
|
||||
}
|
||||
|
||||
public static void deactivate(Level world, BlockPos pos, BlockState state) {
|
||||
48
patches/server/Collision-API.patch
Normal file
48
patches/server/Collision-API.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Wed, 6 Oct 2021 20:10:44 -0400
|
||||
Subject: [PATCH] Collision API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
|
||||
return this.getHandle().clip(new net.minecraft.world.level.ClipContext(start, end, net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, net.minecraft.world.phys.shapes.CollisionContext.empty())).getType() == net.minecraft.world.phys.HitResult.Type.MISS;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasCollisionsIn(@org.jetbrains.annotations.NotNull org.bukkit.util.BoundingBox boundingBox) {
|
||||
+ net.minecraft.world.phys.AABB aabb = new net.minecraft.world.phys.AABB(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ());
|
||||
+
|
||||
+ return !this.getHandle().noCollision(aabb);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return this.getHandle().noPhysics;
|
||||
}
|
||||
// Paper end - missing entity api
|
||||
+
|
||||
+ // Paper start - Collision API
|
||||
+ @Override
|
||||
+ public boolean collidesAt(@org.jetbrains.annotations.NotNull Location location) {
|
||||
+ net.minecraft.world.phys.AABB aabb = this.getHandle().getBoundingBoxAt(location.getX(), location.getY(), location.getZ());
|
||||
+
|
||||
+ return !this.getHandle().level().noCollision(this.getHandle(), aabb);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean wouldCollideUsing(@org.jetbrains.annotations.NotNull BoundingBox boundingBox) {
|
||||
+ net.minecraft.world.phys.AABB aabb = new AABB(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ());
|
||||
+
|
||||
+ return !this.getHandle().level().noCollision(this.getHandle(), aabb);
|
||||
+ }
|
||||
+ // Paper end - Collision API
|
||||
}
|
||||
39
patches/server/Configurable-Region-Compression-Format.patch
Normal file
39
patches/server/Configurable-Region-Compression-Format.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Astralchroma <astralchroma@proton.me>
|
||||
Date: Thu, 27 Oct 2022 22:19:31 +0100
|
||||
Subject: [PATCH] Configurable Region Compression Format
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
protected final RegionBitmap usedSectors;
|
||||
|
||||
public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException {
|
||||
- this(storageKey, directory, path, RegionFileVersion.getSelected(), dsync);
|
||||
+ this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format
|
||||
}
|
||||
|
||||
public RegionFile(RegionStorageInfo storageKey, Path path, Path directory, RegionFileVersion compressionFormat, boolean dsync) throws IOException {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFileVersion {
|
||||
private final RegionFileVersion.StreamWrapper<InputStream> inputWrapper;
|
||||
private final RegionFileVersion.StreamWrapper<OutputStream> outputWrapper;
|
||||
|
||||
+ // Paper start - Configurable region compression format
|
||||
+ public static RegionFileVersion getCompressionFormat() {
|
||||
+ return switch (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.compressionFormat) {
|
||||
+ case GZIP -> VERSION_GZIP;
|
||||
+ case ZLIB -> VERSION_DEFLATE;
|
||||
+ case NONE -> VERSION_NONE;
|
||||
+ };
|
||||
+ }
|
||||
+ // Paper end - Configurable region compression format
|
||||
private RegionFileVersion(
|
||||
int id,
|
||||
@Nullable String name,
|
||||
19
patches/server/Configurable-Sand-Duping.patch
Normal file
19
patches/server/Configurable-Sand-Duping.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sat, 15 Jun 2024 22:01:39 -0400
|
||||
Subject: [PATCH] Configurable Sand Duping
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class FallingBlockEntity extends Entity {
|
||||
boolean flag = (resourcekey1 == Level.END || resourcekey == Level.END) && resourcekey1 != resourcekey;
|
||||
Entity entity = super.teleport(teleportTarget);
|
||||
|
||||
- this.forceTickAfterTeleportToDuplicate = entity != null && flag;
|
||||
+ this.forceTickAfterTeleportToDuplicate = entity != null && flag && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation; // Paper
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
47
patches/server/Configurable-chat-thread-limit.patch
Normal file
47
patches/server/Configurable-chat-thread-limit.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 18 Sep 2022 06:33:17 +0100
|
||||
Subject: [PATCH] Configurable chat thread limit
|
||||
|
||||
By default, spigot shifts chat over to an unbounded thread pool,
|
||||
on a normal server, this really offers no gains, the creation of a thread
|
||||
on submitting to the pool on these servers eats more time vs just running it in
|
||||
the netty pipeline, however, on servers using plugins which do work in here, there
|
||||
could be some overall benefits to moving this stuff outside of the pipeline.
|
||||
|
||||
In general, this patch does two things:
|
||||
1) Exposes the core size for the pool, this allows for ensuring that a number of threads
|
||||
sit around in the pool, mitigating the need for creating new threads; This IS however
|
||||
caveated, the ThreadPoolExecutor will ONLY create core threads as they're needed, it
|
||||
just won't allow for us to dip back under the # of core threads, this can potentially
|
||||
be mitigated by calling prestartCoreThread, however, I'm not sure if there is much justification
|
||||
for this
|
||||
2) Exposes a max size for the pool, as stated, by default this is unbounded, for most
|
||||
servers limiting the size of the pool is going to have 0 effects given how fast chat
|
||||
is actually processed, this is honestly really just exposed for the misnomers or people
|
||||
who just wanna ensure that this won't grow over a specific size if chat gets stupidly active
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
|
||||
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
|
||||
@@ -0,0 +0,0 @@ public class GlobalConfiguration extends ConfigurationPart {
|
||||
|
||||
@PostProcess
|
||||
private void postProcess() {
|
||||
- // TODO: fill in separate patch
|
||||
+ //noinspection ConstantConditions
|
||||
+ if (net.minecraft.server.MinecraftServer.getServer() == null) return; // In testing env, this will be null here
|
||||
+ int _chatExecutorMaxSize = (this.chatExecutorMaxSize <= 0) ? Integer.MAX_VALUE : this.chatExecutorMaxSize; // This is somewhat dumb, but, this is the default, do we cap this?;
|
||||
+ int _chatExecutorCoreSize = Math.max(this.chatExecutorCoreSize, 0);
|
||||
+
|
||||
+ if (_chatExecutorMaxSize < _chatExecutorCoreSize) {
|
||||
+ _chatExecutorMaxSize = _chatExecutorCoreSize;
|
||||
+ }
|
||||
+
|
||||
+ java.util.concurrent.ThreadPoolExecutor executor = (java.util.concurrent.ThreadPoolExecutor) net.minecraft.server.MinecraftServer.getServer().chatExecutor;
|
||||
+ executor.setCorePoolSize(_chatExecutorCoreSize);
|
||||
+ executor.setMaximumPoolSize(_chatExecutorMaxSize);
|
||||
}
|
||||
}
|
||||
public int maxJoinsPerTick = 5;
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <git@lynxplay.dev>
|
||||
Date: Thu, 13 Jun 2024 17:16:01 +0200
|
||||
Subject: [PATCH] Configurable damage tick when blocking with shield
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ return !io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.skipVanillaDamageTickWhenShieldBlocked; // Paper - this should always return true, however expose an unsupported setting to flip this to false to enable "shield stunning".
|
||||
} else {
|
||||
return true; // Paper - return false ONLY if event was cancelled
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ruViolence <78062896+ruViolence@users.noreply.github.com>
|
||||
Date: Tue, 27 Jun 2023 15:38:18 +0800
|
||||
Subject: [PATCH] Configurable entity tracking range by Y coordinate
|
||||
|
||||
Options to configure entity tracking by Y coordinate, also for each entity category.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
double d0 = (double) Math.min(this.getEffectiveRange(), i * 16);
|
||||
double d1 = vec3d.x * vec3d.x + vec3d.z * vec3d.z;
|
||||
double d2 = d0 * d0;
|
||||
- boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
+ // Paper start - Configurable entity tracking range by Y
|
||||
+ boolean flag = d1 <= d2;
|
||||
+ if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
|
||||
+ double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
+ if (rangeY != -1) {
|
||||
+ double vec3d_dy = player.getY() - this.entity.getY();
|
||||
+ flag = vec3d_dy * vec3d_dy <= rangeY * rangeY;
|
||||
+ }
|
||||
+ }
|
||||
+ flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
||||
+ // Paper end - Configurable entity tracking range by Y
|
||||
|
||||
// CraftBukkit start - respect vanish API
|
||||
if (!player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) {
|
||||
22
patches/server/Configurable-max-block-fluid-ticks.patch
Normal file
22
patches/server/Configurable-max-block-fluid-ticks.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Gero <gecam59@gmail.com>
|
||||
Date: Mon, 19 Feb 2024 17:39:59 +0100
|
||||
Subject: [PATCH] Configurable max block/fluid ticks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (!this.isDebug() && flag) {
|
||||
j = this.getGameTime();
|
||||
gameprofilerfiller.push("blockTicks");
|
||||
- this.blockTicks.tick(j, 65536, this::tickBlock);
|
||||
+ this.blockTicks.tick(j, paperConfig().environment.maxBlockTicks, this::tickBlock); // Paper - configurable max block ticks
|
||||
gameprofilerfiller.popPush("fluidTicks");
|
||||
- this.fluidTicks.tick(j, 65536, this::tickFluid);
|
||||
+ this.fluidTicks.tick(j, paperConfig().environment.maxFluidTicks, this::tickFluid); // Paper - configurable max fluid ticks
|
||||
gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Newwind <support@newwindserver.com>
|
||||
Date: Wed, 7 Aug 2024 13:25:55 +0200
|
||||
Subject: [PATCH] Configuration for horizontal-only item merging
|
||||
|
||||
Most of the visual artifacts that result from having item merge radius above vanilla levels is from items merging vertically,
|
||||
which realistically, only happens when a player is dropping items, or items are dropping from breaking a block.
|
||||
|
||||
Most of the scenarios where item merging makes sense involves the two item entities being on the same Y level. i.e on the ground next to each other.
|
||||
This is even more apparent since paper fixed items being able to merge through blocks.
|
||||
|
||||
This patch allows us to configure items to only merge horizontally, which is what vanilla does.
|
||||
This allows us to have both the reduced number of item entities a high item-merge radius provides,
|
||||
without most of the visual artifacts caused by items merging vertically.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
if (this.isMergable()) {
|
||||
// Spigot start
|
||||
double radius = this.level().spigotConfig.itemMerge;
|
||||
- List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, radius - 0.5D, radius), (entityitem) -> {
|
||||
+ List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D, radius), (entityitem) -> { // Paper - configuration to only merge items horizontally
|
||||
// Spigot end
|
||||
return entityitem != this && entityitem.isMergable();
|
||||
});
|
||||
28
patches/server/Configure-sniffer-egg-hatch-time.patch
Normal file
28
patches/server/Configure-sniffer-egg-hatch-time.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Tue, 27 Jun 2023 13:26:06 +0200
|
||||
Subject: [PATCH] Configure sniffer egg hatch time
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
|
||||
@@ -0,0 +0,0 @@ public class SnifferEggBlock extends Block {
|
||||
|
||||
// Paper start - Call BlockFadeEvent
|
||||
private void rescheduleTick(ServerLevel world, BlockPos pos) {
|
||||
- int baseDelay = hatchBoost(world, pos) ? BOOSTED_HATCH_TIME_TICKS : REGULAR_HATCH_TIME_TICKS;
|
||||
+ int baseDelay = hatchBoost(world, pos) ? world.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : world.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper - Configure sniffer egg hatch time
|
||||
world.scheduleTick(pos, this, (baseDelay / 3) + world.random.nextInt(RANDOM_HATCH_OFFSET_TICKS));
|
||||
// reschedule to avoid being stuck here and behave like the other calls (see #onPlace)
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class SnifferEggBlock extends Block {
|
||||
world.levelEvent(3009, pos, 0);
|
||||
}
|
||||
|
||||
- int i = bl ? 12000 : 24000;
|
||||
+ int i = bl ? world.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : world.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper
|
||||
int j = i / 3;
|
||||
world.gameEvent(GameEvent.BLOCK_PLACE, pos, GameEvent.Context.of(state));
|
||||
world.scheduleTick(pos, this, j + world.random.nextInt(300));
|
||||
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 5 Mar 2023 14:38:21 -0800
|
||||
Subject: [PATCH] Correctly handle ArmorStand invisibility
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
this.getHandle().noPhysics = !gravity;
|
||||
}
|
||||
|
||||
+ // Paper start - Armor Stand has its own invisible field
|
||||
+ @Override
|
||||
+ public void setInvisible(final boolean invisible) {
|
||||
+ this.getHandle().setInvisible(invisible);
|
||||
+ super.setInvisible(invisible);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return !this.getHandle().isInvisible();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user