2024-12-11 22:26:55 +01:00
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -103,10 +103,6 @@
import net.minecraft.util.Unit;
import net.minecraft.util.profiling.Profiler;
import net.minecraft.util.profiling.ProfilerFiller;
-import net.minecraft.world.Container;
-import net.minecraft.world.Difficulty;
-import net.minecraft.world.InteractionHand;
-import net.minecraft.world.MenuProvider;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.effect.MobEffectInstance;
@@ -135,15 +131,16 @@
import net.minecraft.world.entity.player.ChatVisiblity;
import net.minecraft.world.entity.player.Input;
import net.minecraft.world.entity.player.Inventory;
-import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.entity.vehicle.AbstractBoat;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
+import net.minecraft.world.food.FoodData;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerListener;
import net.minecraft.world.inventory.ContainerSynchronizer;
import net.minecraft.world.inventory.HorseInventoryMenu;
+import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.inventory.ResultSlot;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.Item;
@@ -154,8 +151,6 @@
import net.minecraft.world.item.WrittenBookItem;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
-import net.minecraft.world.item.enchantment.EnchantmentHelper;
-import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.GameType;
@@ -163,12 +158,14 @@
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.RespawnAnchorBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.CommandBlockEntity;
import net.minecraft.world.level.block.entity.SignBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.portal.TeleportTransition;
import net.minecraft.world.level.saveddata.maps.MapId;
2021-01-29 17:54:03 +01:00
@@ -179,11 +176,48 @@
2024-12-11 22:26:55 +01:00
import net.minecraft.world.scores.PlayerTeam;
import net.minecraft.world.scores.ScoreAccess;
import net.minecraft.world.scores.ScoreHolder;
+import org.slf4j.Logger;
+import net.minecraft.world.Container;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.MenuProvider;
2014-11-25 22:32:16 +01:00
+// CraftBukkit start
2021-03-15 23:00:00 +01:00
+import net.minecraft.world.damagesource.CombatTracker;
2024-06-13 17:05:00 +02:00
+import net.minecraft.world.item.enchantment.EnchantmentEffectComponents;
2024-12-11 22:26:55 +01:00
+import net.minecraft.world.item.enchantment.EnchantmentHelper;
+import net.minecraft.world.item.trading.MerchantOffers;
2021-03-15 23:00:00 +01:00
+import net.minecraft.world.scores.Scoreboard;
2024-12-11 22:26:55 +01:00
import net.minecraft.world.scores.Team;
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
-import org.slf4j.Logger;
2021-01-29 17:54:03 +01:00
+import io.papermc.paper.adventure.PaperAdventure; // Paper
2014-11-25 22:32:16 +01:00
+import org.bukkit.Bukkit;
2018-07-15 02:00:00 +02:00
+import org.bukkit.Location;
2014-11-25 22:32:16 +01:00
+import org.bukkit.WeatherType;
2024-10-22 17:15:00 +02:00
+import org.bukkit.command.CommandSender;
2014-11-25 22:32:16 +01:00
+import org.bukkit.craftbukkit.CraftWorld;
2022-04-09 01:39:33 +02:00
+import org.bukkit.craftbukkit.CraftWorldBorder;
2014-11-25 22:32:16 +01:00
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
2020-08-14 00:26:40 +02:00
+import org.bukkit.craftbukkit.event.CraftPortalEvent;
2014-11-25 22:32:16 +01:00
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
2021-05-15 02:06:25 +02:00
+import org.bukkit.craftbukkit.util.CraftDimensionUtil;
2023-04-19 11:59:19 +02:00
+import org.bukkit.craftbukkit.util.CraftLocation;
2024-06-13 17:05:00 +02:00
+import org.bukkit.entity.Player;
2023-12-05 17:40:00 +01:00
+import org.bukkit.event.entity.EntityExhaustionEvent;
2021-01-29 01:22:42 +01:00
+import org.bukkit.event.player.PlayerBedLeaveEvent;
2016-05-27 10:53:36 +02:00
+import org.bukkit.event.player.PlayerChangedMainHandEvent;
2019-05-06 00:38:29 +02:00
+import org.bukkit.event.player.PlayerChangedWorldEvent;
2024-10-22 17:15:00 +02:00
+import org.bukkit.event.player.PlayerDropItemEvent;
2017-05-26 23:37:06 +02:00
+import org.bukkit.event.player.PlayerLocaleChangeEvent;
2019-04-23 04:00:00 +02:00
+import org.bukkit.event.player.PlayerPortalEvent;
2024-06-13 17:05:00 +02:00
+import org.bukkit.event.player.PlayerRespawnEvent;
2023-04-17 11:33:17 +02:00
+import org.bukkit.event.player.PlayerSpawnChangeEvent;
2019-04-23 04:00:00 +02:00
+import org.bukkit.event.player.PlayerTeleportEvent;
2014-11-25 22:32:16 +01:00
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
2016-05-27 10:53:36 +02:00
+import org.bukkit.inventory.MainHand;
2014-11-25 22:32:16 +01:00
+// CraftBukkit end
2024-12-11 22:26:55 +01:00
-public class ServerPlayer extends Player {
+public class ServerPlayer extends net.minecraft.world.entity.player.Player {
2014-11-25 22:32:16 +01:00
2022-02-28 16:00:00 +01:00
private static final Logger LOGGER = LogUtils.getLogger();
2024-12-11 22:26:55 +01:00
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
2021-01-29 17:54:03 +01:00
@@ -225,7 +259,8 @@
2023-09-21 18:40:00 +02:00
private int levitationStartTime;
private boolean disconnected;
private int requestedViewDistance;
- public String language;
2016-04-19 21:09:31 +02:00
+ public String language = null; // CraftBukkit - default // Paper - default to null
2021-01-29 17:54:03 +01:00
+ public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
2023-09-21 18:40:00 +02:00
@Nullable
2024-12-11 22:26:55 +01:00
private Vec3 startingToFallPosition;
2023-09-21 18:40:00 +02:00
@Nullable
2022-01-14 19:20:40 +01:00
@@ -258,7 +293,35 @@
2016-03-03 06:34:44 +01:00
private final CommandSource commandSource;
2023-09-21 18:40:00 +02:00
private int containerCounter;
2021-06-11 07:00:00 +02:00
public boolean wonGame;
2016-03-03 06:34:44 +01:00
+ private int containerUpdateDelay; // Paper - Configurable container update tick rate
2019-01-02 07:35:43 +01:00
+ public long loginTime; // Paper - Replace OfflinePlayer#getLastPlayed
2020-02-01 16:50:39 +01:00
+ public int patrolSpawnDelay; // Paper - Pillager patrol spawn settings and per player options
2018-08-21 02:39:35 +02:00
+ // Paper start - cancellable death event
+ public boolean queueHealthUpdatePacket;
+ public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
+ // Paper end - cancellable death event
2022-01-14 19:20:40 +01:00
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
2024-04-23 17:15:00 +02:00
+ public CraftPlayer.TransferCookieConnection transferCookieConnection;
2014-11-25 22:32:16 +01:00
+ public String displayName;
2021-01-29 17:54:03 +01:00
+ public net.kyori.adventure.text.Component adventure$displayName; // Paper
2024-12-11 22:26:55 +01:00
+ public Component listName;
2024-10-22 17:15:00 +02:00
+ public int listOrder = 0;
2014-11-25 22:32:16 +01:00
+ public org.bukkit.Location compassTarget;
+ public int newExp = 0;
+ public int newLevel = 0;
+ public int newTotalExp = 0;
+ public boolean keepLevel = false;
+ public double maxHealthCache;
+ public boolean joining = true;
2017-04-28 06:53:31 +02:00
+ public boolean sentListPacket = false;
Fire PlayerJoinEvent when Player is actually ready
For years, plugin developers have had to delay many things they do
inside of the PlayerJoinEvent by 1 tick to make it actually work.
This all boiled down to 1 reason why: The event fired before the
player was fully ready and joined to the world!
Additionally, if that player logged out on a vehicle, the event
fired before the vehicle was even loaded, so that plugins had no
access to the vehicle during this event either.
This change finally fixes this issue, fully preparing the player
into the world as a fully ready entity, vehicle included.
There should be no plugins that break because of this change, but might
improve consistency with other plugins instead.
For example, if 2 plugins listens to this event, and the first one
teleported the player in the event, then the 2nd plugin actually
would be getting a valid player!
This was very non deterministic. This change will ensure every plugin
receives a deterministic result, and should no longer require 1 tick
delays anymore.
== AT ==
public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V
2020-04-19 06:05:46 +02:00
+ public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2016-03-29 02:55:47 +02:00
+ public boolean isRealPlayer; // Paper
2018-01-14 23:36:02 +01:00
+ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
2020-04-11 13:10:58 +02:00
+ public @Nullable String clientBrandName = null; // Paper - Brand support
2020-11-14 16:19:52 +01:00
+ public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
2022-01-14 19:20:40 +01:00
+
2024-12-11 22:26:55 +01:00
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
2022-01-14 19:20:40 +01:00
this.chatVisibility = ChatVisiblity.FULL;
2021-07-08 01:19:41 +02:00
@@ -266,7 +329,7 @@
2016-04-19 21:09:31 +02:00
this.canChatColor = true;
this.lastActionTime = Util.getMillis();
this.requestedViewDistance = 2;
- this.language = "en_us";
+ this.language = null; // Paper - default to null
this.lastSectionPos = SectionPos.of(0, 0, 0);
this.chunkTrackingView = ChunkTrackingView.EMPTY;
this.respawnDimension = Level.OVERWORLD;
2022-01-14 19:20:40 +01:00
@@ -285,7 +348,14 @@
}
+ // 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));
}
@@ -316,6 +386,25 @@
2022-04-24 22:56:59 +02:00
}
}
+ // Paper start - Add PlayerInventorySlotChangeEvent
+ @Override
+ public void slotChanged(AbstractContainerMenu handler, int slotId, ItemStack oldStack, ItemStack stack) {
+ Slot slot = handler.getSlot(slotId);
+ if (!(slot instanceof ResultSlot)) {
+ if (slot.container == ServerPlayer.this.getInventory()) {
+ if (io.papermc.paper.event.player.PlayerInventorySlotChangeEvent.getHandlerList().getRegisteredListeners().length == 0) {
+ CriteriaTriggers.INVENTORY_CHANGED.trigger(ServerPlayer.this, ServerPlayer.this.getInventory(), stack);
+ return;
+ }
+ io.papermc.paper.event.player.PlayerInventorySlotChangeEvent event = new io.papermc.paper.event.player.PlayerInventorySlotChangeEvent(ServerPlayer.this.getBukkitEntity(), slotId, CraftItemStack.asBukkitCopy(oldStack), CraftItemStack.asBukkitCopy(stack));
+ event.callEvent();
+ if (event.shouldTriggerAdvancements()) {
+ CriteriaTriggers.INVENTORY_CHANGED.trigger(ServerPlayer.this, ServerPlayer.this.getInventory(), stack);
+ }
+ }
+ }
+ }
+ // Paper end - Add PlayerInventorySlotChangeEvent
@Override
public void dataChanged(AbstractContainerMenu handler, int property, int value) {}
2022-01-14 19:20:40 +01:00
@@ -340,6 +429,13 @@
2024-12-11 22:26:55 +01:00
public void sendSystemMessage(Component message) {
ServerPlayer.this.sendSystemMessage(message);
2024-10-22 17:15:00 +02:00
}
+
+ // CraftBukkit start
+ @Override
2024-12-11 22:26:55 +01:00
+ public CommandSender getBukkitSender(CommandSourceStack wrapper) {
+ return ServerPlayer.this.getBukkitEntity();
2024-10-22 17:15:00 +02:00
+ }
+ // CraftBukkit end
};
2024-12-11 22:26:55 +01:00
this.textFilter = server.createTextFilterForPlayer(this);
this.gameMode = server.createGameModeForPlayer(this);
2022-01-14 19:20:40 +01:00
@@ -349,17 +445,71 @@
2020-04-10 03:20:33 +02:00
this.server = server;
this.stats = server.getPlayerList().getPlayerStats(this);
this.advancements = server.getPlayerList().getPlayerAdvancements(this);
- this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
2020-01-20 21:38:15 +01:00
- this.updateOptions(clientOptions);
2020-04-10 03:20:33 +02:00
+ // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn
2020-01-20 21:38:15 +01:00
+ this.updateOptionsNoEvents(clientOptions); // Paper - don't call options events on login
2024-04-23 17:15:00 +02:00
this.object = null;
2018-03-07 11:43:33 +01:00
+
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
2021-11-21 23:00:00 +01:00
+ this.displayName = this.getScoreboardName();
2021-01-29 17:54:03 +01:00
+ this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper
2021-06-11 07:00:00 +02:00
+ this.bukkitPickUpLoot = true;
2014-11-25 22:32:16 +01:00
+ this.maxHealthCache = this.getMaxHealth();
2022-04-24 22:56:59 +02:00
}
2024-04-27 23:27:19 +02:00
+ // Use method to resend items in hands in case of client desync, because the item use got cancelled.
+ // For example, when cancelling the leash event
+ public void resendItemInHands() {
2024-12-11 22:26:55 +01:00
+ this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> {
+ this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem());
2024-04-27 23:27:19 +02:00
+ });
2024-12-11 22:26:55 +01:00
+ this.containerSynchronizer.sendSlotChange(this.inventoryMenu, InventoryMenu.SHIELD_SLOT, this.getOffhandItem());
2024-04-27 23:27:19 +02:00
+ }
+
2018-07-15 02:00:00 +02:00
+ // Yes, this doesn't match Vanilla, but it's the best we can do for now.
+ // If this is an issue, PRs are welcome
2024-12-11 22:26:55 +01:00
+ public final BlockPos getSpawnPoint(ServerLevel worldserver) {
+ BlockPos blockposition = worldserver.getSharedSpawnPos();
2018-07-15 02:00:00 +02:00
+
2024-12-11 22:26:55 +01:00
+ if (worldserver.dimensionType().hasSkyLight() && worldserver.serverLevelData.getGameType() != GameType.ADVENTURE) {
2021-11-21 23:00:00 +01:00
+ int i = Math.max(0, this.server.getSpawnRadius(worldserver));
2024-12-11 22:26:55 +01:00
+ int j = Mth.floor(worldserver.getWorldBorder().getDistanceToBorder((double) blockposition.getX(), (double) blockposition.getZ()));
2018-07-15 02:00:00 +02:00
+
+ if (j < i) {
+ i = j;
+ }
+
+ if (j <= 1) {
+ i = 1;
+ }
+
2020-06-25 02:00:00 +02:00
+ long k = (long) (i * 2 + 1);
+ long l = k * k;
+ int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l;
2021-11-21 23:00:00 +01:00
+ int j1 = this.getCoprime(i1);
2022-06-07 18:00:00 +02:00
+ int k1 = RandomSource.create().nextInt(i1);
2018-07-15 02:00:00 +02:00
+
2020-06-25 02:00:00 +02:00
+ for (int l1 = 0; l1 < i1; ++l1) {
+ int i2 = (k1 + j1 * l1) % i1;
+ int j2 = i2 % (i * 2 + 1);
+ int k2 = i2 / (i * 2 + 1);
2024-12-11 22:26:55 +01:00
+ BlockPos blockposition1 = PlayerRespawnLogic.getOverworldRespawnPos(worldserver, blockposition.getX() + j2 - i, blockposition.getZ() + k2 - i);
2018-07-15 02:00:00 +02:00
+
+ if (blockposition1 != null) {
2020-06-30 02:35:28 +02:00
+ return blockposition1;
2018-07-15 02:00:00 +02:00
+ }
+ }
+ }
+
2018-03-07 11:43:33 +01:00
+ return blockposition;
2022-04-24 22:56:59 +02:00
+ }
2018-03-07 11:43:33 +01:00
+ // CraftBukkit end
2022-04-24 22:56:59 +02:00
+
2024-06-13 17:05:00 +02:00
@Override
2024-12-11 22:26:55 +01:00
public BlockPos adjustSpawnLocation(ServerLevel world, BlockPos basePos) {
AABB axisalignedbb = this.getDimensions(Pose.STANDING).makeBoundingBox(Vec3.ZERO);
BlockPos blockposition1 = basePos;
2020-07-17 00:56:56 +02:00
2024-12-11 22:26:55 +01:00
- if (world.dimensionType().hasSkyLight() && world.getServer().getWorldData().getGameType() != GameType.ADVENTURE) {
+ if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
int i = Math.max(0, this.server.getSpawnRadius(world));
int j = Mth.floor(world.getWorldBorder().getDistanceToBorder((double) basePos.getX(), (double) basePos.getZ()));
2020-07-17 00:56:56 +02:00
2022-01-14 19:20:40 +01:00
@@ -395,14 +545,20 @@
2024-10-22 17:15:00 +02:00
2024-12-11 22:26:55 +01:00
Objects.requireNonNull(basePos);
crashreportsystemdetails.setDetail("Origin", basePos::toString);
2024-10-22 17:15:00 +02:00
+ // CraftBukkit start - decompile error
+ int finalI = i;
crashreportsystemdetails.setDetail("Radius", () -> {
- return Integer.toString(i);
+ return Integer.toString(finalI);
+ // CraftBukkit end
});
crashreportsystemdetails.setDetail("Candidate", () -> {
return "[" + l2 + "," + i3 + "]";
});
+ // CraftBukkit start - decompile error
+ int finalL1 = l1;
crashreportsystemdetails.setDetail("Progress", () -> {
- return "" + l1 + " out of " + i1;
+ return "" + finalL1 + " out of " + i1;
+ // CraftBukkit end
});
throw new ReportedException(crashreport);
}
2022-01-14 19:20:40 +01:00
@@ -440,7 +596,7 @@
2024-12-11 22:26:55 +01:00
dataresult = WardenSpawnTracker.CODEC.parse(new Dynamic(NbtOps.INSTANCE, nbt.get("warden_spawn_tracker")));
logger = ServerPlayer.LOGGER;
2022-12-07 17:00:00 +01:00
Objects.requireNonNull(logger);
2024-04-23 17:15:00 +02:00
- dataresult.resultOrPartial(logger::error).ifPresent((wardenspawntracker) -> {
+ ((DataResult<WardenSpawnTracker>) dataresult).resultOrPartial(logger::error).ifPresent((wardenspawntracker) -> {
this.wardenSpawnTracker = wardenspawntracker;
});
}
2022-01-14 19:20:40 +01:00
@@ -457,17 +613,26 @@
2024-10-22 17:15:00 +02:00
return this.server.getRecipeManager().byKey(resourcekey).isPresent();
});
2014-11-25 22:32:16 +01:00
}
2024-12-11 22:26:55 +01:00
+ this.getBukkitEntity().readExtraData(nbt); // CraftBukkit
2017-05-14 04:00:00 +02:00
2019-04-23 04:00:00 +02:00
if (this.isSleeping()) {
2021-11-21 23:00:00 +01:00
this.stopSleeping();
2022-06-12 20:47:24 +02:00
}
2022-04-24 22:56:59 +02:00
2020-06-25 02:00:00 +02:00
+ // CraftBukkit start
2024-12-11 22:26:55 +01:00
+ String spawnWorld = nbt.getString("SpawnWorld");
2020-06-25 02:00:00 +02:00
+ CraftWorld oldWorld = (CraftWorld) Bukkit.getWorld(spawnWorld);
+ if (oldWorld != null) {
2021-11-21 23:00:00 +01:00
+ this.respawnDimension = oldWorld.getHandle().dimension();
2022-06-12 20:47:24 +02:00
+ }
2020-06-25 02:00:00 +02:00
+ // CraftBukkit end
2022-04-24 22:56:59 +02:00
+
2024-12-11 22:26:55 +01:00
if (nbt.contains("SpawnX", 99) && nbt.contains("SpawnY", 99) && nbt.contains("SpawnZ", 99)) {
this.respawnPosition = new BlockPos(nbt.getInt("SpawnX"), nbt.getInt("SpawnY"), nbt.getInt("SpawnZ"));
this.respawnForced = nbt.getBoolean("SpawnForced");
this.respawnAngle = nbt.getFloat("SpawnAngle");
if (nbt.contains("SpawnDimension")) {
- DataResult dataresult1 = Level.RESOURCE_KEY_CODEC.parse(NbtOps.INSTANCE, nbt.get("SpawnDimension"));
+ DataResult<ResourceKey<Level>> dataresult1 = Level.RESOURCE_KEY_CODEC.parse(NbtOps.INSTANCE, nbt.get("SpawnDimension")); // CraftBukkit - decompile error
Logger logger1 = ServerPlayer.LOGGER;
2022-02-28 16:00:00 +01:00
2022-12-07 17:00:00 +01:00
Objects.requireNonNull(logger1);
2022-01-14 19:20:40 +01:00
@@ -482,7 +647,7 @@
2024-12-11 22:26:55 +01:00
dataresult = BlockPos.CODEC.parse(NbtOps.INSTANCE, nbtbase);
logger = ServerPlayer.LOGGER;
2024-04-23 17:15:00 +02:00
Objects.requireNonNull(logger);
- dataresult.resultOrPartial(logger::error).ifPresent((blockposition) -> {
2024-12-11 22:26:55 +01:00
+ ((DataResult<BlockPos>) dataresult).resultOrPartial(logger::error).ifPresent((blockposition) -> { // CraftBukkit - decompile error
2024-04-23 17:15:00 +02:00
this.raidOmenPosition = blockposition;
});
}
2022-01-14 19:20:40 +01:00
@@ -492,7 +657,7 @@
2022-12-07 17:00:00 +01:00
@Override
2024-12-11 22:26:55 +01:00
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
- DataResult dataresult = WardenSpawnTracker.CODEC.encodeStart(NbtOps.INSTANCE, this.wardenSpawnTracker);
+ DataResult<Tag> dataresult = WardenSpawnTracker.CODEC.encodeStart(NbtOps.INSTANCE, this.wardenSpawnTracker); // CraftBukkit - decompile error
Logger logger = ServerPlayer.LOGGER;
2022-12-07 17:00:00 +01:00
Objects.requireNonNull(logger);
2022-01-14 19:20:40 +01:00
@@ -526,6 +691,7 @@
2024-12-11 22:26:55 +01:00
nbt.put("SpawnDimension", nbtbase);
2024-10-22 17:15:00 +02:00
});
}
2024-12-11 22:26:55 +01:00
+ this.getBukkitEntity().setExtraData(nbt); // CraftBukkit
2024-10-22 17:15:00 +02:00
2024-12-11 22:26:55 +01:00
nbt.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall);
2024-10-22 17:15:00 +02:00
if (this.raidOmenPosition != null) {
2022-01-14 19:20:40 +01:00
@@ -544,7 +710,20 @@
2018-06-14 19:59:21 +02:00
Entity entity = this.getRootVehicle();
Entity entity1 = this.getVehicle();
2021-11-21 23:00:00 +01:00
- if (entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger()) {
2018-06-14 19:59:21 +02:00
+ // CraftBukkit start - handle non-persistent vehicles
+ boolean persistVehicle = true;
+ if (entity1 != null) {
+ Entity vehicle;
+ for (vehicle = entity1; vehicle != null; vehicle = vehicle.getVehicle()) {
+ if (!vehicle.persist) {
+ persistVehicle = false;
+ break;
+ }
+ }
+ }
+
2021-09-28 09:47:47 +02:00
+ if (persistVehicle && entity1 != null && entity != this && entity.hasExactlyOnePlayerPassenger() && !entity.isRemoved()) { // Paper - Ensure valid vehicle status
2018-06-14 19:59:21 +02:00
+ // CraftBukkit end
2024-12-11 22:26:55 +01:00
CompoundTag nbttagcompound1 = new CompoundTag();
CompoundTag nbttagcompound2 = new CompoundTag();
2018-06-14 19:59:21 +02:00
2022-01-14 19:20:40 +01:00
@@ -564,7 +743,7 @@
2019-03-24 05:24:52 +01:00
ServerLevel worldserver = (ServerLevel) world;
CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle");
Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver, EntitySpawnReason.LOAD, (entity1) -> {
- return !worldserver.addWithUUID(entity1) ? null : entity1;
+ return !worldserver.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // CraftBukkit - decompile error // Paper - Entity#getEntitySpawnReason
});
if (entity == null) {
2022-01-14 19:20:40 +01:00
@@ -598,12 +777,12 @@
2024-04-23 17:15:00 +02:00
2024-10-22 17:15:00 +02:00
if (!this.isPassenger()) {
2024-12-11 22:26:55 +01:00
ServerPlayer.LOGGER.warn("Couldn't reattach entity to player");
2024-10-22 17:15:00 +02:00
- entity.discard();
+ entity.discard(null); // CraftBukkit - add Bukkit remove cause
iterator = entity.getIndirectPassengers().iterator();
while (iterator.hasNext()) {
entity1 = (Entity) iterator.next();
- entity1.discard();
+ entity1.discard(null); // CraftBukkit - add Bukkit remove cause
}
}
}
2022-01-14 19:20:40 +01:00
@@ -625,7 +804,7 @@
2024-12-11 22:26:55 +01:00
CompoundTag nbttagcompound1 = new CompoundTag();
2024-10-22 17:15:00 +02:00
entityenderpearl.save(nbttagcompound1);
2024-12-11 22:26:55 +01:00
- DataResult dataresult = ResourceLocation.CODEC.encodeStart(NbtOps.INSTANCE, entityenderpearl.level().dimension().location());
+ DataResult<Tag> dataresult = ResourceLocation.CODEC.encodeStart(NbtOps.INSTANCE, entityenderpearl.level().dimension().location()); // CraftBukkit - decompile error
Logger logger = ServerPlayer.LOGGER;
2024-10-22 17:15:00 +02:00
Objects.requireNonNull(logger);
2022-01-14 19:20:40 +01:00
@@ -651,7 +830,7 @@
2024-10-22 17:15:00 +02:00
nbttaglist.forEach((nbtbase1) -> {
2024-12-11 22:26:55 +01:00
if (nbtbase1 instanceof CompoundTag nbttagcompound) {
2024-10-22 17:15:00 +02:00
if (nbttagcompound.contains("ender_pearl_dimension")) {
2024-12-11 22:26:55 +01:00
- DataResult dataresult = Level.RESOURCE_KEY_CODEC.parse(NbtOps.INSTANCE, nbttagcompound.get("ender_pearl_dimension"));
+ DataResult<ResourceKey<Level>> dataresult = Level.RESOURCE_KEY_CODEC.parse(NbtOps.INSTANCE, nbttagcompound.get("ender_pearl_dimension")); // CraftBukkit - decompile error
Logger logger = ServerPlayer.LOGGER;
2024-10-22 17:15:00 +02:00
Objects.requireNonNull(logger);
2022-01-14 19:20:40 +01:00
@@ -684,7 +863,30 @@
}
}
2020-06-25 02:00:00 +02:00
2022-01-14 19:20:40 +01:00
+ }
+
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - World fallback code, either respawn location or global spawn
2024-12-11 22:26:55 +01:00
+ public void spawnIn(Level world) {
2023-06-07 17:30:00 +02:00
+ this.setLevel(world);
2014-11-25 22:32:16 +01:00
+ if (world == null) {
2021-06-11 07:00:00 +02:00
+ this.unsetRemoved();
2024-12-11 22:26:55 +01:00
+ Vec3 position = null;
2021-06-11 07:00:00 +02:00
+ if (this.respawnDimension != null) {
2023-04-19 11:59:19 +02:00
+ world = this.server.getLevel(this.respawnDimension);
2021-11-21 23:00:00 +01:00
+ if (world != null && this.getRespawnPosition() != null) {
2024-12-11 22:26:55 +01:00
+ position = ServerPlayer.findRespawnAndUseSpawnBlock((ServerLevel) world, this.getRespawnPosition(), this.getRespawnAngle(), false, false).map(ServerPlayer.RespawnPosAngle::position).orElse(null);
2014-11-25 22:32:16 +01:00
+ }
+ }
+ if (world == null || position == null) {
+ world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
2024-12-11 22:26:55 +01:00
+ position = Vec3.atCenterOf(world.getSharedSpawnPos());
2014-11-25 22:32:16 +01:00
+ }
2023-06-07 17:30:00 +02:00
+ this.setLevel(world);
2020-04-10 03:20:33 +02:00
+ this.setPosRaw(position.x(), position.y(), position.z()); // Paper - don't register to chunks yet
2014-11-25 22:32:16 +01:00
+ }
2024-12-11 22:26:55 +01:00
+ this.gameMode.setLevel((ServerLevel) world);
2022-01-14 19:20:40 +01:00
}
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2022-01-14 19:20:40 +01:00
2024-12-11 22:26:55 +01:00
public void setExperiencePoints(int points) {
2021-11-21 23:00:00 +01:00
float f = (float) this.getXpNeededForNextLevel();
2022-01-14 19:20:40 +01:00
@@ -744,6 +946,11 @@
2014-11-25 22:32:16 +01:00
2019-04-23 04:00:00 +02:00
@Override
2018-07-15 02:00:00 +02:00
public void tick() {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
+ if (this.joining) {
+ this.joining = false;
+ }
+ // CraftBukkit end
2024-12-03 17:20:00 +01:00
this.tickClientLoadTimeout();
2021-11-21 23:00:00 +01:00
this.gameMode.tick();
2022-12-07 17:00:00 +01:00
this.wardenSpawnTracker.tick();
2022-01-14 19:20:40 +01:00
@@ -751,9 +958,13 @@
2016-03-03 06:34:44 +01:00
--this.invulnerableTime;
}
- this.containerMenu.broadcastChanges();
2020-04-13 08:31:44 +02:00
- if (!this.containerMenu.stillValid(this)) {
- this.closeContainer();
2016-03-03 06:34:44 +01:00
+ if (--this.containerUpdateDelay <= 0) {
+ this.containerMenu.broadcastChanges();
+ this.containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate;
+ }
+ // Paper end - Configurable container update tick rate
2020-04-13 08:31:44 +02:00
+ if (this.containerMenu != this.inventoryMenu && (this.isImmobile() || !this.containerMenu.stillValid(this))) { // Paper - Prevent opening inventories when frozen
2018-07-04 03:56:23 +02:00
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason
2016-03-03 06:34:44 +01:00
this.containerMenu = this.inventoryMenu;
2018-07-04 03:56:23 +02:00
}
2022-01-14 19:20:40 +01:00
@@ -807,7 +1018,7 @@
2020-04-02 23:16:48 +02:00
public void doTick() {
try {
- if (!this.isSpectator() || !this.touchingUnloadedChunk()) {
+ if (valid && !this.isSpectator() || !this.touchingUnloadedChunk()) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
super.tick();
}
2022-01-14 19:20:40 +01:00
@@ -820,7 +1031,7 @@
2016-03-05 22:38:01 +01:00
}
2021-06-11 07:00:00 +02:00
if (this.getHealth() != this.lastSentHealth || this.lastSentFood != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) {
2024-12-11 22:26:55 +01:00
- this.connection.send(new ClientboundSetHealthPacket(this.getHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel()));
+ this.connection.send(new ClientboundSetHealthPacket(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); // CraftBukkit
2021-06-11 07:00:00 +02:00
this.lastSentHealth = this.getHealth();
this.lastSentFood = this.foodData.getFoodLevel();
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
2022-01-14 19:20:40 +01:00
@@ -851,6 +1062,12 @@
2024-12-11 22:26:55 +01:00
this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float) this.lastRecordedExperience));
2016-04-19 21:09:31 +02:00
}
2018-10-21 04:34:02 +02:00
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - Force max health updates
+ if (this.maxHealthCache != this.getMaxHealth()) {
+ this.getBukkitEntity().updateScaledHealth();
2016-04-19 21:09:31 +02:00
+ }
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2018-10-21 04:34:02 +02:00
+
2021-06-11 07:00:00 +02:00
if (this.experienceLevel != this.lastRecordedLevel) {
this.lastRecordedLevel = this.experienceLevel;
2018-10-21 04:34:02 +02:00
this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float) this.lastRecordedLevel));
2022-01-14 19:20:40 +01:00
@@ -863,8 +1080,22 @@
2021-04-23 23:42:42 +02:00
2022-01-14 19:20:40 +01:00
if (this.tickCount % 20 == 0) {
CriteriaTriggers.LOCATION.trigger(this);
+ }
+
2022-04-09 01:39:33 +02:00
+ // CraftBukkit start - initialize oldLevel, fire PlayerLevelChangeEvent, and tick client-sided world border
2014-11-25 22:32:16 +01:00
+ if (this.oldLevel == -1) {
2021-06-11 07:00:00 +02:00
+ this.oldLevel = this.experienceLevel;
2022-01-14 19:20:40 +01:00
}
2021-06-11 07:00:00 +02:00
+ if (this.oldLevel != this.experienceLevel) {
2021-06-20 01:27:32 +02:00
+ CraftEventFactory.callPlayerLevelChangeEvent(this.getBukkitEntity(), this.oldLevel, this.experienceLevel);
2021-06-11 07:00:00 +02:00
+ this.oldLevel = this.experienceLevel;
2021-04-23 23:42:42 +02:00
+ }
+
2022-04-09 01:39:33 +02:00
+ if (this.getBukkitEntity().hasClientWorldBorder()) {
+ ((CraftWorldBorder) this.getBukkitEntity().getWorldBorder()).getHandle().tick();
+ }
2015-02-26 23:41:06 +01:00
+ // CraftBukkit end
2014-11-25 22:32:16 +01:00
} catch (Throwable throwable) {
2021-11-21 23:00:00 +01:00
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking player");
2024-12-11 22:26:55 +01:00
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Player being ticked");
2022-01-14 19:20:40 +01:00
@@ -893,7 +1124,7 @@
2024-12-11 22:26:55 +01:00
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
2024-10-22 17:15:00 +02:00
if (this.tickCount % 20 == 0) {
if (this.getHealth() < this.getMaxHealth()) {
- this.heal(1.0F);
+ this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit - added regain reason of "REGEN" for filtering purposes.
}
float f = this.foodData.getSaturationLevel();
2022-01-14 19:20:40 +01:00
@@ -946,19 +1177,105 @@
2016-03-12 07:57:40 +01:00
}
2024-12-11 22:26:55 +01:00
private void updateScoreForCriteria(ObjectiveCriteria criterion, int score) {
- this.getScoreboard().forAllObjectives(criterion, this, (scoreaccess) -> {
2018-07-15 02:00:00 +02:00
+ // CraftBukkit - Use our scores instead
2024-12-11 22:26:55 +01:00
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(criterion, this, (scoreaccess) -> {
scoreaccess.set(score);
2018-07-15 02:00:00 +02:00
});
2022-06-12 20:47:24 +02:00
}
2019-03-28 04:01:33 +01:00
+ // Paper start - PlayerDeathEvent#getItemsToKeep
+ private static void processKeep(org.bukkit.event.entity.PlayerDeathEvent event, NonNullList<ItemStack> inv) {
+ List<org.bukkit.inventory.ItemStack> itemsToKeep = event.getItemsToKeep();
+ if (inv == null) {
+ // remainder of items left in toKeep - plugin added stuff on death that wasn't in the initial loot?
+ if (!itemsToKeep.isEmpty()) {
+ for (org.bukkit.inventory.ItemStack itemStack : itemsToKeep) {
+ event.getEntity().getInventory().addItem(itemStack);
+ }
+ }
+
+ return;
+ }
+
+ for (int i = 0; i < inv.size(); ++i) {
+ ItemStack item = inv.get(i);
+ if (EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP) || itemsToKeep.isEmpty() || item.isEmpty()) {
+ inv.set(i, ItemStack.EMPTY);
+ continue;
+ }
+
+ final org.bukkit.inventory.ItemStack bukkitStack = item.getBukkitStack();
+ boolean keep = false;
+ final Iterator<org.bukkit.inventory.ItemStack> iterator = itemsToKeep.iterator();
+ while (iterator.hasNext()) {
+ final org.bukkit.inventory.ItemStack itemStack = iterator.next();
+ if (bukkitStack.equals(itemStack)) {
+ iterator.remove();
+ keep = true;
+ break;
+ }
+ }
+
+ if (!keep) {
+ inv.set(i, ItemStack.EMPTY);
+ }
+ }
2022-06-12 20:47:24 +02:00
+ }
2019-03-28 04:01:33 +01:00
+ // Paper end - PlayerDeathEvent#getItemsToKeep
2022-06-12 20:47:24 +02:00
+
2018-08-21 02:39:35 +02:00
@Override
2024-12-11 22:26:55 +01:00
public void die(DamageSource damageSource) {
2018-08-21 02:39:35 +02:00
- this.gameEvent(GameEvent.ENTITY_DIE);
+ // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check
2024-10-22 17:15:00 +02:00
boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - fire PlayerDeathEvent
2021-06-11 07:00:00 +02:00
+ if (this.isRemoved()) {
2014-11-25 22:32:16 +01:00
+ return;
+ }
2024-06-29 06:03:10 +02:00
+ java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize());
2024-10-22 17:15:00 +02:00
+ boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
2023-09-21 18:57:13 +02:00
- if (flag) {
2024-12-11 22:26:55 +01:00
- Component ichatbasecomponent = this.getCombatTracker().getDeathMessage();
2014-11-25 22:32:16 +01:00
+ if (!keepInventory) {
2021-06-11 07:00:00 +02:00
+ for (ItemStack item : this.getInventory().getContents()) {
2024-12-11 22:26:55 +01:00
+ if (!item.isEmpty() && !EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) {
2024-07-06 09:25:39 +02:00
+ loot.add(CraftItemStack.asCraftMirror(item).markForInventoryDrop());
2016-02-29 22:32:46 +01:00
+ }
2014-11-25 22:32:16 +01:00
+ }
2019-07-22 04:12:48 +02:00
+ }
2022-03-22 17:50:40 +01:00
+ if (this.shouldDropLoot() && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
2019-07-22 04:12:48 +02:00
+ // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
2024-12-11 22:26:55 +01:00
+ this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0);
+ this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag);
2019-03-28 04:01:33 +01:00
2024-06-29 06:03:10 +02:00
+ loot.addAll(this.drops);
2019-07-22 04:12:48 +02:00
+ this.drops.clear(); // SPIGOT-5188: make sure to clear
2022-03-22 17:50:40 +01:00
+ } // Paper - fix player loottables running when mob loot gamerule is false
2023-09-21 18:57:13 +02:00
+
2024-12-11 22:26:55 +01:00
+ Component defaultMessage = this.getCombatTracker().getDeathMessage();
2018-06-14 19:59:21 +02:00
+
2018-08-26 04:00:00 +02:00
+ String deathmessage = defaultMessage.getString();
2024-12-11 22:26:55 +01:00
+ this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
2021-01-29 17:54:03 +01:00
+ org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, damageSource, loot, PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure
2018-08-21 02:39:35 +02:00
+ // Paper start - cancellable death event
+ if (event.isCancelled()) {
+ // make compatible with plugins that might have already set the health in an event listener
+ if (this.getHealth() <= 0) {
+ this.setHealth((float) event.getReviveHealth());
+ }
+ return;
+ }
+ this.gameEvent(GameEvent.ENTITY_DIE); // moved from the top of this method
+ // Paper end
2018-09-28 09:32:19 +02:00
+
2018-12-27 01:36:53 +01:00
+ // SPIGOT-943 - only call if they have an inventory open
2021-06-11 07:00:00 +02:00
+ if (this.containerMenu != this.inventoryMenu) {
2018-07-04 03:56:23 +02:00
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper - Inventory close reason
2018-12-27 01:36:53 +01:00
+ }
2018-11-15 14:38:37 +01:00
+
2018-07-04 03:56:23 +02:00
+ net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
2019-03-28 04:01:33 +01:00
+
2021-01-29 17:54:03 +01:00
+ if (deathMessage != null && deathMessage != net.kyori.adventure.text.Component.empty() && flag) { // Paper - Adventure // TODO: allow plugins to override?
+ Component ichatbasecomponent = PaperAdventure.asVanilla(deathMessage); // Paper - Adventure
2014-11-25 22:32:16 +01:00
+
2023-06-07 17:30:00 +02:00
this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), ichatbasecomponent), PacketSendListener.exceptionallySend(() -> {
2022-07-27 20:00:00 +02:00
boolean flag1 = true;
2021-01-29 17:54:03 +01:00
String s = ichatbasecomponent.getString(256);
2022-01-14 19:20:40 +01:00
@@ -988,12 +1305,23 @@
2024-10-22 17:15:00 +02:00
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_FORGIVE_DEAD_PLAYERS)) {
2021-11-21 23:00:00 +01:00
this.tellNeutralMobsThatIDied();
2014-11-25 22:32:16 +01:00
}
2020-06-25 02:00:00 +02:00
-
2019-04-23 04:00:00 +02:00
- if (!this.isSpectator()) {
2024-12-11 22:26:55 +01:00
- this.dropAllDeathLoot(this.serverLevel(), damageSource);
2019-12-24 04:07:25 +01:00
+ // SPIGOT-5478 must be called manually now
2019-12-24 01:35:42 +01:00
+ if (event.shouldDropExperience()) this.dropExperience(this.serverLevel(), damageSource.getEntity()); // Paper - tie to event
2014-11-25 22:32:16 +01:00
+ // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
+ if (!event.getKeepInventory()) {
2019-03-28 04:01:33 +01:00
+ // Paper start - PlayerDeathEvent#getItemsToKeep
+ for (NonNullList<ItemStack> inv : this.getInventory().compartments) {
+ processKeep(event, inv);
+ }
+ processKeep(event, null);
+ // Paper end - PlayerDeathEvent#getItemsToKeep
2019-04-23 06:00:30 +02:00
}
2018-12-27 01:36:53 +01:00
2024-12-11 22:26:55 +01:00
- this.getScoreboard().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this, ScoreAccess::increment);
2021-11-21 23:00:00 +01:00
+ this.setCamera(this); // Remove spectated target
2019-04-23 06:00:30 +02:00
+ // CraftBukkit end
+
2014-11-25 22:32:16 +01:00
+ // CraftBukkit - Get our scores instead
2024-12-11 22:26:55 +01:00
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this, ScoreAccess::increment);
LivingEntity entityliving = this.getKillCredit();
2014-11-25 22:32:16 +01:00
2018-07-15 02:00:00 +02:00
if (entityliving != null) {
2022-01-14 19:20:40 +01:00
@@ -1028,10 +1356,12 @@
2024-12-11 22:26:55 +01:00
public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
if (entityKilled != this) {
super.awardKillScore(entityKilled, damageSource);
- this.getScoreboard().forAllObjectives(ObjectiveCriteria.KILL_COUNT_ALL, this, ScoreAccess::increment);
- if (entityKilled instanceof Player) {
2017-05-14 04:00:00 +02:00
+ // CraftBukkit - Get our scores instead
2024-12-11 22:26:55 +01:00
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(ObjectiveCriteria.KILL_COUNT_ALL, this, ScoreAccess::increment);
+ if (entityKilled instanceof net.minecraft.world.entity.player.Player) {
this.awardStat(Stats.PLAYER_KILLS);
- this.getScoreboard().forAllObjectives(ObjectiveCriteria.KILL_COUNT_PLAYERS, this, ScoreAccess::increment);
2017-05-14 04:00:00 +02:00
+ // CraftBukkit - Get our scores instead
2024-12-11 22:26:55 +01:00
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(ObjectiveCriteria.KILL_COUNT_PLAYERS, this, ScoreAccess::increment);
2017-05-14 04:00:00 +02:00
} else {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.MOB_KILLS);
2017-05-14 04:00:00 +02:00
}
2022-01-14 19:20:40 +01:00
@@ -1049,7 +1379,8 @@
2021-11-21 23:00:00 +01:00
int i = scoreboardteam.getColor().getId();
2017-05-14 04:00:00 +02:00
2024-12-11 22:26:55 +01:00
if (i >= 0 && i < criterions.length) {
- this.getScoreboard().forAllObjectives(criterions[i], targetScoreHolder, ScoreAccess::increment);
2017-05-14 04:00:00 +02:00
+ // CraftBukkit - Get our scores instead
2024-12-11 22:26:55 +01:00
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(criterions[i], targetScoreHolder, ScoreAccess::increment);
2017-05-14 04:00:00 +02:00
}
}
2022-01-14 19:20:40 +01:00
@@ -1062,8 +1393,8 @@
2024-12-11 22:26:55 +01:00
} else {
Entity entity = source.getEntity();
- if (entity instanceof Player) {
- Player entityhuman = (Player) entity;
+ if (entity instanceof net.minecraft.world.entity.player.Player) {
+ net.minecraft.world.entity.player.Player entityhuman = (net.minecraft.world.entity.player.Player) entity;
if (!this.canHarmPlayer(entityhuman)) {
return false;
2022-01-14 19:20:40 +01:00
@@ -1074,8 +1405,8 @@
2024-12-11 22:26:55 +01:00
AbstractArrow entityarrow = (AbstractArrow) entity;
Entity entity1 = entityarrow.getOwner();
- if (entity1 instanceof Player) {
- Player entityhuman1 = (Player) entity1;
+ if (entity1 instanceof net.minecraft.world.entity.player.Player) {
+ net.minecraft.world.entity.player.Player entityhuman1 = (net.minecraft.world.entity.player.Player) entity1;
if (!this.canHarmPlayer(entityhuman1)) {
return false;
2022-01-14 19:20:40 +01:00
@@ -1083,38 +1414,84 @@
2018-08-21 02:39:35 +02:00
}
}
- return super.hurtServer(world, source, amount);
+ // Paper start - cancellable death events
+ // return super.hurtServer(world, source, amount);
+ this.queueHealthUpdatePacket = true;
+ boolean damaged = super.hurtServer(world, source, amount);
+ this.queueHealthUpdatePacket = false;
+ if (this.queuedHealthUpdatePacket != null) {
+ this.connection.send(this.queuedHealthUpdatePacket);
+ this.queuedHealthUpdatePacket = null;
+ }
+ return damaged;
+ // Paper end - cancellable death events
}
2024-12-11 22:26:55 +01:00
}
@Override
- public boolean canHarmPlayer(Player player) {
+ public boolean canHarmPlayer(net.minecraft.world.entity.player.Player player) {
return !this.isPvpAllowed() ? false : super.canHarmPlayer(player);
2014-11-25 22:32:16 +01:00
}
2021-11-21 23:00:00 +01:00
private boolean isPvpAllowed() {
- return this.server.isPvpAllowed();
+ // CraftBukkit - this.server.isPvpAllowed() -> this.world.pvpMode
2023-06-07 17:30:00 +02:00
+ return this.level().pvpMode;
2014-11-25 22:32:16 +01:00
}
2024-12-11 22:26:55 +01:00
- public TeleportTransition findRespawnPositionAndUseSpawnBlock(boolean alive, TeleportTransition.PostTeleportTransition postDimensionTransition) {
2024-06-13 17:05:00 +02:00
+ // CraftBukkit start
2024-12-11 22:26:55 +01:00
+ public TeleportTransition findRespawnPositionAndUseSpawnBlock(boolean flag, TeleportTransition.PostTeleportTransition teleporttransition_a, PlayerRespawnEvent.RespawnReason reason) {
2024-10-22 17:15:00 +02:00
+ TeleportTransition teleportTransition;
2024-06-13 17:05:00 +02:00
+ boolean isBedSpawn = false;
+ boolean isAnchorSpawn = false;
+ // CraftBukkit end
2024-12-11 22:26:55 +01:00
BlockPos blockposition = this.getRespawnPosition();
2024-06-13 17:05:00 +02:00
float f = this.getRespawnAngle();
boolean flag1 = this.isRespawnForced();
2024-12-11 22:26:55 +01:00
ServerLevel worldserver = this.server.getLevel(this.getRespawnDimension());
if (worldserver != null && blockposition != null) {
- Optional<ServerPlayer.RespawnPosAngle> optional = ServerPlayer.findRespawnAndUseSpawnBlock(worldserver, blockposition, f, flag1, alive);
+ Optional<ServerPlayer.RespawnPosAngle> optional = ServerPlayer.findRespawnAndUseSpawnBlock(worldserver, blockposition, f, flag1, flag);
2024-06-13 17:05:00 +02:00
if (optional.isPresent()) {
2024-12-11 22:26:55 +01:00
ServerPlayer.RespawnPosAngle entityplayer_respawnposangle = (ServerPlayer.RespawnPosAngle) optional.get();
2024-06-13 17:05:00 +02:00
2024-12-11 22:26:55 +01:00
- return new TeleportTransition(worldserver, entityplayer_respawnposangle.position(), Vec3.ZERO, entityplayer_respawnposangle.yaw(), 0.0F, postDimensionTransition);
2024-06-13 17:05:00 +02:00
+ // CraftBukkit start
+ isBedSpawn = entityplayer_respawnposangle.isBedSpawn();
+ isAnchorSpawn = entityplayer_respawnposangle.isAnchorSpawn();
2024-12-11 22:26:55 +01:00
+ teleportTransition = new TeleportTransition(worldserver, entityplayer_respawnposangle.position(), Vec3.ZERO, entityplayer_respawnposangle.yaw(), 0.0F, teleporttransition_a);
2024-06-13 17:05:00 +02:00
+ // CraftBukkit end
} else {
2024-12-11 22:26:55 +01:00
- return TeleportTransition.missingRespawnBlock(this.server.overworld(), this, postDimensionTransition);
2024-10-22 17:15:00 +02:00
+ teleportTransition = TeleportTransition.missingRespawnBlock(this.server.overworld(), this, teleporttransition_a); // CraftBukkit
2024-06-13 17:05:00 +02:00
}
2020-08-11 23:00:00 +02:00
} else {
2024-12-11 22:26:55 +01:00
- return new TeleportTransition(this.server.overworld(), this, postDimensionTransition);
2024-10-22 17:15:00 +02:00
+ teleportTransition = new TeleportTransition(this.server.overworld(), this, teleporttransition_a); // CraftBukkit
2024-07-06 09:25:39 +02:00
}
2019-04-23 04:00:00 +02:00
+ // CraftBukkit start
2024-06-13 17:05:00 +02:00
+ if (reason == null) {
2024-10-22 17:15:00 +02:00
+ return teleportTransition;
2024-07-06 09:25:39 +02:00
+ }
2019-04-23 04:00:00 +02:00
+
2024-06-13 17:05:00 +02:00
+ Player respawnPlayer = this.getBukkitEntity();
2024-10-22 17:15:00 +02:00
+ Location location = CraftLocation.toBukkit(teleportTransition.position(), teleportTransition.newLevel().getWorld(), teleportTransition.yRot(), teleportTransition.xRot());
2024-06-13 17:05:00 +02:00
+
2021-04-23 23:42:42 +02:00
+ // Paper start - respawn flags
+ com.google.common.collect.ImmutableSet.Builder<org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag> builder = com.google.common.collect.ImmutableSet.builder();
+ if (reason == org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.END_PORTAL) {
+ builder.add(org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag.END_PORTAL);
+ }
+ PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn, isAnchorSpawn, reason, builder);
+ // Paper end - respawn flags
2024-06-13 17:05:00 +02:00
+ this.level().getCraftServer().getPluginManager().callEvent(respawnEvent);
2013-06-11 21:23:03 +02:00
+ // Spigot Start
+ if (this.connection.isDisconnected()) {
+ return null;
+ }
+ // Spigot End
2024-06-13 17:05:00 +02:00
+
+ location = respawnEvent.getRespawnLocation();
+
2024-10-22 17:15:00 +02:00
+ return new TeleportTransition(((CraftWorld) location.getWorld()).getHandle(), CraftLocation.toVec3D(location), teleportTransition.deltaMovement(), location.getYaw(), location.getPitch(), teleportTransition.missingRespawnBlock(), teleportTransition.asPassenger(), teleportTransition.relatives(), teleportTransition.postTeleportTransition(), teleportTransition.cause());
2019-04-23 04:00:00 +02:00
+ // CraftBukkit end
2024-06-13 17:05:00 +02:00
}
2019-12-11 02:36:03 +01:00
2024-12-11 22:26:55 +01:00
public static Optional<ServerPlayer.RespawnPosAngle> findRespawnAndUseSpawnBlock(ServerLevel world, BlockPos pos, float spawnAngle, boolean spawnForced, boolean alive) {
2022-01-14 19:20:40 +01:00
@@ -1129,11 +1506,11 @@
2024-06-13 17:05:00 +02:00
}
2020-08-11 23:00:00 +02:00
2024-06-13 17:05:00 +02:00
return optional.map((vec3d) -> {
2024-12-11 22:26:55 +01:00
- return ServerPlayer.RespawnPosAngle.of(vec3d, pos);
+ return ServerPlayer.RespawnPosAngle.of(vec3d, pos, false, true); // CraftBukkit
2024-06-13 17:05:00 +02:00
});
2024-12-11 22:26:55 +01:00
} else if (block instanceof BedBlock && BedBlock.canSetSpawn(world)) {
return BedBlock.findStandUpPosition(EntityType.PLAYER, world, pos, (Direction) iblockdata.getValue(BedBlock.FACING), spawnAngle).map((vec3d) -> {
- return ServerPlayer.RespawnPosAngle.of(vec3d, pos);
+ return ServerPlayer.RespawnPosAngle.of(vec3d, pos, true, false); // CraftBukkit
2024-06-13 17:05:00 +02:00
});
2024-12-11 22:26:55 +01:00
} else if (!spawnForced) {
2024-06-13 17:05:00 +02:00
return Optional.empty();
2022-01-14 19:20:40 +01:00
@@ -1142,7 +1519,7 @@
2024-12-11 22:26:55 +01:00
BlockState iblockdata1 = world.getBlockState(pos.above());
2024-06-13 17:05:00 +02:00
boolean flag3 = iblockdata1.getBlock().isPossibleToRespawnInThis(iblockdata1);
2024-12-11 22:26:55 +01:00
- return flag2 && flag3 ? Optional.of(new ServerPlayer.RespawnPosAngle(new Vec3((double) pos.getX() + 0.5D, (double) pos.getY() + 0.1D, (double) pos.getZ() + 0.5D), spawnAngle)) : Optional.empty();
+ return flag2 && flag3 ? Optional.of(new ServerPlayer.RespawnPosAngle(new Vec3((double) pos.getX() + 0.5D, (double) pos.getY() + 0.1D, (double) pos.getZ() + 0.5D), spawnAngle, false, false)) : Optional.empty(); // CraftBukkit
2024-06-13 17:05:00 +02:00
}
}
2022-01-14 19:20:40 +01:00
@@ -1160,6 +1537,7 @@
2024-06-13 17:05:00 +02:00
@Nullable
@Override
2024-12-11 22:26:55 +01:00
public ServerPlayer teleport(TeleportTransition teleportTarget) {
2024-06-13 17:05:00 +02:00
+ if (this.isSleeping()) return null; // CraftBukkit - SPIGOT-3154
if (this.isRemoved()) {
return null;
} else {
2022-01-14 19:20:40 +01:00
@@ -1169,39 +1547,78 @@
2024-06-13 17:05:00 +02:00
2024-12-11 22:26:55 +01:00
ServerLevel worldserver = teleportTarget.newLevel();
ServerLevel worldserver1 = this.serverLevel();
- ResourceKey<Level> resourcekey = worldserver1.dimension();
2024-06-13 17:05:00 +02:00
+ // CraftBukkit start
2024-12-11 22:26:55 +01:00
+ ResourceKey<LevelStem> resourcekey = worldserver1.getTypeKey();
2024-10-22 17:15:00 +02:00
+ Location enter = this.getBukkitEntity().getLocation();
2024-12-11 22:26:55 +01:00
+ PositionMoveRotation absolutePosition = PositionMoveRotation.calculateAbsolute(PositionMoveRotation.of(this), PositionMoveRotation.of(teleportTarget), teleportTarget.relatives());
2022-12-15 19:33:39 +01:00
+ Location exit = /* (worldserver == null) ? null : // Paper - always non-null */CraftLocation.toBukkit(absolutePosition.position(), worldserver.getWorld(), absolutePosition.yRot(), absolutePosition.xRot());
2024-12-11 22:26:55 +01:00
+ PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.getBukkitEntity(), enter, exit, teleportTarget.cause());
2017-01-01 03:44:50 +01:00
+ // 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) {
+ tpEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), enter, exit, new org.bukkit.craftbukkit.block.CraftEndGateway(this.serverLevel().getWorld(), theEndGatewayBlockEntity));
+ }
+ // Paper end - gateway-specific teleport event
2024-10-22 17:15:00 +02:00
+ Bukkit.getServer().getPluginManager().callEvent(tpEvent);
+ Location newExit = tpEvent.getTo();
+ if (tpEvent.isCancelled() || newExit == null) {
+ return null;
+ }
+ if (!newExit.equals(exit)) {
+ worldserver = ((CraftWorld) newExit.getWorld()).getHandle();
2024-12-11 22:26:55 +01:00
+ teleportTarget = new TeleportTransition(worldserver, CraftLocation.toVec3D(newExit), Vec3.ZERO, newExit.getYaw(), newExit.getPitch(), teleportTarget.missingRespawnBlock(), teleportTarget.asPassenger(), Set.of(), teleportTarget.postTeleportTransition(), teleportTarget.cause());
2024-10-22 17:15:00 +02:00
+ }
+ // CraftBukkit end
2024-12-11 22:26:55 +01:00
+
if (!teleportTarget.asPassenger()) {
2024-10-22 17:15:00 +02:00
this.stopRiding();
}
2024-06-13 17:05:00 +02:00
- if (worldserver.dimension() == resourcekey) {
2024-12-11 22:26:55 +01:00
- this.connection.teleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives());
2024-10-22 17:15:00 +02:00
+ // CraftBukkit start
+ if (worldserver != null && worldserver.dimension() == worldserver1.dimension()) {
2024-12-11 22:26:55 +01:00
+ this.connection.internalTeleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives());
2024-06-13 17:05:00 +02:00
+ // CraftBukkit end
this.connection.resetPosition();
2024-12-11 22:26:55 +01:00
teleportTarget.postTeleportTransition().onTransition(this);
2024-06-13 17:05:00 +02:00
return this;
} else {
+ // CraftBukkit start
+ /*
this.isChangingDimension = true;
2024-12-11 22:26:55 +01:00
- LevelData worlddata = worldserver.getLevelData();
+ WorldData worlddata = worldserver.getLevelData();
- this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(worldserver), (byte) 3));
- this.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
+ this.connection.send(new PacketPlayOutRespawn(this.createCommonSpawnInfo(worldserver), (byte) 3));
+ this.connection.send(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
PlayerList playerlist = this.server.getPlayerList();
2024-06-13 17:05:00 +02:00
playerlist.sendPlayerPermissionLevel(this);
worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
this.unsetRemoved();
+ */
+ // CraftBukkit end
2024-12-11 22:26:55 +01:00
ProfilerFiller gameprofilerfiller = Profiler.get();
2024-10-22 17:15:00 +02:00
gameprofilerfiller.push("moving");
2024-12-11 22:26:55 +01:00
- if (resourcekey == Level.OVERWORLD && worldserver.dimension() == Level.NETHER) {
+ if (worldserver != null && resourcekey == LevelStem.OVERWORLD && worldserver.getTypeKey() == LevelStem.NETHER) { // CraftBukkit - empty to fall through to null to event
2021-11-21 23:00:00 +01:00
this.enteredNetherPosition = this.position();
2020-06-25 02:00:00 +02:00
}
2023-09-21 18:57:13 +02:00
2024-10-22 17:15:00 +02:00
gameprofilerfiller.pop();
gameprofilerfiller.push("placing");
2024-06-13 17:05:00 +02:00
+ // CraftBukkit start
2021-06-11 07:00:00 +02:00
+ this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds
2024-12-11 22:26:55 +01:00
+ LevelData worlddata = worldserver.getLevelData();
2020-01-12 01:02:13 +01:00
+
2024-12-11 22:26:55 +01:00
+ this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(worldserver), (byte) 3));
+ this.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
2020-08-11 23:00:00 +02:00
+ PlayerList playerlist = this.server.getPlayerList();
2020-01-12 01:02:13 +01:00
+
2021-11-21 23:00:00 +01:00
+ playerlist.sendPlayerPermissionLevel(this);
+ worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
2021-06-11 07:00:00 +02:00
+ this.unsetRemoved();
2020-08-11 23:00:00 +02:00
+ // CraftBukkit end
2023-06-07 17:30:00 +02:00
this.setServerLevel(worldserver);
2024-12-11 22:26:55 +01:00
- this.connection.teleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives());
+ this.connection.internalTeleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); // CraftBukkit - use internal teleport without event
2022-12-07 17:00:00 +01:00
this.connection.resetPosition();
2024-06-13 17:05:00 +02:00
worldserver.addDuringTeleport(this);
2024-10-22 17:15:00 +02:00
gameprofilerfiller.pop();
2022-01-14 19:20:40 +01:00
@@ -1215,12 +1632,35 @@
2020-08-11 23:00:00 +02:00
this.lastSentExp = -1;
2021-06-11 07:00:00 +02:00
this.lastSentHealth = -1.0F;
this.lastSentFood = -1;
2020-08-11 23:00:00 +02:00
+
+ // CraftBukkit start
+ PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld());
2023-06-07 17:30:00 +02:00
+ this.level().getCraftServer().getPluginManager().callEvent(changeEvent);
2020-08-11 23:00:00 +02:00
+ // CraftBukkit end
2021-01-24 17:55:19 +01:00
+ // Paper start - Reset shield blocking on dimension change
+ if (this.isBlocking()) {
+ this.stopUsingItem();
+ }
+ // Paper end - Reset shield blocking on dimension change
2024-06-13 17:05:00 +02:00
return this;
2020-08-11 23:00:00 +02:00
}
2022-01-14 19:20:40 +01:00
}
}
2020-08-14 00:26:40 +02:00
+ // CraftBukkit start
2022-01-14 19:20:40 +01:00
@Override
2024-06-13 17:05:00 +02:00
+ public CraftPortalEvent callPortalEvent(Entity entity, Location exit, TeleportCause cause, int searchRadius, int creationRadius) {
2020-08-14 00:26:40 +02:00
+ Location enter = this.getBukkitEntity().getLocation();
2020-11-13 08:06:34 +01:00
+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, searchRadius, true, creationRadius);
2020-08-14 00:26:40 +02:00
+ Bukkit.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null) {
+ return null;
2022-01-14 19:20:40 +01:00
+ }
2020-08-14 00:26:40 +02:00
+ return new CraftPortalEvent(event);
2022-01-14 19:20:40 +01:00
+ }
2020-08-14 00:26:40 +02:00
+ // CraftBukkit end
2022-01-14 19:20:40 +01:00
+
+ @Override
2024-12-11 22:26:55 +01:00
public void forceSetRotation(float yaw, float pitch) {
2022-01-14 19:20:40 +01:00
this.connection.send(new ClientboundPlayerRotationPacket(yaw, pitch));
}
@@ -1228,13 +1668,27 @@
2024-12-11 22:26:55 +01:00
public void triggerDimensionChangeTriggers(ServerLevel origin) {
ResourceKey<Level> resourcekey = origin.dimension();
ResourceKey<Level> resourcekey1 = this.level().dimension();
2021-05-15 02:06:25 +02:00
+ // CraftBukkit start
2024-12-11 22:26:55 +01:00
+ ResourceKey<Level> maindimensionkey = CraftDimensionUtil.getMainDimensionKey(origin);
+ ResourceKey<Level> maindimensionkey1 = CraftDimensionUtil.getMainDimensionKey(this.level());
2023-09-21 18:57:13 +02:00
2024-12-11 22:26:55 +01:00
- CriteriaTriggers.CHANGED_DIMENSION.trigger(this, resourcekey, resourcekey1);
- if (resourcekey == Level.NETHER && resourcekey1 == Level.OVERWORLD && this.enteredNetherPosition != null) {
2022-06-12 20:47:24 +02:00
+ // Paper start - Add option for strict advancement dimension checks
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.strictAdvancementDimensionCheck) {
+ maindimensionkey = resourcekey;
+ maindimensionkey1 = resourcekey1;
+ }
+ // Paper end - Add option for strict advancement dimension checks
2024-12-11 22:26:55 +01:00
+ CriteriaTriggers.CHANGED_DIMENSION.trigger(this, maindimensionkey, maindimensionkey1);
2021-05-15 02:06:25 +02:00
+ if (maindimensionkey != resourcekey || maindimensionkey1 != resourcekey1) {
2024-12-11 22:26:55 +01:00
+ CriteriaTriggers.CHANGED_DIMENSION.trigger(this, resourcekey, resourcekey1);
2021-05-15 02:06:25 +02:00
+ }
2023-09-21 18:57:13 +02:00
+
2024-12-11 22:26:55 +01:00
+ if (maindimensionkey == Level.NETHER && maindimensionkey1 == Level.OVERWORLD && this.enteredNetherPosition != null) {
2021-05-15 02:06:25 +02:00
+ // CraftBukkit end
2024-12-11 22:26:55 +01:00
CriteriaTriggers.NETHER_TRAVEL.trigger(this, this.enteredNetherPosition);
2021-05-15 02:06:25 +02:00
}
2024-12-11 22:26:55 +01:00
- if (resourcekey1 != Level.NETHER) {
+ if (maindimensionkey1 != Level.NETHER) { // CraftBukkit
2021-06-11 07:00:00 +02:00
this.enteredNetherPosition = null;
2021-05-15 02:06:25 +02:00
}
2022-01-14 19:20:40 +01:00
@@ -1251,36 +1705,63 @@
2021-11-21 23:00:00 +01:00
this.containerMenu.broadcastChanges();
2019-03-13 04:48:19 +01:00
}
2019-04-23 04:00:00 +02:00
- @Override
2024-12-11 22:26:55 +01:00
- public Either<Player.BedSleepingProblem, Unit> startSleepInBed(BlockPos pos) {
- Direction enumdirection = (Direction) this.level().getBlockState(pos).getValue(HorizontalDirectionalBlock.FACING);
2020-06-25 02:00:00 +02:00
-
+ // CraftBukkit start - moved bed result checks from below into separate method
2024-12-11 22:26:55 +01:00
+ private Either<net.minecraft.world.entity.player.Player.BedSleepingProblem, Unit> getBedResult(BlockPos blockposition, Direction enumdirection) {
2020-06-25 02:00:00 +02:00
if (!this.isSleeping() && this.isAlive()) {
2023-06-07 17:30:00 +02:00
- if (!this.level().dimensionType().natural()) {
2024-12-11 22:26:55 +01:00
- return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_HERE);
- } else if (!this.bedInRange(pos, enumdirection)) {
- return Either.left(Player.BedSleepingProblem.TOO_FAR_AWAY);
- } else if (this.bedBlocked(pos, enumdirection)) {
- return Either.left(Player.BedSleepingProblem.OBSTRUCTED);
2023-06-07 17:30:00 +02:00
+ if (!this.level().dimensionType().natural() || !this.level().dimensionType().bedWorks()) {
2024-12-11 22:26:55 +01:00
+ return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_POSSIBLE_HERE);
+ } else if (!this.bedInRange(blockposition, enumdirection)) {
+ return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.TOO_FAR_AWAY);
+ } else if (this.bedBlocked(blockposition, enumdirection)) {
+ return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.OBSTRUCTED);
2023-04-17 11:33:17 +02:00
} else {
2024-12-11 22:26:55 +01:00
- this.setRespawnPosition(this.level().dimension(), pos, this.getYRot(), false, true);
2021-05-20 03:59:10 +02:00
+ this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.BED); // Paper - Add PlayerSetSpawnEvent
2023-06-07 17:30:00 +02:00
if (this.level().isDay()) {
2024-12-11 22:26:55 +01:00
- return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
+ return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
2023-04-17 11:33:17 +02:00
} else {
2024-12-11 22:26:55 +01:00
if (!this.isCreative()) {
double d0 = 8.0D;
double d1 = 5.0D;
- Vec3 vec3d = Vec3.atBottomCenterOf(pos);
+ Vec3 vec3d = Vec3.atBottomCenterOf(blockposition);
List<Monster> list = this.level().getEntitiesOfClass(Monster.class, new AABB(vec3d.x() - 8.0D, vec3d.y() - 5.0D, vec3d.z() - 8.0D, vec3d.x() + 8.0D, vec3d.y() + 5.0D, vec3d.z() + 8.0D), (entitymonster) -> {
return entitymonster.isPreventingPlayerRest(this.serverLevel(), this);
});
if (!list.isEmpty()) {
- return Either.left(Player.BedSleepingProblem.NOT_SAFE);
+ return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_SAFE);
2020-06-25 02:00:00 +02:00
}
}
2024-12-11 22:26:55 +01:00
- Either<Player.BedSleepingProblem, Unit> either = super.startSleepInBed(pos).ifRight((unit) -> {
2020-06-25 02:00:00 +02:00
+ return Either.right(Unit.INSTANCE);
+ }
+ }
+ } else {
2024-12-11 22:26:55 +01:00
+ return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.OTHER_PROBLEM);
2020-06-25 02:00:00 +02:00
+ }
2019-03-13 04:48:19 +01:00
+ }
+
2019-04-23 04:00:00 +02:00
+ @Override
2024-12-11 22:26:55 +01:00
+ public Either<net.minecraft.world.entity.player.Player.BedSleepingProblem, Unit> startSleepInBed(BlockPos blockposition, boolean force) {
+ Direction enumdirection = (Direction) this.level().getBlockState(blockposition).getValue(HorizontalDirectionalBlock.FACING);
+ Either<net.minecraft.world.entity.player.Player.BedSleepingProblem, Unit> bedResult = this.getBedResult(blockposition, enumdirection);
2020-06-25 02:00:00 +02:00
+
2024-12-11 22:26:55 +01:00
+ if (bedResult.left().orElse(null) == net.minecraft.world.entity.player.Player.BedSleepingProblem.OTHER_PROBLEM) {
2020-06-25 02:00:00 +02:00
+ return bedResult; // return immediately if the result is not bypassable by plugins
+ }
+
+ if (force) {
+ bedResult = Either.right(Unit.INSTANCE);
+ }
+
+ bedResult = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBedEnterEvent(this, blockposition, bedResult);
+ if (bedResult.left().isPresent()) {
+ return bedResult;
+ }
+
+ {
+ {
+ {
2024-12-11 22:26:55 +01:00
+ Either<net.minecraft.world.entity.player.Player.BedSleepingProblem, Unit> either = super.startSleepInBed(blockposition, force).ifRight((unit) -> {
this.awardStat(Stats.SLEEP_IN_BED);
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
2020-06-25 02:00:00 +02:00
});
2022-01-14 19:20:40 +01:00
@@ -1293,9 +1774,8 @@
2020-06-25 02:00:00 +02:00
return either;
}
}
- } else {
2024-12-11 22:26:55 +01:00
- return Either.left(Player.BedSleepingProblem.OTHER_PROBLEM);
2020-06-25 02:00:00 +02:00
}
2019-03-13 04:48:19 +01:00
+ // CraftBukkit end
2020-06-25 02:00:00 +02:00
}
@Override
2022-01-14 19:20:40 +01:00
@@ -1322,13 +1802,31 @@
2014-11-25 22:32:16 +01:00
2019-04-23 04:00:00 +02:00
@Override
2024-12-11 22:26:55 +01:00
public void stopSleepInBed(boolean skipSleepTimer, boolean updateSleepingPlayers) {
2019-04-23 04:00:00 +02:00
+ if (!this.isSleeping()) return; // CraftBukkit - Can't leave bed if not in one!
2021-01-29 01:22:42 +01:00
+ // CraftBukkit start - fire PlayerBedLeaveEvent
+ CraftPlayer player = this.getBukkitEntity();
2024-12-11 22:26:55 +01:00
+ BlockPos bedPosition = this.getSleepingPos().orElse(null);
2021-01-29 01:22:42 +01:00
+
+ org.bukkit.block.Block bed;
+ if (bedPosition != null) {
2023-06-07 17:30:00 +02:00
+ bed = this.level().getWorld().getBlockAt(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ());
2021-01-29 01:22:42 +01:00
+ } else {
2023-06-07 17:30:00 +02:00
+ bed = this.level().getWorld().getBlockAt(player.getLocation());
2021-01-29 01:22:42 +01:00
+ }
+
+ PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed, true);
2023-06-07 17:30:00 +02:00
+ this.level().getCraftServer().getPluginManager().callEvent(event);
2021-01-29 01:22:42 +01:00
+ if (event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
2014-11-25 22:32:16 +01:00
if (this.isSleeping()) {
2024-12-11 22:26:55 +01:00
this.serverLevel().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(this, 2));
2015-02-20 05:37:17 +01:00
}
2023-07-29 01:58:01 +02:00
2024-12-11 22:26:55 +01:00
super.stopSleepInBed(skipSleepTimer, updateSleepingPlayers);
2023-07-29 01:58:01 +02:00
if (this.connection != null) {
- this.connection.teleport(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
+ this.connection.teleport(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot(), TeleportCause.EXIT_BED); // CraftBukkit
}
}
2022-01-14 19:20:40 +01:00
@@ -1341,7 +1839,7 @@
2021-06-20 17:35:42 +02:00
@Override
public boolean isInvulnerableTo(ServerLevel world, DamageSource source) {
- return super.isInvulnerableTo(world, source) || this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL) || !this.hasClientLoaded();
+ return (super.isInvulnerableTo(world, source) || this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL) || !this.hasClientLoaded()) || (!this.level().paperConfig().collisions.allowPlayerCrammingDamage && source.is(DamageTypes.CRAMMING)); // Paper - disable player cramming
}
@Override
2022-01-14 19:20:40 +01:00
@@ -1387,8 +1885,9 @@
2024-12-11 22:26:55 +01:00
this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front));
2014-11-25 22:32:16 +01:00
}
2016-02-29 22:32:46 +01:00
- public void nextContainerCounter() {
+ public int nextContainerCounter() { // CraftBukkit - void -> int
2014-11-25 22:32:16 +01:00
this.containerCounter = this.containerCounter % 100 + 1;
2024-12-11 22:26:55 +01:00
+ return this.containerCounter; // CraftBukkit
2014-11-25 22:32:16 +01:00
}
2019-04-23 04:00:00 +02:00
@Override
2022-01-14 19:20:40 +01:00
@@ -1396,13 +1895,35 @@
2024-12-11 22:26:55 +01:00
if (factory == null) {
2021-07-30 11:08:43 +02:00
return OptionalInt.empty();
} else {
+ // CraftBukkit start - SPIGOT-6552: Handle inventory closing in CraftEventFactory#callInventoryOpenEvent(...)
+ /*
if (this.containerMenu != this.inventoryMenu) {
2021-11-21 23:00:00 +01:00
this.closeContainer();
2021-07-30 11:08:43 +02:00
}
+ */
+ // CraftBukkit end
2016-11-17 02:41:03 +01:00
this.nextContainerCounter();
2024-12-11 22:26:55 +01:00
AbstractContainerMenu container = factory.createMenu(this.containerCounter, this.getInventory(), this);
2020-04-10 03:20:33 +02:00
2019-04-23 04:00:00 +02:00
+ // CraftBukkit start - Inventory open hook
+ if (container != null) {
2024-12-11 22:26:55 +01:00
+ container.setTitle(factory.getDisplayName());
2020-04-10 03:20:33 +02:00
+
2019-04-23 04:00:00 +02:00
+ boolean cancelled = false;
+ container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled);
+ if (container == null && !cancelled) { // Let pre-cancelled events fall through
2019-08-24 12:02:14 +02:00
+ // SPIGOT-5263 - close chest if cancelled
2024-12-11 22:26:55 +01:00
+ if (factory instanceof Container) {
+ ((Container) factory).stopOpen(this);
+ } else if (factory instanceof ChestBlock.DoubleInventory) {
2019-10-09 10:51:18 +02:00
+ // SPIGOT-5355 - double chests too :(
2024-12-11 22:26:55 +01:00
+ ((ChestBlock.DoubleInventory) factory).inventorylargechest.stopOpen(this);
2019-08-24 12:02:14 +02:00
+ }
2019-04-23 04:00:00 +02:00
+ return OptionalInt.empty();
+ }
2017-01-09 23:56:20 +01:00
+ }
2019-04-23 04:00:00 +02:00
+ // CraftBukkit end
if (container == null) {
if (this.isSpectator()) {
2024-12-11 22:26:55 +01:00
this.displayClientMessage(Component.translatable("container.spectatorCantOpen").withStyle(ChatFormatting.RED), true);
2022-01-14 19:20:40 +01:00
@@ -1410,9 +1931,11 @@
2014-11-25 22:32:16 +01:00
2019-04-23 04:00:00 +02:00
return OptionalInt.empty();
2016-02-29 22:32:46 +01:00
} else {
2024-12-11 22:26:55 +01:00
- this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), factory.getDisplayName()));
2021-06-11 07:00:00 +02:00
- this.initMenu(container);
2019-04-23 04:00:00 +02:00
+ // CraftBukkit start
2021-06-11 07:00:00 +02:00
this.containerMenu = container;
2020-04-13 08:31:44 +02:00
+ if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper - Prevent opening inventories when frozen
2019-04-23 04:00:00 +02:00
+ // CraftBukkit end
2021-06-11 07:00:00 +02:00
+ this.initMenu(container);
2019-04-23 04:00:00 +02:00
return OptionalInt.of(this.containerCounter);
2016-02-29 22:32:46 +01:00
}
2019-04-23 04:00:00 +02:00
}
2022-01-14 19:20:40 +01:00
@@ -1425,15 +1948,26 @@
2014-11-25 22:32:16 +01:00
2019-04-23 04:00:00 +02:00
@Override
2024-12-11 22:26:55 +01:00
public void openHorseInventory(AbstractHorse horse, Container inventory) {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - Inventory open hook
2019-04-23 04:00:00 +02:00
+ this.nextContainerCounter();
2024-12-11 22:26:55 +01:00
+ AbstractContainerMenu container = new HorseInventoryMenu(this.containerCounter, this.getInventory(), inventory, horse, horse.getInventoryColumns());
+ container.setTitle(horse.getDisplayName());
2019-05-10 09:41:05 +02:00
+ container = CraftEventFactory.callInventoryOpenEvent(this, container);
+
2014-11-25 22:32:16 +01:00
+ if (container == null) {
2024-12-11 22:26:55 +01:00
+ inventory.stopOpen(this);
2014-11-25 22:32:16 +01:00
+ return;
+ }
2015-02-26 23:41:06 +01:00
+ // CraftBukkit end
2021-06-11 07:00:00 +02:00
if (this.containerMenu != this.inventoryMenu) {
2018-07-04 03:56:23 +02:00
- this.closeContainer();
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason
2014-11-25 22:32:16 +01:00
}
2019-04-23 04:00:00 +02:00
- this.nextContainerCounter();
+ // this.nextContainerCounter(); // CraftBukkit - moved up
2024-12-11 22:26:55 +01:00
int i = horse.getInventoryColumns();
2024-06-13 17:05:00 +02:00
2024-12-11 22:26:55 +01:00
this.connection.send(new ClientboundHorseScreenOpenPacket(this.containerCounter, i, horse.getId()));
- this.containerMenu = new HorseInventoryMenu(this.containerCounter, this.getInventory(), inventory, horse, i);
2021-06-11 07:00:00 +02:00
+ this.containerMenu = container; // CraftBukkit
this.initMenu(this.containerMenu);
2014-11-25 22:32:16 +01:00
}
2022-01-14 19:20:40 +01:00
@@ -1456,9 +1990,28 @@
2014-11-25 22:32:16 +01:00
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void closeContainer() {
2018-07-04 03:56:23 +02:00
+ // Paper start - Inventory close reason
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
+ }
+ @Override
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
+ // Paper end - Inventory close reason
2024-12-11 22:26:55 +01:00
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
2021-11-21 23:00:00 +01:00
this.doCloseContainer();
2022-04-24 22:56:59 +02:00
}
2021-03-11 12:03:32 +01:00
+ // Paper start - special close for unloaded inventory
+ @Override
+ public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ // copied from above
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
+ // Paper end
+ // copied from below
+ this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
+ this.containerMenu = this.inventoryMenu;
+ // do not run close logic
2022-04-24 22:56:59 +02:00
+ }
2021-03-11 12:03:32 +01:00
+ // Paper end - special close for unloaded inventory
@Override
public void doCloseContainer() {
2022-01-14 19:20:40 +01:00
@@ -1485,19 +2038,19 @@
2024-12-11 22:26:55 +01:00
i = Math.round((float) Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * 100.0F);
2023-12-05 17:40:00 +01:00
if (i > 0) {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.SWIM_ONE_CM, i);
2023-12-05 17:40:00 +01:00
- this.causeFoodExhaustion(0.01F * (float) i * 0.01F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.swimMultiplier * (float) i * 0.01F, EntityExhaustionEvent.ExhaustionReason.SWIM); // CraftBukkit - EntityExhaustionEvent // Spigot
2023-12-05 17:40:00 +01:00
}
2024-12-11 22:26:55 +01:00
} else if (this.isEyeInFluid(FluidTags.WATER)) {
i = Math.round((float) Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * 100.0F);
2023-12-05 17:40:00 +01:00
if (i > 0) {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.WALK_UNDER_WATER_ONE_CM, i);
2023-12-05 17:40:00 +01:00
- this.causeFoodExhaustion(0.01F * (float) i * 0.01F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.swimMultiplier * (float) i * 0.01F, EntityExhaustionEvent.ExhaustionReason.WALK_UNDERWATER); // CraftBukkit - EntityExhaustionEvent // Spigot
2023-12-05 17:40:00 +01:00
}
} else if (this.isInWater()) {
2024-12-11 22:26:55 +01:00
i = Math.round((float) Math.sqrt(deltaX * deltaX + deltaZ * deltaZ) * 100.0F);
2023-12-05 17:40:00 +01:00
if (i > 0) {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.WALK_ON_WATER_ONE_CM, i);
2023-12-05 17:40:00 +01:00
- this.causeFoodExhaustion(0.01F * (float) i * 0.01F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.swimMultiplier * (float) i * 0.01F, EntityExhaustionEvent.ExhaustionReason.WALK_ON_WATER); // CraftBukkit - EntityExhaustionEvent // Spigot
2023-12-05 17:40:00 +01:00
}
} else if (this.onClimbable()) {
2024-12-11 22:26:55 +01:00
if (deltaY > 0.0D) {
2022-01-14 19:20:40 +01:00
@@ -1508,13 +2061,13 @@
2023-12-05 17:40:00 +01:00
if (i > 0) {
if (this.isSprinting()) {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.SPRINT_ONE_CM, i);
2023-12-05 17:40:00 +01:00
- this.causeFoodExhaustion(0.1F * (float) i * 0.01F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.sprintMultiplier * (float) i * 0.01F, EntityExhaustionEvent.ExhaustionReason.SPRINT); // CraftBukkit - EntityExhaustionEvent // Spigot
2023-12-05 17:40:00 +01:00
} else if (this.isCrouching()) {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.CROUCH_ONE_CM, i);
2023-12-05 17:40:00 +01:00
- this.causeFoodExhaustion(0.0F * (float) i * 0.01F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.otherMultiplier * (float) i * 0.01F, EntityExhaustionEvent.ExhaustionReason.CROUCH); // CraftBukkit - EntityExhaustionEvent // Spigot
2023-12-05 17:40:00 +01:00
} else {
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.WALK_ONE_CM, i);
2023-12-05 17:40:00 +01:00
- this.causeFoodExhaustion(0.0F * (float) i * 0.01F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.otherMultiplier * (float) i * 0.01F, EntityExhaustionEvent.ExhaustionReason.WALK); // CraftBukkit - EntityExhaustionEvent // Spigot
2023-12-05 17:40:00 +01:00
}
}
} else if (this.isFallFlying()) {
2022-01-14 19:20:40 +01:00
@@ -1557,7 +2110,7 @@
2019-04-23 04:00:00 +02:00
@Override
2024-12-11 22:26:55 +01:00
public void awardStat(Stat<?> stat, int amount) {
this.stats.increment(this, stat, amount);
- this.getScoreboard().forAllObjectives(stat, this, (scoreaccess) -> {
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(stat, this, (scoreaccess) -> {
scoreaccess.add(amount);
2018-07-15 02:00:00 +02:00
});
2017-05-14 04:00:00 +02:00
}
2022-01-14 19:20:40 +01:00
@@ -1565,7 +2118,7 @@
2019-04-23 04:00:00 +02:00
@Override
2024-12-11 22:26:55 +01:00
public void resetStat(Stat<?> stat) {
this.stats.setValue(this, stat, 0);
- this.getScoreboard().forAllObjectives(stat, this, ScoreAccess::reset);
+ this.level().getCraftServer().getScoreboardManager().forAllObjectives(stat, this, ScoreAccess::reset); // CraftBukkit - Get our scores instead
2014-11-25 22:32:16 +01:00
}
2017-05-14 04:00:00 +02:00
2019-04-23 04:00:00 +02:00
@Override
2022-01-14 19:20:40 +01:00
@@ -1597,9 +2150,9 @@
2024-10-22 17:15:00 +02:00
super.jumpFromGround();
2024-12-11 22:26:55 +01:00
this.awardStat(Stats.JUMP);
2024-10-22 17:15:00 +02:00
if (this.isSprinting()) {
- this.causeFoodExhaustion(0.2F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.jumpSprintExhaustion, EntityExhaustionEvent.ExhaustionReason.JUMP_SPRINT); // CraftBukkit - EntityExhaustionEvent // Spigot - Change to use configurable value
2024-10-22 17:15:00 +02:00
} else {
- this.causeFoodExhaustion(0.05F);
2014-08-17 11:56:17 +02:00
+ this.causeFoodExhaustion(this.level().spigotConfig.jumpWalkExhaustion, EntityExhaustionEvent.ExhaustionReason.JUMP); // CraftBukkit - EntityExhaustionEvent // Spigot - Change to use configurable value
2024-10-22 17:15:00 +02:00
}
}
2022-01-14 19:20:40 +01:00
@@ -1613,6 +2166,13 @@
2019-01-07 21:43:48 +01:00
public void disconnect() {
this.disconnected = true;
this.ejectPassengers();
+
+ // Paper start - Workaround vehicle not tracking the passenger disconnection dismount
+ if (this.isPassenger() && this.getVehicle() instanceof ServerPlayer) {
+ this.stopRiding();
+ }
+ // Paper end - Workaround vehicle not tracking the passenger disconnection dismount
+
if (this.isSleeping()) {
this.stopSleepInBed(true, false);
}
2022-01-14 19:20:40 +01:00
@@ -1625,6 +2185,7 @@
2014-11-25 22:32:16 +01:00
2021-11-21 23:00:00 +01:00
public void resetSentInfo() {
2021-06-11 07:00:00 +02:00
this.lastSentHealth = -1.0E8F;
2014-11-25 22:32:16 +01:00
+ this.lastSentExp = -1; // CraftBukkit - Added to reset
2022-04-09 01:39:33 +02:00
}
2019-04-23 04:00:00 +02:00
@Override
2022-01-14 19:20:40 +01:00
@@ -1661,7 +2222,7 @@
2024-11-12 10:51:01 +01:00
this.onUpdateAbilities();
2024-12-11 22:26:55 +01:00
if (alive) {
this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
- this.getAttributes().assignPermanentModifiers(oldPlayer.getAttributes());
2024-11-12 10:51:01 +01:00
+ // this.getAttributes().assignPermanentModifiers(entityplayer.getAttributes()); // CraftBukkit
2024-12-11 22:26:55 +01:00
this.setHealth(oldPlayer.getHealth());
this.foodData = oldPlayer.foodData;
Iterator iterator = oldPlayer.getActiveEffects().iterator();
2022-01-14 19:20:40 +01:00
@@ -1669,7 +2230,7 @@
2024-06-23 08:45:29 +02:00
while (iterator.hasNext()) {
2024-12-11 22:26:55 +01:00
MobEffectInstance mobeffect = (MobEffectInstance) iterator.next();
2024-06-23 08:45:29 +02:00
2024-12-11 22:26:55 +01:00
- this.addEffect(new MobEffectInstance(mobeffect));
2024-06-23 08:45:29 +02:00
+ // this.addEffect(new MobEffect(mobeffect)); // CraftBukkit
}
2024-12-11 22:26:55 +01:00
this.getInventory().replaceWith(oldPlayer.getInventory());
2022-01-14 19:20:40 +01:00
@@ -1680,7 +2241,7 @@
2024-12-11 22:26:55 +01:00
this.portalProcess = oldPlayer.portalProcess;
2024-10-22 17:15:00 +02:00
} else {
2024-12-11 22:26:55 +01:00
this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
2024-10-22 17:15:00 +02:00
- this.setHealth(this.getMaxHealth());
+ // this.setHealth(this.getMaxHealth()); // CraftBukkit
2024-12-11 22:26:55 +01:00
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || oldPlayer.isSpectator()) {
this.getInventory().replaceWith(oldPlayer.getInventory());
this.experienceLevel = oldPlayer.experienceLevel;
2022-01-14 19:20:40 +01:00
@@ -1696,7 +2257,7 @@
2017-05-15 10:11:48 +02:00
this.lastSentExp = -1;
2021-06-11 07:00:00 +02:00
this.lastSentHealth = -1.0F;
this.lastSentFood = -1;
2024-12-11 22:26:55 +01:00
- this.recipeBook.copyOverData(oldPlayer.recipeBook);
2021-11-21 23:00:00 +01:00
+ // this.recipeBook.copyOverData(entityplayer.recipeBook); // CraftBukkit
2024-12-11 22:26:55 +01:00
this.seenCredits = oldPlayer.seenCredits;
this.enteredNetherPosition = oldPlayer.enteredNetherPosition;
this.chunkTrackingView = oldPlayer.chunkTrackingView;
2022-01-14 19:20:40 +01:00
@@ -1752,19 +2313,19 @@
2024-10-22 17:15:00 +02:00
}
2023-03-14 17:30:00 +01:00
@Override
2024-12-11 22:26:55 +01:00
- public boolean teleportTo(ServerLevel world, double destX, double destY, double destZ, Set<Relative> flags, float yaw, float pitch, boolean resetCamera) {
+ public boolean teleportTo(ServerLevel worldserver, double d0, double d1, double d2, Set<Relative> set, float f, float f1, boolean flag, TeleportCause cause) { // CraftBukkit
2024-12-03 17:20:00 +01:00
if (this.isSleeping()) {
this.stopSleepInBed(true, true);
}
2024-12-11 22:26:55 +01:00
- if (resetCamera) {
+ if (flag) {
2024-10-22 17:15:00 +02:00
this.setCamera(this);
2023-03-14 17:30:00 +01:00
}
2024-12-11 22:26:55 +01:00
- boolean flag1 = super.teleportTo(world, destX, destY, destZ, flags, yaw, pitch, resetCamera);
2024-10-22 17:15:00 +02:00
+ boolean flag1 = super.teleportTo(worldserver, d0, d1, d2, set, f, f1, flag, cause); // CraftBukkit
2023-03-14 17:30:00 +01:00
2024-10-22 17:15:00 +02:00
if (flag1) {
2024-12-11 22:26:55 +01:00
- this.setYHeadRot(flags.contains(Relative.Y_ROT) ? this.getYHeadRot() + yaw : yaw);
+ this.setYHeadRot(set.contains(Relative.Y_ROT) ? this.getYHeadRot() + f : f);
}
return flag1;
2022-01-14 19:20:40 +01:00
@@ -1799,10 +2360,18 @@
2021-05-15 19:04:43 +02:00
}
public boolean setGameMode(GameType gameMode) {
+ // Paper start - Expand PlayerGameModeChangeEvent
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = this.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.UNKNOWN, null);
+ return event == null ? false : event.isCancelled();
+ }
+ @Nullable
+ public org.bukkit.event.player.PlayerGameModeChangeEvent setGameMode(GameType gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause cause, @Nullable net.kyori.adventure.text.Component message) {
boolean flag = this.isSpectator();
- if (!this.gameMode.changeGameModeForPlayer(gameMode)) {
- return false;
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = this.gameMode.changeGameModeForPlayer(gameMode, cause, message);
+ if (event == null || event.isCancelled()) {
+ return null;
+ // Paper end - Expand PlayerGameModeChangeEvent
} else {
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId()));
if (gameMode == GameType.SPECTATOR) {
2022-01-14 19:20:40 +01:00
@@ -1818,7 +2387,7 @@
2021-05-15 19:04:43 +02:00
this.onUpdateAbilities();
this.updateEffectVisibility();
- return true;
+ return event; // Paper - Expand PlayerGameModeChangeEvent
}
}
2022-01-14 19:20:40 +01:00
@@ -1861,8 +2430,13 @@
2021-01-29 17:54:03 +01:00
}
public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) {
+ // Paper start
+ this.sendChatMessage(message, filterMaskEnabled, params, null);
+ }
+ public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params, @Nullable Component unsigned) {
+ // Paper end
if (this.acceptsChatMessages()) {
- message.sendToPlayer(this, filterMaskEnabled, params);
+ message.sendToPlayer(this, filterMaskEnabled, params, unsigned); // Paper
}
}
2022-01-14 19:20:40 +01:00
@@ -1878,7 +2452,36 @@
2016-05-27 10:53:36 +02:00
}
2024-12-11 22:26:55 +01:00
public void updateOptions(ClientInformation clientOptions) {
2020-01-20 21:38:15 +01:00
+ // Paper start - settings event
+ new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(this.getBukkitEntity(), Util.make(new java.util.IdentityHashMap<>(), map -> {
+ map.put(com.destroystokyo.paper.ClientOption.LOCALE, clientOptions.language());
+ map.put(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE, clientOptions.viewDistance());
+ map.put(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(clientOptions.chatVisibility().name()));
+ map.put(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED, clientOptions.chatColors());
+ map.put(com.destroystokyo.paper.ClientOption.SKIN_PARTS, new com.destroystokyo.paper.PaperSkinParts(clientOptions.modelCustomisation()));
+ map.put(com.destroystokyo.paper.ClientOption.MAIN_HAND, clientOptions.mainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
+ map.put(com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED, clientOptions.textFilteringEnabled());
+ map.put(com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS, clientOptions.allowsListing());
+ map.put(com.destroystokyo.paper.ClientOption.PARTICLE_VISIBILITY, com.destroystokyo.paper.ClientOption.ParticleVisibility.valueOf(clientOptions.particleStatus().name()));
+ })).callEvent();
+ // Paper end - settings event
2016-05-27 10:53:36 +02:00
+ // CraftBukkit start
2024-12-11 22:26:55 +01:00
+ if (this.getMainArm() != clientOptions.mainHand()) {
+ PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
2016-05-27 10:53:36 +02:00
+ this.server.server.getPluginManager().callEvent(event);
+ }
2016-04-19 21:09:31 +02:00
+ if (this.language == null || !this.language.equals(clientOptions.language())) { // Paper
2024-12-11 22:26:55 +01:00
+ PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(this.getBukkitEntity(), clientOptions.language());
2017-05-26 23:37:06 +02:00
+ this.server.server.getPluginManager().callEvent(event);
+ }
2016-05-27 10:53:36 +02:00
+ // CraftBukkit end
2020-01-20 21:38:15 +01:00
+ // Paper start - don't call options events on login
+ this.updateOptionsNoEvents(clientOptions);
+ }
+ public void updateOptionsNoEvents(ClientInformation clientOptions) {
+ // Paper end
2024-12-11 22:26:55 +01:00
this.language = clientOptions.language();
2021-01-29 17:54:03 +01:00
+ this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper
2024-12-11 22:26:55 +01:00
this.requestedViewDistance = clientOptions.viewDistance();
this.chatVisibility = clientOptions.chatVisibility();
2021-01-29 17:54:03 +01:00
this.canChatColor = clientOptions.chatColors();
2022-01-14 19:20:40 +01:00
@@ -1957,12 +2560,27 @@
2018-09-28 09:32:19 +02:00
this.camera = (Entity) (entity == null ? this : entity);
if (entity1 != this.camera) {
+ // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
+ if (this.camera == this) {
+ com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity());
+ if (!playerStopSpectatingEntityEvent.callEvent()) {
+ this.camera = entity1; // rollback camera entity again
+ return;
+ }
+ } else {
+ com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent playerStartSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity(), entity.getBukkitEntity());
+ if (!playerStartSpectatingEntityEvent.callEvent()) {
+ this.camera = entity1; // rollback camera entity again
+ return;
+ }
+ }
+ // Paper end - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
Level world = this.camera.level();
2024-12-11 22:26:55 +01:00
if (world instanceof ServerLevel) {
ServerLevel worldserver = (ServerLevel) world;
2023-03-14 17:30:00 +01:00
2024-10-22 17:15:00 +02:00
- this.teleportTo(worldserver, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot(), false);
+ this.teleportTo(worldserver, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot(), false, TeleportCause.SPECTATE); // CraftBukkit
2023-03-14 17:30:00 +01:00
}
2017-03-24 05:08:19 +01:00
2023-03-14 17:30:00 +01:00
if (entity != null) {
2022-01-14 19:20:40 +01:00
@@ -1999,11 +2617,11 @@
2016-03-02 08:32:06 +01:00
2016-05-10 13:47:39 +02:00
@Nullable
2024-12-11 22:26:55 +01:00
public Component getTabListDisplayName() {
2016-03-02 08:32:06 +01:00
- return null;
2024-12-11 22:26:55 +01:00
+ return this.listName; // CraftBukkit
2016-03-02 08:32:06 +01:00
}
2024-10-22 17:15:00 +02:00
public int getTabListOrder() {
- return 0;
2024-12-11 22:26:55 +01:00
+ return this.listOrder; // CraftBukkit
2019-04-23 04:00:00 +02:00
}
2024-10-22 17:15:00 +02:00
@Override
2022-01-14 19:20:40 +01:00
@@ -2045,12 +2663,44 @@
2021-05-20 03:59:10 +02:00
this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false);
2023-04-17 11:33:17 +02:00
}
2021-05-20 03:59:10 +02:00
+ @Deprecated // Paper - Add PlayerSetSpawnEvent
2024-12-11 22:26:55 +01:00
public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
2021-05-20 03:59:10 +02:00
+ // Paper start - Add PlayerSetSpawnEvent
+ this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.UNKNOWN);
2023-04-17 11:33:17 +02:00
+ }
2021-05-20 03:59:10 +02:00
+ @Deprecated
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, PlayerSpawnChangeEvent.Cause cause) {
+ return this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, cause == PlayerSpawnChangeEvent.Cause.RESET ?
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN : com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.valueOf(cause.name()));
+ }
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause cause) {
+ Location spawnLoc = null;
+ boolean willNotify = false;
if (pos != null) {
boolean flag2 = pos.equals(this.respawnPosition) && dimension.equals(this.respawnDimension);
+ spawnLoc = io.papermc.paper.util.MCUtil.toLocation(this.getServer().getLevel(dimension), pos);
+ spawnLoc.setYaw(angle);
+ willNotify = sendMessage && !flag2;
+ }
2024-12-11 22:26:55 +01:00
- if (sendMessage && !flag2) {
2021-05-20 03:59:10 +02:00
- this.sendSystemMessage(Component.translatable("block.minecraft.set_spawn"));
+ PlayerSpawnChangeEvent dumbEvent = new PlayerSpawnChangeEvent(this.getBukkitEntity(), spawnLoc, forced,
+ cause == com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN ? PlayerSpawnChangeEvent.Cause.RESET : PlayerSpawnChangeEvent.Cause.valueOf(cause.name()));
+ dumbEvent.callEvent();
+
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent event = new com.destroystokyo.paper.event.player.PlayerSetSpawnEvent(this.getBukkitEntity(), cause, dumbEvent.getNewSpawn(), dumbEvent.isForced(), willNotify, willNotify ? net.kyori.adventure.text.Component.translatable("block.minecraft.set_spawn") : null);
+ event.setCancelled(dumbEvent.isCancelled());
+ if (!event.callEvent()) {
+ return false;
2023-04-17 11:33:17 +02:00
+ }
2021-05-20 03:59:10 +02:00
+ if (event.getLocation() != null) {
+ dimension = event.getLocation().getWorld() != null ? ((CraftWorld) event.getLocation().getWorld()).getHandle().dimension() : dimension;
+ pos = io.papermc.paper.util.MCUtil.toBlockPosition(event.getLocation());
+ angle = event.getLocation().getYaw();
+ forced = event.isForced();
+ // Paper end - Add PlayerSetSpawnEvent
+
+ if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper - Add PlayerSetSpawnEvent
+ this.sendSystemMessage(PaperAdventure.asVanilla(event.getNotification())); // Paper - Add PlayerSetSpawnEvent
2024-12-11 22:26:55 +01:00
}
2023-04-17 11:33:17 +02:00
2021-05-20 03:59:10 +02:00
this.respawnPosition = pos;
2022-01-14 19:20:40 +01:00
@@ -2064,6 +2714,7 @@
2021-05-20 03:59:10 +02:00
this.respawnForced = false;
}
+ return true; // Paper - Add PlayerSetSpawnEvent
}
public SectionPos getLastSectionPos() {
2022-01-14 19:20:40 +01:00
@@ -2088,18 +2739,44 @@
2024-10-22 17:15:00 +02:00
}
2024-06-29 06:03:10 +02:00
@Override
2024-12-11 22:26:55 +01:00
- public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) {
- ItemEntity entityitem = this.createItemStackToDrop(stack, throwRandomly, retainOwnership);
+ public ItemEntity drop(ItemStack itemstack, boolean flag, boolean flag1, boolean callEvent) { // CraftBukkit - SPIGOT-2942: Add boolean to call event
+ ItemEntity entityitem = this.createItemStackToDrop(itemstack, flag, flag1);
2024-06-29 06:03:10 +02:00
if (entityitem == null) {
return null;
2024-10-22 17:15:00 +02:00
} else {
+ // CraftBukkit start - fire PlayerDropItemEvent
+ if (callEvent) {
+ Player player = (Player) this.getBukkitEntity();
+ org.bukkit.entity.Item drop = (org.bukkit.entity.Item) entityitem.getBukkitEntity();
+
+ PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop);
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ org.bukkit.inventory.ItemStack cur = player.getInventory().getItemInHand();
+ if (flag1 && (cur == null || cur.getAmount() == 0)) {
+ // The complete stack was dropped
+ player.getInventory().setItemInHand(drop.getItemStack());
+ } else if (flag1 && cur.isSimilar(drop.getItemStack()) && cur.getAmount() < cur.getMaxStackSize() && drop.getItemStack().getAmount() == 1) {
+ // Only one item is dropped
+ cur.setAmount(cur.getAmount() + 1);
+ player.getInventory().setItemInHand(cur);
+ } else {
+ // Fallback
+ player.getInventory().addItem(drop.getItemStack());
+ }
+ return null;
+ }
+ }
+ // CraftBukkit end
+
this.level().addFreshEntity(entityitem);
ItemStack itemstack1 = entityitem.getItem();
2024-12-11 22:26:55 +01:00
- if (retainOwnership) {
+ if (flag1) {
if (!itemstack1.isEmpty()) {
- this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), stack.getCount());
2021-06-21 06:55:59 +02:00
+ this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), itemstack1.getCount()); // Paper - Fix PlayerDropItemEvent using wrong item
2024-12-11 22:26:55 +01:00
}
this.awardStat(Stats.DROP);
2022-01-14 19:20:40 +01:00
@@ -2115,6 +2792,11 @@
2021-06-21 06:55:59 +02:00
return null;
} else {
double d0 = this.getEyeY() - 0.30000001192092896D;
+ // Paper start
+ ItemStack tmp = stack.copy();
+ stack.setCount(0);
+ stack = tmp;
+ // Paper end
ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), d0, this.getZ(), stack);
entityitem.setPickUpDelay(40);
2022-01-14 19:20:40 +01:00
@@ -2166,6 +2848,16 @@
2021-05-15 19:04:43 +02:00
}
public void loadGameTypes(@Nullable CompoundTag nbt) {
+ // Paper start - Expand PlayerGameModeChangeEvent
+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != ServerPlayer.readPlayerMode(nbt, "playerGameType")) {
+ if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
+ this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE);
+ } else {
+ this.gameMode.setGameModeForPlayer(ServerPlayer.readPlayerMode(nbt,"playerGameType"), ServerPlayer.readPlayerMode(nbt, "previousPlayerGameType"));
+ }
+ return;
+ }
+ // Paper end - Expand PlayerGameModeChangeEvent
this.gameMode.setGameModeForPlayer(this.calculateGameModeForNewPlayer(ServerPlayer.readPlayerMode(nbt, "playerGameType")), ServerPlayer.readPlayerMode(nbt, "previousPlayerGameType"));
}
2022-01-14 19:20:40 +01:00
@@ -2275,9 +2967,15 @@
2018-11-15 14:38:37 +01:00
@Override
public void stopRiding() {
+ // Paper start - Force entity dismount during teleportation
+ this.stopRiding(false);
+ }
+ @Override
+ public void stopRiding(boolean suppressCancellation) {
+ // Paper end - Force entity dismount during teleportation
Entity entity = this.getVehicle();
- super.stopRiding();
+ super.stopRiding(suppressCancellation); // Paper - Force entity dismount during teleportation
if (entity instanceof LivingEntity entityliving) {
Iterator iterator = entityliving.getActiveEffects().iterator();
2022-01-14 19:20:40 +01:00
@@ -2375,10 +3073,12 @@
2024-10-22 17:15:00 +02:00
return TicketType.ENDER_PEARL.timeout();
2024-06-13 17:05:00 +02:00
}
2024-12-11 22:26:55 +01:00
- public static record RespawnPosAngle(Vec3 position, float yaw) {
2024-06-13 17:05:00 +02:00
+ // CraftBukkit start
2024-12-11 22:26:55 +01:00
+ public static record RespawnPosAngle(Vec3 position, float yaw, boolean isBedSpawn, boolean isAnchorSpawn) {
2024-06-13 17:05:00 +02:00
2024-12-11 22:26:55 +01:00
- public static ServerPlayer.RespawnPosAngle of(Vec3 respawnPos, BlockPos currentPos) {
- return new ServerPlayer.RespawnPosAngle(respawnPos, calculateLookAtYaw(respawnPos, currentPos));
+ public static ServerPlayer.RespawnPosAngle of(Vec3 vec3d, BlockPos blockposition, boolean isBedSpawn, boolean isAnchorSpawn) {
+ return new ServerPlayer.RespawnPosAngle(vec3d, calculateLookAtYaw(vec3d, blockposition), isBedSpawn, isAnchorSpawn);
2024-06-13 17:05:00 +02:00
+ // CraftBukkit end
}
2024-12-11 22:26:55 +01:00
private static float calculateLookAtYaw(Vec3 respawnPos, BlockPos currentPos) {
2022-01-14 19:20:40 +01:00
@@ -2387,4 +3087,147 @@
2024-12-11 22:26:55 +01:00
return (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D);
2021-03-11 12:03:32 +01:00
}
}
2014-11-25 22:32:16 +01:00
+
+ // CraftBukkit start - Add per-player time and weather.
+ public long timeOffset = 0;
+ public boolean relativeTime = true;
+
+ public long getPlayerTime() {
+ if (this.relativeTime) {
+ // Adds timeOffset to the current server time.
2023-06-07 17:30:00 +02:00
+ return this.level().getDayTime() + this.timeOffset;
2014-11-25 22:32:16 +01:00
+ } else {
+ // Adds timeOffset to the beginning of this day.
2023-06-07 17:30:00 +02:00
+ return this.level().getDayTime() - (this.level().getDayTime() % 24000) + this.timeOffset;
2019-03-28 04:01:33 +01:00
+ }
+ }
2014-11-25 22:32:16 +01:00
+
+ public WeatherType weather = null;
+
+ public WeatherType getPlayerWeather() {
+ return this.weather;
+ }
+
+ public void setPlayerWeather(WeatherType type, boolean plugin) {
+ if (!plugin && this.weather != null) {
+ return;
2021-03-11 12:03:32 +01:00
+ }
2014-11-25 22:32:16 +01:00
+
+ if (plugin) {
+ this.weather = type;
2019-03-24 05:24:52 +01:00
+ }
2014-11-25 22:32:16 +01:00
+
+ if (type == WeatherType.DOWNFALL) {
2024-12-11 22:26:55 +01:00
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.STOP_RAINING, 0));
2020-06-29 00:25:59 +02:00
+ } else {
2024-12-11 22:26:55 +01:00
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0));
2018-10-21 04:34:02 +02:00
+ }
2021-03-11 12:03:32 +01:00
+ }
2015-02-26 23:41:06 +01:00
+
2014-12-02 16:13:07 +01:00
+ private float pluginRainPosition;
+ private float pluginRainPositionPrevious;
2015-02-26 23:41:06 +01:00
+
2014-12-02 16:13:07 +01:00
+ public void updateWeather(float oldRain, float newRain, float oldThunder, float newThunder) {
+ if (this.weather == null) {
+ // Vanilla
+ if (oldRain != newRain) {
2024-12-11 22:26:55 +01:00
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, newRain));
2015-02-26 23:41:06 +01:00
+ }
2014-12-02 16:13:07 +01:00
+ } else {
+ // Plugin
2024-12-11 22:26:55 +01:00
+ if (this.pluginRainPositionPrevious != this.pluginRainPosition) {
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, this.pluginRainPosition));
2015-02-26 23:41:06 +01:00
+ }
2016-03-03 06:34:44 +01:00
+ }
2014-12-02 16:13:07 +01:00
+
+ if (oldThunder != newThunder) {
2024-12-11 22:26:55 +01:00
+ if (this.weather == WeatherType.DOWNFALL || this.weather == null) {
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, newThunder));
2014-12-02 16:13:07 +01:00
+ } else {
2024-12-11 22:26:55 +01:00
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, 0));
2014-12-02 16:13:07 +01:00
+ }
+ }
2016-03-03 06:34:44 +01:00
+ }
2015-02-26 23:41:06 +01:00
+
2014-12-02 16:13:07 +01:00
+ public void tickWeather() {
+ if (this.weather == null) return;
+
2024-12-11 22:26:55 +01:00
+ this.pluginRainPositionPrevious = this.pluginRainPosition;
+ if (this.weather == WeatherType.DOWNFALL) {
+ this.pluginRainPosition += 0.01;
2014-12-02 16:13:07 +01:00
+ } else {
2024-12-11 22:26:55 +01:00
+ this.pluginRainPosition -= 0.01;
2014-12-02 16:13:07 +01:00
+ }
+
2024-12-11 22:26:55 +01:00
+ this.pluginRainPosition = Mth.clamp(this.pluginRainPosition, 0.0F, 1.0F);
2014-12-02 16:13:07 +01:00
+ }
2014-11-25 22:32:16 +01:00
+
+ public void resetPlayerWeather() {
+ this.weather = null;
2023-06-07 17:30:00 +02:00
+ this.setPlayerWeather(this.level().getLevelData().isRaining() ? WeatherType.DOWNFALL : WeatherType.CLEAR, false);
2014-11-25 22:32:16 +01:00
+ }
+
+ @Override
+ public String toString() {
2021-11-21 23:00:00 +01:00
+ return super.toString() + "(" + this.getScoreboardName() + " at " + this.getX() + "," + this.getY() + "," + this.getZ() + ")";
2014-11-25 22:32:16 +01:00
+ }
+
2016-10-23 05:00:35 +02:00
+ // SPIGOT-1903, MC-98153
+ public void forceSetPositionRotation(double x, double y, double z, float yaw, float pitch) {
2021-11-21 23:00:00 +01:00
+ this.moveTo(x, y, z, yaw, pitch);
+ this.connection.resetPosition();
2016-10-23 05:00:35 +02:00
+ }
+
2016-11-29 23:16:01 +01:00
+ @Override
2021-11-21 23:00:00 +01:00
+ public boolean isImmobile() {
2016-12-27 02:57:57 +01:00
+ return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper - Fix duplication bugs
2016-11-29 23:16:01 +01:00
+ }
+
2017-08-05 01:15:52 +02:00
+ @Override
+ public Scoreboard getScoreboard() {
2024-12-11 22:26:55 +01:00
+ return this.getBukkitEntity().getScoreboard().getHandle();
2017-08-05 01:15:52 +02:00
+ }
+
2014-11-25 22:32:16 +01:00
+ public void reset() {
+ float exp = 0;
+
2021-08-11 10:49:49 +02:00
+ if (this.keepLevel) { // CraftBukkit - SPIGOT-6687: Only use keepLevel (was pre-set with RULE_KEEPINVENTORY value in PlayerDeathEvent)
2021-06-11 07:00:00 +02:00
+ exp = this.experienceProgress;
+ this.newTotalExp = this.totalExperience;
+ this.newLevel = this.experienceLevel;
2014-11-25 22:32:16 +01:00
+ }
+
+ this.setHealth(this.getMaxHealth());
2021-11-21 23:00:00 +01:00
+ this.stopUsingItem(); // CraftBukkit - SPIGOT-6682: Clear active item on reset
2018-10-21 04:34:02 +02:00
+ this.setAirSupply(this.getMaxAirSupply()); // Paper - Reset players airTicks on respawn
2023-06-11 09:30:03 +02:00
+ this.setRemainingFireTicks(0);
2014-11-25 22:32:16 +01:00
+ this.fallDistance = 0;
2024-12-11 22:26:55 +01:00
+ this.foodData = new FoodData();
2021-06-11 07:00:00 +02:00
+ this.experienceLevel = this.newLevel;
+ this.totalExperience = this.newTotalExp;
+ this.experienceProgress = 0;
+ this.deathTime = 0;
2020-09-02 10:52:40 +02:00
+ this.setArrowCount(0, true); // CraftBukkit - ArrowBodyCountChangeEvent
2018-07-20 08:04:37 +02:00
+ this.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.DEATH);
2021-06-11 07:00:00 +02:00
+ this.effectsDirty = true;
+ this.containerMenu = this.inventoryMenu;
+ this.lastHurtByPlayer = null;
+ this.lastHurtByMob = null;
2014-11-25 22:32:16 +01:00
+ this.combatTracker = new CombatTracker(this);
+ this.lastSentExp = -1;
2021-08-11 10:49:49 +02:00
+ if (this.keepLevel) { // CraftBukkit - SPIGOT-6687: Only use keepLevel (was pre-set with RULE_KEEPINVENTORY value in PlayerDeathEvent)
2021-06-11 07:00:00 +02:00
+ this.experienceProgress = exp;
2014-11-25 22:32:16 +01:00
+ } else {
2021-11-21 23:00:00 +01:00
+ this.giveExperiencePoints(this.newExp);
2014-11-25 22:32:16 +01:00
+ }
+ this.keepLevel = false;
2022-05-17 11:22:58 +02:00
+ this.setDeltaMovement(0, 0, 0); // CraftBukkit - SPIGOT-6948: Reset velocity on death
2023-12-25 21:42:19 +01:00
+ this.skipDropExperience = false; // CraftBukkit - SPIGOT-7462: Reset experience drop skip, so that further deaths drop xp
2014-11-25 22:32:16 +01:00
+ }
2019-04-23 04:00:00 +02:00
+
2014-11-25 22:32:16 +01:00
+ @Override
+ public CraftPlayer getBukkitEntity() {
+ return (CraftPlayer) super.getBukkitEntity();
2019-04-23 04:00:00 +02:00
+ }
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
}