MOOOOOOOOOOORE
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Villim <jan.villim@student.tuke.sk>
|
||||
Date: Sat, 22 Jan 2022 17:56:19 +0100
|
||||
Subject: [PATCH] Ability to control player's insomnia and phantoms
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
@@ -0,0 +0,0 @@ public final class EntitySelector {
|
||||
};
|
||||
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith);
|
||||
public static final Predicate<Entity> CAN_BE_PICKED = EntitySelector.NO_SPECTATORS.and(Entity::isPickable);
|
||||
- public static Predicate<Player> IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - Add phantom creative and insomniac controls
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ public static Predicate<Player> IS_INSOMNIAC = (player) -> {
|
||||
+ net.minecraft.server.level.ServerPlayer serverPlayer = (net.minecraft.server.level.ServerPlayer) player;
|
||||
+ int playerInsomniaTicks = serverPlayer.level().paperConfig().entities.behavior.playerInsomniaStartTicks;
|
||||
+
|
||||
+ if (playerInsomniaTicks <= 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return net.minecraft.util.Mth.clamp(serverPlayer.getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= playerInsomniaTicks;
|
||||
+ };
|
||||
+ // Paper end - Ability to control player's insomnia and phantoms
|
||||
|
||||
private EntitySelector() {}
|
||||
// Paper start - Affects Spawning API
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -0,0 +0,0 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
} else if (!world.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) {
|
||||
return 0;
|
||||
} else {
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ if (world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds <= 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // Paper end - Ability to control player's insomnia and phantoms
|
||||
RandomSource randomsource = world.random;
|
||||
|
||||
--this.nextTick;
|
||||
if (this.nextTick > 0) {
|
||||
return 0;
|
||||
} else {
|
||||
- this.nextTick += (60 + randomsource.nextInt(60)) * 20;
|
||||
+ // Paper start - Ability to control player's insomnia and phantoms
|
||||
+ int spawnAttemptMinSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMinSeconds;
|
||||
+ int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds;
|
||||
+ this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20;
|
||||
+ // Paper end - Ability to control player's insomnia and phantoms
|
||||
if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
|
||||
boolean flag2 = true;
|
||||
|
||||
- if (randomsource.nextInt(j) >= 72000) {
|
||||
+ if (randomsource.nextInt(j) >= world.paperConfig().entities.behavior.playerInsomniaStartTicks) { // Paper - Ability to control player's insomnia and phantoms
|
||||
BlockPos blockposition1 = blockposition.above(20 + randomsource.nextInt(15)).east(-10 + randomsource.nextInt(21)).south(-10 + randomsource.nextInt(21));
|
||||
BlockState iblockdata = world.getBlockState(blockposition1);
|
||||
FluidState fluid = world.getFluidState(blockposition1);
|
||||
70
patches/server/Add-BlockLockCheckEvent.patch
Normal file
70
patches/server/Add-BlockLockCheckEvent.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 21 May 2022 20:59:45 -0700
|
||||
Subject: [PATCH] Add BlockLockCheckEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
|
||||
protected abstract Component getDefaultName();
|
||||
|
||||
public boolean canOpen(Player player) {
|
||||
- return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName());
|
||||
+ return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName(), this); // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add BlockLockCheckEvent
|
||||
public static boolean canUnlock(Player player, LockCode lock, Component containerName) {
|
||||
+ // Paper start - Add BlockLockCheckEvent
|
||||
+ return canUnlock(player, lock, containerName, null);
|
||||
+ }
|
||||
+ public static boolean canUnlock(Player player, LockCode lock, Component containerName, @Nullable BlockEntity blockEntity) {
|
||||
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != null && blockEntity.getLevel().getBlockEntity(blockEntity.getBlockPos()) == blockEntity) {
|
||||
+ final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(blockEntity.getLevel(), blockEntity.getBlockPos());
|
||||
+ net.kyori.adventure.text.Component lockedMessage = net.kyori.adventure.text.Component.translatable("container.isLocked", io.papermc.paper.adventure.PaperAdventure.asAdventure(containerName));
|
||||
+ net.kyori.adventure.sound.Sound lockedSound = net.kyori.adventure.sound.Sound.sound(org.bukkit.Sound.BLOCK_CHEST_LOCKED, net.kyori.adventure.sound.Sound.Source.BLOCK, 1.0F, 1.0F);
|
||||
+ final io.papermc.paper.event.block.BlockLockCheckEvent event = new io.papermc.paper.event.block.BlockLockCheckEvent(block, serverPlayer.getBukkitEntity(), lockedMessage, lockedSound);
|
||||
+ event.callEvent();
|
||||
+ if (event.getResult() == org.bukkit.event.Event.Result.ALLOW) {
|
||||
+ return true;
|
||||
+ } else if (event.getResult() == org.bukkit.event.Event.Result.DENY || (!player.isSpectator() && !lock.unlocksWith(event.isUsingCustomKeyItemStack() ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getKeyItem()) : player.getMainHandItem()))) {
|
||||
+ if (event.getLockedMessage() != null) {
|
||||
+ event.getPlayer().sendActionBar(event.getLockedMessage());
|
||||
+ }
|
||||
+ if (event.getLockedSound() != null) {
|
||||
+ event.getPlayer().playSound(event.getLockedSound());
|
||||
+ }
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ } else { // logic below is replaced by logic above
|
||||
+ // Paper end - Add BlockLockCheckEvent
|
||||
if (!player.isSpectator() && !lock.unlocksWith(player.getMainHandItem())) {
|
||||
- player.displayClientMessage(Component.translatable("container.isLocked", containerName), true);
|
||||
+ player.displayClientMessage(Component.translatable("container.isLocked", containerName), true); // Paper - diff on change
|
||||
player.playNotifySound(SoundEvents.CHEST_LOCKED, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
+ } // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
protected abstract NonNullList<ItemStack> getItems();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
|
||||
- return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName()) ? new BeaconMenu(syncId, playerInventory, this.dataAccess, ContainerLevelAccess.create(this.level, this.getBlockPos())) : null;
|
||||
+ return BaseContainerBlockEntity.canUnlock(player, this.lockKey, this.getDisplayName(), this) ? new BeaconMenu(syncId, playerInventory, this.dataAccess, ContainerLevelAccess.create(this.level, this.getBlockPos())) : null; // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
29
patches/server/Add-Sneaking-API-for-Entities.patch
Normal file
29
patches/server/Add-Sneaking-API-for-Entities.patch
Normal file
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: dawon <dawon@dawon.eu>
|
||||
Date: Wed, 19 Oct 2022 23:31:53 +0200
|
||||
Subject: [PATCH] Add Sneaking API for Entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return Pose.values()[this.getHandle().getPose().ordinal()];
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setSneaking(boolean sneak) {
|
||||
+ this.getHandle().setShiftKeyDown(sneak);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSneaking() {
|
||||
+ return this.getHandle().isShiftKeyDown();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public SpawnCategory getSpawnCategory() {
|
||||
return CraftSpawnCategory.toBukkit(this.getHandle().getType().getCategory());
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 27 Oct 2022 15:35:47 +0200
|
||||
Subject: [PATCH] Add config option for spider worldborder climbing
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -0,0 +0,0 @@ public class Spider extends Monster {
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!this.level().isClientSide) {
|
||||
- this.setClimbing(this.horizontalCollision);
|
||||
+ this.setClimbing(this.horizontalCollision && (this.level().paperConfig().entities.behavior.allowSpiderWorldBorderClimbing || !(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(this.level().getWorldBorder(), this.getBoundingBox().inflate(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON)) && this.level().getWorldBorder().isInsideCloseToBorder(this, this.getBoundingBox())))); // Paper - Add config option for spider worldborder climbing (Inflate by +EPSILON as collision will just barely place us outside border)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NonSwag <mrminecraft00@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 20:25:05 +0100
|
||||
Subject: [PATCH] Add missing SpigotConfig logCommands check
|
||||
|
||||
Co-authored-by: david <mrminecraft00@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
private void performUnsignedChatCommand(String command) {
|
||||
// CraftBukkit start
|
||||
String command1 = "/" + command;
|
||||
+ if (org.spigotmc.SpigotConfig.logCommands) { // Paper - Add missing SpigotConfig logCommands check
|
||||
ServerGamePacketListenerImpl.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command1);
|
||||
+ }
|
||||
|
||||
PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command1, new LazyPlayerSet(this.server));
|
||||
this.cserver.getPluginManager().callEvent(event);
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
private void performSignedChatCommand(ServerboundChatCommandSignedPacket packet, LastSeenMessages lastSeenMessages) {
|
||||
// CraftBukkit start
|
||||
String command = "/" + packet.command();
|
||||
+ if (org.spigotmc.SpigotConfig.logCommands) { // Paper - Add missing SpigotConfig logCommands check
|
||||
ServerGamePacketListenerImpl.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command);
|
||||
+ } // Paper - Add missing SpigotConfig logCommands check
|
||||
|
||||
PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command, new LazyPlayerSet(this.server));
|
||||
this.cserver.getPluginManager().callEvent(event);
|
||||
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <git@lynxplay.dev>
|
||||
Date: Tue, 10 Jan 2023 21:06:42 +0100
|
||||
Subject: [PATCH] Correctly shrink items during EntityResurrectEvent
|
||||
|
||||
The EntityResurrectEvent logic is supposed to locate a totem of undying
|
||||
in any of the interaction slots of the player inventory and then, if the
|
||||
called EntityResurrectEvent is not cancelled, shrink that item by 1,
|
||||
usually reducing it to zero.
|
||||
|
||||
For this, the logic iterates over the items in the interaction slots and
|
||||
breaks out the loop if a totem of undying was found.
|
||||
However, even if no totem of undying was found, the iteration item stack
|
||||
variable remains as a refernce to the last interaction slot probed.
|
||||
|
||||
Plugins uncancelling a EntityResurrectEvent, which is published
|
||||
pre-cancelled to listeners if no totem of undying could be found,
|
||||
would hence cause the server logic to shrink completely unrelated items
|
||||
found in, at the writing of this patch, the players off hand slot.
|
||||
|
||||
This patch corrects this behaviour by only shrinking the item if a totem
|
||||
of undying was found and the event was called uncancelled.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
- if (!itemstack1.isEmpty()) {
|
||||
+ if (!itemstack1.isEmpty() && itemstack != null) { // Paper - only reduce item if actual totem was found
|
||||
itemstack1.shrink(1);
|
||||
}
|
||||
if (itemstack != null && this instanceof ServerPlayer) {
|
||||
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Tue, 11 Oct 2022 23:30:32 +0300
|
||||
Subject: [PATCH] Expose pre-collision moving velocity to
|
||||
VehicleBlockCollisionEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
public void move(MoverType type, Vec3 movement) {
|
||||
+ final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
|
||||
if (this.noPhysics) {
|
||||
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
if (!bl.getType().isAir()) {
|
||||
- VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
|
||||
+ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl, org.bukkit.craftbukkit.util.CraftVector.toBukkit(originalMovement)); // Paper - Expose pre-collision velocity
|
||||
this.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NonSwag <mrminecraft00@gmail.com>
|
||||
Date: Tue, 6 Dec 2022 23:04:21 +0100
|
||||
Subject: [PATCH] Fix NPE on Allay#stopDancing while not dancing
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java
|
||||
@@ -0,0 +0,0 @@ public class CraftAllay extends CraftCreature implements org.bukkit.entity.Allay
|
||||
public void stopDancing() {
|
||||
this.getHandle().forceDancing = false;
|
||||
this.getHandle().jukeboxPos = null;
|
||||
- this.getHandle().setJukeboxPlaying(null, false);
|
||||
+ this.getHandle().setDancing(false); // Paper - Directly modify set dancing to avoid NPE
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 18 Mar 2022 21:30:00 -0700
|
||||
Subject: [PATCH] Fix async entity add due to fungus trees
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
|
||||
@@ -0,0 +0,0 @@ public class WorldGenRegion implements WorldGenLevel {
|
||||
if (iblockdata.isAir()) {
|
||||
return false;
|
||||
} else {
|
||||
+ if (drop) LOGGER.warn("Potential async entity add during worldgen", new Throwable()); // Paper - Fix async entity add due to fungus trees; log when this happens
|
||||
if (false) { // CraftBukkit - SPIGOT-6833: Do not drop during world generation
|
||||
BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null;
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
((ChorusFlowerBlock) Blocks.CHORUS_FLOWER).generatePlant(access, pos, random, 8);
|
||||
return true;
|
||||
case CRIMSON_FUNGUS:
|
||||
- gen = TreeFeatures.CRIMSON_FUNGUS_PLANTED;
|
||||
+ gen = this.isNormalWorld() ? TreeFeatures.CRIMSON_FUNGUS_PLANTED : TreeFeatures.CRIMSON_FUNGUS; // Paper - Fix async entity add due to fungus trees; if world gen, don't use planted version
|
||||
break;
|
||||
case WARPED_FUNGUS:
|
||||
- gen = TreeFeatures.WARPED_FUNGUS_PLANTED;
|
||||
+ gen = this.isNormalWorld() ? TreeFeatures.WARPED_FUNGUS_PLANTED : TreeFeatures.WARPED_FUNGUS; // Paper - Fix async entity add due to fungus trees; if world gen, don't use planted version
|
||||
break;
|
||||
case AZALEA:
|
||||
gen = TreeFeatures.AZALEA_TREE;
|
||||
61
patches/server/Fix-premature-player-kicks-on-shutdown.patch
Normal file
61
patches/server/Fix-premature-player-kicks-on-shutdown.patch
Normal file
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 11 Apr 2024 16:37:44 +0100
|
||||
Subject: [PATCH] Fix premature player kicks on shutdown
|
||||
|
||||
When the server is stopping, the default execution handler method will throw a
|
||||
RejectedExecutionException in order to prevent further execution, this causes
|
||||
us to lose the actual kick reason. To mitigate this, we'll use a seperate marked
|
||||
class in order to gracefully ignore these.
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/util/ServerStopRejectedExecutionException.java b/src/main/java/io/papermc/paper/util/ServerStopRejectedExecutionException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/util/ServerStopRejectedExecutionException.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.util;
|
||||
+
|
||||
+import java.util.concurrent.RejectedExecutionException;
|
||||
+
|
||||
+public class ServerStopRejectedExecutionException extends RejectedExecutionException {
|
||||
+ public ServerStopRejectedExecutionException() {
|
||||
+ }
|
||||
+
|
||||
+ public ServerStopRejectedExecutionException(final String message) {
|
||||
+ super(message);
|
||||
+ }
|
||||
+
|
||||
+ public ServerStopRejectedExecutionException(final String message, final Throwable cause) {
|
||||
+ super(message, cause);
|
||||
+ }
|
||||
+
|
||||
+ public ServerStopRejectedExecutionException(final Throwable cause) {
|
||||
+ super(cause);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
Connection.genericsFtw(packet, packetlistener);
|
||||
} catch (RunningOnDifferentThreadException cancelledpackethandleexception) {
|
||||
;
|
||||
+ } catch (io.papermc.paper.util.ServerStopRejectedExecutionException ignored) { // Paper - do not prematurely disconnect players on stop
|
||||
} catch (RejectedExecutionException rejectedexecutionexception) {
|
||||
this.disconnect((Component) Component.translatable("multiplayer.disconnect.server_shutdown"));
|
||||
} catch (ClassCastException classcastexception) {
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@Override
|
||||
public void executeIfPossible(Runnable runnable) {
|
||||
if (this.isStopped()) {
|
||||
- throw new RejectedExecutionException("Server already shutting down");
|
||||
+ throw new io.papermc.paper.util.ServerStopRejectedExecutionException("Server already shutting down"); // Paper - do not prematurely disconnect players on stop
|
||||
} else {
|
||||
super.executeIfPossible(runnable);
|
||||
}
|
||||
51
patches/server/Flying-Fall-Damage.patch
Normal file
51
patches/server/Flying-Fall-Damage.patch
Normal file
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: TreyRuffy <TreyRuffy@users.noreply.github.com>
|
||||
Date: Fri, 27 May 2022 02:26:08 -0600
|
||||
Subject: [PATCH] Flying Fall Damage
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
private boolean ignoreFallDamageFromCurrentImpulse;
|
||||
private int currentImpulseContextResetGraceTime;
|
||||
public boolean affectsSpawning = true; // Paper - Affects Spawning API
|
||||
+ public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
|
||||
|
||||
// CraftBukkit start
|
||||
public boolean fauxSleeping;
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public boolean causeFallDamage(float fallDistance, float damageMultiplier, DamageSource damageSource) {
|
||||
- if (this.abilities.mayfly) {
|
||||
+ if (this.abilities.mayfly && !this.flyingFallDamage.toBooleanOrElse(false)) { // Paper - flying fall damage
|
||||
return false;
|
||||
} else {
|
||||
if (fallDistance >= 2.0F) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.getHandle().onUpdateAbilities();
|
||||
}
|
||||
|
||||
+ // Paper start - flying fall damage
|
||||
+ @Override
|
||||
+ public void setFlyingFallDamage(@NotNull net.kyori.adventure.util.TriState flyingFallDamage) {
|
||||
+ getHandle().flyingFallDamage = flyingFallDamage;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.util.TriState hasFlyingFallDamage() {
|
||||
+ return getHandle().flyingFallDamage;
|
||||
+ }
|
||||
+ // Paper end - flying fall damage
|
||||
+
|
||||
@Override
|
||||
public int getNoDamageTicks() {
|
||||
if (this.getHandle().spawnInvulnerableTime > 0) {
|
||||
156
patches/server/Friction-API.patch
Normal file
156
patches/server/Friction-API.patch
Normal file
@@ -0,0 +1,156 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Noah van der Aa <ndvdaa@gmail.com>
|
||||
Date: Wed, 15 Sep 2021 20:44:22 +0200
|
||||
Subject: [PATCH] Friction API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
public boolean bukkitPickUpLoot;
|
||||
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
|
||||
public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
|
||||
+ public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||
|
||||
@Override
|
||||
public float getBukkitYaw() {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
public boolean shouldDiscardFriction() {
|
||||
- return this.discardFriction;
|
||||
+ return !this.frictionState.toBooleanOrElse(!this.discardFriction); // Paper - Friction API
|
||||
}
|
||||
|
||||
public void setDiscardFriction(boolean noDrag) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
+ // Paper start - Friction API
|
||||
+ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) {
|
||||
+ nbt.putString("Paper.FrictionState", this.frictionState.toString());
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
nbt.putFloat("Health", this.getHealth());
|
||||
nbt.putShort("HurtTime", (short) this.hurtTime);
|
||||
nbt.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp);
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
this.internalSetAbsorptionAmount(absorptionAmount);
|
||||
// Paper end - Check for NaN
|
||||
+ // Paper start - Friction API
|
||||
+ if (nbt.contains("Paper.FrictionState")) {
|
||||
+ String fs = nbt.getString("Paper.FrictionState");
|
||||
+ try {
|
||||
+ frictionState = net.kyori.adventure.util.TriState.valueOf(fs);
|
||||
+ } catch (Exception ignored) {
|
||||
+ LOGGER.error("Unknown friction state " + fs + " for " + this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
if (nbt.contains("attributes", 9) && this.level() != null && !this.level().isClientSide) {
|
||||
this.getAttributes().load(nbt.getList("attributes", 10));
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
|
||||
public boolean canMobPickup = true; // Paper - Item#canEntityPickup
|
||||
private int despawnRate = -1; // Paper - Alternative item-despawn-rate
|
||||
+ public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||
|
||||
public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
this.applyEffectsFromBlocks();
|
||||
float f = 0.98F;
|
||||
|
||||
- if (this.onGround()) {
|
||||
+ // Paper start - Friction API
|
||||
+ if (frictionState == net.kyori.adventure.util.TriState.FALSE) {
|
||||
+ f = 1F;
|
||||
+ } else if (this.onGround()) {
|
||||
+ // Paper end - Friction API
|
||||
f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
+ // Paper start - Friction API
|
||||
+ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) {
|
||||
+ nbt.putString("Paper.FrictionState", this.frictionState.toString());
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
nbt.putShort("Health", (short) this.health);
|
||||
nbt.putShort("Age", (short) this.age);
|
||||
nbt.putShort("PickupDelay", (short) this.pickupDelay);
|
||||
@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
this.setItem(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
+ // Paper start - Friction API
|
||||
+ if (nbt.contains("Paper.FrictionState")) {
|
||||
+ String fs = nbt.getString("Paper.FrictionState");
|
||||
+ try {
|
||||
+ frictionState = net.kyori.adventure.util.TriState.valueOf(fs);
|
||||
+ } catch (Exception ignored) {
|
||||
+ com.mojang.logging.LogUtils.getLogger().error("Unknown friction state " + fs + " for " + this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
+
|
||||
if (this.getItem().isEmpty()) {
|
||||
this.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
@@ -0,0 +0,0 @@ public class CraftItem extends CraftEntity implements Item {
|
||||
this.getHandle().age = willAge ? 0 : NO_AGE_TIME;
|
||||
}
|
||||
|
||||
+ @org.jetbrains.annotations.NotNull
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.util.TriState getFrictionState() {
|
||||
+ return this.getHandle().frictionState;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setFrictionState(@org.jetbrains.annotations.NotNull net.kyori.adventure.util.TriState state) {
|
||||
+ java.util.Objects.requireNonNull(state, "state may not be null");
|
||||
+ this.getHandle().frictionState = state;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public int getHealth() {
|
||||
return this.getHandle().health;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
nmsStack.hurtAndBreak(amount, this.getHandle(), slot, true);
|
||||
}
|
||||
// Paper end - ItemStack damage API
|
||||
+ // Paper start - friction API
|
||||
+ @org.jetbrains.annotations.NotNull
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.util.TriState getFrictionState() {
|
||||
+ return this.getHandle().frictionState;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setFrictionState(@org.jetbrains.annotations.NotNull net.kyori.adventure.util.TriState state) {
|
||||
+ java.util.Objects.requireNonNull(state, "state may not be null");
|
||||
+ this.getHandle().frictionState = state;
|
||||
+ }
|
||||
+ // Paper end - friction API
|
||||
}
|
||||
184
patches/server/Improve-PortalEvents.patch
Normal file
184
patches/server/Improve-PortalEvents.patch
Normal file
@@ -0,0 +1,184 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 15 Dec 2022 10:33:39 -0800
|
||||
Subject: [PATCH] Improve PortalEvents
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
|
||||
Location enter = this.getBukkitEntity().getLocation();
|
||||
PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives());
|
||||
- Location exit = (worldserver == null) ? null : CraftLocation.toBukkit(absolutePosition.position(), worldserver.getWorld(), absolutePosition.yRot(), absolutePosition.xRot());
|
||||
+ Location exit = /* (worldserver == null) ? null : // Paper - always non-null */CraftLocation.toBukkit(absolutePosition.position(), worldserver.getWorld(), absolutePosition.yRot(), absolutePosition.xRot());
|
||||
PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.getBukkitEntity(), enter, exit, teleportTarget.cause());
|
||||
// Paper start - gateway-specific teleport event
|
||||
if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
|
||||
Location enter = bukkitEntity.getLocation();
|
||||
|
||||
- EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius, true, creationRadius);
|
||||
+ // Paper start
|
||||
+ final org.bukkit.PortalType portalType = switch (cause) {
|
||||
+ case END_PORTAL -> org.bukkit.PortalType.ENDER;
|
||||
+ case NETHER_PORTAL -> org.bukkit.PortalType.NETHER;
|
||||
+ case END_GATEWAY -> org.bukkit.PortalType.END_GATEWAY; // not actually used yet
|
||||
+ default -> org.bukkit.PortalType.CUSTOM;
|
||||
+ };
|
||||
+ EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius, true, creationRadius, portalType);
|
||||
+ // Paper end
|
||||
event.getEntity().getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !entity.isAlive()) {
|
||||
return null;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
|
||||
@@ -0,0 +0,0 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal {
|
||||
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
if (entity.canUsePortal(false)) {
|
||||
+ // Paper start - call EntityPortalEnterEvent
|
||||
+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.END_GATEWAY); // Paper - add portal type
|
||||
+ if (!event.callEvent()) return;
|
||||
+ // Paper end - call EntityPortalEnterEvent
|
||||
BlockEntity tileentity = world.getBlockEntity(pos);
|
||||
|
||||
if (!world.isClientSide && tileentity instanceof TheEndGatewayBlockEntity) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
|
||||
@@ -0,0 +0,0 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
if (entity.canUsePortal(false)) {
|
||||
// CraftBukkit start - Entity in portal
|
||||
- EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
|
||||
+ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ if (event.isCancelled()) return; // Paper - make cancellable
|
||||
// CraftBukkit end
|
||||
if (!world.isClientSide && world.dimension() == Level.END && entity instanceof ServerPlayer) {
|
||||
ServerPlayer entityplayer = (ServerPlayer) entity;
|
||||
@@ -0,0 +0,0 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {
|
||||
ServerLevel worldserver1 = world.getServer().getLevel(resourcekey);
|
||||
|
||||
if (worldserver1 == null) {
|
||||
- return new TeleportTransition(PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit- always fire event in case plugins wish to change it
|
||||
+ return null; // Paper - keep previous behavior of not firing PlayerTeleportEvent if the target world doesn't exist
|
||||
} else {
|
||||
boolean flag = resourcekey == Level.END;
|
||||
BlockPos blockposition1 = flag ? ServerLevel.END_SPAWN_POINT : worldserver1.getSharedSpawnPos();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block implements Portal {
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
if (entity.canUsePortal(false)) {
|
||||
// CraftBukkit start - Entity in portal
|
||||
- EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
|
||||
+ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ if (event.isCancelled()) return; // Paper - make cancellable
|
||||
// CraftBukkit end
|
||||
entity.setAsInsidePortal(this, pos);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block implements Portal {
|
||||
// Paper end - Add EntityPortalReadyEvent
|
||||
|
||||
if (worldserver1 == null) {
|
||||
- return new TeleportTransition(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // always fire event in case plugins wish to change it
|
||||
+ return null; // Paper - keep previous behavior of not firing PlayerTeleportEvent if the target world doesn't exist
|
||||
} else {
|
||||
boolean flag = worldserver1.getTypeKey() == LevelStem.NETHER;
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java b/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/minecraft/world/level/portal/DimensionTransition.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package net.minecraft.world.level.portal;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.phys.Vec3;
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
+
|
||||
+public record DimensionTransition(ServerLevel newLevel, Vec3 pos, Vec3 speed, float yRot, float xRot, boolean missingRespawnBlock, DimensionTransition.PostDimensionTransition postDimensionTransition, PlayerTeleportEvent.TeleportCause cause) {
|
||||
+
|
||||
+ public DimensionTransition(ServerLevel newLevel, Vec3 pos, Vec3 speed, float yRot, float xRot, boolean missingRespawnBlock, DimensionTransition.PostDimensionTransition postDimensionTransition) {
|
||||
+ this(newLevel, pos, speed, yRot, xRot, missingRespawnBlock, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
+ }
|
||||
+
|
||||
+ // Paper - remove unused constructor (for safety)
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ public static final DimensionTransition.PostDimensionTransition DO_NOTHING = (entity) -> {
|
||||
+ };
|
||||
+ public static final DimensionTransition.PostDimensionTransition PLAY_PORTAL_SOUND = DimensionTransition::playPortalSound;
|
||||
+ public static final DimensionTransition.PostDimensionTransition PLACE_PORTAL_TICKET = DimensionTransition::placePortalTicket;
|
||||
+
|
||||
+ public DimensionTransition(ServerLevel world, Vec3 pos, Vec3 velocity, float yaw, float pitch, DimensionTransition.PostDimensionTransition postDimensionTransition) {
|
||||
+ // CraftBukkit start
|
||||
+ this(world, pos, velocity, yaw, pitch, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
+ }
|
||||
+
|
||||
+ public DimensionTransition(ServerLevel worldserver, Vec3 vec3d, Vec3 vec3d1, float f, float f1, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) {
|
||||
+ this(worldserver, vec3d, vec3d1, f, f1, false, dimensiontransition_a, cause);
|
||||
+ }
|
||||
+
|
||||
+ public DimensionTransition(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) {
|
||||
+ this(world, entity, postDimensionTransition, PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
+ }
|
||||
+
|
||||
+ public DimensionTransition(ServerLevel worldserver, Entity entity, DimensionTransition.PostDimensionTransition dimensiontransition_a, PlayerTeleportEvent.TeleportCause cause) {
|
||||
+ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, worldserver.getSharedSpawnAngle(), 0.0F, false, dimensiontransition_a, cause); // Paper - MC-200092 - fix spawn pos yaw being ignored
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+
|
||||
+ private static void playPortalSound(Entity entity) {
|
||||
+ if (entity instanceof ServerPlayer entityplayer) {
|
||||
+ entityplayer.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false));
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ private static void placePortalTicket(Entity entity) {
|
||||
+ entity.placePortalTicket(BlockPos.containing(entity.position()));
|
||||
+ }
|
||||
+
|
||||
+ public static DimensionTransition missingRespawnBlock(ServerLevel world, Entity entity, DimensionTransition.PostDimensionTransition postDimensionTransition) {
|
||||
+ return new DimensionTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, world.getSharedSpawnAngle(), 0.0F, true, postDimensionTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored
|
||||
+ }
|
||||
+
|
||||
+ private static Vec3 findAdjustedSharedSpawnPos(ServerLevel world, Entity entity) {
|
||||
+ return entity.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter();
|
||||
+ }
|
||||
+
|
||||
+ @FunctionalInterface
|
||||
+ public interface PostDimensionTransition {
|
||||
+
|
||||
+ void onTransition(Entity entity);
|
||||
+
|
||||
+ default DimensionTransition.PostDimensionTransition then(DimensionTransition.PostDimensionTransition next) {
|
||||
+ return (entity) -> {
|
||||
+ this.onTransition(entity);
|
||||
+ next.onTransition(entity);
|
||||
+ };
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,78 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 6 Jul 2020 20:46:50 -0700
|
||||
Subject: [PATCH] Improve inlining for some hot BlockBehavior and FluidState
|
||||
methods
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
return this.shapeExceedsCube; // Paper - moved into shape cache init
|
||||
}
|
||||
|
||||
- public boolean useShapeForLightOcclusion() {
|
||||
+ public final boolean useShapeForLightOcclusion() { // Paper - Perf: Final for inlining
|
||||
return this.useShapeForLightOcclusion;
|
||||
}
|
||||
|
||||
- public int getLightEmission() {
|
||||
+ public final int getLightEmission() { // Paper - Perf: Final for inlining
|
||||
return this.lightEmission;
|
||||
}
|
||||
|
||||
- public boolean isAir() {
|
||||
+ public final boolean isAir() { // Paper - Perf: Final for inlining
|
||||
return this.isAir;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
return this.solidRender;
|
||||
}
|
||||
|
||||
- public boolean canOcclude() {
|
||||
+ public final boolean canOcclude() { // Paper - Perf: Final for inlining
|
||||
return this.canOcclude;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
return this.getBlock().builtInRegistryHolder().is(key);
|
||||
}
|
||||
|
||||
- public FluidState getFluidState() {
|
||||
+ public final FluidState getFluidState() { // Paper - Perf: Final for inlining
|
||||
return this.fluidState;
|
||||
}
|
||||
|
||||
- public boolean isRandomlyTicking() {
|
||||
+ public final boolean isRandomlyTicking() { // Paper - Perf: Final for inlining
|
||||
return this.isRandomlyTicking;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/material/FluidState.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/material/FluidState.java
|
||||
@@ -0,0 +0,0 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
|
||||
public static final Codec<FluidState> CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable();
|
||||
public static final int AMOUNT_MAX = 9;
|
||||
public static final int AMOUNT_FULL = 8;
|
||||
+ protected final boolean isEmpty; // Paper - Perf: moved from isEmpty()
|
||||
|
||||
public FluidState(Fluid fluid, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<FluidState> codec) {
|
||||
super(fluid, propertyMap, codec);
|
||||
+ this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty()
|
||||
}
|
||||
|
||||
public Fluid getType() {
|
||||
@@ -0,0 +0,0 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
- return this.getType().isEmpty();
|
||||
+ return this.isEmpty; // Paper - Perf: moved into constructor
|
||||
}
|
||||
|
||||
public float getHeight(BlockGetter world, BlockPos pos) {
|
||||
104
patches/server/Improve-logging-and-errors.patch
Normal file
104
patches/server/Improve-logging-and-errors.patch
Normal file
@@ -0,0 +1,104 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 14 Dec 2022 15:52:11 -0800
|
||||
Subject: [PATCH] Improve logging and errors
|
||||
|
||||
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/advancements/AdvancementTree.java b/src/main/java/net/minecraft/advancements/AdvancementTree.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/advancements/AdvancementTree.java
|
||||
+++ b/src/main/java/net/minecraft/advancements/AdvancementTree.java
|
||||
@@ -0,0 +0,0 @@ public class AdvancementTree {
|
||||
this.remove(advancementnode1);
|
||||
}
|
||||
|
||||
- AdvancementTree.LOGGER.info("Forgot about advancement {}", advancement.holder());
|
||||
+ AdvancementTree.LOGGER.debug("Forgot about advancement {}", advancement.holder()); // Paper - Improve logging and errors
|
||||
this.nodes.remove(advancement.holder().id());
|
||||
if (advancement.parent() == null) {
|
||||
this.roots.remove(advancement);
|
||||
@@ -0,0 +0,0 @@ public class AdvancementTree {
|
||||
}
|
||||
}
|
||||
|
||||
- // AdvancementTree.LOGGER.info("Loaded {} advancements", this.nodes.size()); // CraftBukkit - moved to AdvancementDataWorld#reload
|
||||
+ // AdvancementTree.LOGGER.info("Loaded {} advancements", this.nodes.size()); // CraftBukkit - moved to AdvancementDataWorld#reload // Paper - Improve logging and errors; you say it was moved... but it wasn't :) it should be moved however, since this is called when the API creates an advancement
|
||||
}
|
||||
|
||||
private boolean tryInsert(AdvancementHolder advancement) {
|
||||
diff --git a/src/main/java/net/minecraft/server/ServerAdvancementManager.java b/src/main/java/net/minecraft/server/ServerAdvancementManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ServerAdvancementManager.java
|
||||
+++ b/src/main/java/net/minecraft/server/ServerAdvancementManager.java
|
||||
@@ -0,0 +0,0 @@ public class ServerAdvancementManager extends SimpleJsonResourceReloadListener<A
|
||||
AdvancementTree advancementtree = new AdvancementTree();
|
||||
|
||||
advancementtree.addAll(this.advancements.values());
|
||||
+ LOGGER.info("Loaded {} advancements", advancementtree.nodes().size()); // Paper - Improve logging and errors; moved from AdvancementTree#addAll
|
||||
Iterator iterator = advancementtree.roots().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!");
|
||||
DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString());
|
||||
DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?");
|
||||
+ if (true) throw new IllegalStateException("Failed to bind to port", ioexception); // Paper - Propagate failed to bind to port error
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator));
|
||||
} catch (ProfilePublicKey.ValidationException profilepublickey_b) {
|
||||
- ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage());
|
||||
+ // ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage()); // Paper - Improve logging and errors
|
||||
this.disconnect(profilepublickey_b.getComponent(), profilepublickey_b.kickCause); // Paper - kick event causes
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/packs/PathPackResources.java b/src/main/java/net/minecraft/server/packs/PathPackResources.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/packs/PathPackResources.java
|
||||
+++ b/src/main/java/net/minecraft/server/packs/PathPackResources.java
|
||||
@@ -0,0 +0,0 @@ public class PathPackResources extends AbstractPackResources {
|
||||
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path)) {
|
||||
for (Path path2 : directoryStream) {
|
||||
String string = path2.getFileName().toString();
|
||||
+ // Paper start - Improve logging and errors
|
||||
+ if (!Files.isDirectory(path2)) {
|
||||
+ LOGGER.error("Invalid directory entry: {} in {}.", string, this.root, new java.nio.file.NotDirectoryException(string));
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - Improve logging and errors
|
||||
if (ResourceLocation.isValidNamespace(string)) {
|
||||
set.add(string);
|
||||
} else {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.material.MaterialData;
|
||||
*/
|
||||
@Deprecated
|
||||
public final class CraftLegacy {
|
||||
+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper - Improve logging and errors
|
||||
|
||||
private static final Map<Byte, Material> SPAWN_EGGS = new HashMap<>();
|
||||
private static final Set<String> whitelistedStates = new HashSet<>(Arrays.asList("explode", "check_decay", "decayable", "facing"));
|
||||
@@ -0,0 +0,0 @@ public final class CraftLegacy {
|
||||
}
|
||||
|
||||
static {
|
||||
- System.err.println("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!");
|
||||
+ LOGGER.warn("Initializing Legacy Material Support. Unless you have legacy plugins and/or data this is a bug!"); // Paper - Improve logging and errors; doesn't need to be an error
|
||||
if (MinecraftServer.getServer() != null && MinecraftServer.getServer().isDebugging()) {
|
||||
new Exception().printStackTrace();
|
||||
}
|
||||
118
patches/server/ItemStack-damage-API.patch
Normal file
118
patches/server/ItemStack-damage-API.patch
Normal file
@@ -0,0 +1,118 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 8 May 2022 13:35:45 -0700
|
||||
Subject: [PATCH] ItemStack damage API
|
||||
|
||||
Adds methods notify clients about item breaks and
|
||||
to simulate damage done to an itemstack and all
|
||||
the logic associated with damaging them
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.LivingEntity entityEventForEquipmentBreak(Lnet/minecraft/world/entity/EquipmentSlot;)B
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
}
|
||||
|
||||
public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer<Item> breakCallback) { // Paper - Add EntityDamageItemEvent
|
||||
+ // Paper start - add force boolean overload
|
||||
+ this.hurtAndBreak(amount, world, player, breakCallback, false);
|
||||
+ }
|
||||
+ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer<Item> breakCallback, boolean force) { // Paper - Add EntityDamageItemEvent
|
||||
+ // Paper end
|
||||
int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent
|
||||
- int j = this.processDurabilityChange(amount, world, player);
|
||||
+ int j = this.processDurabilityChange(amount, world, player, force); // Paper
|
||||
// CraftBukkit start
|
||||
if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
|
||||
PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j, originalDamage); // Paper - Add EntityDamageItemEvent
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
|
||||
}
|
||||
|
||||
- private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent
|
||||
- return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent
|
||||
+ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player, boolean force) { // Paper - Add EntityDamageItemEvent
|
||||
+ return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() && !force ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent
|
||||
}
|
||||
|
||||
private void applyDamage(int damage, @Nullable LivingEntity player, Consumer<Item> breakCallback) { // Paper - Add EntityDamageItemEvent
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
}
|
||||
|
||||
public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) {
|
||||
+ // Paper start - add param to skip infinite mats check
|
||||
+ this.hurtAndBreak(amount, entity, slot, false);
|
||||
+ }
|
||||
+ public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot, boolean force) {
|
||||
+ // Paper end - add param to skip infinite mats check
|
||||
Level world = entity.level();
|
||||
|
||||
if (world instanceof ServerLevel worldserver) {
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
}
|
||||
|
||||
this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent
|
||||
- entity.onEquippedItemBroken(item, slot);
|
||||
- });
|
||||
+ if (slot != null) entity.onEquippedItemBroken(item, slot); // Paper - itemstack damage API - do not process entity related callbacks when damaging from API
|
||||
+ }, force); // Paper - itemstack damage API
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
this.getHandle().knockback(strength, directionX, directionZ);
|
||||
};
|
||||
// Paper end - knockback API
|
||||
+
|
||||
+ // Paper start - ItemStack damage API
|
||||
+ public void broadcastSlotBreak(final org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ this.getHandle().level().broadcastEntityEvent(this.getHandle(), net.minecraft.world.entity.LivingEntity.entityEventForEquipmentBreak(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void broadcastSlotBreak(final org.bukkit.inventory.EquipmentSlot slot, final Collection<org.bukkit.entity.Player> players) {
|
||||
+ if (players.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ final net.minecraft.network.protocol.game.ClientboundEntityEventPacket packet = new net.minecraft.network.protocol.game.ClientboundEntityEventPacket(
|
||||
+ this.getHandle(),
|
||||
+ net.minecraft.world.entity.LivingEntity.entityEventForEquipmentBreak(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot))
|
||||
+ );
|
||||
+ players.forEach(player -> ((CraftPlayer) player).getHandle().connection.send(packet));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack damageItemStack(ItemStack stack, final int amount) {
|
||||
+ final net.minecraft.world.item.ItemStack nmsStack;
|
||||
+ if (stack instanceof final CraftItemStack craftItemStack) {
|
||||
+ if (craftItemStack.handle == null || craftItemStack.handle.isEmpty()) {
|
||||
+ return stack;
|
||||
+ }
|
||||
+ nmsStack = craftItemStack.handle;
|
||||
+ } else {
|
||||
+ nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||
+ stack = CraftItemStack.asCraftMirror(nmsStack); // mirror to capture changes in hurt logic & events
|
||||
+ }
|
||||
+ this.damageItemStack0(nmsStack, amount, null);
|
||||
+ return stack;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void damageItemStack(final org.bukkit.inventory.EquipmentSlot slot, final int amount) {
|
||||
+ final net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot);
|
||||
+ this.damageItemStack0(this.getHandle().getItemBySlot(nmsSlot), amount, nmsSlot);
|
||||
+ }
|
||||
+
|
||||
+ private void damageItemStack0(final net.minecraft.world.item.ItemStack nmsStack, final int amount, final net.minecraft.world.entity.EquipmentSlot slot) {
|
||||
+ nmsStack.hurtAndBreak(amount, this.getHandle(), slot, true);
|
||||
+ }
|
||||
+ // Paper end - ItemStack damage API
|
||||
}
|
||||
19
patches/server/Limit-pet-look-distance.patch
Normal file
19
patches/server/Limit-pet-look-distance.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Noah van der Aa <ndvdaa@gmail.com>
|
||||
Date: Tue, 6 Dec 2022 18:45:54 +0100
|
||||
Subject: [PATCH] Limit pet look distance
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java
|
||||
@@ -0,0 +0,0 @@ public class FollowOwnerGoal extends Goal {
|
||||
public void tick() {
|
||||
boolean bl = this.tamable.shouldTryTeleportToOwner();
|
||||
if (!bl) {
|
||||
- this.tamable.getLookControl().setLookAt(this.owner, 10.0F, (float)this.tamable.getMaxHeadXRot());
|
||||
+ if (this.tamable.distanceToSqr(this.owner) <= 16 * 16) this.tamable.getLookControl().setLookAt(this.owner, 10.0F, (float)this.tamable.getMaxHeadXRot()); // Paper - Limit pet look distance
|
||||
}
|
||||
|
||||
if (--this.timeToRecalcPath <= 0) {
|
||||
42
patches/server/Player-Entity-Tracking-Events.patch
Normal file
42
patches/server/Player-Entity-Tracking-Events.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yannick Lamprecht <yannicklamprecht@live.de>
|
||||
Date: Wed, 30 Mar 2022 18:16:52 +0200
|
||||
Subject: [PATCH] Player Entity Tracking Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// CraftBukkit end
|
||||
if (flag) {
|
||||
if (this.seenBy.add(player.connection)) {
|
||||
+ // Paper start - entity tracking events
|
||||
+ if (io.papermc.paper.event.player.PlayerTrackEntityEvent.getHandlerList().getRegisteredListeners().length == 0 || new io.papermc.paper.event.player.PlayerTrackEntityEvent(player.getBukkitEntity(), this.entity.getBukkitEntity()).callEvent()) {
|
||||
this.serverEntity.addPairing(player);
|
||||
+ }
|
||||
+ // Paper end - entity tracking events
|
||||
}
|
||||
} else if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
public void startSeenByPlayer(ServerPlayer player) {}
|
||||
|
||||
- public void stopSeenByPlayer(ServerPlayer player) {}
|
||||
+ // Paper start - entity tracking events
|
||||
+ public void stopSeenByPlayer(ServerPlayer player) {
|
||||
+ // Since this event cannot be cancelled, we should call it here to catch all "un-tracks"
|
||||
+ if (io.papermc.paper.event.player.PlayerUntrackEntityEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ new io.papermc.paper.event.player.PlayerUntrackEntityEvent(player.getBukkitEntity(), this.getBukkitEntity()).callEvent();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - entity tracking events
|
||||
|
||||
public float rotate(Rotation rotation) {
|
||||
float f = Mth.wrapDegrees(this.getYRot());
|
||||
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
|
||||
Date: Mon, 23 Jan 2023 19:19:01 -0500
|
||||
Subject: [PATCH] Remove CraftItemStack#setAmount null assignment
|
||||
|
||||
This creates a problem with Paper's item serialization
|
||||
api where deserialized items, which are internally
|
||||
created as a CraftItemStack, will be completely lost if
|
||||
#setAmount(0) is invoked (since the underlying handle
|
||||
is set to null), while a regular Bukkit ItemStack
|
||||
simply sets the amount field to zero, retaining the
|
||||
item's data.
|
||||
|
||||
Vanilla treats items with zero amounts the same as items
|
||||
with less than zero amounts, so this code doesn't create
|
||||
a problem with operations on the vanilla ItemStack.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
}
|
||||
|
||||
this.handle.setCount(amount);
|
||||
- if (amount == 0) {
|
||||
+ if (false && amount == 0) { // Paper - remove CraftItemStack#setAmount null assignment
|
||||
this.handle = null;
|
||||
}
|
||||
}
|
||||
51
patches/server/Sync-offhand-slot-in-menus.patch
Normal file
51
patches/server/Sync-offhand-slot-in-menus.patch
Normal file
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 14 Jan 2022 10:20:40 -0800
|
||||
Subject: [PATCH] Sync offhand slot in menus
|
||||
|
||||
Menus don't add slots for the offhand, so on sendAllDataToRemote calls the
|
||||
offhand slot isn't sent. This is not correct because you *can* put stuff into the offhand
|
||||
by pressing the offhand swap item
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Sync offhand slot in menus
|
||||
+ @Override
|
||||
+ public void sendOffHandSlotChange() {
|
||||
+ ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(ServerPlayer.this.inventoryMenu.containerId, ServerPlayer.this.inventoryMenu.incrementStateId(), net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT, ServerPlayer.this.inventoryMenu.getSlot(net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT).getItem().copy()));
|
||||
+ }
|
||||
+ // Paper end - Sync offhand slot in menus
|
||||
+
|
||||
@Override
|
||||
public void sendSlotChange(AbstractContainerMenu handler, int slot, ItemStack stack) {
|
||||
ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(handler.containerId, handler.incrementStateId(), slot, stack));
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractContainerMenu {
|
||||
|
||||
if (this.synchronizer != null) {
|
||||
this.synchronizer.sendInitialData(this, this.remoteSlots, this.remoteCarried, this.remoteDataSlots.toIntArray());
|
||||
+ this.synchronizer.sendOffHandSlotChange(); // Paper - Sync offhand slot in menus; update player's offhand since the offhand slot is not added to the slots for menus but can be changed by swapping from a menu slot
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/ContainerSynchronizer.java b/src/main/java/net/minecraft/world/inventory/ContainerSynchronizer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/ContainerSynchronizer.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/ContainerSynchronizer.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.item.ItemStack;
|
||||
public interface ContainerSynchronizer {
|
||||
void sendInitialData(AbstractContainerMenu handler, NonNullList<ItemStack> stacks, ItemStack cursorStack, int[] properties);
|
||||
|
||||
+ default void sendOffHandSlotChange() {} // Paper - Sync offhand slot in menus
|
||||
void sendSlotChange(AbstractContainerMenu handler, int slot, ItemStack stack);
|
||||
|
||||
void sendCarriedChange(AbstractContainerMenu handler, ItemStack stack);
|
||||
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 8 Jan 2023 17:38:28 -0800
|
||||
Subject: [PATCH] Use single player info update packet on join
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
this.signedMessageDecoder = session.createMessageDecoder(this.player.getUUID());
|
||||
this.chatMessageChain.append(() -> {
|
||||
this.player.setChatSession(session);
|
||||
- this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)));
|
||||
+ this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)), this.player); // Paper - Use single player info update packet on join
|
||||
});
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start - sendAll above replaced with this loop
|
||||
ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player));
|
||||
|
||||
+ final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
entityplayer1.connection.send(packet);
|
||||
}
|
||||
|
||||
- if (!bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) {
|
||||
+ if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player
|
||||
continue;
|
||||
}
|
||||
|
||||
- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1)));
|
||||
+ onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join
|
||||
}
|
||||
+ // Paper start - Use single player info update packet on join
|
||||
+ if (!onlinePlayers.isEmpty()) {
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers));
|
||||
+ }
|
||||
+ // Paper end - Use single player info update packet on join
|
||||
player.sentListPacket = true;
|
||||
player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
|
||||
((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
|
||||
38
patches/server/Win-Screen-API.patch
Normal file
38
patches/server/Win-Screen-API.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lama06 <andreasprues36@gmail.com>
|
||||
Date: Sat, 21 Jan 2023 13:53:23 +0100
|
||||
Subject: [PATCH] Win Screen API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.level.ServerPlayer seenCredits
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.getHandle().connection.send(packet);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void showWinScreen() {
|
||||
+ if (getHandle().connection == null) return;
|
||||
+ var packet = new ClientboundGameEventPacket(ClientboundGameEventPacket.WIN_GAME, 1);
|
||||
+ getHandle().connection.send(packet);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasSeenWinScreen() {
|
||||
+ return getHandle().seenCredits;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasSeenWinScreen(boolean hasSeenWinScreen) {
|
||||
+ getHandle().seenCredits = hasSeenWinScreen;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void setRotation(float yaw, float pitch) {
|
||||
// Paper start - Teleport API
|
||||
@@ -0,0 +1,85 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 22 Nov 2022 13:16:01 -0800
|
||||
Subject: [PATCH] check global player list where appropriate
|
||||
|
||||
Makes certain entities check all players when searching for a player
|
||||
instead of just checking players in their world.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::move);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - check global player list where appropriate
|
||||
+ @Override
|
||||
+ @Nullable
|
||||
+ public Player getGlobalPlayerByUUID(UUID uuid) {
|
||||
+ return this.server.getPlayerList().getPlayer(uuid);
|
||||
+ }
|
||||
+ // Paper end - check global player list where appropriate
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
public void onItemPickup(ItemEntity item) {
|
||||
- Entity entity = item.getOwner();
|
||||
+ Entity entity = item.thrower != null ? this.level().getGlobalPlayerByUUID(item.thrower) : null; // Paper - check global player list where appropriate
|
||||
|
||||
if (entity instanceof ServerPlayer) {
|
||||
CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.trigger((ServerPlayer) entity, item.getItem(), this);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
|
||||
@@ -0,0 +0,0 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
|
||||
entityvillager.finalizeSpawn(world, world.getCurrentDifficultyAt(entityvillager.blockPosition()), EntitySpawnReason.CONVERSION, (SpawnGroupData) null);
|
||||
entityvillager.refreshBrain(world);
|
||||
if (this.conversionStarter != null) {
|
||||
- Player entityhuman = world.getPlayerByUUID(this.conversionStarter);
|
||||
+ Player entityhuman = world.getGlobalPlayerByUUID(this.conversionStarter); // Paper - check global player list where appropriate
|
||||
|
||||
if (entityhuman instanceof ServerPlayer) {
|
||||
CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer) entityhuman, this, entityvillager);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface EntityGetter {
|
||||
|
||||
return null;
|
||||
}
|
||||
+
|
||||
+ // Paper start - check global player list where appropriate
|
||||
+ @Nullable
|
||||
+ default Player getGlobalPlayerByUUID(UUID uuid) {
|
||||
+ return this.getPlayerByUUID(uuid);
|
||||
+ }
|
||||
+ // Paper end - check global player list where appropriate
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SculkShriekerBlockEntity extends BlockEntity implements GameEventLi
|
||||
|
||||
@Nullable
|
||||
public static ServerPlayer tryGetPlayer(@Nullable Entity entity) {
|
||||
+ // Paper start - check global player list where appropriate; ensure level is the same for sculk events
|
||||
+ final ServerPlayer player = tryGetPlayer0(entity);
|
||||
+ return player != null && player.level() == entity.level() ? player : null;
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ private static ServerPlayer tryGetPlayer0(@Nullable Entity entity) {
|
||||
+ // Paper end - check global player list where appropriate
|
||||
if (entity instanceof ServerPlayer) {
|
||||
return (ServerPlayer)entity;
|
||||
} else {
|
||||
27
patches/server/config-for-disabling-entity-tag-tags.patch
Normal file
27
patches/server/config-for-disabling-entity-tag-tags.patch
Normal file
@@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 15 Sep 2021 14:52:42 -0700
|
||||
Subject: [PATCH] config for disabling entity tag tags
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
@@ -0,0 +0,0 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
|
||||
if (minecraftserver != null && entity != null) {
|
||||
if (world.isClientSide || !entity.onlyOpCanSetNbt() || player != null && minecraftserver.getPlayerList().isOp(player.getGameProfile())) {
|
||||
+ // Paper start - filter out protected tags
|
||||
+ if (player == null || !player.getBukkitEntity().hasPermission("minecraft.nbt.place")) {
|
||||
+ nbt = nbt.update((compound) -> {
|
||||
+ for (net.minecraft.commands.arguments.NbtPathArgument.NbtPath tag : world.paperConfig().entities.spawning.filteredEntityTagNbtPaths) {
|
||||
+ tag.remove(compound);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+ // Paper end - filter out protected tags
|
||||
+
|
||||
nbt.loadInto(entity);
|
||||
}
|
||||
}
|
||||
57
patches/server/fix-Instruments.patch
Normal file
57
patches/server/fix-Instruments.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 9 Dec 2022 01:47:23 -0800
|
||||
Subject: [PATCH] fix Instruments
|
||||
|
||||
properly handle Player#playNote
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
Sound instrumentSound = instrument.getSound();
|
||||
if (instrumentSound == null) return;
|
||||
|
||||
- float pitch = note.getPitch();
|
||||
+ // Paper start - use correct pitch (modeled off of NoteBlock)
|
||||
+ final net.minecraft.world.level.block.state.properties.NoteBlockInstrument noteBlockInstrument = CraftBlockData.toNMS(instrument, net.minecraft.world.level.block.state.properties.NoteBlockInstrument.class);
|
||||
+ final float pitch = noteBlockInstrument.isTunable() ? note.getPitch() : 1.0f;
|
||||
+ // Paper end
|
||||
this.getHandle().connection.send(new ClientboundSoundPacket(CraftSound.bukkitToMinecraftHolder(instrumentSound), net.minecraft.sounds.SoundSource.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, pitch, this.getHandle().getRandom().nextLong()));
|
||||
}
|
||||
|
||||
diff --git a/src/test/java/io/papermc/paper/block/InstrumentSoundTest.java b/src/test/java/io/papermc/paper/block/InstrumentSoundTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/block/InstrumentSoundTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.block;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+import java.util.stream.Stream;
|
||||
+import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
||||
+import org.bukkit.Instrument;
|
||||
+import org.bukkit.craftbukkit.CraftSound;
|
||||
+import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
+import org.bukkit.support.environment.AllFeatures;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+
|
||||
+@AllFeatures
|
||||
+class InstrumentSoundTest {
|
||||
+
|
||||
+ static Stream<Instrument> bukkitInstruments() {
|
||||
+ return Arrays.stream(Instrument.values()).filter(i -> i.getSound() != null);
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest
|
||||
+ @MethodSource("bukkitInstruments")
|
||||
+ void checkInstrumentSound(final Instrument bukkit) {
|
||||
+ final NoteBlockInstrument nms = CraftBlockData.toNMS(bukkit, NoteBlockInstrument.class);
|
||||
+ assertEquals(nms.getSoundEvent(), CraftSound.bukkitToMinecraftHolder(bukkit.getSound()));
|
||||
+ }
|
||||
+}
|
||||
Reference in New Issue
Block a user