2021-03-15 23:00:00 +01:00
--- a/net/minecraft/server/network/PlayerConnection.java
+++ b/net/minecraft/server/network/PlayerConnection.java
2022-08-14 03:27:22 +02:00
@@ -184,6 +184,67 @@
2022-02-28 16:00:00 +01:00
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
2014-11-25 22:32:16 +01:00
+// CraftBukkit start
2022-08-14 03:27:22 +02:00
+import java.util.Arrays;
2014-11-25 22:32:16 +01:00
+import java.util.concurrent.ExecutionException;
2021-06-11 07:00:00 +02:00
+import java.util.concurrent.atomic.AtomicInteger;
2022-07-27 20:00:00 +02:00
+import net.minecraft.network.chat.OutgoingPlayerChatMessage;
2021-03-15 23:00:00 +01:00
+import net.minecraft.network.protocol.game.PacketPlayOutAttachEntity;
2022-08-14 03:27:22 +02:00
+import net.minecraft.network.protocol.game.PacketPlayOutEntityEquipment;
2021-03-15 23:00:00 +01:00
+import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
2022-06-07 18:00:00 +02:00
+import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity;
2021-03-15 23:00:00 +01:00
+import net.minecraft.network.protocol.game.PacketPlayOutSpawnPosition;
+import net.minecraft.world.entity.EntityInsentient;
2021-12-21 22:04:07 +01:00
+import net.minecraft.world.entity.animal.Bucketable;
+import net.minecraft.world.entity.EntityLiving;
2022-08-14 03:27:22 +02:00
+import net.minecraft.world.entity.EnumItemSlot;
+import net.minecraft.world.entity.animal.allay.Allay;
2021-03-15 23:00:00 +01:00
+import net.minecraft.world.inventory.InventoryClickType;
2021-06-11 07:00:00 +02:00
+import net.minecraft.world.inventory.Slot;
2021-03-15 23:00:00 +01:00
+import net.minecraft.world.item.crafting.IRecipe;
+import net.minecraft.world.level.RayTrace;
+import net.minecraft.world.phys.MovingObjectPosition;
2016-02-29 22:32:46 +01:00
+import org.bukkit.Location;
2014-11-25 22:32:16 +01:00
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.craftbukkit.util.CraftChatMessage;
2018-07-15 02:00:00 +02:00
+import org.bukkit.craftbukkit.util.CraftMagicNumbers;
2014-11-25 22:32:16 +01:00
+import org.bukkit.craftbukkit.util.LazyPlayerSet;
+import org.bukkit.craftbukkit.util.Waitable;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.block.SignChangeEvent;
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.event.inventory.CraftItemEvent;
+import org.bukkit.event.inventory.InventoryAction;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCreativeEvent;
+import org.bukkit.event.inventory.InventoryType.SlotType;
2021-04-18 10:03:23 +02:00
+import org.bukkit.event.inventory.SmithItemEvent;
2014-11-25 22:32:16 +01:00
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+import org.bukkit.event.player.PlayerAnimationEvent;
2022-06-09 13:30:25 +02:00
+import org.bukkit.event.player.PlayerAnimationType;
2014-11-25 22:32:16 +01:00
+import org.bukkit.event.player.PlayerChatEvent;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.event.player.PlayerInteractAtEntityEvent;
2016-02-29 22:32:46 +01:00
+import org.bukkit.event.player.PlayerInteractEntityEvent;
2014-11-25 22:32:16 +01:00
+import org.bukkit.event.player.PlayerItemHeldEvent;
+import org.bukkit.event.player.PlayerKickEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
2015-07-25 10:19:37 +02:00
+import org.bukkit.event.player.PlayerResourcePackStatusEvent;
2016-03-14 06:53:46 +01:00
+import org.bukkit.event.player.PlayerSwapHandItemsEvent;
2014-11-25 22:32:16 +01:00
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.bukkit.event.player.PlayerToggleFlightEvent;
+import org.bukkit.event.player.PlayerToggleSneakEvent;
+import org.bukkit.event.player.PlayerToggleSprintEvent;
+import org.bukkit.inventory.CraftingInventory;
2016-03-04 05:24:51 +01:00
+import org.bukkit.inventory.EquipmentSlot;
2014-11-25 22:32:16 +01:00
+import org.bukkit.inventory.InventoryView;
2021-04-18 10:03:23 +02:00
+import org.bukkit.inventory.SmithingInventory;
2014-11-25 22:32:16 +01:00
+// CraftBukkit end
+
2022-07-27 20:00:00 +02:00
public class PlayerConnection implements ServerPlayerConnection, TickablePacketListener, PacketListenerPlayIn {
2014-11-25 22:32:16 +01:00
2022-02-28 16:00:00 +01:00
static final Logger LOGGER = LogUtils.getLogger();
2022-08-14 03:27:22 +02:00
@@ -199,7 +260,9 @@
2021-06-11 07:00:00 +02:00
private long keepAliveTime;
private boolean keepAlivePending;
private long keepAliveChallenge;
- private int chatSpamTickCount;
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - multithreaded fields
2021-11-21 23:00:00 +01:00
+ private final AtomicInteger chatSpamTickCount = new AtomicInteger();
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2021-06-11 07:00:00 +02:00
private int dropSpamTickCount;
private double firstGoodX;
private double firstGoodY;
2022-08-14 03:27:22 +02:00
@@ -250,8 +313,32 @@
2022-07-27 20:00:00 +02:00
this.signedMessageDecoder = SignedMessageChain.a.UNSIGNED;
}
- this.chatMessageChain = new FutureChain(minecraftserver);
+ this.chatMessageChain = new FutureChain(minecraftserver.chatExecutor); // CraftBukkit - async chat
2021-06-11 07:00:00 +02:00
+
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - add fields and methods
2021-06-11 07:00:00 +02:00
+ this.cserver = minecraftserver.server;
+ }
+
+ private final org.bukkit.craftbukkit.CraftServer cserver;
2019-02-03 04:23:04 +01:00
+ public boolean processedDisconnect;
2014-11-25 22:32:16 +01:00
+ private int lastTick = MinecraftServer.currentTick;
2016-02-29 22:32:46 +01:00
+ private int allowedPlayerTicks = 1;
2014-11-25 22:32:16 +01:00
+ private int lastDropTick = MinecraftServer.currentTick;
2017-04-20 14:10:31 +02:00
+ private int lastBookTick = MinecraftServer.currentTick;
2014-11-25 22:32:16 +01:00
+ private int dropCount = 0;
+
+ // Get position of last block hit for BlockDamageLevel.STOPPED
+ private double lastPosX = Double.MAX_VALUE;
+ private double lastPosY = Double.MAX_VALUE;
+ private double lastPosZ = Double.MAX_VALUE;
+ private float lastPitch = Float.MAX_VALUE;
+ private float lastYaw = Float.MAX_VALUE;
+ private boolean justTeleported = false;
+
2021-11-21 23:00:00 +01:00
+ public CraftPlayer getCraftPlayer() {
2014-11-25 22:32:16 +01:00
+ return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
2021-06-11 07:00:00 +02:00
}
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2021-06-11 07:00:00 +02:00
2022-07-27 20:00:00 +02:00
@Override
2018-12-13 01:00:00 +01:00
public void tick() {
2022-08-14 03:27:22 +02:00
@@ -306,7 +393,7 @@
2021-11-21 23:00:00 +01:00
this.server.getProfiler().push("keepAlive");
long i = SystemUtils.getMillis();
2017-10-06 11:49:22 +02:00
2021-06-11 07:00:00 +02:00
- if (i - this.keepAliveTime >= 15000L) {
+ if (i - this.keepAliveTime >= 25000L) { // CraftBukkit
if (this.keepAlivePending) {
2022-06-07 18:00:00 +02:00
this.disconnect(IChatBaseComponent.translatable("disconnect.timeout"));
2017-10-06 11:49:22 +02:00
} else {
2022-08-14 03:27:22 +02:00
@@ -318,15 +405,21 @@
2014-11-25 22:32:16 +01:00
}
2021-11-21 23:00:00 +01:00
this.server.getProfiler().pop();
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
2021-06-11 07:00:00 +02:00
+ for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
2014-11-25 22:32:16 +01:00
+ /* Use thread-safe field access instead
2021-06-11 07:00:00 +02:00
if (this.chatSpamTickCount > 0) {
--this.chatSpamTickCount;
2014-11-25 22:32:16 +01:00
}
+ */
+ // CraftBukkit end
2021-06-11 07:00:00 +02:00
if (this.dropSpamTickCount > 0) {
--this.dropSpamTickCount;
2015-05-21 09:15:47 +02:00
}
2021-11-21 23:00:00 +01:00
if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && SystemUtils.getMillis() - this.player.getLastActionTime() > (long) (this.server.getPlayerIdleTimeout() * 1000 * 60)) {
+ this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
2022-06-07 18:00:00 +02:00
this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.idling"));
2015-05-21 09:15:47 +02:00
}
2022-08-14 03:27:22 +02:00
@@ -351,16 +444,67 @@
2021-11-21 23:00:00 +01:00
return this.server.isSingleplayerOwner(this.player.getGameProfile());
2014-11-25 22:32:16 +01:00
}
2017-05-30 13:25:59 +02:00
+ // CraftBukkit start
+ @Deprecated
2018-07-15 02:00:00 +02:00
public void disconnect(IChatBaseComponent ichatbasecomponent) {
SPIGOT-4441: Fix serializing Components to and from Legacy
While 9862a0135d0 might of semi helped being able to save black text
lore, it actually took a fundamental problem with the legacy serialization
code and expanded it to break even more aspects of the server when dealing
with Component to Legacy conversion.
This is causing data loss in Spigot with cases such as setting an item name
to white gets stripped resulting in it being italic.
Additionally, things such as book pages have been returning black formatting
codes for the end of the line even when the user doesn't have colors in the book.
The root issue is that the "Default Color" system is fundamentally wrong.
Components do not and should not care about what element of the game they
are being used by, and that's what the default color system did.
It results in components that if obtained from 1 source such as a Book
where the default / rendered color is black, is then copied to another
source such as an Entity name, the black is carried forward and shown
in the Entity name, when in reality it should have been white.
This commit reverts 9862a0135d0 and fixes the underlying serialization
issues when it comes to Legacy to and From conversions.
There was quite a number of issues with this code overall, in how
it handles inserting color codes, new line parsing and such.
Books was using mojangs own "getLegacyString" which doesn't match behavior.
We also do not want to use Mojangs method as there is no guarantee they don't
remove that in future.
Plus, everything about books uses the CB implementation anyways, and it should
be consistent (this was mandatory to avoid serialization format changes on old vs new)
These changes as is results in Item Stacks already serialized will not
change contents when they go to component and back, so this won't impact
any existing data.
Newly created books though for example will change behavior in that they
will no longer insert black color codes in the serialized data and will
only represent intentional color changes by the creator of the book.
This will result in cleaner data on them, and books are the only thing
I'm aware of that has a behavioral shift due to the likelyhood of the
default color system kicking in on other parts of the string.
A unit test has been added to verify integrity of serialization to
ensure that any legacy string that is converted into Components will
always re-encode back in the same way when going back to Legacy.
By: Aikar <aikar@aikar.co>
2020-06-01 11:19:42 +02:00
+ disconnect(CraftChatMessage.fromComponent(ichatbasecomponent));
2017-05-30 13:25:59 +02:00
+ }
+ // CraftBukkit end
+
+ public void disconnect(String s) {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - fire PlayerKickEvent
2016-06-15 05:45:11 +02:00
+ if (this.processedDisconnect) {
+ return;
+ }
2022-07-27 20:00:00 +02:00
+ if (!this.cserver.isPrimaryThread()) {
+ Waitable waitable = new Waitable() {
+ @Override
+ protected Object evaluate() {
+ PlayerConnection.this.disconnect(s);
+ return null;
+ }
+ };
+
+ this.server.processQueue.add(waitable);
+
+ try {
+ waitable.get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ return;
+ }
+
2021-11-21 23:00:00 +01:00
+ String leaveMessage = EnumChatFormat.YELLOW + this.player.getScoreboardName() + " left the game.";
2014-11-25 22:32:16 +01:00
+
2021-06-20 01:27:32 +02:00
+ PlayerKickEvent event = new PlayerKickEvent(this.player.getBukkitEntity(), s, leaveMessage);
2014-11-25 22:32:16 +01:00
+
2021-06-11 07:00:00 +02:00
+ if (this.cserver.getServer().isRunning()) {
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+ }
+
+ if (event.isCancelled()) {
+ // Do not kick the player
+ return;
+ }
2022-03-16 09:49:07 +01:00
+ this.player.kickLeaveMessage = event.getLeaveMessage(); // CraftBukkit - SPIGOT-3034: Forward leave message to PlayerQuitEvent
2014-11-25 22:32:16 +01:00
+ // Send the possibly modified leave message
2022-07-27 20:00:00 +02:00
+ final IChatBaseComponent ichatbasecomponent = CraftChatMessage.fromString(event.getReason(), true)[0];
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2017-05-30 13:25:59 +02:00
+
2022-07-27 20:00:00 +02:00
this.connection.send(new PacketPlayOutKickDisconnect(ichatbasecomponent), PacketSendListener.thenRun(() -> {
2021-11-21 23:00:00 +01:00
this.connection.disconnect(ichatbasecomponent);
2022-07-27 20:00:00 +02:00
}));
2021-11-21 23:00:00 +01:00
+ this.onDisconnect(ichatbasecomponent); // CraftBukkit - fire quit instantly
this.connection.setReadOnly();
2021-06-11 07:00:00 +02:00
MinecraftServer minecraftserver = this.server;
NetworkManager networkmanager = this.connection;
2018-07-15 02:00:00 +02:00
2021-06-11 07:00:00 +02:00
Objects.requireNonNull(this.connection);
2021-11-21 23:00:00 +01:00
- minecraftserver.executeBlocking(networkmanager::handleDisconnection);
2015-04-17 12:55:10 +02:00
+ // CraftBukkit - Don't wait
2021-11-21 23:00:00 +01:00
+ minecraftserver.wrapRunnable(networkmanager::handleDisconnection);
2014-11-25 22:32:16 +01:00
}
2022-07-27 20:00:00 +02:00
private <T, R> CompletableFuture<R> filterTextPacket(T t0, BiFunction<ITextFilter, T, CompletableFuture<R>> bifunction) {
2022-08-14 03:27:22 +02:00
@@ -424,7 +568,34 @@
2021-11-21 23:00:00 +01:00
double d9 = entity.getDeltaMovement().lengthSqr();
2016-03-06 22:33:27 +01:00
double d10 = d6 * d6 + d7 * d7 + d8 * d8;
2021-11-21 23:00:00 +01:00
- if (d10 - d9 > 100.0D && !this.isSingleplayerOwner()) {
2016-03-06 22:33:27 +01:00
+
+ // CraftBukkit start - handle custom speeds and skipped ticks
+ this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick;
+ this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1);
+ this.lastTick = (int) (System.currentTimeMillis() / 50);
+
2021-06-11 07:00:00 +02:00
+ ++this.receivedMovePacketCount;
+ int i = this.receivedMovePacketCount - this.knownMovePacketCount;
2016-03-06 22:33:27 +01:00
+ if (i > Math.max(this.allowedPlayerTicks, 5)) {
2021-11-21 23:00:00 +01:00
+ PlayerConnection.LOGGER.debug(this.player.getScoreboardName() + " is sending move packets too frequently (" + i + " packets since last tick)");
2016-03-06 22:33:27 +01:00
+ i = 1;
+ }
+
+ if (d10 > 0) {
+ allowedPlayerTicks -= 1;
+ } else {
+ allowedPlayerTicks = 20;
+ }
2018-07-15 02:00:00 +02:00
+ double speed;
2021-06-11 07:00:00 +02:00
+ if (player.getAbilities().flying) {
+ speed = player.getAbilities().flyingSpeed * 20f;
2016-03-06 22:33:27 +01:00
+ } else {
2021-06-11 07:00:00 +02:00
+ speed = player.getAbilities().walkingSpeed * 10f;
2016-03-06 22:33:27 +01:00
+ }
+ speed *= 2f; // TODO: Get the speed of the vehicle instead of the player
+
2021-11-21 23:00:00 +01:00
+ if (d10 - d9 > Math.max(100.0D, Math.pow((double) (10.0F * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
2016-03-06 22:33:27 +01:00
+ // CraftBukkit end
2022-02-28 16:00:00 +01:00
PlayerConnection.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8});
2021-11-21 23:00:00 +01:00
this.connection.send(new PacketPlayOutVehicleMove(entity));
2016-03-06 22:33:27 +01:00
return;
2022-08-14 03:27:22 +02:00
@@ -456,14 +627,72 @@
2018-09-26 09:19:16 +02:00
}
2021-11-21 23:00:00 +01:00
entity.absMoveTo(d3, d4, d5, f, f1);
+ player.absMoveTo(d3, d4, d5, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
2022-02-28 16:00:00 +01:00
boolean flag3 = worldserver.noCollision(entity, entity.getBoundingBox().deflate(0.0625D));
2018-09-26 09:19:16 +02:00
2022-02-28 16:00:00 +01:00
if (flag && (flag2 || !flag3)) {
2021-11-21 23:00:00 +01:00
entity.absMoveTo(d0, d1, d2, f, f1);
+ player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
this.connection.send(new PacketPlayOutVehicleMove(entity));
2016-02-29 22:32:46 +01:00
return;
2014-11-25 22:32:16 +01:00
}
2016-02-29 22:32:46 +01:00
2015-05-22 15:33:34 +02:00
+ // CraftBukkit start - fire PlayerMoveEvent
2021-11-21 23:00:00 +01:00
+ Player player = this.getCraftPlayer();
2015-05-22 15:33:34 +02:00
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
+
+ // If the packet contains movement information then we update the To location with the correct XYZ.
2016-02-29 22:32:46 +01:00
+ to.setX(packetplayinvehiclemove.getX());
+ to.setY(packetplayinvehiclemove.getY());
+ to.setZ(packetplayinvehiclemove.getZ());
+
2014-11-25 22:32:16 +01:00
+
2015-05-22 15:33:34 +02:00
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
2021-11-21 23:00:00 +01:00
+ to.setYaw(packetplayinvehiclemove.getYRot());
+ to.setPitch(packetplayinvehiclemove.getXRot());
2014-11-25 22:32:16 +01:00
+
2015-05-22 15:33:34 +02:00
+ // Prevent 40 event-calls for less than a single pixel of movement >.>
+ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
+ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
+
2021-11-21 23:00:00 +01:00
+ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.isImmobile()) {
2015-05-22 15:33:34 +02:00
+ this.lastPosX = to.getX();
+ this.lastPosY = to.getY();
+ this.lastPosZ = to.getZ();
+ this.lastYaw = to.getYaw();
+ this.lastPitch = to.getPitch();
+
+ // Skip the first time we do this
+ if (from.getX() != Double.MAX_VALUE) {
+ Location oldTo = to.clone();
+ PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2015-05-22 15:33:34 +02:00
+
+ // If the event is cancelled we move the player back to their old location.
+ if (event.isCancelled()) {
2016-03-06 23:17:32 +01:00
+ teleport(from);
2015-05-22 15:33:34 +02:00
+ return;
+ }
2016-02-29 22:32:46 +01:00
+
+ // If a Plugin has changed the To destination then we teleport the Player
+ // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
+ // We only do this if the Event was not cancelled.
2015-05-22 15:33:34 +02:00
+ if (!oldTo.equals(event.getTo()) && !event.isCancelled()) {
2017-03-24 05:09:34 +01:00
+ this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.PLUGIN);
2015-05-22 15:33:34 +02:00
+ return;
+ }
2015-04-15 17:24:53 +02:00
+
2016-02-29 22:32:46 +01:00
+ // Check to see if the Players Location has some how changed during the call of the event.
+ // This can happen due to a plugin teleporting the player instead of using .setTo()
2021-11-21 23:00:00 +01:00
+ if (!from.equals(this.getCraftPlayer().getLocation()) && this.justTeleported) {
2015-05-22 15:33:34 +02:00
+ this.justTeleported = false;
+ return;
+ }
2014-11-25 22:32:16 +01:00
+ }
+ }
2016-02-29 22:32:46 +01:00
+ // CraftBukkit end
2015-07-20 23:31:49 +02:00
+
2021-11-21 23:00:00 +01:00
this.player.getLevel().getChunkSource().move(this.player);
this.player.checkMovementStatistics(this.player.getX() - d0, this.player.getY() - d1, this.player.getZ() - d2);
2022-02-28 16:00:00 +01:00
this.clientVehicleIsFloating = d11 >= -0.03125D && !flag1 && !this.server.isFlightAllowed() && !entity.isNoGravity() && this.noBlocksAround(entity);
2022-08-14 03:27:22 +02:00
@@ -497,6 +726,7 @@
2018-09-03 00:00:50 +02:00
}
2021-06-11 07:00:00 +02:00
this.awaitingPositionFromClient = null;
2021-11-21 23:00:00 +01:00
+ this.player.getLevel().getChunkSource().move(this.player); // CraftBukkit
2018-09-03 00:00:50 +02:00
}
}
2022-08-14 03:27:22 +02:00
@@ -504,7 +734,7 @@
2020-08-11 23:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleRecipeBookSeenRecipePacket(PacketPlayInRecipeDisplayed packetplayinrecipedisplayed) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinrecipedisplayed, this, this.player.getLevel());
- Optional optional = this.server.getRecipeManager().byKey(packetplayinrecipedisplayed.getRecipe());
+ Optional<? extends IRecipe<?>> optional = this.server.getRecipeManager().byKey(packetplayinrecipedisplayed.getRecipe()); // CraftBukkit - decompile error
2020-08-11 23:00:00 +02:00
RecipeBookServer recipebookserver = this.player.getRecipeBook();
2019-04-23 04:00:00 +02:00
2021-06-11 07:00:00 +02:00
Objects.requireNonNull(recipebookserver);
2022-08-14 03:27:22 +02:00
@@ -534,6 +764,12 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleCustomCommandSuggestions(PacketPlayInTabComplete packetplayintabcomplete) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayintabcomplete, this, this.player.getLevel());
2018-07-15 02:00:00 +02:00
+ // CraftBukkit start
2021-11-21 23:00:00 +01:00
+ if (chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
2022-06-07 18:00:00 +02:00
+ this.disconnect(IChatBaseComponent.translatable("disconnect.spam"));
2018-07-15 02:00:00 +02:00
+ return;
+ }
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
StringReader stringreader = new StringReader(packetplayintabcomplete.getCommand());
2018-08-26 04:00:00 +02:00
2018-12-25 22:00:00 +01:00
if (stringreader.canRead() && stringreader.peek() == '/') {
2022-08-14 03:27:22 +02:00
@@ -543,6 +779,7 @@
2021-11-21 23:00:00 +01:00
ParseResults<CommandListenerWrapper> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
2018-07-15 02:00:00 +02:00
2021-11-21 23:00:00 +01:00
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
2020-06-25 02:00:00 +02:00
+ if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
2021-11-21 23:00:00 +01:00
this.connection.send(new PacketPlayOutTabComplete(packetplayintabcomplete.getId(), suggestions));
2018-07-15 02:00:00 +02:00
});
}
2022-08-14 03:27:22 +02:00
@@ -792,6 +1029,13 @@
2019-04-28 04:35:28 +02:00
if (container instanceof ContainerMerchant) {
ContainerMerchant containermerchant = (ContainerMerchant) container;
2022-01-28 23:27:01 +01:00
+ // CraftBukkit start
+ final org.bukkit.event.inventory.TradeSelectEvent tradeSelectEvent = CraftEventFactory.callTradeSelectEvent(this.player, i, containermerchant);
+ if (tradeSelectEvent.isCancelled()) {
+ this.player.getBukkitEntity().updateInventory();
+ return;
+ }
+ // CraftBukkit end
2019-04-28 04:35:28 +02:00
2022-07-27 20:00:00 +02:00
if (!containermerchant.stillValid(this.player)) {
PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, containermerchant);
2022-08-14 03:27:22 +02:00
@@ -806,6 +1050,13 @@
2020-11-02 21:00:00 +01:00
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleEditBook(PacketPlayInBEdit packetplayinbedit) {
2018-07-15 02:00:00 +02:00
+ // CraftBukkit start
+ if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
+ this.disconnect("Book edited too quickly!");
+ return;
+ }
+ this.lastBookTick = MinecraftServer.currentTick;
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
int i = packetplayinbedit.getSlot();
2021-06-11 07:00:00 +02:00
2021-11-21 23:00:00 +01:00
if (PlayerInventory.isHotbarSlot(i) || i == 40) {
2022-08-14 03:27:22 +02:00
@@ -814,7 +1065,7 @@
2021-07-06 16:00:00 +02:00
Objects.requireNonNull(list);
optional.ifPresent(list::add);
2021-11-21 23:00:00 +01:00
- Stream stream = packetplayinbedit.getPages().stream().limit(100L);
+ Stream<String> stream = packetplayinbedit.getPages().stream().limit(100L); // CraftBukkit - decompile error
2021-07-06 16:00:00 +02:00
Objects.requireNonNull(list);
stream.forEach(list::add);
2022-08-14 03:27:22 +02:00
@@ -832,7 +1083,7 @@
2021-06-12 08:14:12 +02:00
ItemStack itemstack = this.player.getInventory().getItem(i);
2021-11-21 23:00:00 +01:00
if (itemstack.is(Items.WRITABLE_BOOK)) {
- this.updateBookPages(list, UnaryOperator.identity(), itemstack);
+ this.updateBookPages(list, UnaryOperator.identity(), itemstack.copy(), i, itemstack); // CraftBukkit
2021-06-12 08:14:12 +02:00
}
}
2022-08-14 03:27:22 +02:00
@@ -857,16 +1108,16 @@
2021-06-12 08:14:12 +02:00
2021-11-21 23:00:00 +01:00
this.updateBookPages(list, (s) -> {
2022-06-07 18:00:00 +02:00
return IChatBaseComponent.ChatSerializer.toJson(IChatBaseComponent.literal(s));
2021-06-12 08:14:12 +02:00
- }, itemstack1);
2021-06-14 11:37:21 +02:00
- this.player.getInventory().setItem(i, itemstack1);
2021-06-12 08:14:12 +02:00
+ }, itemstack1, i, itemstack); // CraftBukkit
2021-06-14 11:37:21 +02:00
+ this.player.getInventory().setItem(i, itemstack); // CraftBukkit - event factory updates the hand book
2020-11-04 09:45:54 +01:00
}
}
2022-07-27 20:00:00 +02:00
- private void updateBookPages(List<FilteredText> list, UnaryOperator<String> unaryoperator, ItemStack itemstack) {
+ private void updateBookPages(List<FilteredText> list, UnaryOperator<String> unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit
2021-06-11 07:00:00 +02:00
NBTTagList nbttaglist = new NBTTagList();
2020-11-02 21:00:00 +01:00
2021-11-21 23:00:00 +01:00
if (this.player.isTextFilteringEnabled()) {
2022-06-07 18:00:00 +02:00
- Stream stream = list.stream().map((filteredtext) -> {
+ Stream<NBTTagString> stream = list.stream().map((filteredtext) -> { // CraftBukkit - decompile error
2022-07-27 20:00:00 +02:00
return NBTTagString.valueOf((String) unaryoperator.apply(filteredtext.filteredOrEmpty()));
2021-06-11 07:00:00 +02:00
});
2020-11-02 21:00:00 +01:00
2022-08-14 03:27:22 +02:00
@@ -892,6 +1143,7 @@
2021-06-12 08:14:12 +02:00
}
2021-11-21 23:00:00 +01:00
itemstack.addTagElement("pages", nbttaglist);
2021-06-14 11:37:21 +02:00
+ CraftEventFactory.handleEditBookEvent(player, slot, handItem, itemstack); // CraftBukkit
2021-06-12 08:14:12 +02:00
}
@Override
2022-08-14 03:27:22 +02:00
@@ -928,7 +1180,7 @@
2016-04-24 18:35:59 +02:00
} else {
2021-11-21 23:00:00 +01:00
WorldServer worldserver = this.player.getLevel();
2016-04-24 18:35:59 +02:00
2021-06-11 07:00:00 +02:00
- if (!this.player.wonGame) {
2021-11-21 23:00:00 +01:00
+ if (!this.player.wonGame && !this.player.isImmobile()) { // CraftBukkit
2021-06-11 07:00:00 +02:00
if (this.tickCount == 0) {
2021-11-21 23:00:00 +01:00
this.resetPosition();
2016-04-24 18:35:59 +02:00
}
2022-08-14 03:27:22 +02:00
@@ -938,7 +1190,7 @@
2021-06-11 07:00:00 +02:00
this.awaitingTeleportTime = this.tickCount;
2021-11-21 23:00:00 +01:00
this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
2016-02-29 22:32:46 +01:00
}
-
+ this.allowedPlayerTicks = 20; // CraftBukkit
} else {
2021-06-11 07:00:00 +02:00
this.awaitingTeleportTime = this.tickCount;
2021-11-21 23:00:00 +01:00
double d0 = clampHorizontal(packetplayinflying.getX(this.player.getX()));
2022-08-14 03:27:22 +02:00
@@ -950,7 +1202,15 @@
2016-02-29 22:32:46 +01:00
if (this.player.isPassenger()) {
2021-11-21 23:00:00 +01:00
this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
this.player.getLevel().getChunkSource().move(this.player);
2016-02-29 22:32:46 +01:00
+ this.allowedPlayerTicks = 20; // CraftBukkit
} else {
2016-03-03 12:15:04 +01:00
+ // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify
2021-11-21 23:00:00 +01:00
+ double prevX = player.getX();
+ double prevY = player.getY();
+ double prevZ = player.getZ();
2021-06-11 07:00:00 +02:00
+ float prevYaw = player.getYRot();
+ float prevPitch = player.getXRot();
2016-03-03 12:15:04 +01:00
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
double d3 = this.player.getX();
double d4 = this.player.getY();
double d5 = this.player.getZ();
2022-08-14 03:27:22 +02:00
@@ -970,15 +1230,33 @@
2021-06-11 07:00:00 +02:00
++this.receivedMovePacketCount;
int i = this.receivedMovePacketCount - this.knownMovePacketCount;
2016-12-20 21:00:00 +01:00
- if (i > 5) {
+ // CraftBukkit start - handle custom speeds and skipped ticks
+ this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick;
+ this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1);
+ this.lastTick = (int) (System.currentTimeMillis() / 50);
+
+ if (i > Math.max(this.allowedPlayerTicks, 5)) {
2021-11-21 23:00:00 +01:00
PlayerConnection.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), i);
2016-12-20 21:00:00 +01:00
i = 1;
}
2015-05-22 15:33:34 +02:00
2021-06-11 07:00:00 +02:00
+ if (packetplayinflying.hasRot || d11 > 0) {
2016-12-20 21:00:00 +01:00
+ allowedPlayerTicks -= 1;
+ } else {
+ allowedPlayerTicks = 20;
+ }
2018-07-15 02:00:00 +02:00
+ double speed;
2021-06-11 07:00:00 +02:00
+ if (player.getAbilities().flying) {
+ speed = player.getAbilities().flyingSpeed * 20f;
2016-12-20 21:00:00 +01:00
+ } else {
2021-06-11 07:00:00 +02:00
+ speed = player.getAbilities().walkingSpeed * 10f;
2016-12-20 21:00:00 +01:00
+ }
2016-02-29 22:32:46 +01:00
+
2021-11-21 23:00:00 +01:00
if (!this.player.isChangingDimension() && (!this.player.getLevel().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) {
float f2 = this.player.isFallFlying() ? 300.0F : 100.0F;
2016-02-29 22:32:46 +01:00
2021-11-21 23:00:00 +01:00
- if (d11 - d10 > (double) (f2 * (float) i) && !this.isSingleplayerOwner()) {
+ if (d11 - d10 > Math.max(f2, Math.pow((double) (10.0F * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
2016-12-20 21:00:00 +01:00
+ // CraftBukkit end
2022-02-28 16:00:00 +01:00
PlayerConnection.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d7, d8, d9});
2021-11-21 23:00:00 +01:00
this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot());
2016-12-20 21:00:00 +01:00
return;
2022-08-14 03:27:22 +02:00
@@ -999,6 +1277,7 @@
2022-02-28 16:00:00 +01:00
boolean flag1 = this.player.verticalCollisionBelow;
2020-06-28 02:15:32 +02:00
this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9));
2021-12-02 02:45:58 +01:00
+ this.player.onGround = packetplayinflying.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
2020-06-28 02:15:32 +02:00
double d12 = d8;
2021-11-21 23:00:00 +01:00
d7 = d0 - this.player.getX();
2022-08-14 03:27:22 +02:00
@@ -1018,8 +1297,71 @@
2022-05-24 12:45:57 +02:00
this.player.absMoveTo(d0, d1, d2, f, f1);
2022-02-28 16:00:00 +01:00
if (!this.player.noPhysics && !this.player.isSleeping() && (flag2 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb))) {
2022-05-24 12:45:57 +02:00
- this.teleport(d3, d4, d5, f, f1);
+ this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet(), false); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
2020-06-25 02:00:00 +02:00
} else {
+ // CraftBukkit start - fire PlayerMoveEvent
+ // Rest to old location first
2021-11-21 23:00:00 +01:00
+ this.player.absMoveTo(prevX, prevY, prevZ, prevYaw, prevPitch);
2020-06-25 02:00:00 +02:00
+
2021-11-21 23:00:00 +01:00
+ Player player = this.getCraftPlayer();
2020-06-25 02:00:00 +02:00
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
+
+ // If the packet contains movement information then we update the To location with the correct XYZ.
+ if (packetplayinflying.hasPos) {
+ to.setX(packetplayinflying.x);
+ to.setY(packetplayinflying.y);
+ to.setZ(packetplayinflying.z);
+ }
2016-02-29 22:32:46 +01:00
+
2020-06-25 02:00:00 +02:00
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
2021-06-11 07:00:00 +02:00
+ if (packetplayinflying.hasRot) {
+ to.setYaw(packetplayinflying.yRot);
+ to.setPitch(packetplayinflying.xRot);
2020-06-25 02:00:00 +02:00
+ }
2016-02-29 22:32:46 +01:00
+
2020-06-25 02:00:00 +02:00
+ // Prevent 40 event-calls for less than a single pixel of movement >.>
+ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
+ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
+
2021-11-21 23:00:00 +01:00
+ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.isImmobile()) {
2020-06-25 02:00:00 +02:00
+ this.lastPosX = to.getX();
+ this.lastPosY = to.getY();
+ this.lastPosZ = to.getZ();
+ this.lastYaw = to.getYaw();
+ this.lastPitch = to.getPitch();
+
+ // Skip the first time we do this
+ if (from.getX() != Double.MAX_VALUE) {
+ Location oldTo = to.clone();
+ PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2020-06-25 02:00:00 +02:00
+
+ // If the event is cancelled we move the player back to their old location.
+ if (event.isCancelled()) {
+ teleport(from);
+ return;
+ }
2016-02-29 22:32:46 +01:00
+
2020-06-25 02:00:00 +02:00
+ // If a Plugin has changed the To destination then we teleport the Player
+ // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
+ // We only do this if the Event was not cancelled.
+ if (!oldTo.equals(event.getTo()) && !event.isCancelled()) {
+ this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.PLUGIN);
+ return;
+ }
2016-02-29 22:32:46 +01:00
+
2020-06-25 02:00:00 +02:00
+ // Check to see if the Players Location has some how changed during the call of the event.
+ // This can happen due to a plugin teleporting the player instead of using .setTo()
2021-11-21 23:00:00 +01:00
+ if (!from.equals(this.getCraftPlayer().getLocation()) && this.justTeleported) {
2020-06-25 02:00:00 +02:00
+ this.justTeleported = false;
+ return;
+ }
2016-12-20 21:00:00 +01:00
+ }
2016-02-29 22:32:46 +01:00
+ }
2021-11-21 23:00:00 +01:00
+ this.player.absMoveTo(d0, d1, d2, f, f1); // Copied from above
2020-06-25 02:00:00 +02:00
+ // CraftBukkit end
2022-02-28 16:00:00 +01:00
+
this.clientIsFloating = d12 >= -0.03125D && !flag1 && this.player.gameMode.getGameModeForPlayer() != EnumGamemode.SPECTATOR && !this.server.isFlightAllowed() && !this.player.getAbilities().mayfly && !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.isFallFlying() && !this.player.isAutoSpinAttack() && this.noBlocksAround(this.player);
2021-11-21 23:00:00 +01:00
this.player.getLevel().getChunkSource().move(this.player);
this.player.doCheckFallDamage(this.player.getY() - d6, packetplayinflying.isOnGround());
2022-08-14 03:27:22 +02:00
@@ -1058,19 +1400,80 @@
2021-11-21 23:00:00 +01:00
return true;
2015-02-26 23:41:06 +01:00
}
2021-06-11 07:00:00 +02:00
+ // CraftBukkit start - Delegate to teleport(Location)
2021-11-21 23:00:00 +01:00
public void dismount(double d0, double d1, double d2, float f, float f1) {
- this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), true);
+ this.dismount(d0, d1, d2, f, f1, PlayerTeleportEvent.TeleportCause.UNKNOWN);
2017-03-24 05:08:19 +01:00
+ }
+
2021-11-21 23:00:00 +01:00
+ public void dismount(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) {
+ this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), true, cause);
2021-06-11 07:00:00 +02:00
}
2021-11-21 23:00:00 +01:00
public void teleport(double d0, double d1, double d2, float f, float f1) {
- this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), false);
+ this.teleport(d0, d1, d2, f, f1, PlayerTeleportEvent.TeleportCause.UNKNOWN);
2021-06-11 07:00:00 +02:00
+ }
+
2021-11-21 23:00:00 +01:00
+ public void teleport(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) {
+ this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), false, cause);
2017-03-24 05:23:23 +01:00
}
2021-11-21 23:00:00 +01:00
public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) {
- this.teleport(d0, d1, d2, f, f1, set, false);
+ this.teleport(d0, d1, d2, f, f1, set, PlayerTeleportEvent.TeleportCause.UNKNOWN);
2022-01-28 23:27:01 +01:00
+ }
+
2021-11-21 23:00:00 +01:00
+ public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, PlayerTeleportEvent.TeleportCause cause) {
+ this.teleport(d0, d1, d2, f, f1, set, false, cause);
2022-08-14 03:27:22 +02:00
+ }
+
2021-11-21 23:00:00 +01:00
+ public boolean teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag, PlayerTeleportEvent.TeleportCause cause) { // CraftBukkit - Return event status
+ Player player = this.getCraftPlayer();
2014-11-25 22:32:16 +01:00
+ Location from = player.getLocation();
2015-07-20 23:31:49 +02:00
+
+ double x = d0;
+ double y = d1;
+ double z = d2;
+ float yaw = f;
+ float pitch = f1;
+
2021-11-21 23:00:00 +01:00
+ Location to = new Location(this.getCraftPlayer().getWorld(), x, y, z, yaw, pitch);
2019-07-16 02:15:59 +02:00
+ // SPIGOT-5171: Triggered on join
+ if (from.equals(to)) {
2021-06-11 07:00:00 +02:00
+ this.internalTeleport(d0, d1, d2, f, f1, set, flag);
2021-05-25 00:24:08 +02:00
+ return false; // CraftBukkit - Return event status
2019-07-16 02:15:59 +02:00
+ }
+
2017-03-24 05:08:19 +01:00
+ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
2016-05-30 21:29:10 +02:00
+ if (event.isCancelled() || !to.equals(event.getTo())) {
2015-07-20 23:31:49 +02:00
+ set.clear(); // Can't relative teleport
+ to = event.isCancelled() ? event.getFrom() : event.getTo();
+ d0 = to.getX();
+ d1 = to.getY();
+ d2 = to.getZ();
+ f = to.getYaw();
+ f1 = to.getPitch();
+ }
2016-03-01 03:52:34 +01:00
+
2021-06-11 07:00:00 +02:00
+ this.internalTeleport(d0, d1, d2, f, f1, set, flag);
2021-05-25 00:24:08 +02:00
+ return event.isCancelled(); // CraftBukkit - Return event status
2022-08-14 03:27:22 +02:00
}
- public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) {
2022-02-28 16:00:00 +01:00
+ public void teleport(Location dest) {
+ internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet(), true);
2022-06-07 18:00:00 +02:00
+ }
+
2021-06-11 07:00:00 +02:00
+ private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) {
2016-11-17 02:41:03 +01:00
+ // CraftBukkit start
2014-11-25 22:32:16 +01:00
+ if (Float.isNaN(f)) {
+ f = 0;
+ }
+ if (Float.isNaN(f1)) {
+ f1 = 0;
+ }
2016-06-30 06:27:49 +02:00
+
2016-11-17 02:41:03 +01:00
+ this.justTeleported = true;
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
double d3 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X) ? this.player.getX() : 0.0D;
double d4 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y) ? this.player.getY() : 0.0D;
double d5 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z) ? this.player.getZ() : 0.0D;
2022-08-14 03:27:22 +02:00
@@ -1082,6 +1485,14 @@
2021-06-11 07:00:00 +02:00
this.awaitingTeleport = 0;
2015-07-23 21:37:58 +02:00
}
+ // CraftBukkit start - update last location
2021-06-11 07:00:00 +02:00
+ this.lastPosX = this.awaitingPositionFromClient.x;
+ this.lastPosY = this.awaitingPositionFromClient.y;
+ this.lastPosZ = this.awaitingPositionFromClient.z;
2018-09-04 12:57:55 +02:00
+ this.lastYaw = f;
+ this.lastPitch = f1;
2015-07-23 21:37:58 +02:00
+ // CraftBukkit end
+
2021-06-11 07:00:00 +02:00
this.awaitingTeleportTime = this.tickCount;
2021-11-21 23:00:00 +01:00
this.player.absMoveTo(d0, d1, d2, f, f1);
this.player.connection.send(new PacketPlayOutPosition(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport, flag));
2022-08-14 03:27:22 +02:00
@@ -1090,6 +1501,7 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handlePlayerAction(PacketPlayInBlockDig packetplayinblockdig) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockdig, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
BlockPosition blockposition = packetplayinblockdig.getPos();
2014-11-25 22:32:16 +01:00
2021-11-21 23:00:00 +01:00
this.player.resetLastActionTime();
2022-08-14 03:27:22 +02:00
@@ -1100,14 +1512,46 @@
2019-05-27 22:30:00 +02:00
if (!this.player.isSpectator()) {
2021-11-21 23:00:00 +01:00
ItemStack itemstack = this.player.getItemInHand(EnumHand.OFF_HAND);
2019-05-27 22:30:00 +02:00
2021-11-21 23:00:00 +01:00
- this.player.setItemInHand(EnumHand.OFF_HAND, this.player.getItemInHand(EnumHand.MAIN_HAND));
- this.player.setItemInHand(EnumHand.MAIN_HAND, itemstack);
2019-05-27 22:30:00 +02:00
+ // CraftBukkit start - inspiration taken from DispenserRegistry (See SpigotCraft#394)
+ CraftItemStack mainHand = CraftItemStack.asCraftMirror(itemstack);
2021-11-21 23:00:00 +01:00
+ CraftItemStack offHand = CraftItemStack.asCraftMirror(this.player.getItemInHand(EnumHand.MAIN_HAND));
+ PlayerSwapHandItemsEvent swapItemsEvent = new PlayerSwapHandItemsEvent(getCraftPlayer(), mainHand.clone(), offHand.clone());
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(swapItemsEvent);
2019-05-27 22:30:00 +02:00
+ if (swapItemsEvent.isCancelled()) {
2014-11-25 22:32:16 +01:00
+ return;
+ }
2019-05-27 22:30:00 +02:00
+ if (swapItemsEvent.getOffHandItem().equals(offHand)) {
2021-11-21 23:00:00 +01:00
+ this.player.setItemInHand(EnumHand.OFF_HAND, this.player.getItemInHand(EnumHand.MAIN_HAND));
2019-05-27 22:30:00 +02:00
+ } else {
2021-11-21 23:00:00 +01:00
+ this.player.setItemInHand(EnumHand.OFF_HAND, CraftItemStack.asNMSCopy(swapItemsEvent.getOffHandItem()));
2019-05-27 22:30:00 +02:00
+ }
+ if (swapItemsEvent.getMainHandItem().equals(mainHand)) {
2021-11-21 23:00:00 +01:00
+ this.player.setItemInHand(EnumHand.MAIN_HAND, itemstack);
2019-05-27 22:30:00 +02:00
+ } else {
2021-11-21 23:00:00 +01:00
+ this.player.setItemInHand(EnumHand.MAIN_HAND, CraftItemStack.asNMSCopy(swapItemsEvent.getMainHandItem()));
2019-05-27 22:30:00 +02:00
+ }
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
this.player.stopUsingItem();
2019-05-27 22:30:00 +02:00
}
2014-11-25 22:32:16 +01:00
2019-05-27 22:30:00 +02:00
return;
case DROP_ITEM:
if (!this.player.isSpectator()) {
+ // limit how quickly items can be dropped
+ // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick.
+ if (this.lastDropTick != MinecraftServer.currentTick) {
+ this.dropCount = 0;
+ this.lastDropTick = MinecraftServer.currentTick;
+ } else {
+ // Else we increment the drop count and check the amount.
+ this.dropCount++;
+ if (this.dropCount >= 20) {
2021-11-21 23:00:00 +01:00
+ LOGGER.warn(this.player.getScoreboardName() + " dropped their items too quickly!");
2019-05-27 22:30:00 +02:00
+ this.disconnect("You dropped your items too quickly (Hacking?)");
+ return;
2014-11-25 22:32:16 +01:00
+ }
2019-05-27 22:30:00 +02:00
+ }
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
this.player.drop(false);
2019-05-27 22:30:00 +02:00
}
2022-08-14 03:27:22 +02:00
@@ -1145,6 +1589,7 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleUseItemOn(PacketPlayInUseItem packetplayinuseitem) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseitem, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
2022-06-07 18:00:00 +02:00
this.player.connection.ackBlockChangesUpTo(packetplayinuseitem.getSequence());
2021-11-21 23:00:00 +01:00
WorldServer worldserver = this.player.getLevel();
EnumHand enumhand = packetplayinuseitem.getHand();
2022-08-14 03:27:22 +02:00
@@ -1166,6 +1611,7 @@
2021-06-11 07:00:00 +02:00
2022-02-28 16:00:00 +01:00
if (blockposition.getY() < i) {
if (this.awaitingPositionFromClient == null && this.player.distanceToSqr((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.mayInteract(this.player, blockposition)) {
+ this.player.stopUsingItem(); // CraftBukkit - SPIGOT-4706
EnumInteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock);
2016-02-29 22:32:46 +01:00
2022-02-28 16:00:00 +01:00
if (enumdirection == EnumDirection.UP && !enuminteractionresult.consumesAction() && blockposition.getY() >= i - 1 && wasBlockPlacementAttempt(this.player, itemstack)) {
2022-08-14 03:27:22 +02:00
@@ -1193,6 +1639,7 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleUseItem(PacketPlayInBlockPlace packetplayinblockplace) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockplace, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
2022-06-07 18:00:00 +02:00
this.ackBlockChangesUpTo(packetplayinblockplace.getSequence());
2021-11-21 23:00:00 +01:00
WorldServer worldserver = this.player.getLevel();
EnumHand enumhand = packetplayinblockplace.getHand();
2022-08-14 03:27:22 +02:00
@@ -1200,6 +1647,44 @@
2021-11-21 23:00:00 +01:00
this.player.resetLastActionTime();
2016-11-17 02:41:03 +01:00
if (!itemstack.isEmpty()) {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
2014-12-07 12:04:22 +01:00
+ // Raytrace to look for 'rogue armswings'
2021-06-11 07:00:00 +02:00
+ float f1 = this.player.getXRot();
+ float f2 = this.player.getYRot();
2021-11-21 23:00:00 +01:00
+ double d0 = this.player.getX();
+ double d1 = this.player.getY() + (double) this.player.getEyeHeight();
+ double d2 = this.player.getZ();
2014-12-07 12:04:22 +01:00
+ Vec3D vec3d = new Vec3D(d0, d1, d2);
+
+ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F);
+ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F);
+ float f5 = -MathHelper.cos(-f1 * 0.017453292F);
+ float f6 = MathHelper.sin(-f1 * 0.017453292F);
+ float f7 = f4 * f5;
+ float f8 = f3 * f5;
2021-11-21 23:00:00 +01:00
+ double d3 = player.gameMode.getGameModeForPlayer()== EnumGamemode.CREATIVE ? 5.0D : 4.5D;
2014-12-07 12:04:22 +01:00
+ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3);
2021-11-21 23:00:00 +01:00
+ MovingObjectPosition movingobjectposition = this.player.level.clip(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, player));
2014-12-07 12:04:22 +01:00
+
2016-11-17 02:41:03 +01:00
+ boolean cancelled;
2019-04-23 04:00:00 +02:00
+ if (movingobjectposition == null || movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.BLOCK) {
2016-03-08 19:00:23 +01:00
+ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand);
2014-12-09 13:20:44 +01:00
+ cancelled = event.useItemInHand() == Event.Result.DENY;
+ } else {
2020-09-12 00:36:10 +02:00
+ MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition;
2021-11-21 23:00:00 +01:00
+ if (player.gameMode.firedInteract && player.gameMode.interactPosition.equals(movingobjectpositionblock.getBlockPos()) && player.gameMode.interactHand == enumhand && ItemStack.tagMatches(player.gameMode.interactItemStack, itemstack)) {
2021-06-11 07:00:00 +02:00
+ cancelled = player.gameMode.interactResult;
2020-09-03 22:39:01 +02:00
+ } else {
2021-11-21 23:00:00 +01:00
+ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectpositionblock.getBlockPos(), movingobjectpositionblock.getDirection(), itemstack, true, enumhand);
2020-09-03 22:39:01 +02:00
+ cancelled = event.useItemInHand() == Event.Result.DENY;
+ }
2021-06-11 07:00:00 +02:00
+ player.gameMode.firedInteract = false;
2016-11-17 02:41:03 +01:00
+ }
+
2016-12-10 02:36:09 +01:00
+ if (cancelled) {
+ this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
2020-06-25 02:00:00 +02:00
+ return;
2014-11-25 22:32:16 +01:00
+ }
2021-11-21 23:00:00 +01:00
EnumInteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand);
2016-02-29 22:32:46 +01:00
2021-11-21 23:00:00 +01:00
if (enuminteractionresult.shouldSwing()) {
2022-08-14 03:27:22 +02:00
@@ -1220,7 +1705,7 @@
2021-11-21 23:00:00 +01:00
Entity entity = packetplayinspectate.getEntity(worldserver);
2018-07-15 02:00:00 +02:00
2019-04-23 04:00:00 +02:00
if (entity != null) {
2021-11-21 23:00:00 +01:00
- this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
+ this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit
2019-04-23 04:00:00 +02:00
return;
}
2015-01-06 21:21:14 +01:00
}
2022-08-14 03:27:22 +02:00
@@ -1235,6 +1720,7 @@
2021-11-21 23:00:00 +01:00
PlayerConnection.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName());
2022-06-07 18:00:00 +02:00
this.disconnect(IChatBaseComponent.translatable("multiplayer.requiredTexturePrompt.disconnect"));
2021-06-11 07:00:00 +02:00
}
2021-11-21 23:00:00 +01:00
+ this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getCraftPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.action.ordinal()])); // CraftBukkit
2018-07-18 02:00:43 +02:00
2021-06-11 07:00:00 +02:00
}
2018-07-18 02:00:43 +02:00
2022-08-14 03:27:22 +02:00
@@ -1254,11 +1740,26 @@
2016-02-29 22:32:46 +01:00
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void onDisconnect(IChatBaseComponent ichatbasecomponent) {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - Rarely it would send a disconnect line twice
+ if (this.processedDisconnect) {
+ return;
+ } else {
+ this.processedDisconnect = true;
+ }
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
PlayerConnection.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), ichatbasecomponent.getString());
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - Replace vanilla quit message handling with our own.
+ /*
2021-11-21 23:00:00 +01:00
this.server.invalidateStatus();
2022-07-27 20:00:00 +02:00
this.server.getPlayerList().broadcastSystemMessage(IChatBaseComponent.translatable("multiplayer.player.left", this.player.getDisplayName()).withStyle(EnumChatFormat.YELLOW), false);
2014-11-25 22:32:16 +01:00
+ */
2015-02-26 23:41:06 +01:00
+
2021-11-21 23:00:00 +01:00
this.player.disconnect();
- this.server.getPlayerList().remove(this.player);
+ String quitMessage = this.server.getPlayerList().remove(this.player);
2014-11-25 22:32:16 +01:00
+ if ((quitMessage != null) && (quitMessage.length() > 0)) {
2021-11-21 23:00:00 +01:00
+ this.server.getPlayerList().broadcastMessage(CraftChatMessage.fromString(quitMessage));
2014-11-25 22:32:16 +01:00
+ }
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
this.player.getTextFilter().leave();
if (this.isSingleplayerOwner()) {
2021-06-11 07:00:00 +02:00
PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out");
2022-08-14 03:27:22 +02:00
@@ -1281,6 +1782,15 @@
2021-06-11 07:00:00 +02:00
}
2015-02-26 23:41:06 +01:00
2022-07-27 20:00:00 +02:00
public void send(Packet<?> packet, @Nullable PacketSendListener packetsendlistener) {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
+ if (packet == null) {
+ return;
+ } else if (packet instanceof PacketPlayOutSpawnPosition) {
+ PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet;
2021-11-21 23:00:00 +01:00
+ this.player.compassTarget = new Location(this.getCraftPlayer().getWorld(), packet6.pos.getX(), packet6.pos.getY(), packet6.pos.getZ());
2014-11-25 22:32:16 +01:00
+ }
+ // CraftBukkit end
2015-02-26 23:41:06 +01:00
+
2014-11-25 22:32:16 +01:00
try {
2022-07-27 20:00:00 +02:00
this.connection.send(packet, packetsendlistener);
2015-02-26 23:41:06 +01:00
} catch (Throwable throwable) {
2022-08-14 03:27:22 +02:00
@@ -1297,7 +1807,16 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleSetCarriedItem(PacketPlayInHeldItemSlot packetplayinhelditemslot) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinhelditemslot, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
if (packetplayinhelditemslot.getSlot() >= 0 && packetplayinhelditemslot.getSlot() < PlayerInventory.getSelectionSize()) {
+ PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getCraftPlayer(), this.player.getInventory().selected, packetplayinhelditemslot.getSlot());
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+ if (event.isCancelled()) {
2021-11-21 23:00:00 +01:00
+ this.send(new PacketPlayOutHeldItemSlot(this.player.getInventory().selected));
+ this.player.resetLastActionTime();
2014-11-25 22:32:16 +01:00
+ return;
+ }
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
if (this.player.getInventory().selected != packetplayinhelditemslot.getSlot() && this.player.getUsedItemHand() == EnumHand.MAIN_HAND) {
this.player.stopUsingItem();
2020-06-25 02:00:00 +02:00
}
2022-08-14 03:27:22 +02:00
@@ -1306,16 +1825,23 @@
2021-11-21 23:00:00 +01:00
this.player.resetLastActionTime();
2014-11-25 22:32:16 +01:00
} else {
2021-11-21 23:00:00 +01:00
PlayerConnection.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
2019-01-05 06:21:07 +01:00
+ this.disconnect("Invalid hotbar selection (Hacking?)"); // CraftBukkit
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 handleChat(PacketPlayInChat packetplayinchat) {
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - async chat
2017-11-08 00:36:11 +01:00
+ // SPIGOT-3638
2021-06-11 07:00:00 +02:00
+ if (this.server.isStopped()) {
2017-11-08 00:36:11 +01:00
+ return;
+ }
2014-11-25 22:32:16 +01:00
+ // CraftBukkit end
2022-07-27 20:00:00 +02:00
if (isChatMessageIllegal(packetplayinchat.message())) {
2022-06-07 18:00:00 +02:00
this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.illegal_characters"));
2020-11-02 21:00:00 +01:00
} else {
2022-07-27 20:00:00 +02:00
if (this.tryHandleChat(packetplayinchat.message(), packetplayinchat.timeStamp(), packetplayinchat.lastSeenMessages())) {
- this.server.submit(() -> {
+ // this.server.submit(() -> { // CraftBukkit - async chat
PlayerChatMessage playerchatmessage = this.getSignedMessage(packetplayinchat);
if (this.verifyChatMessage(playerchatmessage)) {
2022-08-14 03:27:22 +02:00
@@ -1328,10 +1854,10 @@
2022-07-27 20:00:00 +02:00
PlayerChatMessage playerchatmessage1 = ((PlayerChatMessage) completablefuture1.join()).filter(filtermask);
this.broadcastChatMessage(playerchatmessage1);
- }, this.server);
+ }, this.server.chatExecutor); // CraftBukkit - async chat
});
}
2022-06-07 18:00:00 +02:00
- });
2022-07-27 20:00:00 +02:00
+ // }); // CraftBukkit - async chat
2022-06-07 18:00:00 +02:00
}
2020-11-02 21:00:00 +01:00
}
2022-08-14 03:27:22 +02:00
@@ -1353,8 +1879,21 @@
2020-11-02 21:00:00 +01:00
}
2022-07-27 20:00:00 +02:00
private void performChatCommand(ServerboundChatCommandPacket serverboundchatcommandpacket) {
- ParseResults<CommandListenerWrapper> parseresults = this.parseCommand(serverboundchatcommandpacket.command());
- Map<String, PlayerChatMessage> map = this.collectSignedArguments(serverboundchatcommandpacket, PreviewableCommand.of(parseresults));
+ // CraftBukkit start
+ String command = "/" + serverboundchatcommandpacket.command();
+ PlayerConnection.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command);
+
+ PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(getCraftPlayer(), command, new LazyPlayerSet(server));
+ this.cserver.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+ command = event.getMessage().substring(1);
+
+ ParseResults<CommandListenerWrapper> parseresults = this.parseCommand(command);
+ Map<String, PlayerChatMessage> map = (serverboundchatcommandpacket.command().equals(command)) ? this.collectSignedArguments(serverboundchatcommandpacket, PreviewableCommand.of(parseresults)) : Collections.emptyMap();
+ // CraftBukkit end
Iterator iterator = map.values().iterator();
PlayerChatMessage playerchatmessage;
2022-08-14 03:27:22 +02:00
@@ -1366,7 +1905,7 @@
2022-07-27 20:00:00 +02:00
parseresults = CommandDispatcher.mapSource(parseresults, (commandlistenerwrapper) -> {
return commandlistenerwrapper.withSigningContext(commandsigningcontext_a);
});
- this.server.getCommands().performCommand(parseresults, serverboundchatcommandpacket.command());
+ this.server.getCommands().performCommand(parseresults, command); // CraftBukkit
return;
}
2022-06-07 18:00:00 +02:00
2022-08-14 03:27:22 +02:00
@@ -1415,7 +1954,7 @@
2022-07-27 20:00:00 +02:00
PlayerConnection.LOGGER.warn("{} sent out-of-order chat: '{}'", this.player.getName().getString(), s);
this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.out_of_order_chat"));
return false;
- } else if (this.player.getChatVisibility() == EnumChatVisibility.HIDDEN) {
+ } else if (this.player.isRemoved() || this.player.getChatVisibility() == EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales
this.send(new ClientboundSystemChatPacket(IChatBaseComponent.translatable("chat.disabled.options").withStyle(EnumChatFormat.RED), false));
return false;
2022-06-07 18:00:00 +02:00
} else {
2022-08-14 03:27:22 +02:00
@@ -1459,6 +1998,135 @@
2022-07-27 20:00:00 +02:00
return false;
2015-02-26 23:41:06 +01:00
}
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - add method
2022-07-27 20:00:00 +02:00
+ public void chat(String s, PlayerChatMessage original, boolean async) {
2021-11-21 23:00:00 +01:00
+ if (s.isEmpty() || this.player.getChatVisibility() == EnumChatVisibility.HIDDEN) {
2014-11-25 22:32:16 +01:00
+ return;
+ }
2022-07-27 20:00:00 +02:00
+ OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(original);
2014-11-25 22:32:16 +01:00
+
+ if (!async && s.startsWith("/")) {
+ this.handleCommand(s);
2021-11-21 23:00:00 +01:00
+ } else if (this.player.getChatVisibility() == EnumChatVisibility.SYSTEM) {
2014-11-25 22:32:16 +01:00
+ // Do nothing, this is coming from a plugin
+ } else {
2021-11-21 23:00:00 +01:00
+ Player player = this.getCraftPlayer();
2021-06-11 07:00:00 +02:00
+ AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet(server));
2022-07-27 20:00:00 +02:00
+ String originalFormat = event.getFormat(), originalMessage = event.getMessage();
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
+ if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) {
+ // Evil plugins still listening to deprecated event
+ final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients());
+ queueEvent.setCancelled(event.isCancelled());
+ Waitable waitable = new Waitable() {
+ @Override
+ protected Object evaluate() {
+ org.bukkit.Bukkit.getPluginManager().callEvent(queueEvent);
2014-12-07 12:04:22 +01:00
+
2014-11-25 22:32:16 +01:00
+ if (queueEvent.isCancelled()) {
2022-07-27 20:00:00 +02:00
+ if (outgoing != null) {
+ outgoing.sendHeadersToRemainingPlayers(PlayerConnection.this.server.getPlayerList());
+ }
2014-11-25 22:32:16 +01:00
+ return null;
+ }
+
+ String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage());
+ if (((LazyPlayerSet) queueEvent.getRecipients()).isLazy()) {
2022-07-27 20:00:00 +02:00
+ if (originalFormat.equals(queueEvent.getFormat()) && originalMessage.equals(queueEvent.getMessage()) && queueEvent.getPlayer().getName().equalsIgnoreCase(queueEvent.getPlayer().getDisplayName())) {
+ PlayerConnection.this.server.getPlayerList().broadcastChatMessage(original, PlayerConnection.this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) PlayerConnection.this.player));
+ return null;
+ } else if (CraftChatMessage.fromComponent(original.serverContent()).equals(message)) {
+ PlayerConnection.this.server.getPlayerList().broadcastChatMessage(original, PlayerConnection.this.player, ChatMessageType.bind(ChatMessageType.RAW, (Entity) PlayerConnection.this.player));
+ return null;
+ }
+
2021-06-11 07:00:00 +02:00
+ for (EntityPlayer recipient : server.getPlayerList().players) {
2021-11-21 23:00:00 +01:00
+ recipient.getBukkitEntity().sendMessage(PlayerConnection.this.player.getUUID(), message);
2014-11-25 22:32:16 +01:00
+ }
+ } else {
+ for (Player player : queueEvent.getRecipients()) {
2021-11-21 23:00:00 +01:00
+ player.sendMessage(PlayerConnection.this.player.getUUID(), message);
2014-11-25 22:32:16 +01:00
+ }
+ }
2022-07-27 20:00:00 +02:00
+ PlayerConnection.this.server.console.sendMessage(message);
+
+ if (outgoing != null) {
+ outgoing.sendHeadersToRemainingPlayers(PlayerConnection.this.server.getPlayerList());
+ }
2014-11-25 22:32:16 +01:00
+ return null;
+ }};
+ if (async) {
2021-06-11 07:00:00 +02:00
+ server.processQueue.add(waitable);
2014-11-25 22:32:16 +01:00
+ } else {
+ waitable.run();
+ }
+ try {
+ waitable.get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on!
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Exception processing chat event", e.getCause());
+ }
+ } else {
+ if (event.isCancelled()) {
2022-07-27 20:00:00 +02:00
+ if (outgoing != null) {
+ outgoing.sendHeadersToRemainingPlayers(PlayerConnection.this.server.getPlayerList());
+ }
2014-11-25 22:32:16 +01:00
+ return;
+ }
2015-02-26 23:41:06 +01:00
+
2014-11-25 22:32:16 +01:00
+ s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage());
+ if (((LazyPlayerSet) event.getRecipients()).isLazy()) {
2022-07-27 20:00:00 +02:00
+ if (originalFormat.equals(event.getFormat()) && originalMessage.equals(event.getMessage()) && event.getPlayer().getName().equalsIgnoreCase(event.getPlayer().getDisplayName())) {
+ PlayerConnection.this.server.getPlayerList().broadcastChatMessage(original, PlayerConnection.this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) PlayerConnection.this.player));
+ return;
+ } else if (CraftChatMessage.fromComponent(original.serverContent()).equals(s)) {
+ PlayerConnection.this.server.getPlayerList().broadcastChatMessage(original, PlayerConnection.this.player, ChatMessageType.bind(ChatMessageType.RAW, (Entity) PlayerConnection.this.player));
+ return;
+ }
+
2021-06-11 07:00:00 +02:00
+ for (EntityPlayer recipient : server.getPlayerList().players) {
2021-11-21 23:00:00 +01:00
+ recipient.getBukkitEntity().sendMessage(PlayerConnection.this.player.getUUID(), s);
2014-11-25 22:32:16 +01:00
+ }
+ } else {
+ for (Player recipient : event.getRecipients()) {
2021-11-21 23:00:00 +01:00
+ recipient.sendMessage(PlayerConnection.this.player.getUUID(), s);
2014-11-25 22:32:16 +01:00
+ }
+ }
2022-07-27 20:00:00 +02:00
+ server.console.sendMessage(s);
+
+ if (outgoing != null) {
+ outgoing.sendHeadersToRemainingPlayers(PlayerConnection.this.server.getPlayerList());
+ }
2014-11-25 22:32:16 +01:00
+ }
2015-02-26 23:41:06 +01:00
+ }
+ }
+
2022-06-07 18:00:00 +02:00
+ private void handleCommand(String s) {
2021-11-21 23:00:00 +01:00
+ this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s);
2014-11-25 22:32:16 +01:00
+
2021-11-21 23:00:00 +01:00
+ CraftPlayer player = this.getCraftPlayer();
2014-11-25 22:32:16 +01:00
+
2021-06-11 07:00:00 +02:00
+ PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s, new LazyPlayerSet(server));
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
+ if (event.isCancelled()) {
+ return;
+ }
+
+ try {
2021-06-11 07:00:00 +02:00
+ if (this.cserver.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) {
2014-11-25 22:32:16 +01:00
+ return;
+ }
+ } catch (org.bukkit.command.CommandException ex) {
+ player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
+ java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+ return;
+ }
2022-06-07 18:00:00 +02:00
+ }
+ // CraftBukkit end
+
2022-07-27 20:00:00 +02:00
private PlayerChatMessage getSignedMessage(PacketPlayInChat packetplayinchat) {
MessageSigner messagesigner = packetplayinchat.getSigner(this.player);
SignedMessageChain.c signedmessagechain_c = new SignedMessageChain.c(packetplayinchat.signature());
2022-08-14 03:27:22 +02:00
@@ -1475,7 +2143,25 @@
2022-07-27 20:00:00 +02:00
}
private void broadcastChatMessage(PlayerChatMessage playerchatmessage) {
- this.server.getPlayerList().broadcastChatMessage(playerchatmessage, this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) this.player));
+ // CraftBukkit start
+ String s = playerchatmessage.signedContent().plain();
+ if (s.isEmpty()) {
+ LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message");
+ } else if (getCraftPlayer().isConversing()) {
+ final String conversationInput = s;
+ this.server.processQueue.add(new Runnable() {
+ @Override
+ public void run() {
+ getCraftPlayer().acceptConversationInput(conversationInput);
+ }
+ });
+ } else if (this.player.getChatVisibility() == EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check
+ this.send(new ClientboundSystemChatPacket(IChatBaseComponent.translatable("chat.cannotSend").withStyle(EnumChatFormat.RED), false));
+ } else {
+ this.chat(s, playerchatmessage, true);
+ }
+ // this.server.getPlayerList().broadcastChatMessage(playerchatmessage, this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) this.player));
+ // CraftBukkit end
this.detectRateSpam();
}
2022-08-14 03:27:22 +02:00
@@ -1503,8 +2189,10 @@
2022-07-27 20:00:00 +02:00
}
private void detectRateSpam() {
- this.chatSpamTickCount += 20;
- if (this.chatSpamTickCount > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
+ // CraftBukkit start - replaced with thread safe throttle
2022-06-07 18:00:00 +02:00
+ // this.chatSpamTickCount += 20;
+ if (this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
+ // CraftBukkit end
2022-07-27 20:00:00 +02:00
this.disconnect(IChatBaseComponent.translatable("disconnect.spam"));
2022-06-07 18:00:00 +02:00
}
2022-08-14 03:27:22 +02:00
@@ -1568,7 +2256,7 @@
2022-07-27 20:00:00 +02:00
List<PreviewableCommand.a<CommandListenerWrapper>> list = previewablecommand.arguments();
2022-06-07 18:00:00 +02:00
2022-07-27 20:00:00 +02:00
if (list.isEmpty()) {
2022-06-07 18:00:00 +02:00
- return CompletableFuture.completedFuture((Object) null);
+ return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
} else {
2022-07-27 20:00:00 +02:00
for (int i = list.size() - 1; i >= 0; --i) {
PreviewableCommand.a previewablecommand_a = (PreviewableCommand.a) list.get(i);
2022-08-14 03:27:22 +02:00
@@ -1580,11 +2268,11 @@
2022-07-27 20:00:00 +02:00
return completablefuture;
2022-06-07 18:00:00 +02:00
}
2022-07-27 20:00:00 +02:00
} catch (CommandSyntaxException commandsyntaxexception) {
- return CompletableFuture.completedFuture((Object) null);
+ return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
2022-06-07 18:00:00 +02:00
}
}
- return CompletableFuture.completedFuture((Object) null);
+ return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
}
2014-11-25 22:32:16 +01:00
}
2022-08-14 03:27:22 +02:00
@@ -1611,13 +2299,65 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleAnimate(PacketPlayInArmAnimation packetplayinarmanimation) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinarmanimation, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start - Raytrace to look for 'rogue armswings'
2021-06-11 07:00:00 +02:00
+ float f1 = this.player.getXRot();
+ float f2 = this.player.getYRot();
2021-11-21 23:00:00 +01:00
+ double d0 = this.player.getX();
+ double d1 = this.player.getY() + (double) this.player.getEyeHeight();
+ double d2 = this.player.getZ();
2014-11-25 22:32:16 +01:00
+ Vec3D vec3d = new Vec3D(d0, d1, d2);
+
+ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F);
+ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F);
+ float f5 = -MathHelper.cos(-f1 * 0.017453292F);
+ float f6 = MathHelper.sin(-f1 * 0.017453292F);
+ float f7 = f4 * f5;
+ float f8 = f3 * f5;
2021-11-21 23:00:00 +01:00
+ double d3 = player.gameMode.getGameModeForPlayer()== EnumGamemode.CREATIVE ? 5.0D : 4.5D;
2014-11-25 22:32:16 +01:00
+ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3);
2021-11-21 23:00:00 +01:00
+ MovingObjectPosition movingobjectposition = this.player.level.clip(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, player));
2014-11-25 22:32:16 +01:00
+
2019-04-23 04:00:00 +02:00
+ if (movingobjectposition == null || movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.BLOCK) {
2021-11-21 23:00:00 +01:00
+ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelected(), EnumHand.MAIN_HAND);
2014-11-25 22:32:16 +01:00
+ }
+
+ // Arm swing animation
2022-06-09 13:30:25 +02:00
+ PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), (packetplayinarmanimation.getHand() == EnumHand.MAIN_HAND) ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
+ if (event.isCancelled()) return;
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
this.player.swing(packetplayinarmanimation.getHand());
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 handlePlayerCommand(PacketPlayInEntityAction packetplayinentityaction) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinentityaction, this, this.player.getLevel());
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
2021-06-11 07:00:00 +02:00
+ if (this.player.isRemoved()) return;
2021-11-21 23:00:00 +01:00
+ switch (packetplayinentityaction.getAction()) {
2019-12-10 23:00:00 +01:00
+ case PRESS_SHIFT_KEY:
+ case RELEASE_SHIFT_KEY:
2021-11-21 23:00:00 +01:00
+ PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getCraftPlayer(), packetplayinentityaction.getAction() == PacketPlayInEntityAction.EnumPlayerAction.PRESS_SHIFT_KEY);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
+ if (event.isCancelled()) {
+ return;
+ }
+ break;
+ case START_SPRINTING:
2015-02-26 23:41:06 +01:00
+ case STOP_SPRINTING:
2021-11-21 23:00:00 +01:00
+ PlayerToggleSprintEvent e2 = new PlayerToggleSprintEvent(this.getCraftPlayer(), packetplayinentityaction.getAction() == PacketPlayInEntityAction.EnumPlayerAction.START_SPRINTING);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(e2);
2014-11-25 22:32:16 +01:00
+
+ if (e2.isCancelled()) {
+ return;
+ }
+ break;
+ }
2015-02-26 23:41:06 +01:00
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
this.player.resetLastActionTime();
2016-02-29 22:32:46 +01:00
IJumpable ijumpable;
2014-11-25 22:32:16 +01:00
2022-08-14 03:27:22 +02:00
@@ -1702,6 +2442,7 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleInteract(PacketPlayInUseEntity packetplayinuseentity) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseentity, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
WorldServer worldserver = this.player.getLevel();
final Entity entity = packetplayinuseentity.getTarget(worldserver);
2022-08-14 03:27:22 +02:00
@@ -1714,10 +2455,49 @@
2021-11-21 23:00:00 +01:00
2022-06-07 18:00:00 +02:00
if (entity.distanceToSqr(this.player.getEyePosition()) < PlayerConnection.MAX_INTERACTION_DISTANCE) {
2021-11-21 23:00:00 +01:00
packetplayinuseentity.dispatch(new PacketPlayInUseEntity.c() {
- private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a) {
+ private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit
ItemStack itemstack = PlayerConnection.this.player.getItemInHand(enumhand).copy();
2021-06-11 07:00:00 +02:00
+ // CraftBukkit start
2021-11-21 23:00:00 +01:00
+ ItemStack itemInHand = PlayerConnection.this.player.getItemInHand(enumhand);
2021-06-11 07:00:00 +02:00
+ boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient;
2021-11-21 23:00:00 +01:00
+ Item origItem = player.getInventory().getSelected() == null ? null : player.getInventory().getSelected().getItem();
2021-06-11 07:00:00 +02:00
+
+ cserver.getPluginManager().callEvent(event);
+
2021-12-21 22:04:07 +01:00
+ // Entity in bucket - SPIGOT-4048 and SPIGOT-6859
+ if ((entity instanceof Bucketable && entity instanceof EntityLiving && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) {
2022-06-07 18:00:00 +02:00
+ send(new PacketPlayOutSpawnEntity(entity));
2021-11-21 23:00:00 +01:00
+ player.containerMenu.sendAllDataToRemote();
2021-06-11 07:00:00 +02:00
+ }
2014-11-25 22:32:16 +01:00
+
2021-11-21 23:00:00 +01:00
+ if (triggerLeashUpdate && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) {
2021-06-11 07:00:00 +02:00
+ // Refresh the current leash state
2021-11-21 23:00:00 +01:00
+ send(new PacketPlayOutAttachEntity(entity, ((EntityInsentient) entity).getLeashHolder()));
2021-06-11 07:00:00 +02:00
+ }
2018-07-19 02:37:25 +02:00
+
2021-11-21 23:00:00 +01:00
+ if (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem) {
2021-06-11 07:00:00 +02:00
+ // Refresh the current entity metadata
2021-11-21 23:00:00 +01:00
+ send(new PacketPlayOutEntityMetadata(entity.getId(), entity.getEntityData(), true));
2022-08-14 03:27:22 +02:00
+ // SPIGOT-7136 - Allays
+ if (entity instanceof Allay) {
+ send(new PacketPlayOutEntityEquipment(entity.getId(), Arrays.stream(EnumItemSlot.values()).map((slot) -> Pair.of(slot, ((EntityLiving) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
+ player.containerMenu.sendAllDataToRemote();
+ }
2021-06-11 07:00:00 +02:00
+ }
2014-11-25 22:32:16 +01:00
+
2021-06-11 07:00:00 +02:00
+ if (event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
2014-11-25 22:32:16 +01:00
+
2021-06-11 07:00:00 +02:00
EnumInteractionResult enuminteractionresult = playerconnection_a.run(PlayerConnection.this.player, entity, enumhand);
+ // CraftBukkit start
+ if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
2022-08-14 03:27:22 +02:00
+ player.containerMenu.sendAllDataToRemote();
2021-06-11 07:00:00 +02:00
+ }
+ // CraftBukkit end
2016-02-29 22:32:46 +01:00
+
2021-11-21 23:00:00 +01:00
if (enuminteractionresult.consumesAction()) {
CriterionTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(PlayerConnection.this.player, itemstack, entity);
if (enuminteractionresult.shouldSwing()) {
2022-08-14 03:27:22 +02:00
@@ -1729,20 +2509,27 @@
2021-06-11 07:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void onInteraction(EnumHand enumhand) {
- this.performInteraction(enumhand, EntityHuman::interactOn);
+ this.performInteraction(enumhand, EntityHuman::interactOn, new PlayerInteractEntityEvent(getCraftPlayer(), entity.getBukkitEntity(), (enumhand == EnumHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
2014-11-25 22:32:16 +01:00
}
2021-06-11 07:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void onInteraction(EnumHand enumhand, Vec3D vec3d) {
this.performInteraction(enumhand, (entityplayer, entity1, enumhand1) -> {
return entity1.interactAt(entityplayer, vec3d, enumhand1);
2021-06-11 07:00:00 +02:00
- });
2021-11-21 23:00:00 +01:00
+ }, new PlayerInteractAtEntityEvent(getCraftPlayer(), entity.getBukkitEntity(), new org.bukkit.util.Vector(vec3d.x, vec3d.y, vec3d.z), (enumhand == EnumHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND)); // CraftBukkit
2021-06-11 07:00:00 +02:00
}
2020-06-25 02:00:00 +02:00
2021-06-11 07:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void onAttack() {
2021-06-11 07:00:00 +02:00
- if (!(entity instanceof EntityItem) && !(entity instanceof EntityExperienceOrb) && !(entity instanceof EntityArrow) && entity != PlayerConnection.this.player) {
+ // CraftBukkit start
+ if (!(entity instanceof EntityItem) && !(entity instanceof EntityExperienceOrb) && !(entity instanceof EntityArrow) && (entity != PlayerConnection.this.player || player.isSpectator())) {
2021-11-21 23:00:00 +01:00
+ ItemStack itemInHand = PlayerConnection.this.player.getMainHandItem();
2021-06-11 07:00:00 +02:00
PlayerConnection.this.player.attack(entity);
+
+ if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
2021-11-21 23:00:00 +01:00
+ player.containerMenu.sendAllDataToRemote();
2021-06-11 07:00:00 +02:00
+ }
+ // CraftBukkit end
} else {
2022-06-07 18:00:00 +02:00
PlayerConnection.this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.invalid_entity_attacked"));
2021-11-21 23:00:00 +01:00
PlayerConnection.LOGGER.warn("Player {} tried to attack an invalid entity", PlayerConnection.this.player.getName().getString());
2022-08-14 03:27:22 +02:00
@@ -1787,15 +2574,21 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleContainerClose(PacketPlayInCloseWindow packetplayinclosewindow) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.getLevel());
2015-02-26 23:41:06 +01:00
+
2021-11-21 23:00:00 +01:00
+ if (this.player.isImmobile()) return; // CraftBukkit
2014-11-25 22:32:16 +01:00
+ CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
2015-02-26 23:41:06 +01:00
+
2021-11-21 23:00:00 +01:00
this.player.doCloseContainer();
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 handleContainerClick(PacketPlayInWindowClick packetplayinwindowclick) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinwindowclick, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
- if (this.player.containerMenu.containerId == packetplayinwindowclick.getContainerId()) {
2015-05-05 22:43:47 +02:00
- if (this.player.isSpectator()) {
2021-11-21 23:00:00 +01:00
+ if (this.player.containerMenu.containerId == packetplayinwindowclick.getContainerId() && this.player.containerMenu.stillValid(this.player)) { // CraftBukkit
2015-05-05 22:43:47 +02:00
+ boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if
2016-02-29 22:32:46 +01:00
+ if (false/*this.player.isSpectator()*/) { // CraftBukkit
2021-11-21 23:00:00 +01:00
this.player.containerMenu.sendAllDataToRemote();
2022-07-27 20:00:00 +02:00
} else if (!this.player.containerMenu.stillValid(this.player)) {
PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
2022-08-14 03:27:22 +02:00
@@ -1808,7 +2601,284 @@
2022-02-28 16:00:00 +01:00
boolean flag = packetplayinwindowclick.getStateId() != this.player.containerMenu.getStateId();
this.player.containerMenu.suppressRemoteUpdates();
- this.player.containerMenu.clicked(i, packetplayinwindowclick.getButtonNum(), packetplayinwindowclick.getClickType(), this.player);
+ // CraftBukkit start - Call InventoryClickEvent
+ if (packetplayinwindowclick.getSlotNum() < -1 && packetplayinwindowclick.getSlotNum() != -999) {
+ return;
+ }
2019-05-27 22:30:00 +02:00
+
2022-02-28 16:00:00 +01:00
+ InventoryView inventory = this.player.containerMenu.getBukkitView();
+ SlotType type = inventory.getSlotType(packetplayinwindowclick.getSlotNum());
2020-09-03 22:39:01 +02:00
+
2022-02-28 16:00:00 +01:00
+ InventoryClickEvent event;
+ ClickType click = ClickType.UNKNOWN;
+ InventoryAction action = InventoryAction.UNKNOWN;
2014-11-25 22:32:16 +01:00
+
2022-02-28 16:00:00 +01:00
+ ItemStack itemstack = ItemStack.EMPTY;
2014-11-25 22:32:16 +01:00
+
2022-02-28 16:00:00 +01:00
+ switch (packetplayinwindowclick.getClickType()) {
+ case PICKUP:
+ if (packetplayinwindowclick.getButtonNum() == 0) {
+ click = ClickType.LEFT;
+ } else if (packetplayinwindowclick.getButtonNum() == 1) {
+ click = ClickType.RIGHT;
+ }
+ if (packetplayinwindowclick.getButtonNum() == 0 || packetplayinwindowclick.getButtonNum() == 1) {
+ action = InventoryAction.NOTHING; // Don't want to repeat ourselves
+ if (packetplayinwindowclick.getSlotNum() == -999) {
+ if (!player.containerMenu.getCarried().isEmpty()) {
+ action = packetplayinwindowclick.getButtonNum() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR;
+ }
+ } else if (packetplayinwindowclick.getSlotNum() < 0) {
+ action = InventoryAction.NOTHING;
+ } else {
+ Slot slot = this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum());
+ if (slot != null) {
+ ItemStack clickedItem = slot.getItem();
+ ItemStack cursor = player.containerMenu.getCarried();
+ if (clickedItem.isEmpty()) {
+ if (!cursor.isEmpty()) {
+ action = packetplayinwindowclick.getButtonNum() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE;
2016-02-29 22:32:46 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ } else if (slot.mayPickup(player)) {
+ if (cursor.isEmpty()) {
+ action = packetplayinwindowclick.getButtonNum() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF;
+ } else if (slot.mayPlace(cursor)) {
+ if (clickedItem.sameItem(cursor) && ItemStack.tagMatches(clickedItem, cursor)) {
+ int toPlace = packetplayinwindowclick.getButtonNum() == 0 ? cursor.getCount() : 1;
+ toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.getCount());
+ toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount());
+ if (toPlace == 1) {
+ action = InventoryAction.PLACE_ONE;
+ } else if (toPlace == cursor.getCount()) {
+ action = InventoryAction.PLACE_ALL;
+ } else if (toPlace < 0) {
+ action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks
+ } else if (toPlace != 0) {
+ action = InventoryAction.PLACE_SOME;
+ }
+ } else if (cursor.getCount() <= slot.getMaxStackSize()) {
+ action = InventoryAction.SWAP_WITH_CURSOR;
+ }
+ } else if (cursor.getItem() == clickedItem.getItem() && ItemStack.tagMatches(cursor, clickedItem)) {
+ if (clickedItem.getCount() >= 0) {
+ if (clickedItem.getCount() + cursor.getCount() <= cursor.getMaxStackSize()) {
+ // As of 1.5, this is result slots only
+ action = InventoryAction.PICKUP_ALL;
+ }
2016-02-29 22:32:46 +01:00
+ }
2014-11-25 22:32:16 +01:00
+ }
+ }
+ }
+ }
+ }
2022-02-28 16:00:00 +01:00
+ break;
+ // TODO check on updates
+ case QUICK_MOVE:
+ if (packetplayinwindowclick.getButtonNum() == 0) {
+ click = ClickType.SHIFT_LEFT;
+ } else if (packetplayinwindowclick.getButtonNum() == 1) {
+ click = ClickType.SHIFT_RIGHT;
+ }
+ if (packetplayinwindowclick.getButtonNum() == 0 || packetplayinwindowclick.getButtonNum() == 1) {
+ if (packetplayinwindowclick.getSlotNum() < 0) {
2016-02-29 22:32:46 +01:00
+ action = InventoryAction.NOTHING;
2022-02-28 16:00:00 +01:00
+ } else {
+ Slot slot = this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum());
+ if (slot != null && slot.mayPickup(this.player) && slot.hasItem()) {
+ action = InventoryAction.MOVE_TO_OTHER_INVENTORY;
+ } else {
+ action = InventoryAction.NOTHING;
+ }
2016-02-29 22:32:46 +01:00
+ }
2014-11-25 22:32:16 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ break;
+ case SWAP:
+ if ((packetplayinwindowclick.getButtonNum() >= 0 && packetplayinwindowclick.getButtonNum() < 9) || packetplayinwindowclick.getButtonNum() == 40) {
+ click = (packetplayinwindowclick.getButtonNum() == 40) ? ClickType.SWAP_OFFHAND : ClickType.NUMBER_KEY;
+ Slot clickedSlot = this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum());
+ if (clickedSlot.mayPickup(player)) {
+ ItemStack hotbar = this.player.getInventory().getItem(packetplayinwindowclick.getButtonNum());
+ boolean canCleanSwap = hotbar.isEmpty() || (clickedSlot.container == player.getInventory() && clickedSlot.mayPlace(hotbar)); // the slot will accept the hotbar item
+ if (clickedSlot.hasItem()) {
+ if (canCleanSwap) {
+ action = InventoryAction.HOTBAR_SWAP;
+ } else {
+ action = InventoryAction.HOTBAR_MOVE_AND_READD;
+ }
+ } else if (!clickedSlot.hasItem() && !hotbar.isEmpty() && clickedSlot.mayPlace(hotbar)) {
2016-02-29 22:32:46 +01:00
+ action = InventoryAction.HOTBAR_SWAP;
2014-11-25 22:32:16 +01:00
+ } else {
2022-02-28 16:00:00 +01:00
+ action = InventoryAction.NOTHING;
2014-11-25 22:32:16 +01:00
+ }
2016-02-29 22:32:46 +01:00
+ } else {
+ action = InventoryAction.NOTHING;
2014-11-25 22:32:16 +01:00
+ }
+ }
2022-02-28 16:00:00 +01:00
+ break;
+ case CLONE:
+ if (packetplayinwindowclick.getButtonNum() == 2) {
+ click = ClickType.MIDDLE;
+ if (packetplayinwindowclick.getSlotNum() < 0) {
2016-02-29 22:32:46 +01:00
+ action = InventoryAction.NOTHING;
2022-02-28 16:00:00 +01:00
+ } else {
+ Slot slot = this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum());
+ if (slot != null && slot.hasItem() && player.getAbilities().instabuild && player.containerMenu.getCarried().isEmpty()) {
+ action = InventoryAction.CLONE_STACK;
+ } else {
+ action = InventoryAction.NOTHING;
+ }
2016-02-29 22:32:46 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ } else {
+ click = ClickType.UNKNOWN;
+ action = InventoryAction.UNKNOWN;
2014-11-25 22:32:16 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ break;
+ case THROW:
+ if (packetplayinwindowclick.getSlotNum() >= 0) {
+ if (packetplayinwindowclick.getButtonNum() == 0) {
+ click = ClickType.DROP;
+ Slot slot = this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum());
+ if (slot != null && slot.hasItem() && slot.mayPickup(player) && !slot.getItem().isEmpty() && slot.getItem().getItem() != Item.byBlock(Blocks.AIR)) {
+ action = InventoryAction.DROP_ONE_SLOT;
+ } else {
+ action = InventoryAction.NOTHING;
+ }
+ } else if (packetplayinwindowclick.getButtonNum() == 1) {
+ click = ClickType.CONTROL_DROP;
+ Slot slot = this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum());
+ if (slot != null && slot.hasItem() && slot.mayPickup(player) && !slot.getItem().isEmpty() && slot.getItem().getItem() != Item.byBlock(Blocks.AIR)) {
+ action = InventoryAction.DROP_ALL_SLOT;
+ } else {
+ action = InventoryAction.NOTHING;
+ }
2016-02-29 22:32:46 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ } else {
+ // Sane default (because this happens when they are holding nothing. Don't ask why.)
+ click = ClickType.LEFT;
+ if (packetplayinwindowclick.getButtonNum() == 1) {
+ click = ClickType.RIGHT;
2016-02-29 22:32:46 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ action = InventoryAction.NOTHING;
2014-11-25 22:32:16 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ break;
+ case QUICK_CRAFT:
+ this.player.containerMenu.clicked(packetplayinwindowclick.getSlotNum(), packetplayinwindowclick.getButtonNum(), packetplayinwindowclick.getClickType(), this.player);
+ break;
+ case PICKUP_ALL:
+ click = ClickType.DOUBLE_CLICK;
2016-02-29 22:32:46 +01:00
+ action = InventoryAction.NOTHING;
2022-02-28 16:00:00 +01:00
+ if (packetplayinwindowclick.getSlotNum() >= 0 && !this.player.containerMenu.getCarried().isEmpty()) {
+ ItemStack cursor = this.player.containerMenu.getCarried();
+ action = InventoryAction.NOTHING;
+ // Quick check for if we have any of the item
+ if (inventory.getTopInventory().contains(CraftMagicNumbers.getMaterial(cursor.getItem())) || inventory.getBottomInventory().contains(CraftMagicNumbers.getMaterial(cursor.getItem()))) {
+ action = InventoryAction.COLLECT_TO_CURSOR;
+ }
2016-02-29 22:32:46 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ break;
+ default:
+ break;
2014-11-25 22:32:16 +01:00
+ }
+
2022-02-28 16:00:00 +01:00
+ if (packetplayinwindowclick.getClickType() != InventoryClickType.QUICK_CRAFT) {
+ if (click == ClickType.NUMBER_KEY) {
+ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.getSlotNum(), click, action, packetplayinwindowclick.getButtonNum());
+ } else {
+ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.getSlotNum(), click, action);
+ }
+
+ org.bukkit.inventory.Inventory top = inventory.getTopInventory();
+ if (packetplayinwindowclick.getSlotNum() == 0 && top instanceof CraftingInventory) {
+ org.bukkit.inventory.Recipe recipe = ((CraftingInventory) top).getRecipe();
+ if (recipe != null) {
+ if (click == ClickType.NUMBER_KEY) {
+ event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.getSlotNum(), click, action, packetplayinwindowclick.getButtonNum());
+ } else {
+ event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.getSlotNum(), click, action);
+ }
2014-11-25 22:32:16 +01:00
+ }
+ }
2020-06-25 02:00:00 +02:00
+
2022-02-28 16:00:00 +01:00
+ if (packetplayinwindowclick.getSlotNum() == 2 && top instanceof SmithingInventory) {
+ org.bukkit.inventory.ItemStack result = ((SmithingInventory) top).getResult();
+ if (result != null) {
+ if (click == ClickType.NUMBER_KEY) {
+ event = new SmithItemEvent(inventory, type, packetplayinwindowclick.getSlotNum(), click, action, packetplayinwindowclick.getButtonNum());
+ } else {
+ event = new SmithItemEvent(inventory, type, packetplayinwindowclick.getSlotNum(), click, action);
+ }
2021-04-18 10:03:23 +02:00
+ }
+ }
+
2022-02-28 16:00:00 +01:00
+ event.setCancelled(cancelled);
+ Container oldContainer = this.player.containerMenu; // SPIGOT-1224
+ cserver.getPluginManager().callEvent(event);
+ if (this.player.containerMenu != oldContainer) {
+ return;
+ }
2021-04-18 10:03:23 +02:00
+
2022-02-28 16:00:00 +01:00
+ switch (event.getResult()) {
+ case ALLOW:
+ case DEFAULT:
+ this.player.containerMenu.clicked(i, packetplayinwindowclick.getButtonNum(), packetplayinwindowclick.getClickType(), this.player);
+ break;
+ case DENY:
+ /* Needs enum constructor in InventoryAction
+ if (action.modifiesOtherSlots()) {
2021-06-11 07:00:00 +02:00
+
2022-02-28 16:00:00 +01:00
+ } else {
+ if (action.modifiesCursor()) {
+ this.player.playerConnection.sendPacket(new Packet103SetSlot(-1, -1, this.player.inventory.getCarried()));
+ }
+ if (action.modifiesClicked()) {
+ this.player.playerConnection.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, packet102windowclick.slot, this.player.activeContainer.getSlot(packet102windowclick.slot).getItem()));
+ }
+ }*/
+ switch (action) {
+ // Modified other slots
+ case PICKUP_ALL:
+ case MOVE_TO_OTHER_INVENTORY:
+ case HOTBAR_MOVE_AND_READD:
+ case HOTBAR_SWAP:
+ case COLLECT_TO_CURSOR:
+ case UNKNOWN:
+ this.player.containerMenu.sendAllDataToRemote();
+ break;
+ // Modified cursor and clicked
+ case PICKUP_SOME:
+ case PICKUP_HALF:
+ case PICKUP_ONE:
+ case PLACE_ALL:
+ case PLACE_SOME:
+ case PLACE_ONE:
+ case SWAP_WITH_CURSOR:
+ this.player.connection.send(new PacketPlayOutSetSlot(-1, -1, this.player.inventoryMenu.incrementStateId(), this.player.containerMenu.getCarried()));
+ this.player.connection.send(new PacketPlayOutSetSlot(this.player.containerMenu.containerId, this.player.inventoryMenu.incrementStateId(), packetplayinwindowclick.getSlotNum(), this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum()).getItem()));
+ break;
+ // Modified clicked only
+ case DROP_ALL_SLOT:
+ case DROP_ONE_SLOT:
+ this.player.connection.send(new PacketPlayOutSetSlot(this.player.containerMenu.containerId, this.player.inventoryMenu.incrementStateId(), packetplayinwindowclick.getSlotNum(), this.player.containerMenu.getSlot(packetplayinwindowclick.getSlotNum()).getItem()));
+ break;
+ // Modified cursor only
+ case DROP_ALL_CURSOR:
+ case DROP_ONE_CURSOR:
+ case CLONE_STACK:
+ this.player.connection.send(new PacketPlayOutSetSlot(-1, -1, this.player.inventoryMenu.incrementStateId(), this.player.containerMenu.getCarried()));
+ break;
+ // Nothing
+ case NOTHING:
+ break;
2014-11-25 22:32:16 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ }
2017-11-08 00:36:11 +01:00
+
2022-02-28 16:00:00 +01:00
+ if (event instanceof CraftItemEvent || event instanceof SmithItemEvent) {
+ // Need to update the inventory on crafting to
+ // correctly support custom recipes
+ player.containerMenu.sendAllDataToRemote();
+ }
2014-12-05 16:04:01 +01:00
+ }
2022-02-28 16:00:00 +01:00
+ // CraftBukkit end
ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packetplayinwindowclick.getChangedSlots()).iterator();
2021-06-11 07:00:00 +02:00
2022-02-28 16:00:00 +01:00
while (objectiterator.hasNext()) {
2022-08-14 03:27:22 +02:00
@@ -1848,6 +2918,7 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleContainerButtonClick(PacketPlayInEnchantItem packetplayinenchantitem) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinenchantitem, this, this.player.getLevel());
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
if (this.player.containerMenu.containerId == packetplayinenchantitem.getContainerId() && !this.player.isSpectator()) {
2022-07-27 20:00:00 +02:00
if (!this.player.containerMenu.stillValid(this.player)) {
2022-08-14 03:27:22 +02:00
@@ -1885,6 +2956,43 @@
2021-11-21 23:00:00 +01:00
boolean flag1 = packetplayinsetcreativeslot.getSlotNum() >= 1 && packetplayinsetcreativeslot.getSlotNum() <= 45;
boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty();
+ if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem(), packetplayinsetcreativeslot.getItem()))) { // Insist on valid slot
2016-11-17 02:41:03 +01:00
+ // CraftBukkit start - Call click event
2021-06-11 07:00:00 +02:00
+ InventoryView inventory = this.player.inventoryMenu.getBukkitView();
2021-11-21 23:00:00 +01:00
+ org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packetplayinsetcreativeslot.getItem());
2014-11-25 22:32:16 +01:00
+
+ SlotType type = SlotType.QUICKBAR;
+ if (flag) {
+ type = SlotType.OUTSIDE;
2021-11-21 23:00:00 +01:00
+ } else if (packetplayinsetcreativeslot.getSlotNum() < 36) {
+ if (packetplayinsetcreativeslot.getSlotNum() >= 5 && packetplayinsetcreativeslot.getSlotNum() < 9) {
2014-11-25 22:32:16 +01:00
+ type = SlotType.ARMOR;
+ } else {
+ type = SlotType.CONTAINER;
+ }
+ }
2021-11-21 23:00:00 +01:00
+ InventoryCreativeEvent event = new InventoryCreativeEvent(inventory, type, flag ? -999 : packetplayinsetcreativeslot.getSlotNum(), item);
2021-06-11 07:00:00 +02:00
+ cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
+ itemstack = CraftItemStack.asNMSCopy(event.getCursor());
+
+ switch (event.getResult()) {
+ case ALLOW:
+ // Plugin cleared the id / stacksize checks
2016-11-17 02:41:03 +01:00
+ flag2 = true;
2014-11-25 22:32:16 +01:00
+ break;
+ case DEFAULT:
+ break;
+ case DENY:
+ // Reset the slot
2021-11-21 23:00:00 +01:00
+ if (packetplayinsetcreativeslot.getSlotNum() >= 0) {
+ this.player.connection.send(new PacketPlayOutSetSlot(this.player.inventoryMenu.containerId, this.player.inventoryMenu.incrementStateId(), packetplayinsetcreativeslot.getSlotNum(), this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem()));
+ this.player.connection.send(new PacketPlayOutSetSlot(-1, this.player.inventoryMenu.incrementStateId(), -1, ItemStack.EMPTY));
2014-11-25 22:32:16 +01:00
+ }
+ return;
+ }
+ }
+ // CraftBukkit end
2016-11-17 02:41:03 +01:00
if (flag1 && flag2) {
2021-11-21 23:00:00 +01:00
this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).set(itemstack);
2022-08-14 03:27:22 +02:00
@@ -1907,6 +3015,7 @@
2020-11-02 21:00:00 +01:00
}
2022-07-27 20:00:00 +02:00
private void updateSignText(PacketPlayInUpdateSign packetplayinupdatesign, List<FilteredText> list) {
2021-11-21 23:00:00 +01:00
+ if (this.player.isImmobile()) return; // CraftBukkit
this.player.resetLastActionTime();
WorldServer worldserver = this.player.getLevel();
BlockPosition blockposition = packetplayinupdatesign.getPos();
2022-08-14 03:27:22 +02:00
@@ -1923,18 +3032,37 @@
2014-11-25 22:32:16 +01:00
2021-11-21 23:00:00 +01:00
if (!tileentitysign.isEditable() || !this.player.getUUID().equals(tileentitysign.getPlayerWhoMayEdit())) {
PlayerConnection.LOGGER.warn("Player {} just tried to change non-editable sign", this.player.getName().getString());
+ this.send(tileentity.getUpdatePacket()); // CraftBukkit
2014-11-25 22:32:16 +01:00
return;
}
+ // CraftBukkit start
2021-06-20 01:27:32 +02:00
+ Player player = this.player.getBukkitEntity();
2021-11-21 23:00:00 +01:00
+ int x = packetplayinupdatesign.getPos().getX();
+ int y = packetplayinupdatesign.getPos().getY();
+ int z = packetplayinupdatesign.getPos().getZ();
2015-02-26 23:41:06 +01:00
+ String[] lines = new String[4];
2015-06-05 12:57:48 +02:00
+
2020-11-02 21:00:00 +01:00
for (int i = 0; i < list.size(); ++i) {
2022-07-27 20:00:00 +02:00
FilteredText filteredtext = (FilteredText) list.get(i);
2021-06-11 07:00:00 +02:00
2021-11-21 23:00:00 +01:00
if (this.player.isTextFilteringEnabled()) {
2022-07-27 20:00:00 +02:00
- tileentitysign.setMessage(i, IChatBaseComponent.literal(filteredtext.filteredOrEmpty()));
+ lines[i] = EnumChatFormat.stripFormatting(filteredtext.filteredOrEmpty());
2021-06-11 07:00:00 +02:00
} else {
2022-07-27 20:00:00 +02:00
- tileentitysign.setMessage(i, IChatBaseComponent.literal(filteredtext.raw()), IChatBaseComponent.literal(filteredtext.filteredOrEmpty()));
+ lines[i] = EnumChatFormat.stripFormatting(filteredtext.raw());
+ }
+ }
2021-06-20 01:27:32 +02:00
+ SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.player.getBukkitEntity(), lines);
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+
+ if (!event.isCancelled()) {
2021-06-11 07:00:00 +02:00
+ IChatBaseComponent[] components = org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines());
+ for (int i = 0; i < components.length; i++) {
2021-11-21 23:00:00 +01:00
+ tileentitysign.setMessage(i, components[i]);
2022-07-27 20:00:00 +02:00
}
2014-11-25 22:32:16 +01:00
+ tileentitysign.isEditable = false;
2022-07-27 20:00:00 +02:00
}
2015-02-26 23:41:06 +01:00
+ // CraftBukkit end
2021-11-21 23:00:00 +01:00
tileentitysign.setChanged();
worldserver.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3);
2022-08-14 03:27:22 +02:00
@@ -1944,6 +3072,7 @@
2017-09-19 00:00:56 +02:00
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleKeepAlive(PacketPlayInKeepAlive packetplayinkeepalive) {
+ PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinkeepalive, this, this.player.getLevel()); // CraftBukkit
if (this.keepAlivePending && packetplayinkeepalive.getId() == this.keepAliveChallenge) {
int i = (int) (SystemUtils.getMillis() - this.keepAliveTime);
2017-09-19 00:00:56 +02:00
2022-08-14 03:27:22 +02:00
@@ -1958,7 +3087,17 @@
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handlePlayerAbilities(PacketPlayInAbilities packetplayinabilities) {
PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinabilities, this, this.player.getLevel());
2021-06-11 07:00:00 +02:00
- this.player.getAbilities().flying = packetplayinabilities.isFlying() && this.player.getAbilities().mayfly;
2014-11-25 22:32:16 +01:00
+ // CraftBukkit start
2021-06-11 07:00:00 +02:00
+ if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packetplayinabilities.isFlying()) {
2021-06-20 01:27:32 +02:00
+ PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.player.getBukkitEntity(), packetplayinabilities.isFlying());
2021-06-11 07:00:00 +02:00
+ this.cserver.getPluginManager().callEvent(event);
2014-11-25 22:32:16 +01:00
+ if (!event.isCancelled()) {
2021-06-11 07:00:00 +02:00
+ this.player.getAbilities().flying = packetplayinabilities.isFlying(); // Actually set the player's flying status
2014-11-25 22:32:16 +01:00
+ } else {
2021-11-21 23:00:00 +01:00
+ this.player.onUpdateAbilities(); // Tell the player their ability was reverted
2014-11-25 22:32:16 +01:00
+ }
+ }
+ // CraftBukkit end
}
2019-04-23 04:00:00 +02:00
@Override
2022-08-14 03:27:22 +02:00
@@ -1967,8 +3106,50 @@
2021-11-21 23:00:00 +01:00
this.player.updateOptions(packetplayinsettings);
2018-07-15 02:00:00 +02:00
}
2017-04-20 14:10:31 +02:00
2019-04-23 04:00:00 +02:00
- @Override
2021-11-21 23:00:00 +01:00
- public void handleCustomPayload(PacketPlayInCustomPayload packetplayincustompayload) {}
2018-07-15 02:00:00 +02:00
+ // CraftBukkit start
+ private static final MinecraftKey CUSTOM_REGISTER = new MinecraftKey("register");
+ private static final MinecraftKey CUSTOM_UNREGISTER = new MinecraftKey("unregister");
+
2019-04-23 04:00:00 +02:00
+ @Override
2021-11-21 23:00:00 +01:00
+ public void handleCustomPayload(PacketPlayInCustomPayload packetplayincustompayload) {
+ PlayerConnectionUtils.ensureRunningOnSameThread(packetplayincustompayload, this, this.player.getLevel());
2021-06-11 07:00:00 +02:00
+ if (packetplayincustompayload.identifier.equals(CUSTOM_REGISTER)) {
2018-07-15 02:00:00 +02:00
+ try {
+ String channels = packetplayincustompayload.data.toString(com.google.common.base.Charsets.UTF_8);
+ for (String channel : channels.split("\0")) {
2021-11-21 23:00:00 +01:00
+ getCraftPlayer().addChannel(channel);
2018-07-15 02:00:00 +02:00
+ }
+ } catch (Exception ex) {
+ PlayerConnection.LOGGER.error("Couldn\'t register custom payload", ex);
+ this.disconnect("Invalid payload REGISTER!");
2017-04-20 14:10:31 +02:00
+ }
2021-06-11 07:00:00 +02:00
+ } else if (packetplayincustompayload.identifier.equals(CUSTOM_UNREGISTER)) {
2018-07-15 02:00:00 +02:00
+ try {
+ String channels = packetplayincustompayload.data.toString(com.google.common.base.Charsets.UTF_8);
+ for (String channel : channels.split("\0")) {
2021-11-21 23:00:00 +01:00
+ getCraftPlayer().removeChannel(channel);
2017-04-20 14:10:31 +02:00
+ }
2018-07-15 02:00:00 +02:00
+ } catch (Exception ex) {
+ PlayerConnection.LOGGER.error("Couldn\'t unregister custom payload", ex);
+ this.disconnect("Invalid payload UNREGISTER!");
+ }
+ } else {
+ try {
+ byte[] data = new byte[packetplayincustompayload.data.readableBytes()];
+ packetplayincustompayload.data.readBytes(data);
2021-06-11 07:00:00 +02:00
+ cserver.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packetplayincustompayload.identifier.toString(), data);
2018-07-15 02:00:00 +02:00
+ } catch (Exception ex) {
+ PlayerConnection.LOGGER.error("Couldn\'t dispatch custom payload", ex);
+ this.disconnect("Invalid custom payload!");
+ }
+ }
+
+ }
2016-11-17 02:41:03 +01:00
+
2014-11-25 22:32:16 +01:00
+ public final boolean isDisconnected() {
2021-06-11 07:00:00 +02:00
+ return !this.player.joining && !this.connection.isConnected();
2016-02-29 23:58:55 +01:00
+ }
2018-07-15 02:00:00 +02:00
+ // CraftBukkit end
2019-04-23 04:00:00 +02:00
@Override
2021-11-21 23:00:00 +01:00
public void handleChangeDifficulty(PacketPlayInDifficultyChange packetplayindifficultychange) {