A bunch of patches
This commit is contained in:
parent
4db250389e
commit
cbf64163ba
21 changed files with 205 additions and 169 deletions
87
patches/server/0574-Add-BlockBreakBlockEvent.patch
Normal file
87
patches/server/0574-Add-BlockBreakBlockEvent.patch
Normal file
|
@ -0,0 +1,87 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 3 Jan 2021 17:58:11 -0800
|
||||
Subject: [PATCH] Add BlockBreakBlockEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
index 43c2b411115d3a8a0e47d3e2277789b2667897af..4d140bd83ca0e1554afad80ec4fc6186188a79d8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -304,6 +304,24 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Add BlockBreakBlockEvent
|
||||
+ public static boolean dropResources(BlockState state, LevelAccessor levelAccessor, BlockPos pos, @Nullable BlockEntity blockEntity, BlockPos source) {
|
||||
+ if (levelAccessor instanceof ServerLevel serverLevel) {
|
||||
+ List<org.bukkit.inventory.ItemStack> items = new java.util.ArrayList<>();
|
||||
+ for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) {
|
||||
+ items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
|
||||
+ }
|
||||
+ io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, pos), org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, source), items);
|
||||
+ event.callEvent();
|
||||
+ for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
|
||||
+ popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
|
||||
+ }
|
||||
+ state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true);
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Add BlockBreakBlockEvent
|
||||
+
|
||||
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
|
||||
if (world instanceof ServerLevel) {
|
||||
Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
index e84501fdce7b94300b1f5d6d20e2db90b175454d..560797552799f7874133fd4aaf6e421609a54dbf 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
@@ -406,7 +406,7 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
iblockdata1 = world.getBlockState(blockposition3);
|
||||
BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
|
||||
|
||||
- dropResources(iblockdata1, world, blockposition3, tileentity);
|
||||
+ dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper - Add BlockBreakBlockEvent
|
||||
world.setBlock(blockposition3, Blocks.AIR.defaultBlockState(), 18);
|
||||
world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1));
|
||||
if (!iblockdata1.is(BlockTags.FIRE)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
||||
index 83dc8bcd9e2b8ecbd32225e4e10aec392ef28325..261e5994d13f8bc30490b86691c80c0a21e7640a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
||||
@@ -316,7 +316,7 @@ public abstract class FlowingFluid extends Fluid {
|
||||
ifluidcontainer.placeLiquid(world, pos, state, fluidState);
|
||||
} else {
|
||||
if (!state.isAir()) {
|
||||
- this.beforeDestroyingBlock(world, pos, state);
|
||||
+ this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper - Add BlockBreakBlockEvent
|
||||
}
|
||||
|
||||
world.setBlock(pos, fluidState.createLegacyBlock(), 3);
|
||||
@@ -324,6 +324,7 @@ public abstract class FlowingFluid extends Fluid {
|
||||
|
||||
}
|
||||
|
||||
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent
|
||||
protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state);
|
||||
|
||||
protected int getSlopeDistance(LevelReader world, BlockPos pos, int i, Direction direction, BlockState state, FlowingFluid.SpreadContext spreadCache) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
||||
index 421f5d9a57d87a87a801213d562ad5fe244e7b65..0a7c05c08bf8c6c331b91e399dc4103a91dc20fe 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
||||
@@ -81,6 +81,13 @@ public abstract class WaterFluid extends FlowingFluid {
|
||||
return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
|
||||
}
|
||||
|
||||
+ // Paper start - Add BlockBreakBlockEvent
|
||||
+ @Override
|
||||
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
|
||||
+ BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
|
||||
+ Block.dropResources(state, world, pos, tileentity, source);
|
||||
+ }
|
||||
+ // Paper end - Add BlockBreakBlockEvent
|
||||
@Override
|
||||
protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state) {
|
||||
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
|
|
@ -0,0 +1,156 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 26 Sep 2021 12:57:28 -0700
|
||||
Subject: [PATCH] Option to prevent data components copy in smithing recipes
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
index fa003ce16020eaab554bfd833ace779c8cefc617..d432b91b4051036d8b339a6418cdbce5c371bc1b 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
@@ -30,8 +30,14 @@ public class SmithingTransformRecipe implements SmithingRecipe {
|
||||
final ItemStack result;
|
||||
@Nullable
|
||||
private PlacementInfo placementInfo;
|
||||
+ final boolean copyDataComponents; // Paper - Option to prevent data components copy
|
||||
|
||||
public SmithingTransformRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition, ItemStack result) {
|
||||
+ this(template, base, addition, result, true);
|
||||
+ }
|
||||
+ public SmithingTransformRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition, ItemStack result, boolean copyDataComponents) {
|
||||
+ this.copyDataComponents = copyDataComponents;
|
||||
+ // Paper end - Option to prevent data components copy
|
||||
this.template = template;
|
||||
this.base = base;
|
||||
this.addition = addition;
|
||||
@@ -41,7 +47,9 @@ public class SmithingTransformRecipe implements SmithingRecipe {
|
||||
public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) {
|
||||
ItemStack itemstack = input.base().transmuteCopy(this.result.getItem(), this.result.getCount());
|
||||
|
||||
+ if (this.copyDataComponents) { // Paper - Option to prevent data components copy
|
||||
itemstack.applyComponents(this.result.getComponentsPatch());
|
||||
+ } // Paper - Option to prevent data components copy
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
@@ -84,7 +92,7 @@ public class SmithingTransformRecipe implements SmithingRecipe {
|
||||
public Recipe toBukkitRecipe(NamespacedKey id) {
|
||||
CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
|
||||
|
||||
- CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
|
||||
+ CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyDataComponents); // Paper - Option to prevent data components copy
|
||||
|
||||
return recipe;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
index a5adce474b2e78233c39cbed367e3d14515923b1..7209170454f10225d7d4a4a107e6717fc18a02ad 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
@@ -35,18 +35,28 @@ public class SmithingTrimRecipe implements SmithingRecipe {
|
||||
final Optional<Ingredient> addition;
|
||||
@Nullable
|
||||
private PlacementInfo placementInfo;
|
||||
+ final boolean copyDataComponents; // Paper - Option to prevent data components copy
|
||||
|
||||
public SmithingTrimRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition) {
|
||||
+ // Paper start - Option to prevent data components copy
|
||||
+ this(template, base, addition, true);
|
||||
+ }
|
||||
+ public SmithingTrimRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition, boolean copyDataComponents) {
|
||||
+ this.copyDataComponents = copyDataComponents;
|
||||
+ // Paper end - Option to prevent data components copy
|
||||
this.template = template;
|
||||
this.base = base;
|
||||
this.addition = addition;
|
||||
}
|
||||
|
||||
public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) {
|
||||
- return SmithingTrimRecipe.applyTrim(registries, input.base(), input.addition(), input.template());
|
||||
+ return SmithingTrimRecipe.applyTrim(registries, input.base(), input.addition(), input.template(), this.copyDataComponents);
|
||||
}
|
||||
|
||||
public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, ItemStack template) {
|
||||
+ return applyTrim(registries, base, addition, template, true);
|
||||
+ }
|
||||
+ public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, ItemStack template, boolean copyDataComponents) {
|
||||
Optional<Holder.Reference<TrimMaterial>> optional = TrimMaterials.getFromIngredient(registries, addition);
|
||||
Optional<Holder.Reference<TrimPattern>> optional1 = TrimPatterns.getFromTemplate(registries, template);
|
||||
|
||||
@@ -56,7 +66,7 @@ public class SmithingTrimRecipe implements SmithingRecipe {
|
||||
if (armortrim != null && armortrim.hasPatternAndMaterial((Holder) optional1.get(), (Holder) optional.get())) {
|
||||
return ItemStack.EMPTY;
|
||||
} else {
|
||||
- ItemStack itemstack3 = base.copyWithCount(1);
|
||||
+ ItemStack itemstack3 = copyDataComponents ? base.copyWithCount(1) : new ItemStack(base.getItem(), 1); // Paper - Option to prevent data components copy
|
||||
|
||||
itemstack3.set(DataComponents.TRIM, new ArmorTrim((Holder) optional.get(), (Holder) optional1.get()));
|
||||
return itemstack3;
|
||||
@@ -107,7 +117,7 @@ public class SmithingTrimRecipe implements SmithingRecipe {
|
||||
// CraftBukkit start
|
||||
@Override
|
||||
public Recipe toBukkitRecipe(NamespacedKey id) {
|
||||
- return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
|
||||
+ return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyDataComponents); // Paper - Option to prevent data components copy
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
index 0dc2be8f502a50f13d8fe860c209ebfa43a931ea..af6c1ccdf2b91b1284daee5552eb44cc9a34cd5f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
@@ -11,12 +11,17 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
|
||||
public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
|
||||
super(key, result, template, base, addition);
|
||||
}
|
||||
+ // Paper start - Option to prevent data components copy
|
||||
+ public CraftSmithingTransformRecipe(NamespacedKey key, ItemStack result, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyDataComponents) {
|
||||
+ super(key, result, template, base, addition, copyDataComponents);
|
||||
+ }
|
||||
+ // Paper end - Option to prevent data components copy
|
||||
|
||||
public static CraftSmithingTransformRecipe fromBukkitRecipe(SmithingTransformRecipe recipe) {
|
||||
if (recipe instanceof CraftSmithingTransformRecipe) {
|
||||
return (CraftSmithingTransformRecipe) recipe;
|
||||
}
|
||||
- CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
|
||||
+ CraftSmithingTransformRecipe ret = new CraftSmithingTransformRecipe(recipe.getKey(), recipe.getResult(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyDataComponents()); // Paper - Option to prevent data components copy
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -24,6 +29,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
|
||||
public void addToCraftingManager() {
|
||||
ItemStack result = this.getResult();
|
||||
|
||||
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false), CraftItemStack.asNMSCopy(result))));
|
||||
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
|
||||
index 202963e2f53b5e7d6fd43c58b27ad49ce009cc3c..fb710aa6dc416a3423345ad5b6e9494507eb0cb4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
|
||||
@@ -11,17 +11,22 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft
|
||||
public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition) {
|
||||
super(key, template, base, addition);
|
||||
}
|
||||
+ // Paper start - Option to prevent data components copy
|
||||
+ public CraftSmithingTrimRecipe(NamespacedKey key, RecipeChoice template, RecipeChoice base, RecipeChoice addition, boolean copyDataComponents) {
|
||||
+ super(key, template, base, addition, copyDataComponents);
|
||||
+ }
|
||||
+ // Paper end - Option to prevent data components copy
|
||||
|
||||
public static CraftSmithingTrimRecipe fromBukkitRecipe(SmithingTrimRecipe recipe) {
|
||||
if (recipe instanceof CraftSmithingTrimRecipe) {
|
||||
return (CraftSmithingTrimRecipe) recipe;
|
||||
}
|
||||
- CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition());
|
||||
+ CraftSmithingTrimRecipe ret = new CraftSmithingTrimRecipe(recipe.getKey(), recipe.getTemplate(), recipe.getBase(), recipe.getAddition(), recipe.willCopyDataComponents()); // Paper - Option to prevent data components copy
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToCraftingManager() {
|
||||
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false))));
|
||||
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftRecipe.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMSOptional(this.getTemplate(), false), this.toNMSOptional(this.getBase(), false), this.toNMSOptional(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
|
||||
}
|
||||
}
|
101
patches/server/0576-More-CommandBlock-API.patch
Normal file
101
patches/server/0576-More-CommandBlock-API.patch
Normal file
|
@ -0,0 +1,101 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 23 Sep 2021 10:40:09 -0700
|
||||
Subject: [PATCH] More CommandBlock API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0463aef1c8be238b00e73907bde927f1522a46ce
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package io.papermc.paper.commands;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import io.papermc.paper.command.CommandBlockHolder;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.minecraft.world.level.BaseCommandBlock;
|
||||
+import org.jspecify.annotations.NullMarked;
|
||||
+import org.jspecify.annotations.Nullable;
|
||||
+
|
||||
+@NullMarked
|
||||
+public interface PaperCommandBlockHolder extends CommandBlockHolder {
|
||||
+
|
||||
+ BaseCommandBlock getCommandBlockHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default Component lastOutput() {
|
||||
+ return PaperAdventure.asAdventure(this.getCommandBlockHandle().getLastOutput());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void lastOutput(final @Nullable Component lastOutput) {
|
||||
+ this.getCommandBlockHandle().setLastOutput(PaperAdventure.asVanilla(lastOutput));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default int getSuccessCount() {
|
||||
+ return this.getCommandBlockHandle().getSuccessCount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void setSuccessCount(final int successCount) {
|
||||
+ this.getCommandBlockHandle().setSuccessCount(successCount);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
|
||||
index f5b0bec4c1164fe7ef6da1f19a6ce9bb3d6864d0..138e6539a7786ded482a24aa88a367da7beaabf9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
|
||||
@@ -6,7 +6,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
|
||||
-public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock {
|
||||
+public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock, io.papermc.paper.commands.PaperCommandBlockHolder {
|
||||
|
||||
public CraftCommandBlock(World world, CommandBlockEntity tileEntity) {
|
||||
super(world, tileEntity);
|
||||
@@ -56,5 +56,10 @@ public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity>
|
||||
public void name(net.kyori.adventure.text.Component name) {
|
||||
getSnapshot().getCommandBlock().setCustomName(name == null ? net.minecraft.network.chat.Component.literal("@") : io.papermc.paper.adventure.PaperAdventure.asVanilla(name));
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
|
||||
+ return getSnapshot().getCommandBlock();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
|
||||
index 9ea1537408ff2d790747b6e5a681d9171a4233ae..f34fa6715e477936097367a7aefd1a2bf87d3d90 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
|
||||
@@ -13,7 +13,7 @@ import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
-public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart {
|
||||
+public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart, io.papermc.paper.commands.PaperCommandBlockHolder {
|
||||
private final PermissibleBase perm = new PermissibleBase(this);
|
||||
|
||||
public CraftMinecartCommand(CraftServer server, MinecartCommandBlock entity) {
|
||||
@@ -64,6 +64,17 @@ public class CraftMinecartCommand extends CraftMinecart implements CommandMineca
|
||||
public net.kyori.adventure.text.@org.jetbrains.annotations.NotNull Component name() {
|
||||
return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getHandle().getCommandBlock().getName());
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
|
||||
+ return getHandle().getCommandBlock();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void lastOutput(net.kyori.adventure.text.Component lastOutput) {
|
||||
+ io.papermc.paper.commands.PaperCommandBlockHolder.super.lastOutput(lastOutput);
|
||||
+ getCommandBlockHandle().onUpdated();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
114
patches/server/0577-Add-missing-team-sidebar-display-slots.patch
Normal file
114
patches/server/0577-Add-missing-team-sidebar-display-slots.patch
Normal file
|
@ -0,0 +1,114 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 1 Oct 2021 08:04:39 -0700
|
||||
Subject: [PATCH] Add missing team sidebar display slots
|
||||
|
||||
== AT ==
|
||||
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations
|
||||
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations toBukkitSlot(Lnet/minecraft/world/scores/DisplaySlot;)Lorg/bukkit/scoreboard/DisplaySlot;
|
||||
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations fromBukkitSlot(Lorg/bukkit/scoreboard/DisplaySlot;)Lnet/minecraft/world/scores/DisplaySlot;
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
|
||||
index b5e0023e431f9fb43c93a3f977144b03545322bb..3ecb1dd1a835efd7026af45562cd3394417130aa 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java
|
||||
@@ -35,6 +35,7 @@ public class FieldRename {
|
||||
}
|
||||
|
||||
return switch (owner) {
|
||||
+ case "org/bukkit/scoreboard/DisplaySlot" -> FieldRename.convertDisplaySlot(from); // Paper - DisplaySlot
|
||||
case "org/bukkit/block/banner/PatternType" -> FieldRename.convertPatternTypeName(apiVersion, from);
|
||||
case "org/bukkit/enchantments/Enchantment" -> FieldRename.convertEnchantmentName(apiVersion, from);
|
||||
case "org/bukkit/block/Biome" -> FieldRename.convertBiomeName(apiVersion, from);
|
||||
@@ -60,6 +61,16 @@ public class FieldRename {
|
||||
//}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - DisplaySlot
|
||||
+ @DoNotReroute
|
||||
+ public static String convertDisplaySlot(final String from) {
|
||||
+ if (from.startsWith("SIDEBAR_") && !from.startsWith("SIDEBAR_TEAM_")) {
|
||||
+ return from.replace("SIDEBAR_", "SIDEBAR_TEAM_");
|
||||
+ }
|
||||
+ return from;
|
||||
+ }
|
||||
+ // Paper end - DisplaySlot
|
||||
+
|
||||
// PatternType
|
||||
private static final FieldRenameData PATTERN_TYPE_DATA = FieldRenameData.Builder.newBuilder()
|
||||
.forVersionsBefore(ApiVersion.FIELD_NAME_PARITY)
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
|
||||
index 73c5ffff70605b32188a9bb5fb6c0ee04cb66efe..711d227f5ee6d63356a94a0567968da48e9f284c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
|
||||
@@ -7,35 +7,22 @@ import org.bukkit.scoreboard.RenderType;
|
||||
|
||||
public final class CraftScoreboardTranslations {
|
||||
static final int MAX_DISPLAY_SLOT = 19;
|
||||
+ @Deprecated // Paper
|
||||
static final ImmutableBiMap<DisplaySlot, String> SLOTS = ImmutableBiMap.<DisplaySlot, String>builder()
|
||||
.put(DisplaySlot.BELOW_NAME, "below_name")
|
||||
.put(DisplaySlot.PLAYER_LIST, "list")
|
||||
.put(DisplaySlot.SIDEBAR, "sidebar")
|
||||
- .put(DisplaySlot.SIDEBAR_BLACK, "sidebar.team.black")
|
||||
- .put(DisplaySlot.SIDEBAR_DARK_BLUE, "sidebar.team.dark_blue")
|
||||
- .put(DisplaySlot.SIDEBAR_DARK_GREEN, "sidebar.team.dark_green")
|
||||
- .put(DisplaySlot.SIDEBAR_DARK_AQUA, "sidebar.team.dark_aqua")
|
||||
- .put(DisplaySlot.SIDEBAR_DARK_RED, "sidebar.team.dark_red")
|
||||
- .put(DisplaySlot.SIDEBAR_DARK_PURPLE, "sidebar.team.dark_purple")
|
||||
- .put(DisplaySlot.SIDEBAR_GOLD, "sidebar.team.gold")
|
||||
- .put(DisplaySlot.SIDEBAR_GRAY, "sidebar.team.gray")
|
||||
- .put(DisplaySlot.SIDEBAR_DARK_GRAY, "sidebar.team.dark_gray")
|
||||
- .put(DisplaySlot.SIDEBAR_BLUE, "sidebar.team.blue")
|
||||
- .put(DisplaySlot.SIDEBAR_GREEN, "sidebar.team.green")
|
||||
- .put(DisplaySlot.SIDEBAR_AQUA, "sidebar.team.aqua")
|
||||
- .put(DisplaySlot.SIDEBAR_RED, "sidebar.team.red")
|
||||
- .put(DisplaySlot.SIDEBAR_LIGHT_PURPLE, "sidebar.team.light_purple")
|
||||
- .put(DisplaySlot.SIDEBAR_YELLOW, "sidebar.team.yellow")
|
||||
- .put(DisplaySlot.SIDEBAR_WHITE, "sidebar.team.white")
|
||||
.buildOrThrow();
|
||||
|
||||
private CraftScoreboardTranslations() {}
|
||||
|
||||
public static DisplaySlot toBukkitSlot(net.minecraft.world.scores.DisplaySlot minecraft) {
|
||||
+ if (true) return DisplaySlot.NAMES.value(minecraft.getSerializedName()); // Paper
|
||||
return CraftScoreboardTranslations.SLOTS.inverse().get(minecraft.getSerializedName());
|
||||
}
|
||||
|
||||
public static net.minecraft.world.scores.DisplaySlot fromBukkitSlot(DisplaySlot slot) {
|
||||
+ if (true) return net.minecraft.world.scores.DisplaySlot.CODEC.byName(slot.getId()); // Paper
|
||||
return net.minecraft.world.scores.DisplaySlot.CODEC.byName(CraftScoreboardTranslations.SLOTS.get(slot));
|
||||
}
|
||||
|
||||
diff --git a/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..345c96bfb6c559b41c2b6682067198a74d35b440
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
|
||||
@@ -0,0 +1,26 @@
|
||||
+package io.papermc.paper.scoreboard;
|
||||
+
|
||||
+import org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations;
|
||||
+import org.bukkit.scoreboard.DisplaySlot;
|
||||
+import org.bukkit.support.environment.Normal;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
+
|
||||
+@Normal
|
||||
+public class DisplaySlotTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void testBukkitToMinecraftDisplaySlots() {
|
||||
+ for (DisplaySlot bukkitSlot : DisplaySlot.values()) {
|
||||
+ assertNotNull(CraftScoreboardTranslations.fromBukkitSlot(bukkitSlot));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testMinecraftToBukkitDisplaySlots() {
|
||||
+ for (net.minecraft.world.scores.DisplaySlot nmsSlot : net.minecraft.world.scores.DisplaySlot.values()) {
|
||||
+ assertNotNull(CraftScoreboardTranslations.toBukkitSlot(nmsSlot));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
47
patches/server/0578-Add-back-EntityPortalExitEvent.patch
Normal file
47
patches/server/0578-Add-back-EntityPortalExitEvent.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: Sun, 16 May 2021 09:39:46 -0700
|
||||
Subject: [PATCH] Add back EntityPortalExitEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index ea1492559653063bb14b934f4d40d910b81d8801..0fd652a60bf9bedda903b734f4fd39153a9c418c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -3491,7 +3491,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (!this.isRemoved()) {
|
||||
// CraftBukkit start
|
||||
PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives());
|
||||
- Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), absolutePosition.xRot());
|
||||
+ Location to = CraftLocation.toBukkit(absolutePosition.position(), teleportTarget.newLevel().getWorld(), absolutePosition.yRot(), this.getXRot()); // Paper - use getXRot (doesn't respect DimensionTransition pitch) // Why?
|
||||
// Paper start - gateway-specific teleport event
|
||||
final EntityTeleportEvent teleEvent;
|
||||
if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level.getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) {
|
||||
@@ -3508,6 +3508,27 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
to = teleEvent.getTo();
|
||||
teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause());
|
||||
}
|
||||
+ // Paper start - Call EntityPortalExitEvent
|
||||
+ if (this.portalProcess != null) { // if in a portal
|
||||
+ CraftEntity bukkitEntity = this.getBukkitEntity();
|
||||
+ Vec3 velocity = teleportTarget.deltaMovement();
|
||||
+ org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent(
|
||||
+ bukkitEntity,
|
||||
+ bukkitEntity.getLocation(), to.clone(),
|
||||
+ bukkitEntity.getVelocity(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(velocity)
|
||||
+ );
|
||||
+ event.callEvent();
|
||||
+
|
||||
+ if (!event.isCancelled() && event.getTo() != null) {
|
||||
+ to = event.getTo().clone();
|
||||
+ velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter());
|
||||
+ }
|
||||
+ teleportTarget = new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), velocity, to.getYaw(), to.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause());
|
||||
+ }
|
||||
+ if (this.isRemoved()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end - Call EntityPortalExitEvent
|
||||
// CraftBukkit end
|
||||
ServerLevel worldserver1 = teleportTarget.newLevel();
|
||||
boolean flag = worldserver1.dimension() != worldserver.dimension();
|
|
@ -0,0 +1,60 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Zacek <dawon@dawon.eu>
|
||||
Date: Mon, 4 Oct 2021 10:16:44 +0200
|
||||
Subject: [PATCH] Add methods to find targets for lightning strikes
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 83f3f05ffe61d77417bce50ce7ae6a8671605e9e..bd99c1ca778270dc80ba83b46dbd178890dd7b53 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -751,6 +751,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
protected BlockPos findLightningTargetAround(BlockPos pos) {
|
||||
+ // Paper start - Add methods to find targets for lightning strikes
|
||||
+ return this.findLightningTargetAround(pos, false);
|
||||
+ }
|
||||
+ public BlockPos findLightningTargetAround(BlockPos pos, boolean returnNullWhenNoTarget) {
|
||||
+ // Paper end - Add methods to find targets for lightning strikes
|
||||
BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
|
||||
Optional<BlockPos> optional = this.findLightningRod(blockposition1);
|
||||
|
||||
@@ -765,6 +770,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (!list.isEmpty()) {
|
||||
return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition();
|
||||
} else {
|
||||
+ if (returnNullWhenNoTarget) return null; // Paper - Add methods to find targets for lightning strikes
|
||||
if (blockposition1.getY() == this.getMinY() - 1) {
|
||||
blockposition1 = blockposition1.above(2);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 1d7865e6de190f7321846bdac52da36a908c7a3d..c2af72ffbe3e58db0b9915f4016811b82313dfdb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -695,6 +695,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
return (LightningStrike) lightning.getBukkitEntity();
|
||||
}
|
||||
|
||||
+ // Paper start - Add methods to find targets for lightning strikes
|
||||
+ @Override
|
||||
+ public Location findLightningRod(Location location) {
|
||||
+ return this.world.findLightningRod(io.papermc.paper.util.MCUtil.toBlockPosition(location))
|
||||
+ .map(blockPos -> io.papermc.paper.util.MCUtil.toLocation(this.world, blockPos)
|
||||
+ // get the actual rod pos
|
||||
+ .subtract(0, 1, 0))
|
||||
+ .orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Location findLightningTarget(Location location) {
|
||||
+ final BlockPos pos = this.world.findLightningTargetAround(io.papermc.paper.util.MCUtil.toBlockPosition(location), true);
|
||||
+ return pos == null ? null : io.papermc.paper.util.MCUtil.toLocation(this.world, pos);
|
||||
+ }
|
||||
+ // Paper end - Add methods to find targets for lightning strikes
|
||||
+
|
||||
@Override
|
||||
public boolean generateTree(Location loc, TreeType type) {
|
||||
return this.generateTree(loc, CraftWorld.rand, type);
|
151
patches/server/0580-Get-entity-default-attributes.patch
Normal file
151
patches/server/0580-Get-entity-default-attributes.patch
Normal file
|
@ -0,0 +1,151 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 20 Aug 2021 13:03:21 -0700
|
||||
Subject: [PATCH] Get entity default attributes
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.ai.attributes.AttributeSupplier getAttributeInstance(Lnet/minecraft/core/Holder;)Lnet/minecraft/world/entity/ai/attributes/AttributeInstance;
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..12135ffeacd648f6bc4d7d327059ea1a7e8c79c4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeInstance.java
|
||||
@@ -0,0 +1,30 @@
|
||||
+package io.papermc.paper.attribute;
|
||||
+
|
||||
+import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
+import org.bukkit.attribute.Attribute;
|
||||
+import org.bukkit.attribute.AttributeModifier;
|
||||
+import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+
|
||||
+public class UnmodifiableAttributeInstance extends CraftAttributeInstance {
|
||||
+
|
||||
+ public UnmodifiableAttributeInstance(AttributeInstance handle, Attribute attribute) {
|
||||
+ super(handle, attribute);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setBaseValue(double d) {
|
||||
+ throw new UnsupportedOperationException("Cannot modify default attributes");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addModifier(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/io/papermc/paper/attribute/UnmodifiableAttributeMap.java b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ec9ebd2d539333293c51b7edfa18f18b066d7e43
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/attribute/UnmodifiableAttributeMap.java
|
||||
@@ -0,0 +1,32 @@
|
||||
+package io.papermc.paper.attribute;
|
||||
+
|
||||
+import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
|
||||
+import org.bukkit.attribute.Attributable;
|
||||
+import org.bukkit.attribute.Attribute;
|
||||
+import org.bukkit.attribute.AttributeInstance;
|
||||
+import org.bukkit.craftbukkit.attribute.CraftAttribute;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class UnmodifiableAttributeMap implements Attributable {
|
||||
+
|
||||
+ private final AttributeSupplier handle;
|
||||
+
|
||||
+ public UnmodifiableAttributeMap(@NotNull AttributeSupplier handle) {
|
||||
+ this.handle = handle;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Nullable AttributeInstance getAttribute(@NotNull Attribute attribute) {
|
||||
+ net.minecraft.core.Holder<net.minecraft.world.entity.ai.attributes.Attribute> nmsAttribute = CraftAttribute.bukkitToMinecraftHolder(attribute);
|
||||
+ if (!this.handle.hasAttribute(nmsAttribute)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return new UnmodifiableAttributeInstance(this.handle.getAttributeInstance(nmsAttribute), attribute);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void registerAttribute(@NotNull Attribute attribute) {
|
||||
+ throw new UnsupportedOperationException("Cannot register new attributes here");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 821f9a2780dc6fa9926fadbec18b51a915767730..d6e9eccd5edce73c9be99e1b9becadf89c593035 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -544,6 +544,18 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
}
|
||||
return CraftMagicNumbers.getItem(itemToBeRepaired.getType()).isValidRepairItem(CraftItemStack.asNMSCopy(itemToBeRepaired), CraftItemStack.asNMSCopy(repairMaterial));
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasDefaultEntityAttributes(NamespacedKey bukkitEntityKey) {
|
||||
+ return net.minecraft.world.entity.ai.attributes.DefaultAttributes.hasSupplier(net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.attribute.Attributable getDefaultEntityAttributes(NamespacedKey bukkitEntityKey) {
|
||||
+ Preconditions.checkArgument(hasDefaultEntityAttributes(bukkitEntityKey), bukkitEntityKey + " doesn't have default attributes");
|
||||
+ 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.get(CraftNamespacedKey.toMinecraft(bukkitEntityKey)));
|
||||
+ return new io.papermc.paper.attribute.UnmodifiableAttributeMap(supplier);
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
diff --git a/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f512d416df883036965ff6c802fd242a4c9c8079
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/attribute/EntityTypeAttributesTest.java
|
||||
@@ -0,0 +1,40 @@
|
||||
+package io.papermc.paper.attribute;
|
||||
+
|
||||
+import org.bukkit.attribute.Attributable;
|
||||
+import org.bukkit.attribute.Attribute;
|
||||
+import org.bukkit.attribute.AttributeInstance;
|
||||
+import org.bukkit.attribute.AttributeModifier;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.support.environment.AllFeatures;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
+import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+@AllFeatures
|
||||
+public class EntityTypeAttributesTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void testIllegalEntity() {
|
||||
+ assertFalse(EntityType.EGG.hasDefaultAttributes());
|
||||
+ assertThrows(IllegalArgumentException.class, EntityType.EGG::getDefaultAttributes);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testLegalEntity() {
|
||||
+ assertTrue(EntityType.ZOMBIE.hasDefaultAttributes());
|
||||
+ EntityType.ZOMBIE.getDefaultAttributes();
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testUnmodifiabilityOfAttributable() {
|
||||
+ Attributable attributable = EntityType.ZOMBIE.getDefaultAttributes();
|
||||
+ assertThrows(UnsupportedOperationException.class, () -> attributable.registerAttribute(Attribute.GENERIC_ATTACK_DAMAGE));
|
||||
+ AttributeInstance instance = attributable.getAttribute(Attribute.GENERIC_FOLLOW_RANGE);
|
||||
+ assertNotNull(instance);
|
||||
+ assertThrows(UnsupportedOperationException.class, () -> instance.addModifier(new AttributeModifier("test", 3, AttributeModifier.Operation.ADD_NUMBER)));
|
||||
+ assertThrows(UnsupportedOperationException.class, () -> instance.setBaseValue(3.2));
|
||||
+ }
|
||||
+}
|
27
patches/server/0581-Left-handed-API.patch
Normal file
27
patches/server/0581-Left-handed-API.patch
Normal file
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 14 Oct 2021 12:36:58 -0500
|
||||
Subject: [PATCH] Left handed API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
index 7cf42f62d91c131b1cab576979f85c58c3cecb3b..e226a99d00c990a4ca4f21b93fcae7a556e01dbb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
@@ -145,6 +145,16 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
public int getMaxHeadPitch() {
|
||||
return getHandle().getMaxHeadXRot();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isLeftHanded() {
|
||||
+ return getHandle().isLeftHanded();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLeftHanded(boolean leftHanded) {
|
||||
+ getHandle().setLeftHanded(leftHanded);
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
// Paper start
|
213
patches/server/0582-Add-more-advancement-API.patch
Normal file
213
patches/server/0582-Add-more-advancement-API.patch
Normal file
|
@ -0,0 +1,213 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: syldium <syldium@mailo.com>
|
||||
Date: Fri, 9 Jul 2021 18:50:40 +0200
|
||||
Subject: [PATCH] Add more advancement API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.advancements.Advancement decorateName(Lnet/minecraft/advancements/DisplayInfo;)Lnet/minecraft/network/chat/Component;
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..adac21ce6db3ff7a56dbcd6bffc02143c2db4046
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java
|
||||
@@ -0,0 +1,69 @@
|
||||
+package io.papermc.paper.advancement;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.minecraft.advancements.Advancement;
|
||||
+import net.minecraft.advancements.AdvancementType;
|
||||
+import net.minecraft.advancements.DisplayInfo;
|
||||
+import org.bukkit.NamespacedKey;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public record PaperAdvancementDisplay(DisplayInfo handle) implements AdvancementDisplay {
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Frame frame() {
|
||||
+ return asPaperFrame(this.handle.getType());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Component title() {
|
||||
+ return PaperAdventure.asAdventure(this.handle.getTitle());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Component description() {
|
||||
+ return PaperAdventure.asAdventure(this.handle.getDescription());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull ItemStack icon() {
|
||||
+ return CraftItemStack.asBukkitCopy(this.handle.getIcon());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean doesShowToast() {
|
||||
+ return this.handle.shouldShowToast();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean doesAnnounceToChat() {
|
||||
+ return this.handle.shouldAnnounceChat();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isHidden() {
|
||||
+ return this.handle.isHidden();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Nullable NamespacedKey backgroundPath() {
|
||||
+ return this.handle.getBackground().map(CraftNamespacedKey::fromMinecraft).orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Component displayName() {
|
||||
+ return PaperAdventure.asAdventure(Advancement.decorateName(java.util.Objects.requireNonNull(this.handle, "cannot build display name for null handle, invalid state")));
|
||||
+ }
|
||||
+
|
||||
+ public static @NotNull Frame asPaperFrame(final @NotNull AdvancementType frameType) {
|
||||
+ return switch (frameType) {
|
||||
+ case TASK -> Frame.TASK;
|
||||
+ case CHALLENGE -> Frame.CHALLENGE;
|
||||
+ case GOAL -> Frame.GOAL;
|
||||
+ };
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/advancements/DisplayInfo.java b/src/main/java/net/minecraft/advancements/DisplayInfo.java
|
||||
index 05de12414a3ad1c8f0f02f7973898dda84b89b82..6581cdbec730d5d184566e7b611369b3c424fecf 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/DisplayInfo.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/DisplayInfo.java
|
||||
@@ -37,6 +37,7 @@ public class DisplayInfo {
|
||||
private final boolean hidden;
|
||||
private float x;
|
||||
private float y;
|
||||
+ public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper - Add more advancement API
|
||||
|
||||
public DisplayInfo(
|
||||
ItemStack icon,
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
|
||||
index 52baf818579a6841b77ff80e42f4f1b9f635ea08..8dfaca2efa0b0bdc97b75aaa83158a2e46361e4e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java
|
||||
@@ -29,12 +29,47 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement {
|
||||
return Collections.unmodifiableCollection(this.handle.value().criteria().keySet());
|
||||
}
|
||||
|
||||
+ // Paper start - Add more advancement API
|
||||
@Override
|
||||
- public AdvancementDisplay getDisplay() {
|
||||
- if (this.handle.value().display().isEmpty()) {
|
||||
- return null;
|
||||
+ public io.papermc.paper.advancement.AdvancementDisplay getDisplay() {
|
||||
+ return this.handle.value().display().map(d -> d.paper).orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ @io.papermc.paper.annotation.DoNotUse
|
||||
+ public AdvancementDisplay getDisplay0() { // May be called by plugins via Commodore
|
||||
+ return this.handle.value().display().map(CraftAdvancementDisplay::new).orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.Component displayName() {
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.asAdventure(net.minecraft.advancements.Advancement.name(this.handle));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.advancement.Advancement getParent() {
|
||||
+ return this.handle.value().parent()
|
||||
+ .map(net.minecraft.server.MinecraftServer.getServer().getAdvancements()::get)
|
||||
+ .map(AdvancementHolder::toBukkit)
|
||||
+ .orElse(null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<org.bukkit.advancement.Advancement> getChildren() {
|
||||
+ final com.google.common.collect.ImmutableList.Builder<org.bukkit.advancement.Advancement> children = com.google.common.collect.ImmutableList.<org.bukkit.advancement.Advancement>builder();
|
||||
+ final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle);
|
||||
+ if (advancementNode != null) {
|
||||
+ for (final net.minecraft.advancements.AdvancementNode child : advancementNode.children()) {
|
||||
+ children.add(child.holder().toBukkit());
|
||||
+ }
|
||||
}
|
||||
+ return children.build();
|
||||
+ }
|
||||
|
||||
- return new CraftAdvancementDisplay(this.handle.value().display().get());
|
||||
+ @Override
|
||||
+ public org.bukkit.advancement.Advancement getRoot() {
|
||||
+ final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle);
|
||||
+ return java.util.Objects.requireNonNull(advancementNode, "could not find internal advancement node for advancement " + this.handle.id()).root().holder().toBukkit();
|
||||
}
|
||||
+ // Paper end - Add more advancement API
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
|
||||
index 8ca86852319d7463f60832bc98b825b0b4325995..62ada73302c6b3ce3fb2dcc8c31a1d9c0ac4fd09 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java
|
||||
@@ -6,6 +6,7 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
+@Deprecated // Paper
|
||||
public class CraftAdvancementDisplay implements org.bukkit.advancement.AdvancementDisplay {
|
||||
|
||||
private final DisplayInfo handle;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
index 760f56d36f0e4a74b58628408a286a499d6664ec..34e41ea24e1673109f14153a1a0c8e794fed20bb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
@@ -453,6 +453,11 @@ public class Commodore {
|
||||
super.visitMethodInsn(opcode, owner, name, "()Lcom/destroystokyo/paper/profile/PlayerProfile;", itf);
|
||||
return;
|
||||
}
|
||||
+ if (owner.equals("org/bukkit/advancement/Advancement") && name.equals("getDisplay") && desc.endsWith(")Lorg/bukkit/advancement/AdvancementDisplay;")) {
|
||||
+ super.visitTypeInsn(Opcodes.CHECKCAST, runtimeCbPkgPrefix() + "advancement/CraftAdvancement");
|
||||
+ super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, runtimeCbPkgPrefix() + "advancement/CraftAdvancement", "getDisplay0", desc, false);
|
||||
+ return;
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
if (modern) {
|
||||
diff --git a/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6fe9c10ffd1dd5244ead05642609794623054cce
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java
|
||||
@@ -0,0 +1,26 @@
|
||||
+package io.papermc.paper.advancement;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.kyori.adventure.text.format.TextColor;
|
||||
+import net.minecraft.advancements.AdvancementType;
|
||||
+import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
+import org.bukkit.support.environment.Normal;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+
|
||||
+@Normal
|
||||
+public class AdvancementFrameTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void test() {
|
||||
+ for (final AdvancementType advancementType : AdvancementType.values()) {
|
||||
+ final TextColor expectedColor = PaperAdventure.asAdventure(advancementType.getChatColor());
|
||||
+ final String expectedTranslationKey = ((TranslatableContents) advancementType.getDisplayName().getContents()).getKey();
|
||||
+ final var frame = PaperAdvancementDisplay.asPaperFrame(advancementType);
|
||||
+ assertEquals(expectedTranslationKey, frame.translationKey(), "The translation keys should be the same");
|
||||
+ assertEquals(expectedColor, frame.color(), "The frame colors should be the same");
|
||||
+ assertEquals(advancementType.getSerializedName(), AdvancementDisplay.Frame.NAMES.key(frame));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
58
patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch
Normal file
58
patches/server/0583-Add-ItemFactory-getSpawnEgg-API.patch
Normal file
|
@ -0,0 +1,58 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 14 Oct 2021 12:09:39 -0500
|
||||
Subject: [PATCH] Add ItemFactory#getSpawnEgg API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 19c1faecb398f5b91dd04827b66038c352e5b4e4..237df8b37ee8cf5b15e8e6d30fa3b51ef394434d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -9,6 +9,7 @@ import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tags.EnchantmentTags;
|
||||
import net.minecraft.util.RandomSource;
|
||||
@@ -289,4 +290,19 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
new net.md_5.bungee.api.chat.TextComponent(customName));
|
||||
}
|
||||
// Paper end - bungee hover events
|
||||
+
|
||||
+ // Paper start - old getSpawnEgg API
|
||||
+ // @Override // used to override, upstream added conflicting method, is called via Commodore now
|
||||
+ @Deprecated
|
||||
+ public ItemStack getSpawnEgg0(org.bukkit.entity.EntityType type) {
|
||||
+ if (type == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ String typeId = type.getKey().toString();
|
||||
+ net.minecraft.resources.ResourceLocation typeKey = ResourceLocation.parse(typeId);
|
||||
+ net.minecraft.world.entity.EntityType<?> nmsType = net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(typeKey);
|
||||
+ net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType);
|
||||
+ return eggItem == null ? null : new net.minecraft.world.item.ItemStack(eggItem).asBukkitMirror();
|
||||
+ }
|
||||
+ // Paper end - old getSpawnEgg API
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
index 34e41ea24e1673109f14153a1a0c8e794fed20bb..63d4ffe93a445abf3c766d4f1f8fbf4a412a2a03 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
@@ -460,6 +460,15 @@ public class Commodore {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - ItemFactory#getSpawnEgg (paper had original method that returned ItemStack, upstream added identical but returned Material)
|
||||
+ if (owner.equals("org/bukkit/inventory/ItemFactory") && name.equals("getSpawnEgg") && desc.equals("(Lorg/bukkit/entity/EntityType;)Lorg/bukkit/inventory/ItemStack;")) {
|
||||
+ super.visitInsn(Opcodes.SWAP); // has 1 param, this moves the owner instance to the top for the checkcast
|
||||
+ super.visitTypeInsn(Opcodes.CHECKCAST, runtimeCbPkgPrefix() + "inventory/CraftItemFactory");
|
||||
+ super.visitInsn(Opcodes.SWAP); // moves param back to the the top of stack
|
||||
+ super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, runtimeCbPkgPrefix() + "inventory/CraftItemFactory", "getSpawnEgg0", desc, false);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - ItemFactory#getSpawnEgg
|
||||
if (modern) {
|
||||
if (owner.equals("org/bukkit/Material") || (instantiatedMethodType != null && instantiatedMethodType.getDescriptor().startsWith("(Lorg/bukkit/Material;)"))) {
|
||||
switch (name) {
|
101
patches/server/0584-Add-critical-damage-API.patch
Normal file
101
patches/server/0584-Add-critical-damage-API.patch
Normal file
|
@ -0,0 +1,101 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: dodison <kacpik@mapik.eu>
|
||||
Date: Mon, 26 Jul 2021 17:32:36 +0200
|
||||
Subject: [PATCH] Add critical damage API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
|
||||
index c1d121d83591ca1b5bf9d9406c9622b4f24eafef..aee26dd78953ff43306aaa64161f5b9edcdd4b83 100644
|
||||
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
|
||||
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
|
||||
@@ -276,4 +276,18 @@ public class DamageSource {
|
||||
public Holder<DamageType> typeHolder() {
|
||||
return this.type;
|
||||
}
|
||||
+
|
||||
+ // Paper start - add critical damage API
|
||||
+ private boolean critical;
|
||||
+ public boolean isCritical() {
|
||||
+ return this.critical;
|
||||
+ }
|
||||
+ public DamageSource critical() {
|
||||
+ return this.critical(true);
|
||||
+ }
|
||||
+ public DamageSource critical(boolean critical) {
|
||||
+ this.critical = critical;
|
||||
+ return this;
|
||||
+ }
|
||||
+ // Paper end - add critical damage 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 57850f16a681af4fc302895c7608247675b44ab4..68a6b1508ce4544fe8b18746d440944d41a2fe5b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1258,6 +1258,7 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
|
||||
if (flag2) {
|
||||
+ damagesource = damagesource.critical(true); // Paper start - critical damage API
|
||||
f *= 1.5F;
|
||||
}
|
||||
|
||||
@@ -1317,7 +1318,7 @@ public abstract class Player extends LivingEntity {
|
||||
float f7 = this.getEnchantedDamage(entityliving2, f6, damagesource) * f2;
|
||||
|
||||
// CraftBukkit start - Only apply knockback if the damage hits
|
||||
- if (!entityliving2.hurtServer((ServerLevel) this.level(), this.damageSources().playerAttack(this).sweep(), f7)) {
|
||||
+ if (!entityliving2.hurtServer((ServerLevel) this.level(), this.damageSources().playerAttack(this).sweep().critical(flag2), f7)) { // Paper - add critical damage API
|
||||
continue;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index bc167c21f82ad09952f6cdbf1016523062890f8b..44bcb1117cfa4d66c500011489ae193a0d1e7d78 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -450,6 +450,7 @@ public abstract class AbstractArrow extends Projectile {
|
||||
entityliving.setLastHurtMob(entity);
|
||||
}
|
||||
|
||||
+ if (this.isCritArrow()) damagesource = damagesource.critical(); // Paper - add critical damage API
|
||||
boolean flag = entity.getType() == EntityType.ENDERMAN;
|
||||
int k = entity.getRemainingFireTicks();
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 83648509a5b90daa4b072650cbc3215b64659a86..376563ea6990aef558a34e4f5889125412b734df 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1078,7 +1078,7 @@ populateFields(victim, event); // Paper - make cancellable
|
||||
return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
|
||||
}
|
||||
DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
|
||||
- return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
|
||||
+ return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
|
||||
} else if (damager != null || source.getDirectEntity() != null) {
|
||||
DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK;
|
||||
|
||||
@@ -1104,7 +1104,7 @@ populateFields(victim, event); // Paper - make cancellable
|
||||
cause = DamageCause.MAGIC;
|
||||
}
|
||||
|
||||
- return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
|
||||
+ return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
|
||||
} else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) {
|
||||
return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
|
||||
} else if (source.is(DamageTypes.LAVA)) {
|
||||
@@ -1164,13 +1164,13 @@ populateFields(victim, event); // Paper - make cancellable
|
||||
cause = DamageCause.CUSTOM;
|
||||
}
|
||||
|
||||
- return CraftEventFactory.callEntityDamageEvent((Entity) null, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
|
||||
+ return CraftEventFactory.callEntityDamageEvent((Entity) null, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
|
||||
}
|
||||
|
||||
- private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) {
|
||||
+ private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled, boolean critical) { // Paper - add critical damage API
|
||||
EntityDamageEvent event;
|
||||
if (damager != null) {
|
||||
- event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
|
||||
+ event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, critical);
|
||||
} else {
|
||||
event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
|
||||
}
|
83
patches/server/0585-Fix-issues-with-mob-conversion.patch
Normal file
83
patches/server/0585-Fix-issues-with-mob-conversion.patch
Normal file
|
@ -0,0 +1,83 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 24 Oct 2021 20:29:45 -0700
|
||||
Subject: [PATCH] Fix issues with mob conversion
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
|
||||
index 6f6454bcec7e0d1cefbf818fc2fc6eb90adeec83..6d176ab1eee654411918e0ee64306d280c7ae816 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Skeleton.java
|
||||
@@ -16,6 +16,8 @@ import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.Level;
|
||||
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
+import org.bukkit.event.entity.EntityTransformEvent;
|
||||
|
||||
public class Skeleton extends AbstractSkeleton {
|
||||
|
||||
@@ -94,12 +96,19 @@ public class Skeleton extends AbstractSkeleton {
|
||||
}
|
||||
|
||||
protected void doFreezeConversion() {
|
||||
- this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), (entityskeletonstray) -> {
|
||||
+ final Stray stray = this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), (entityskeletonstray) -> { // Paper - Fix issues with mob conversion; reset conversion time to prevent event spam
|
||||
if (!this.isSilent()) {
|
||||
this.level().levelEvent((Player) null, 1048, this.blockPosition(), 0);
|
||||
}
|
||||
|
||||
- }, org.bukkit.event.entity.EntityTransformEvent.TransformReason.FROZEN, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.FROZEN); // CraftBukkit - add spawn and transform reasons
|
||||
+ }, EntityTransformEvent.TransformReason.FROZEN, CreatureSpawnEvent.SpawnReason.FROZEN);// CraftBukkit - add spawn and transform reasons
|
||||
+
|
||||
+ // Paper start - Fix issues with mob conversion; reset conversion time to prevent event spam
|
||||
+ if (stray == null) {
|
||||
+ this.conversionTime = 300;
|
||||
+ }
|
||||
+ // Paper end - Fix issues with mob conversion
|
||||
+
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
|
||||
index d51acb788803048c0eacd762a2fd311115ac0970..6ea90e54759dbeab025e0a1896ee834ea9986427 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
|
||||
@@ -260,9 +260,15 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
|
||||
}
|
||||
|
||||
private void finishConversion() {
|
||||
- this.convertTo(
|
||||
+ net.minecraft.world.entity.Entity converted = this.convertTo( // Paper - Fix issues with mob conversion; reset to prevent event spam
|
||||
EntityType.ZOGLIN, ConversionParams.single(this, true, false), zoglin -> zoglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0))
|
||||
);
|
||||
+
|
||||
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
|
||||
+ if (converted == null) {
|
||||
+ this.timeInOverworld = 0;
|
||||
+ }
|
||||
+ // Paper end - Fix issues with mob conversion
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
|
||||
index e2075fb22596b6dc4dbbb9c20c91c63f0ddb7ba7..e3a8aa0ae0d1fa6f2b697e20464224f8b8c6b8ea 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java
|
||||
@@ -100,9 +100,15 @@ public abstract class AbstractPiglin extends Monster {
|
||||
}
|
||||
|
||||
protected void finishConversion(ServerLevel world) {
|
||||
- this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), (entitypigzombie) -> {
|
||||
+ net.minecraft.world.entity.Entity converted = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, true, true), (entitypigzombie) -> { // Paper - Fix issues with mob conversion; reset to prevent event spam
|
||||
entitypigzombie.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0));
|
||||
}, org.bukkit.event.entity.EntityTransformEvent.TransformReason.PIGLIN_ZOMBIFIED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.PIGLIN_ZOMBIFIED); // CraftBukkit - add spawn and transform reasons
|
||||
+
|
||||
+ // Paper start - Fix issues with mob conversion; reset to prevent event spam
|
||||
+ if (converted == null) {
|
||||
+ this.timeInOverworld = 0;
|
||||
+ }
|
||||
+ // Paper end - Fix issues with mob conversion
|
||||
}
|
||||
|
||||
public boolean isAdult() {
|
|
@ -0,0 +1,56 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 4 Nov 2021 11:50:40 -0700
|
||||
Subject: [PATCH] Add hasCollision methods to various places
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.level.block.state.BlockBehaviour hasCollision
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index 9c8aac69f01db647e20d49d272ccc107a7edceaf..d5b495b5a3ca7f4411d1a700f7149042a16509f1 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -457,6 +457,11 @@ public class CraftBlock implements Block {
|
||||
public boolean isSolid() {
|
||||
return this.getNMS().blocksMotion();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCollidable() {
|
||||
+ return getNMS().getBlock().hasCollision;
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
index 1002123cd0c6f57cecc4e80f5f21cc6ff5886d37..e96023b71845526383288917e8d7c5759a4c0e9b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
|
||||
@@ -341,4 +341,11 @@ public class CraftBlockState implements BlockState {
|
||||
public BlockState copy(Location location) {
|
||||
return new CraftBlockState(this, location);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isCollidable() {
|
||||
+ return this.data.getBlock().hasCollision;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java
|
||||
index 2d8a509446c0ed0d7358f10f67ef29c4df683696..785d3fe4929e008d4150f3ecab258fd5b6d7cdaf 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java
|
||||
@@ -241,4 +241,11 @@ public class CraftBlockType<B extends BlockData> implements BlockType.Typed<B>,
|
||||
return this.block.getDescriptionId();
|
||||
}
|
||||
// Paper end - add Translatable
|
||||
+
|
||||
+ // Paper start - hasCollision API
|
||||
+ @Override
|
||||
+ public boolean hasCollision() {
|
||||
+ return this.block.hasCollision;
|
||||
+ }
|
||||
+ // Paper end - hasCollision API
|
||||
}
|
42
patches/server/0587-Goat-ram-API.patch
Normal file
42
patches/server/0587-Goat-ram-API.patch
Normal file
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Seggan <segganew@gmail.com>
|
||||
Date: Thu, 5 Aug 2021 13:10:27 -0400
|
||||
Subject: [PATCH] Goat ram API
|
||||
|
||||
|
||||
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 cccf0084d273eaded91abe249d39a843f11d351b..14e02f9b0169db8388c515a68315ad5cc3f13d22 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
|
||||
@@ -395,4 +395,15 @@ public class Goat extends Animal {
|
||||
public static boolean checkGoatSpawnRules(EntityType<? extends Animal> entityType, LevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) {
|
||||
return world.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos);
|
||||
}
|
||||
+
|
||||
+ // Paper start - Goat ram API
|
||||
+ public void ram(net.minecraft.world.entity.LivingEntity entity) {
|
||||
+ Brain<Goat> brain = this.getBrain();
|
||||
+ brain.setMemory(MemoryModuleType.RAM_TARGET, entity.position());
|
||||
+ brain.eraseMemory(MemoryModuleType.RAM_COOLDOWN_TICKS);
|
||||
+ brain.eraseMemory(MemoryModuleType.BREED_TARGET);
|
||||
+ brain.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
|
||||
+ brain.setActiveActivityIfPossible(net.minecraft.world.entity.schedule.Activity.RAM);
|
||||
+ }
|
||||
+ // Paper end - Goat ram API
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
|
||||
index 65fcb36e849da6949c123a6f3672b485036f368e..2c21de478bff9cdf13ba46cd041831d54c11e924 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java
|
||||
@@ -48,4 +48,11 @@ public class CraftGoat extends CraftAnimals implements Goat {
|
||||
public void setScreaming(boolean screaming) {
|
||||
this.getHandle().setScreamingGoat(screaming);
|
||||
}
|
||||
+
|
||||
+ // Paper start - Goat ram API
|
||||
+ @Override
|
||||
+ public void ram(@org.jetbrains.annotations.NotNull org.bukkit.entity.LivingEntity entity) {
|
||||
+ this.getHandle().ram(((CraftLivingEntity) entity).getHandle());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: booky10 <boooky10@gmail.com>
|
||||
Date: Fri, 5 Nov 2021 21:01:36 +0100
|
||||
Subject: [PATCH] Add API for resetting a single score
|
||||
|
||||
It was only possible to reset all scores for a specific entry, instead of resetting only specific scores.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
index 29e24461e29e4cf3d31497198debcde18761ad73..ceb1a39c02c3cfa7632a0fdca414c7046888fcb1 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
|
||||
@@ -66,4 +66,12 @@ final class CraftScore implements Score {
|
||||
public CraftScoreboard getScoreboard() {
|
||||
return this.objective.getScoreboard();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void resetScore() {
|
||||
+ Scoreboard board = this.objective.checkState().board;
|
||||
+ board.resetSinglePlayerScore(entry, this.objective.getHandle());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
90
patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch
Normal file
90
patches/server/0589-Add-Raw-Byte-Entity-Serialization.patch
Normal file
|
@ -0,0 +1,90 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Sun, 24 Oct 2021 16:20:31 -0400
|
||||
Subject: [PATCH] Add Raw Byte Entity Serialization
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0fd652a60bf9bedda903b734f4fd39153a9c418c..92c743a354e95c8e12fc21673ee172aed07fe1fb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2260,6 +2260,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Entity serialization api
|
||||
+ public boolean serializeEntity(CompoundTag compound) {
|
||||
+ List<Entity> pass = new java.util.ArrayList<>(this.getPassengers());
|
||||
+ this.passengers = ImmutableList.of();
|
||||
+ boolean result = save(compound);
|
||||
+ this.passengers = ImmutableList.copyOf(pass);
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Entity serialization api
|
||||
public boolean save(CompoundTag nbt) {
|
||||
return this.isPassenger() ? false : this.saveAsPassenger(nbt);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0c1c9033646dedcf1d11dee74d6965683adadf0a..1ed01978611cddb2558e441863dadc468bc07c3d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -1088,6 +1088,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
// Paper end - tracked players API
|
||||
|
||||
+ // Paper start - raw entity serialization API
|
||||
+ @Override
|
||||
+ public boolean spawnAt(Location location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ Preconditions.checkNotNull(location, "location cannot be null");
|
||||
+ Preconditions.checkNotNull(reason, "reason cannot be null");
|
||||
+ this.entity.setLevel(((CraftWorld) location.getWorld()).getHandle());
|
||||
+ this.entity.setPos(location.getX(), location.getY(), location.getZ());
|
||||
+ this.entity.setRot(location.getYaw(), location.getPitch());
|
||||
+ return !this.entity.valid && this.entity.level().addFreshEntity(this.entity, reason);
|
||||
+ }
|
||||
+ // Paper end - raw entity serialization API
|
||||
+
|
||||
// Paper start - missing entity api
|
||||
@Override
|
||||
public boolean isInvisible() { // Paper - moved up from LivingEntity
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index d6e9eccd5edce73c9be99e1b9becadf89c593035..98bbbdbf8fd067df936655334ad5ea25ec07daef 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -494,7 +494,33 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow());
|
||||
}
|
||||
|
||||
- private byte[] serializeNbtToBytes(CompoundTag compound) {
|
||||
+ @Override
|
||||
+ public byte[] serializeEntity(org.bukkit.entity.Entity entity) {
|
||||
+ Preconditions.checkNotNull(entity, "null cannot be serialized");
|
||||
+ Preconditions.checkArgument(entity instanceof org.bukkit.craftbukkit.entity.CraftEntity, "only CraftEntities can be serialized");
|
||||
+
|
||||
+ net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag();
|
||||
+ ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().serializeEntity(compound);
|
||||
+ return serializeNbtToBytes(compound);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Entity deserializeEntity(byte[] data, org.bukkit.World world, boolean preserveUUID) {
|
||||
+ Preconditions.checkNotNull(data, "null cannot be deserialized");
|
||||
+ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
|
||||
+
|
||||
+ net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data);
|
||||
+ int dataVersion = compound.getInt("DataVersion");
|
||||
+ compound = (net.minecraft.nbt.CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ENTITY, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, this.getDataVersion()).getValue();
|
||||
+ if (!preserveUUID) {
|
||||
+ // Generate a new UUID so we don't have to worry about deserializing the same entity twice
|
||||
+ compound.remove("UUID");
|
||||
+ }
|
||||
+ return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle())
|
||||
+ .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+ private byte[] serializeNbtToBytes(net.minecraft.nbt.CompoundTag compound) {
|
||||
compound.putInt("DataVersion", getDataVersion());
|
||||
java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
|
||||
try {
|
79
patches/server/0590-Vanilla-command-permission-fixes.patch
Normal file
79
patches/server/0590-Vanilla-command-permission-fixes.patch
Normal file
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Wed, 25 Aug 2021 13:19:53 -0700
|
||||
Subject: [PATCH] Vanilla command permission fixes
|
||||
|
||||
Fixes permission checks for vanilla commands which don't have a
|
||||
requirement, as well as for namespaced vanilla commands.
|
||||
|
||||
== AT ==
|
||||
public-f com.mojang.brigadier.tree.CommandNode requirement
|
||||
|
||||
diff --git a/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java b/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java
|
||||
index 899008b2980d13f1be6280cd8cb959c53a29bebf..d5f7da3502575f6847f3c22ab0e942848a7c6031 100644
|
||||
--- a/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java
|
||||
+++ b/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java
|
||||
@@ -14,9 +14,17 @@ import java.util.Collections;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public abstract class ArgumentBuilder<S, T extends ArgumentBuilder<S, T>> {
|
||||
+ // Paper start - Vanilla command permission fixes
|
||||
+ private static final Predicate<Object> DEFAULT_REQUIREMENT = s -> true;
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ public static <S> Predicate<S> defaultRequirement() {
|
||||
+ return (Predicate<S>) DEFAULT_REQUIREMENT;
|
||||
+ }
|
||||
+ // Paper end - Vanilla command permission fixes
|
||||
private final RootCommandNode<S> arguments = new RootCommandNode<>();
|
||||
private Command<S> command;
|
||||
- private Predicate<S> requirement = s -> true;
|
||||
+ private Predicate<S> requirement = defaultRequirement(); // Paper - Vanilla command permission fixes
|
||||
private CommandNode<S> target;
|
||||
private RedirectModifier<S> modifier = null;
|
||||
private boolean forks;
|
||||
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
|
||||
index 7acd7f60327106d55e8f48247650bc0064dd1b58..bee79fab7f8195e14f6bd22d9cd59bfc704bf903 100644
|
||||
--- a/src/main/java/net/minecraft/commands/Commands.java
|
||||
+++ b/src/main/java/net/minecraft/commands/Commands.java
|
||||
@@ -261,6 +261,13 @@ public class Commands {
|
||||
PublishCommand.register(this.dispatcher);
|
||||
}
|
||||
|
||||
+ // Paper start - Vanilla command permission fixes
|
||||
+ for (final CommandNode<CommandSourceStack> node : this.dispatcher.getRoot().getChildren()) {
|
||||
+ if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.<CommandSourceStack>defaultRequirement()) {
|
||||
+ node.requirement = stack -> stack.source == CommandSource.NULL || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Vanilla command permission fixes
|
||||
// CraftBukkit start
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
index 87c93ee9bbbfff785b7b6a1f0c4b932e36362943..4e81c26fdbd089961b2577168c716bf29d504d40 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
@@ -86,7 +86,21 @@ public final class VanillaCommandWrapper extends BukkitCommand {
|
||||
}
|
||||
|
||||
public static String getPermission(CommandNode<CommandSourceStack> vanillaCommand) {
|
||||
- return "minecraft.command." + ((vanillaCommand.getRedirect() == null) ? vanillaCommand.getName() : vanillaCommand.getRedirect().getName());
|
||||
+ // Paper start - Vanilla command permission fixes
|
||||
+ while (vanillaCommand.getRedirect() != null) {
|
||||
+ vanillaCommand = vanillaCommand.getRedirect();
|
||||
+ }
|
||||
+ final String commandName = vanillaCommand.getName();
|
||||
+ return "minecraft.command." + stripDefaultNamespace(commandName);
|
||||
+ }
|
||||
+
|
||||
+ private static String stripDefaultNamespace(final String maybeNamespaced) {
|
||||
+ final String prefix = "minecraft:";
|
||||
+ if (maybeNamespaced.startsWith(prefix)) {
|
||||
+ return maybeNamespaced.substring(prefix.length());
|
||||
+ }
|
||||
+ return maybeNamespaced;
|
||||
+ // Paper end - Vanilla command permission fixes
|
||||
}
|
||||
|
||||
private String toDispatcher(String[] args, String name) {
|
|
@ -0,0 +1,68 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Thu, 11 Mar 2021 03:03:32 -0800
|
||||
Subject: [PATCH] Do not run close logic for inventories on chunk unload
|
||||
|
||||
Still call the event and change the active container though. We
|
||||
want to avoid close logic because it's possible to load the
|
||||
chunk through it. This should also be OK from a leak prevention/
|
||||
state desync POV because the TE is getting unloaded anyways.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index bd99c1ca778270dc80ba83b46dbd178890dd7b53..cf2b5de61eae020513c50e0903637c55b711fd1b 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1269,9 +1269,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Spigot Start
|
||||
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
|
||||
if (tileentity instanceof net.minecraft.world.Container) {
|
||||
+ // Paper start - this area looks like it can load chunks, change the behavior
|
||||
+ // chests for example can apply physics to the world
|
||||
+ // so instead we just change the active container and call the event
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
|
||||
- h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
|
||||
+ ((org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
|
||||
}
|
||||
+ // Paper end - this area looks like it can load chunks, change the behavior
|
||||
}
|
||||
}
|
||||
// Spigot End
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index c680b311760601bb539d685bceddba6712d141d4..d2fbbdbb451d6c54d847b4ba125397ad41c4f7b4 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1983,6 +1983,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
|
||||
this.doCloseContainer();
|
||||
}
|
||||
+ // Paper start - special close for unloaded inventory
|
||||
+ @Override
|
||||
+ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // copied from above
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
|
||||
+ // Paper end
|
||||
+ // copied from below
|
||||
+ this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
|
||||
+ this.containerMenu = this.inventoryMenu;
|
||||
+ // do not run close logic
|
||||
+ }
|
||||
+ // Paper end - special close for unloaded inventory
|
||||
|
||||
@Override
|
||||
public void doCloseContainer() {
|
||||
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 68a6b1508ce4544fe8b18746d440944d41a2fe5b..b8edbd23d547d7189ec64c5d3a8cd1d51859ce23 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -544,6 +544,11 @@ public abstract class Player extends LivingEntity {
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
// Paper end - Inventory close reason
|
||||
+ // Paper start - special close for unloaded inventory
|
||||
+ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ this.containerMenu = this.inventoryMenu;
|
||||
+ }
|
||||
+ // Paper end - special close for unloaded inventory
|
||||
|
||||
public void closeContainer() {
|
||||
this.containerMenu = this.inventoryMenu;
|
126
patches/server/0592-Fix-GameProfileCache-concurrency.patch
Normal file
126
patches/server/0592-Fix-GameProfileCache-concurrency.patch
Normal file
|
@ -0,0 +1,126 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sat, 11 Jul 2020 05:09:28 -0700
|
||||
Subject: [PATCH] Fix GameProfileCache concurrency
|
||||
|
||||
Separate lookup and state access locks prevent lookups
|
||||
from stalling simple state access/write calls
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index 774d81c702edb76a2f6184d4dc53687de6734a79..34b4166adfae8ff7d1eb73d56a72931b005330a7 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -60,6 +60,11 @@ public class GameProfileCache {
|
||||
@Nullable
|
||||
private Executor executor;
|
||||
|
||||
+ // Paper start - Fix GameProfileCache concurrency
|
||||
+ protected final java.util.concurrent.locks.ReentrantLock stateLock = new java.util.concurrent.locks.ReentrantLock();
|
||||
+ protected final java.util.concurrent.locks.ReentrantLock lookupLock = new java.util.concurrent.locks.ReentrantLock();
|
||||
+ // Paper end - Fix GameProfileCache concurrency
|
||||
+
|
||||
public GameProfileCache(GameProfileRepository profileRepository, File cacheFile) {
|
||||
this.profileRepository = profileRepository;
|
||||
this.file = cacheFile;
|
||||
@@ -67,11 +72,13 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
private void safeAdd(GameProfileCache.GameProfileInfo entry) {
|
||||
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
GameProfile gameprofile = entry.getProfile();
|
||||
|
||||
entry.setLastAccess(this.getNextOperation());
|
||||
this.profilesByName.put(gameprofile.getName().toLowerCase(Locale.ROOT), entry);
|
||||
this.profilesByUUID.put(gameprofile.getId(), entry);
|
||||
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
|
||||
}
|
||||
|
||||
private static Optional<GameProfile> lookupGameProfile(GameProfileRepository repository, String name) {
|
||||
@@ -128,17 +135,20 @@ public class GameProfileCache {
|
||||
|
||||
// Paper start
|
||||
public @Nullable GameProfile getProfileIfCached(String name) {
|
||||
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT));
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
entry.setLastAccess(this.getNextOperation());
|
||||
return entry.getProfile();
|
||||
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
|
||||
}
|
||||
// Paper end
|
||||
|
||||
public Optional<GameProfile> get(String name) {
|
||||
String s1 = name.toLowerCase(Locale.ROOT);
|
||||
+ boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1);
|
||||
boolean flag = false;
|
||||
|
||||
@@ -154,8 +164,12 @@ public class GameProfileCache {
|
||||
if (usercache_usercacheentry != null) {
|
||||
usercache_usercacheentry.setLastAccess(this.getNextOperation());
|
||||
optional = Optional.of(usercache_usercacheentry.getProfile());
|
||||
+ stateLocked = false; this.stateLock.unlock(); // Paper - Fix GameProfileCache concurrency
|
||||
} else {
|
||||
+ stateLocked = false; this.stateLock.unlock(); // Paper - Fix GameProfileCache concurrency
|
||||
+ try { this.lookupLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
optional = GameProfileCache.lookupGameProfile(this.profileRepository, name); // CraftBukkit - use correct case for offline players
|
||||
+ } finally { this.lookupLock.unlock(); } // Paper - Fix GameProfileCache concurrency
|
||||
if (optional.isPresent()) {
|
||||
this.add((GameProfile) optional.get());
|
||||
flag = false;
|
||||
@@ -167,6 +181,7 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
return optional;
|
||||
+ } finally { if (stateLocked) { this.stateLock.unlock(); } } // Paper - Fix GameProfileCache concurrency
|
||||
}
|
||||
|
||||
public CompletableFuture<Optional<GameProfile>> getAsync(String username) {
|
||||
@@ -191,6 +206,7 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
public Optional<GameProfile> get(UUID uuid) {
|
||||
+ try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByUUID.get(uuid);
|
||||
|
||||
if (usercache_usercacheentry == null) {
|
||||
@@ -199,6 +215,7 @@ public class GameProfileCache {
|
||||
usercache_usercacheentry.setLastAccess(this.getNextOperation());
|
||||
return Optional.of(usercache_usercacheentry.getProfile());
|
||||
}
|
||||
+ } finally { this.stateLock.unlock(); } // Paper - Fix GameProfileCache concurrency
|
||||
}
|
||||
|
||||
public void setExecutor(Executor executor) {
|
||||
@@ -279,7 +296,7 @@ public class GameProfileCache {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
DateFormat dateformat = GameProfileCache.createDateFormat();
|
||||
|
||||
- this.getTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot
|
||||
+ this.listTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot // Paper - Fix GameProfileCache concurrency
|
||||
jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat));
|
||||
});
|
||||
String s = this.gson.toJson(jsonarray);
|
||||
@@ -320,8 +337,19 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
private Stream<GameProfileCache.GameProfileInfo> getTopMRUProfiles(int limit) {
|
||||
- return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit);
|
||||
+ // Paper start - Fix GameProfileCache concurrency
|
||||
+ return this.listTopMRUProfiles(limit).stream();
|
||||
+ }
|
||||
+
|
||||
+ private List<GameProfileCache.GameProfileInfo> listTopMRUProfiles(int limit) {
|
||||
+ try {
|
||||
+ this.stateLock.lock();
|
||||
+ return this.profilesByUUID.values().stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit(limit).toList();
|
||||
+ } finally {
|
||||
+ this.stateLock.unlock();
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - Fix GameProfileCache concurrency
|
||||
|
||||
private static JsonElement writeGameProfile(GameProfileCache.GameProfileInfo entry, DateFormat dateFormat) {
|
||||
JsonObject jsonobject = new JsonObject();
|
227
patches/server/0593-Improve-and-expand-AsyncCatcher.patch
Normal file
227
patches/server/0593-Improve-and-expand-AsyncCatcher.patch
Normal file
|
@ -0,0 +1,227 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Wed, 25 Aug 2021 20:17:12 -0700
|
||||
Subject: [PATCH] Improve and expand AsyncCatcher
|
||||
|
||||
Log when the async catcher is tripped
|
||||
The chunk system can swallow the exception given it's all
|
||||
built with completablefuture, so ensure it is at least printed.
|
||||
|
||||
Add/move several async catchers
|
||||
|
||||
Async catch modifications to critical entity state
|
||||
These used to be here from Spigot, but were dropped with 1.17.
|
||||
Now in 1.17, this state is _even more_ critical than it was before,
|
||||
so these must exist to catch stupid plugins.
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@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 74b21852d9346708a62033c78fac04050b98c80b..020aed78c0eb1fdb9fd0d633bf2fe45bb9eb7532 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1589,6 +1589,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
|
||||
public void internalTeleport(PositionMoveRotation positionmoverotation, Set<Relative> set) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper
|
||||
// Paper start - Prevent teleporting dead entities
|
||||
if (player.isRemoved()) {
|
||||
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index eeed7d1d4b7fee0e8ab1f43f9b7ec6f74a01330d..f7e14d9668c74e20bc327b05cf84c8203e4e590b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1145,7 +1145,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
|
||||
- org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot
|
||||
+ // org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
|
||||
if (this.isTickingEffects) {
|
||||
this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
|
||||
return true;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
|
||||
index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0899ade3c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
|
||||
@@ -78,6 +78,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
private boolean addEntityUuid(T entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity add by UUID"); // Paper
|
||||
if (!this.knownUuids.add(entity.getUUID())) {
|
||||
PersistentEntitySectionManager.LOGGER.warn("UUID of added entity already exists: {}", entity);
|
||||
return false;
|
||||
@@ -91,6 +92,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
private boolean addEntity(T entity, boolean existing) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper
|
||||
// Paper start - chunk system hooks
|
||||
if (existing) {
|
||||
// I don't want to know why this is a generic type.
|
||||
@@ -146,19 +148,23 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
void startTicking(T entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity start ticking"); // Paper
|
||||
this.callbacks.onTickingStart(entity);
|
||||
}
|
||||
|
||||
void stopTicking(T entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop ticking"); // Paper
|
||||
this.callbacks.onTickingEnd(entity);
|
||||
}
|
||||
|
||||
void startTracking(T entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity start tracking"); // Paper
|
||||
this.visibleEntityStorage.add(entity);
|
||||
this.callbacks.onTrackingStart(entity);
|
||||
}
|
||||
|
||||
void stopTracking(T entity) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity stop tracking"); // Paper
|
||||
this.callbacks.onTrackingEnd(entity);
|
||||
this.visibleEntityStorage.remove(entity);
|
||||
}
|
||||
@@ -170,6 +176,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Update chunk status"); // Paper
|
||||
long i = chunkPos.toLong();
|
||||
|
||||
if (trackingStatus == Visibility.HIDDEN) {
|
||||
@@ -214,6 +221,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
public void ensureChunkQueuedForLoad(long chunkPos) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk save"); // Paper
|
||||
PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(chunkPos);
|
||||
|
||||
if (persistententitysectionmanager_b == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
|
||||
@@ -258,6 +266,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
private void requestChunkLoad(long chunkPos) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk load request"); // Paper
|
||||
this.chunkLoadStatuses.put(chunkPos, PersistentEntitySectionManager.ChunkLoadStatus.PENDING);
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(chunkPos);
|
||||
CompletableFuture completablefuture = this.permanentStorage.loadEntities(chunkcoordintpair);
|
||||
@@ -271,6 +280,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
private boolean processChunkUnload(long chunkPos) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk unload process"); // Paper
|
||||
boolean flag = this.storeChunkSections(chunkPos, (entityaccess) -> {
|
||||
entityaccess.getPassengersAndSelf().forEach(this::unloadEntity);
|
||||
}, true); // CraftBukkit - add boolean for event call
|
||||
@@ -295,6 +305,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
private void processPendingLoads() {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity chunk process pending loads"); // Paper
|
||||
ChunkEntities<T> chunkentities; // CraftBukkit - decompile error
|
||||
|
||||
while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) {
|
||||
@@ -311,6 +322,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager tick"); // Paper
|
||||
this.processPendingLoads();
|
||||
this.processUnloads();
|
||||
}
|
||||
@@ -331,6 +343,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
public void autoSave() {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager autosave"); // Paper
|
||||
this.getAllChunksToSave().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error
|
||||
boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN;
|
||||
|
||||
@@ -345,6 +358,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity manager save"); // Paper
|
||||
LongSet longset = this.getAllChunksToSave();
|
||||
|
||||
while (!longset.isEmpty()) {
|
||||
@@ -452,6 +466,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
long i = SectionPos.asLong(blockposition);
|
||||
|
||||
if (i != this.currentSectionKey) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity move"); // Paper
|
||||
Visibility visibility = this.currentSection.getStatus();
|
||||
|
||||
if (!this.currentSection.remove(this.entity)) {
|
||||
@@ -506,6 +521,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
|
||||
|
||||
@Override
|
||||
public void onRemove(Entity.RemovalReason reason) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("Entity remove"); // Paper
|
||||
if (!this.currentSection.remove(this.entity)) {
|
||||
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason});
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index c2af72ffbe3e58db0b9915f4016811b82313dfdb..890d3b648b1b991e351538088c06ed93686e35f5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1770,6 +1770,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void playSound(Location loc, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
|
||||
if (loc == null || sound == null || category == null) return;
|
||||
|
||||
double x = loc.getX();
|
||||
@@ -1781,6 +1782,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void playSound(Location loc, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
|
||||
if (loc == null || sound == null || category == null) return;
|
||||
|
||||
double x = loc.getX();
|
||||
@@ -1813,6 +1815,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void playSound(Entity entity, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
|
||||
if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return;
|
||||
|
||||
ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(CraftSound.bukkitToMinecraftHolder(sound), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed);
|
||||
@@ -1833,6 +1836,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void playSound(Entity entity, String sound, org.bukkit.SoundCategory category, float volume, float pitch, long seed) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
|
||||
if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return;
|
||||
|
||||
ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(Holder.direct(SoundEvent.createVariableRangeEvent(ResourceLocation.parse(sound))), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, seed);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 9870222cc1c46bcc37f9d3d44881606f2b9d038e..e148239d4930e5cbb000beed4de386f992f28d88 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -534,6 +534,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
|
||||
@Override
|
||||
public boolean addPotionEffect(PotionEffect effect, boolean force) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("effect add"); // Paper
|
||||
this.getHandle().addEffect(org.bukkit.craftbukkit.potion.CraftPotionUtil.fromBukkit(effect), EntityPotionEffectEvent.Cause.PLUGIN); // Paper - Don't ignore icon
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
index bbf0d9d9c44fe8d7add2f978994ec129420814c7..ef2598760458833021ef1bee92137f42c9fe591f 100644
|
||||
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
@@ -11,6 +11,7 @@ public class AsyncCatcher
|
||||
{
|
||||
if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread )
|
||||
{
|
||||
+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper
|
||||
throw new IllegalStateException( "Asynchronous " + reason + "!" );
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue