diff --git a/paper-server/patches/sources/net/minecraft/server/commands/DefaultGameModeCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/DefaultGameModeCommands.java.patch new file mode 100644 index 0000000000..dfb815a54e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/DefaultGameModeCommands.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/server/commands/DefaultGameModeCommands.java ++++ b/net/minecraft/server/commands/DefaultGameModeCommands.java +@@ -28,9 +28,13 @@ + GameType gameType = minecraftServer.getForcedGameType(); + if (gameType != null) { + for (ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) { +- if (serverPlayer.setGameMode(gameType)) { +- i++; ++ // Paper start - Expand PlayerGameModeChangeEvent ++ org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, net.kyori.adventure.text.Component.empty()); ++ if (event != null && event.isCancelled()) { ++ source.sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), false); + } ++ // Paper end - Expand PlayerGameModeChangeEvent ++ i++; + } + } + diff --git a/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch new file mode 100644 index 0000000000..5984de9d0f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/server/commands/GameModeCommand.java ++++ b/net/minecraft/server/commands/GameModeCommand.java +@@ -60,9 +60,14 @@ + int i = 0; + + for (ServerPlayer serverPlayer : targets) { +- if (serverPlayer.setGameMode(gameMode)) { ++ // Paper start - Expand PlayerGameModeChangeEvent ++ org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty()); ++ if (event != null && !event.isCancelled()) { + logGamemodeChange(context.getSource(), serverPlayer, gameMode); + i++; ++ } else if (event != null && event.cancelMessage() != null) { ++ context.getSource().sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true); ++ // Paper end - Expand PlayerGameModeChangeEvent + } + } + diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index 4f980afca3..7e5548fcb4 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -114,7 +114,7 @@ @Nullable private Vec3 startingToFallPosition; @Nullable -@@ -258,6 +293,35 @@ +@@ -258,7 +293,36 @@ private final CommandSource commandSource; private int containerCounter; public boolean wonGame; @@ -125,7 +125,7 @@ + public boolean queueHealthUpdatePacket; + public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; + // Paper end - cancellable death event -+ + + // CraftBukkit start + public CraftPlayer.TransferCookieConnection transferCookieConnection; + public String displayName; @@ -147,9 +147,10 @@ + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent + public @Nullable String clientBrandName = null; // Paper - Brand support + 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 - ++ public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); + this.chatVisibility = ChatVisiblity.FULL; @@ -266,7 +330,7 @@ this.canChatColor = true; this.lastActionTime = Util.getMillis(); @@ -288,16 +289,16 @@ if (this.isSleeping()) { this.stopSleeping(); - } - ++ } ++ + // CraftBukkit start + String spawnWorld = nbt.getString("SpawnWorld"); + CraftWorld oldWorld = (CraftWorld) Bukkit.getWorld(spawnWorld); + if (oldWorld != null) { + this.respawnDimension = oldWorld.getHandle().dimension(); -+ } + } + // CraftBukkit end -+ + 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"); @@ -913,7 +914,7 @@ this.connection.resetPosition(); worldserver.addDuringTeleport(this); gameprofilerfiller.pop(); -@@ -1215,12 +1605,35 @@ +@@ -1215,10 +1605,33 @@ this.lastSentExp = -1; this.lastSentHealth = -1.0F; this.lastSentFood = -1; @@ -929,26 +930,24 @@ + // Paper end - Reset shield blocking on dimension change return this; } - } - } - ++ } ++ } ++ + // CraftBukkit start - @Override ++ @Override + public CraftPortalEvent callPortalEvent(Entity entity, Location exit, TeleportCause cause, int searchRadius, int creationRadius) { + Location enter = this.getBukkitEntity().getLocation(); + PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, searchRadius, true, creationRadius); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null) { + return null; -+ } + } + return new CraftPortalEvent(event); -+ } -+ // CraftBukkit end -+ -+ @Override - public void forceSetRotation(float yaw, float pitch) { - this.connection.send(new ClientboundPlayerRotationPacket(yaw, pitch)); } ++ // CraftBukkit end + + @Override + public void forceSetRotation(float yaw, float pitch) { @@ -1228,13 +1641,21 @@ public void triggerDimensionChangeTriggers(ServerLevel origin) { ResourceKey resourcekey = origin.dimension(); @@ -1354,7 +1353,37 @@ } return flag1; -@@ -1861,8 +2377,13 @@ +@@ -1799,10 +2315,18 @@ + } + + 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) { +@@ -1818,7 +2342,7 @@ + + this.onUpdateAbilities(); + this.updateEffectVisibility(); +- return true; ++ return event; // Paper - Expand PlayerGameModeChangeEvent + } + } + +@@ -1861,8 +2385,13 @@ } public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) { @@ -1369,7 +1398,7 @@ } } -@@ -1878,7 +2399,36 @@ +@@ -1878,7 +2407,36 @@ } public void updateOptions(ClientInformation clientOptions) { @@ -1406,7 +1435,7 @@ this.requestedViewDistance = clientOptions.viewDistance(); this.chatVisibility = clientOptions.chatVisibility(); this.canChatColor = clientOptions.chatColors(); -@@ -1957,12 +2507,27 @@ +@@ -1957,12 +2515,27 @@ this.camera = (Entity) (entity == null ? this : entity); if (entity1 != this.camera) { @@ -1435,7 +1464,7 @@ } if (entity != null) { -@@ -1999,11 +2564,11 @@ +@@ -1999,11 +2572,11 @@ @Nullable public Component getTabListDisplayName() { @@ -1449,7 +1478,7 @@ } @Override -@@ -2046,17 +2611,43 @@ +@@ -2046,17 +2619,43 @@ } public void setRespawnPosition(ResourceKey dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) { @@ -1500,7 +1529,7 @@ } else { this.respawnPosition = null; this.respawnDimension = Level.OVERWORLD; -@@ -2088,18 +2679,44 @@ +@@ -2088,18 +2687,44 @@ } @Override @@ -1549,7 +1578,24 @@ } this.awardStat(Stats.DROP); -@@ -2275,9 +2892,15 @@ +@@ -2166,6 +2791,16 @@ + } + + 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")); + } + +@@ -2275,9 +2910,15 @@ @Override public void stopRiding() { @@ -1566,7 +1612,7 @@ if (entity instanceof LivingEntity entityliving) { Iterator iterator = entityliving.getActiveEffects().iterator(); -@@ -2375,10 +2998,12 @@ +@@ -2375,10 +3016,12 @@ return TicketType.ENDER_PEARL.timeout(); } @@ -1582,7 +1628,7 @@ } private static float calculateLookAtYaw(Vec3 respawnPos, BlockPos currentPos) { -@@ -2387,4 +3012,147 @@ +@@ -2387,4 +3030,147 @@ return (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D); } } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index a198dc4b0e..adf0ed5d3c 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -39,15 +39,26 @@ public class ServerPlayerGameMode { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -56,9 +75,16 @@ +@@ -53,18 +72,32 @@ + } + + public boolean changeGameModeForPlayer(GameType gameMode) { ++ // Paper start - Expand PlayerGameModeChangeEvent ++ PlayerGameModeChangeEvent event = this.changeGameModeForPlayer(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.UNKNOWN, null); ++ return event != null && event.isCancelled(); ++ } ++ @Nullable ++ public PlayerGameModeChangeEvent changeGameModeForPlayer(GameType gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause cause, @Nullable net.kyori.adventure.text.Component cancelMessage) { ++ // Paper end - Expand PlayerGameModeChangeEvent if (gameMode == this.gameModeForPlayer) { - return false; +- return false; ++ return null; // Paper - Expand PlayerGameModeChangeEvent } else { + // CraftBukkit start -+ PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(this.player.getBukkitEntity(), GameMode.getByValue(gameMode.getId())); ++ PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(this.player.getBukkitEntity(), GameMode.getByValue(gameMode.getId()), cause, cancelMessage); // Paper + this.level.getCraftServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { -+ return false; ++ return event; // Paper - Expand PlayerGameModeChangeEvent + } + // CraftBukkit end this.setGameModeForPlayer(gameMode, this.previousGameModeForPlayer); @@ -57,7 +68,14 @@ this.level.updateSleepingPlayerList(); if (gameMode == GameType.CREATIVE) { this.player.resetCurrentImpulseContext(); -@@ -92,12 +118,12 @@ + } + +- return true; ++ return event; // Paper - Expand PlayerGameModeChangeEvent + } + } + +@@ -92,12 +125,12 @@ } public void tick() { @@ -73,7 +91,7 @@ this.hasDelayedDestroy = false; } else { float f = this.incrementDestroyProgress(iblockdata, this.delayedDestroyPos, this.delayedTickStart); -@@ -108,7 +134,13 @@ +@@ -108,7 +141,13 @@ } } } else if (this.isDestroyingBlock) { @@ -88,7 +106,7 @@ if (iblockdata.isAir()) { this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); this.lastSentState = -1; -@@ -137,6 +169,7 @@ +@@ -137,6 +176,7 @@ public void handleBlockBreakAction(BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight, int sequence) { if (!this.player.canInteractWithBlock(pos, 1.0D)) { @@ -96,7 +114,7 @@ this.debugLogging(pos, false, sequence, "too far"); } else if (pos.getY() > worldHeight) { this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); -@@ -146,16 +179,46 @@ +@@ -146,16 +186,46 @@ if (action == ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK) { if (!this.level.mayInteract(this.player, pos)) { @@ -110,9 +128,9 @@ + this.player.connection.send(tileentity.getUpdatePacket()); + } + // CraftBukkit end - return; - } - ++ return; ++ } ++ + // CraftBukkit start + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND); + if (event.isCancelled()) { @@ -123,10 +141,10 @@ + if (tileentity != null) { + this.player.connection.send(tileentity.getUpdatePacket()); + } -+ return; -+ } + return; + } + // CraftBukkit end -+ + if (this.isCreative()) { this.destroyAndAck(pos, sequence, "creative destroy"); return; @@ -143,7 +161,7 @@ if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); this.debugLogging(pos, false, sequence, "block action restricted"); -@@ -166,7 +229,19 @@ +@@ -166,7 +236,19 @@ float f = 1.0F; iblockdata = this.level.getBlockState(pos); @@ -164,7 +182,7 @@ EnchantmentHelper.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EquipmentSlot.MAINHAND, Vec3.atCenterOf(pos), iblockdata, (item) -> { this.player.onEquippedItemBroken(item, EquipmentSlot.MAINHAND); }); -@@ -174,6 +249,26 @@ +@@ -174,6 +256,26 @@ f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos); } @@ -191,7 +209,7 @@ if (!iblockdata.isAir() && f >= 1.0F) { this.destroyAndAck(pos, sequence, "insta mine"); } else { -@@ -217,14 +312,18 @@ +@@ -217,14 +319,18 @@ this.debugLogging(pos, true, sequence, "stopped destroying"); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { this.isDestroyingBlock = false; @@ -214,7 +232,7 @@ } } -@@ -242,19 +341,78 @@ +@@ -242,19 +348,78 @@ public boolean destroyBlock(BlockPos pos) { BlockState iblockdata = this.level.getBlockState(pos); @@ -295,7 +313,7 @@ BlockState iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player); boolean flag = this.level.removeBlock(pos, false); -@@ -263,19 +421,34 @@ +@@ -263,19 +428,34 @@ } if (this.isCreative()) { @@ -333,7 +351,7 @@ } } } -@@ -321,15 +494,58 @@ +@@ -321,15 +501,58 @@ } } @@ -392,7 +410,7 @@ if (itileinventory != null) { player.openMenu(itileinventory); return InteractionResult.CONSUME; -@@ -359,7 +575,7 @@ +@@ -359,7 +582,7 @@ } } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 1eb7688d7d..4836c4fed1 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -1788,8 +1788,9 @@ + this.player = this.server.getPlayerList().respawn(this.player, false, Entity.RemovalReason.KILLED, RespawnReason.DEATH); // CraftBukkit this.resetPosition(); if (this.server.isHardcore()) { - this.player.setGameMode(GameType.SPECTATOR); +- this.player.setGameMode(GameType.SPECTATOR); - ((GameRules.BooleanValue) this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.server); ++ this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper - Expand PlayerGameModeChangeEvent + ((GameRules.BooleanValue) this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.player.serverLevel()); // CraftBukkit - per-world } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index c93ec7e97c..0b151a66d7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1671,7 +1671,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { Preconditions.checkArgument(mode != null, "GameMode cannot be null"); if (this.getHandle().connection == null) return; - this.getHandle().setGameMode(GameType.byId(mode.getValue())); + this.getHandle().setGameMode(GameType.byId(mode.getValue()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.PLUGIN, null); // Paper - Expand PlayerGameModeChangeEvent } @Override