From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Allink Date: Fri, 2 Jun 2023 20:55:18 +0100 Subject: [PATCH] Implement command block events diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java index c99fc118013cb3d4043638e2001a8297e79ddf9c..cdaa81e1f2167b29ec01cc25e51a8400deb533d2 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.BaseCommandBlock; import net.minecraft.world.level.Level; public class ServerboundSetCommandMinecartPacket implements Packet { - private final int entity; + public final int entity; // Scissors - private -> public private final String command; private final boolean trackOutput; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 26bf05922698c734302fa80076e7a1eadbfe1d8d..5422eb931d83f65d40be5fcca49b6d9e57eec735 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1,6 +1,8 @@ package net.minecraft.server.network; import me.totalfreedom.scissors.ScissorsConfig; +import me.totalfreedom.scissors.event.block.CommandBlockPlayerEditEvent; +import me.totalfreedom.scissors.event.block.CommandMinecartPlayerEditEvent; import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent; import com.google.common.collect.Lists; import com.google.common.primitives.Floats; @@ -160,6 +162,7 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.ProfilePublicKey; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.MinecartCommandBlock; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BucketItem; import net.minecraft.world.item.Item; @@ -188,6 +191,10 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; +import org.bukkit.craftbukkit.block.CraftBlockStates; +import org.bukkit.craftbukkit.block.CraftCommandBlock; +import org.bukkit.craftbukkit.entity.CraftMinecartCommand; +import org.bukkit.entity.minecart.CommandMinecart; import org.slf4j.Logger; // CraftBukkit start @@ -651,14 +658,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && ( !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position()))) || !worldserver.areChunksLoadedForMove(entity.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(entity.position()))) - )) { + )) { this.connection.send(new ClientboundMoveVehiclePacket(entity)); return; } // Paper end if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { - // CraftBukkit end + // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.connection.send(new ClientboundMoveVehiclePacket(entity)); return; @@ -905,11 +912,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic // Paper end - Don't suggest if tab-complete is disabled // Paper start - async tab completion TAB_COMPLETE_EXECUTOR.execute(() -> { - StringReader stringreader = new StringReader(packet.getCommand()); + StringReader stringreader = new StringReader(packet.getCommand()); - if (stringreader.canRead() && stringreader.peek() == '/') { - stringreader.skip(); - } + if (stringreader.canRead() && stringreader.peek() == '/') { + stringreader.skip(); + } final String command = packet.getCommand(); final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getCraftPlayer(), command, true, null); event.callEvent(); @@ -1001,6 +1008,17 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.player.level().getChunkAt(blockposition).setBlockEntity(tileentity); } + CommandBlockPlayerEditEvent event = new CommandBlockPlayerEditEvent(this.getCraftPlayer(), commandblocklistenerabstract.getCommand(), s, new CraftCommandBlock(this.player.level().getWorld(), tileentitycommand)); + + if (!event.callEvent()) { + return; + } + + s = event.getNewCommand(); + + + // Scissors end + commandblocklistenerabstract.setCommand(s); commandblocklistenerabstract.setTrackOutput(flag); if (!flag) { @@ -1032,7 +1050,21 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic BaseCommandBlock commandblocklistenerabstract = packet.getCommandBlock(this.player.level()); if (commandblocklistenerabstract != null) { - commandblocklistenerabstract.setCommand(packet.getCommand()); + // Scissors start - Implement command block events + String command = packet.getCommand(); + CommandMinecartPlayerEditEvent event = new CommandMinecartPlayerEditEvent(this.getCraftPlayer(), commandblocklistenerabstract.getCommand(), command, new CraftMinecartCommand(this.cserver, (MinecartCommandBlock) this.player.level().getEntity(packet.entity))); + + if (!event.callEvent()) { + return; + } + + command = event.getNewCommand(); + commandblocklistenerabstract.setCommand(command); + + // commandblocklistenerabstract.setCommand(packet.getCommand()); + + // Scissors end + commandblocklistenerabstract.setTrackOutput(packet.isTrackOutput()); if (!packet.isTrackOutput()) { commandblocklistenerabstract.setLastOutput((Component) null); @@ -1484,7 +1516,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic float f2 = this.player.isFallFlying() ? 300.0F : 100.0F; if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { - // CraftBukkit end + // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); return; @@ -1979,7 +2011,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic MutableComponent ichatmutablecomponent = Component.translatable("build.tooHigh", i - 1).withStyle(ChatFormatting.RED); this.player.sendSystemMessage(ichatmutablecomponent, true); - } else if (enuminteractionresult.shouldSwing() && !this.player.gameMode.interactResult) { // Paper + } else if (enuminteractionresult.shouldSwing() && !this.player.gameMode.interactResult) { // Paper this.player.swing(enumhand, true); } } @@ -2230,32 +2262,32 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic // CraftBukkit end if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.message())) { this.server.scheduleOnMain(() -> { // Paper - push to main for event firing - this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause + this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause }); // Paper - push to main for event firing } else { Optional optional = this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages()); if (optional.isPresent()) { // this.server.submit(() -> { // CraftBukkit - async chat - PlayerChatMessage playerchatmessage; + PlayerChatMessage playerchatmessage; - try { - playerchatmessage = this.getSignedMessage(packet, (LastSeenMessages) optional.get()); - } catch (SignedMessageChain.DecodeException signedmessagechain_a) { - this.handleMessageDecodeFailure(signedmessagechain_a); - return; - } + try { + playerchatmessage = this.getSignedMessage(packet, (LastSeenMessages) optional.get()); + } catch (SignedMessageChain.DecodeException signedmessagechain_a) { + this.handleMessageDecodeFailure(signedmessagechain_a); + return; + } - CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent()); - CompletableFuture completablefuture1 = this.server.getChatDecorator().decorate(this.player, null, playerchatmessage.decoratedContent()); // Paper + CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent()); + CompletableFuture completablefuture1 = this.server.getChatDecorator().decorate(this.player, null, playerchatmessage.decoratedContent()); // Paper - this.chatMessageChain.append((executor) -> { - return CompletableFuture.allOf(completablefuture, completablefuture1).thenAcceptAsync((ovoid) -> { - PlayerChatMessage playerchatmessage1 = playerchatmessage.filter(((FilteredText) completablefuture.join()).mask()).withResult(completablefuture1.join()); // Paper + this.chatMessageChain.append((executor) -> { + return CompletableFuture.allOf(completablefuture, completablefuture1).thenAcceptAsync((ovoid) -> { + PlayerChatMessage playerchatmessage1 = playerchatmessage.filter(((FilteredText) completablefuture.join()).mask()).withResult(completablefuture1.join()); // Paper - this.broadcastChatMessage(playerchatmessage1); - }, this.server.chatExecutor); // CraftBukkit - async chat - }); + this.broadcastChatMessage(playerchatmessage1); + }, this.server.chatExecutor); // CraftBukkit - async chat + }); // }); // CraftBukkit - async chat } @@ -2266,7 +2298,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic public void handleChatCommand(ServerboundChatCommandPacket packet) { if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) { this.server.scheduleOnMain(() -> { // Paper - push to main for event firing - this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper + this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper }); // Paper - push to main for event firing } else { Optional optional = this.tryHandleChat(packet.command(), packet.timeStamp(), packet.lastSeenMessages()); @@ -2291,7 +2323,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic // CraftBukkit start String command = "/" + packet.command(); if (org.spigotmc.SpigotConfig.logCommands) { // Paper - ServerGamePacketListenerImpl.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command); + ServerGamePacketListenerImpl.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command); } // Paper PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(this.getCraftPlayer(), command, new LazyPlayerSet(this.server)); @@ -2356,7 +2388,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic if (!this.updateChatOrder(timestamp)) { ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}': {} > {}", this.player.getName().getString(), message, this.lastChatTimeStamp.get().getEpochSecond(), timestamp.getEpochSecond()); // Paper this.server.scheduleOnMain(() -> { // Paper - push to main - this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event ca + this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event ca }); // Paper - push to main return Optional.empty(); } else { @@ -2427,7 +2459,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic this.handleCommand(s); } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Do nothing, this is coming from a plugin - // Paper start + // Paper start } else if (true) { final ChatProcessor cp = new ChatProcessor(this.server, this.player, original, async); cp.process(); @@ -2538,7 +2570,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic // Paper End co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot - this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); + this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); CraftPlayer player = this.getCraftPlayer(); @@ -2617,16 +2649,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @Override public void handleChatAck(ServerboundChatAckPacket packet) { LastSeenMessagesValidator lastseenmessagesvalidator = this.lastSeenMessages; - if (!this.lastSeenMessages.applyOffset(packet.offset())) { - synchronized (this.lastSeenMessages) { - // Scissors start - Add configuration option to disable chat signatures - if (!ScissorsConfig.chatSignaturesEnabled) - { - return; - } - // Scissors end - ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); - this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes + if (!this.lastSeenMessages.applyOffset(packet.offset())) { + synchronized (this.lastSeenMessages) { + // Scissors start - Add configuration option to disable chat signatures + if (!ScissorsConfig.chatSignaturesEnabled) + { + return; + } + // Scissors end + ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); + this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes } } @@ -2865,7 +2897,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } if (event.isCancelled()) { - ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory + ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory return; } // CraftBukkit end @@ -3439,19 +3471,19 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic itemstack = CraftItemStack.asNMSCopy(event.getCursor()); switch (event.getResult()) { - case ALLOW: - // Plugin cleared the id / stacksize checks - flag2 = true; - break; - case DEFAULT: - break; - case DENY: - // Reset the slot - if (packet.getSlotNum() >= 0) { - this.player.connection.send(new ClientboundContainerSetSlotPacket(this.player.inventoryMenu.containerId, this.player.inventoryMenu.incrementStateId(), packet.getSlotNum(), this.player.inventoryMenu.getSlot(packet.getSlotNum()).getItem())); - this.player.connection.send(new ClientboundContainerSetSlotPacket(-1, this.player.inventoryMenu.incrementStateId(), -1, ItemStack.EMPTY)); - } - return; + case ALLOW: + // Plugin cleared the id / stacksize checks + flag2 = true; + break; + case DEFAULT: + break; + case DENY: + // Reset the slot + if (packet.getSlotNum() >= 0) { + this.player.connection.send(new ClientboundContainerSetSlotPacket(this.player.inventoryMenu.containerId, this.player.inventoryMenu.incrementStateId(), packet.getSlotNum(), this.player.inventoryMenu.getSlot(packet.getSlotNum()).getItem())); + this.player.connection.send(new ClientboundContainerSetSlotPacket(-1, this.player.inventoryMenu.incrementStateId(), -1, ItemStack.EMPTY)); + } + return; } } // CraftBukkit end @@ -3519,7 +3551,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } else if (!this.isSingleplayerOwner()) { // Paper start - This needs to be handled on the main thread for plugins server.submit(() -> { - this.disconnect(Component.translatable("disconnect.timeout"), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause + this.disconnect(Component.translatable("disconnect.timeout"), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause }); // Paper end }