mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-01 05:47:45 +01:00
AsyncTabCompleteEvent
Let plugins be able to control tab completion of commands and chat async. This will be useful for frameworks like ACF so we can define async safe completion handlers, and avoid going to main for tab completions. Especially useful if you need to query a database in order to obtain the results for tab completion, such as offline players. Also adds isCommand and getLocation to the sync TabCompleteEvent Co-authored-by: Aikar <aikar@aikar.co>
This commit is contained in:
parent
eb20b0b160
commit
ed76af5637
@ -48,7 +48,7 @@
|
|||||||
import net.minecraft.world.level.GameRules;
|
import net.minecraft.world.level.GameRules;
|
||||||
import net.minecraft.world.level.GameType;
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@@ -192,12 +196,72 @@
|
@@ -192,11 +196,71 @@
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
@ -58,7 +58,7 @@
|
|||||||
import net.minecraft.world.phys.shapes.Shapes;
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
+
|
||||||
+// CraftBukkit start
|
+// CraftBukkit start
|
||||||
+import io.papermc.paper.adventure.ChatProcessor; // Paper
|
+import io.papermc.paper.adventure.ChatProcessor; // Paper
|
||||||
+import io.papermc.paper.adventure.PaperAdventure; // Paper
|
+import io.papermc.paper.adventure.PaperAdventure; // Paper
|
||||||
@ -117,10 +117,9 @@
|
|||||||
+import org.bukkit.inventory.InventoryView;
|
+import org.bukkit.inventory.InventoryView;
|
||||||
+import org.bukkit.inventory.SmithingInventory;
|
+import org.bukkit.inventory.SmithingInventory;
|
||||||
+// CraftBukkit end
|
+// CraftBukkit end
|
||||||
+
|
|
||||||
public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener {
|
public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener {
|
||||||
|
|
||||||
static final Logger LOGGER = LogUtils.getLogger();
|
|
||||||
@@ -247,7 +311,7 @@
|
@@ -247,7 +311,7 @@
|
||||||
private boolean waitingForSwitchToConfig;
|
private boolean waitingForSwitchToConfig;
|
||||||
|
|
||||||
@ -130,14 +129,14 @@
|
|||||||
this.chunkSender = new PlayerChunkSender(connection.isMemoryConnection());
|
this.chunkSender = new PlayerChunkSender(connection.isMemoryConnection());
|
||||||
this.player = player;
|
this.player = player;
|
||||||
player.connection = this;
|
player.connection = this;
|
||||||
@@ -256,9 +320,25 @@
|
@@ -256,8 +320,24 @@
|
||||||
|
|
||||||
Objects.requireNonNull(server);
|
Objects.requireNonNull(server);
|
||||||
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(uuid, server::enforceSecureProfile);
|
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(uuid, server::enforceSecureProfile);
|
||||||
- this.chatMessageChain = new FutureChain(server);
|
- this.chatMessageChain = new FutureChain(server);
|
||||||
+ this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat
|
+ this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat
|
||||||
}
|
}
|
||||||
|
+
|
||||||
+ // CraftBukkit start - add fields and methods
|
+ // CraftBukkit start - add fields and methods
|
||||||
+ private int lastTick = MinecraftServer.currentTick;
|
+ private int lastTick = MinecraftServer.currentTick;
|
||||||
+ private int allowedPlayerTicks = 1;
|
+ private int allowedPlayerTicks = 1;
|
||||||
@ -153,10 +152,9 @@
|
|||||||
+ private float lastYaw = Float.MAX_VALUE;
|
+ private float lastYaw = Float.MAX_VALUE;
|
||||||
+ private boolean justTeleported = false;
|
+ private boolean justTeleported = false;
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (this.ackBlockChangesUpTo > -1) {
|
|
||||||
@@ -277,7 +357,7 @@
|
@@ -277,7 +357,7 @@
|
||||||
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
|
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
|
||||||
if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) {
|
if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) {
|
||||||
@ -336,20 +334,63 @@
|
|||||||
this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering());
|
this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,6 +723,12 @@
|
@@ -545,18 +720,62 @@
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start - AsyncTabCompleteEvent
|
||||||
|
+ private static final java.util.concurrent.ExecutorService TAB_COMPLETE_EXECUTOR = java.util.concurrent.Executors.newFixedThreadPool(4,
|
||||||
|
+ new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Tab Complete Thread - #%d").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build());
|
||||||
|
+ // Paper end - AsyncTabCompleteEvent
|
||||||
@Override
|
@Override
|
||||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
|
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ if (!this.chatSpamThrottler.isIncrementAndUnderThreshold(1, 500) && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) {
|
+ if (!this.chatSpamThrottler.isIncrementAndUnderThreshold(1, 500) && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) {
|
||||||
+ this.disconnect(Component.translatable("disconnect.spam"));
|
+ this.disconnect(Component.translatable("disconnect.spam"));
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
+ // Paper start - AsyncTabCompleteEvent
|
||||||
|
+ TAB_COMPLETE_EXECUTOR.execute(() -> this.handleCustomCommandSuggestions0(packet));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void handleCustomCommandSuggestions0(final ServerboundCommandSuggestionPacket packet) {
|
||||||
StringReader stringreader = new StringReader(packet.getCommand());
|
StringReader stringreader = new StringReader(packet.getCommand());
|
||||||
|
|
||||||
if (stringreader.canRead() && stringreader.peek() == '/') {
|
if (stringreader.canRead() && stringreader.peek() == '/') {
|
||||||
@@ -557,6 +738,7 @@
|
stringreader.skip();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getCraftPlayer(), packet.getCommand(), true, null);
|
||||||
|
+ event.callEvent();
|
||||||
|
+ final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions();
|
||||||
|
+ // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server
|
||||||
|
+ if (!event.isHandled()) {
|
||||||
|
+ if (event.isCancelled()) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // This needs to be on main
|
||||||
|
+ this.server.scheduleOnMain(() -> this.sendServerSuggestions(packet, stringreader));
|
||||||
|
+ } else if (!completions.isEmpty()) {
|
||||||
|
+ final com.mojang.brigadier.suggestion.SuggestionsBuilder builder0 = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packet.getCommand(), stringreader.getTotalLength());
|
||||||
|
+ final com.mojang.brigadier.suggestion.SuggestionsBuilder builder = builder0.createOffset(builder0.getInput().lastIndexOf(' ') + 1);
|
||||||
|
+ for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion completion : completions) {
|
||||||
|
+ final Integer intSuggestion = com.google.common.primitives.Ints.tryParse(completion.suggestion());
|
||||||
|
+ if (intSuggestion != null) {
|
||||||
|
+ builder.suggest(intSuggestion, PaperAdventure.asVanilla(completion.tooltip()));
|
||||||
|
+ } else {
|
||||||
|
+ builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip()));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join()));
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringreader) {
|
||||||
|
+ // Paper end - AsyncTabCompleteEvent
|
||||||
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
|
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
|
||||||
|
|
||||||
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
||||||
@ -357,7 +398,7 @@
|
|||||||
Suggestions suggestions1 = suggestions.getList().size() <= 1000 ? suggestions : new Suggestions(suggestions.getRange(), suggestions.getList().subList(0, 1000));
|
Suggestions suggestions1 = suggestions.getList().size() <= 1000 ? suggestions : new Suggestions(suggestions.getRange(), suggestions.getList().subList(0, 1000));
|
||||||
|
|
||||||
this.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions1));
|
this.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions1));
|
||||||
@@ -668,7 +850,7 @@
|
@@ -668,7 +887,7 @@
|
||||||
ItemStack itemstack = iblockdata.getCloneItemStack(worldserver, blockposition, flag);
|
ItemStack itemstack = iblockdata.getCloneItemStack(worldserver, blockposition, flag);
|
||||||
|
|
||||||
if (!itemstack.isEmpty()) {
|
if (!itemstack.isEmpty()) {
|
||||||
@ -366,7 +407,7 @@
|
|||||||
ServerGamePacketListenerImpl.addBlockDataToItem(iblockdata, worldserver, blockposition, itemstack);
|
ServerGamePacketListenerImpl.addBlockDataToItem(iblockdata, worldserver, blockposition, itemstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,6 +1048,13 @@
|
@@ -866,6 +1085,13 @@
|
||||||
AbstractContainerMenu container = this.player.containerMenu;
|
AbstractContainerMenu container = this.player.containerMenu;
|
||||||
|
|
||||||
if (container instanceof MerchantMenu containermerchant) {
|
if (container instanceof MerchantMenu containermerchant) {
|
||||||
@ -380,7 +421,7 @@
|
|||||||
if (!containermerchant.stillValid(this.player)) {
|
if (!containermerchant.stillValid(this.player)) {
|
||||||
ServerGamePacketListenerImpl.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, containermerchant);
|
ServerGamePacketListenerImpl.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, containermerchant);
|
||||||
return;
|
return;
|
||||||
@@ -879,6 +1068,13 @@
|
@@ -879,6 +1105,13 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleEditBook(ServerboundEditBookPacket packet) {
|
public void handleEditBook(ServerboundEditBookPacket packet) {
|
||||||
@ -394,7 +435,7 @@
|
|||||||
int i = packet.slot();
|
int i = packet.slot();
|
||||||
|
|
||||||
if (Inventory.isHotbarSlot(i) || i == 40) {
|
if (Inventory.isHotbarSlot(i) || i == 40) {
|
||||||
@@ -899,12 +1095,16 @@
|
@@ -899,12 +1132,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBookContents(List<FilteredText> pages, int slotId) {
|
private void updateBookContents(List<FilteredText> pages, int slotId) {
|
||||||
@ -412,7 +453,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,12 +1115,13 @@
|
@@ -915,12 +1152,13 @@
|
||||||
ItemStack itemstack1 = itemstack.transmuteCopy(Items.WRITTEN_BOOK);
|
ItemStack itemstack1 = itemstack.transmuteCopy(Items.WRITTEN_BOOK);
|
||||||
|
|
||||||
itemstack1.remove(DataComponents.WRITABLE_BOOK_CONTENT);
|
itemstack1.remove(DataComponents.WRITABLE_BOOK_CONTENT);
|
||||||
@ -428,7 +469,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,7 +1183,7 @@
|
@@ -982,7 +1220,7 @@
|
||||||
} else {
|
} else {
|
||||||
ServerLevel worldserver = this.player.serverLevel();
|
ServerLevel worldserver = this.player.serverLevel();
|
||||||
|
|
||||||
@ -437,7 +478,7 @@
|
|||||||
if (this.tickCount == 0) {
|
if (this.tickCount == 0) {
|
||||||
this.resetPosition();
|
this.resetPosition();
|
||||||
}
|
}
|
||||||
@@ -997,7 +1198,15 @@
|
@@ -997,7 +1235,15 @@
|
||||||
if (this.player.isPassenger()) {
|
if (this.player.isPassenger()) {
|
||||||
this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
|
this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
|
||||||
this.player.serverLevel().getChunkSource().move(this.player);
|
this.player.serverLevel().getChunkSource().move(this.player);
|
||||||
@ -453,7 +494,7 @@
|
|||||||
double d3 = this.player.getX();
|
double d3 = this.player.getX();
|
||||||
double d4 = this.player.getY();
|
double d4 = this.player.getY();
|
||||||
double d5 = this.player.getZ();
|
double d5 = this.player.getZ();
|
||||||
@@ -1019,15 +1228,33 @@
|
@@ -1019,15 +1265,33 @@
|
||||||
++this.receivedMovePacketCount;
|
++this.receivedMovePacketCount;
|
||||||
int i = this.receivedMovePacketCount - this.knownMovePacketCount;
|
int i = this.receivedMovePacketCount - this.knownMovePacketCount;
|
||||||
|
|
||||||
@ -489,7 +530,7 @@
|
|||||||
ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8});
|
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());
|
this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot());
|
||||||
return;
|
return;
|
||||||
@@ -1043,12 +1270,40 @@
|
@@ -1043,12 +1307,40 @@
|
||||||
boolean flag1 = d7 > 0.0D;
|
boolean flag1 = d7 > 0.0D;
|
||||||
|
|
||||||
if (this.player.onGround() && !packet.isOnGround() && flag1) {
|
if (this.player.onGround() && !packet.isOnGround() && flag1) {
|
||||||
@ -531,7 +572,7 @@
|
|||||||
double d11 = d7;
|
double d11 = d7;
|
||||||
|
|
||||||
d6 = d0 - this.player.getX();
|
d6 = d0 - this.player.getX();
|
||||||
@@ -1061,15 +1316,81 @@
|
@@ -1061,15 +1353,81 @@
|
||||||
d10 = d6 * d6 + d7 * d7 + d8 * d8;
|
d10 = d6 * d6 + d7 * d7 + d8 * d8;
|
||||||
boolean flag3 = false;
|
boolean flag3 = false;
|
||||||
|
|
||||||
@ -615,7 +656,7 @@
|
|||||||
this.player.absMoveTo(d0, d1, d2, f, f1);
|
this.player.absMoveTo(d0, d1, d2, f, f1);
|
||||||
boolean flag4 = this.player.isAutoSpinAttack();
|
boolean flag4 = this.player.isAutoSpinAttack();
|
||||||
|
|
||||||
@@ -1119,6 +1440,7 @@
|
@@ -1119,6 +1477,7 @@
|
||||||
this.awaitingTeleportTime = this.tickCount;
|
this.awaitingTeleportTime = this.tickCount;
|
||||||
this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
|
this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
|
||||||
}
|
}
|
||||||
@ -623,7 +664,7 @@
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -1147,23 +1469,83 @@
|
@@ -1147,23 +1506,83 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void teleport(double x, double y, double z, float yaw, float pitch) {
|
public void teleport(double x, double y, double z, float yaw, float pitch) {
|
||||||
@ -710,7 +751,7 @@
|
|||||||
if (this.player.hasClientLoaded()) {
|
if (this.player.hasClientLoaded()) {
|
||||||
BlockPos blockposition = packet.getPos();
|
BlockPos blockposition = packet.getPos();
|
||||||
|
|
||||||
@@ -1175,14 +1557,46 @@
|
@@ -1175,14 +1594,46 @@
|
||||||
if (!this.player.isSpectator()) {
|
if (!this.player.isSpectator()) {
|
||||||
ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND);
|
ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND);
|
||||||
|
|
||||||
@ -759,7 +800,7 @@
|
|||||||
this.player.drop(false);
|
this.player.drop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1218,9 +1632,31 @@
|
@@ -1218,9 +1669,31 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,7 +832,7 @@
|
|||||||
if (this.player.hasClientLoaded()) {
|
if (this.player.hasClientLoaded()) {
|
||||||
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
||||||
ServerLevel worldserver = this.player.serverLevel();
|
ServerLevel worldserver = this.player.serverLevel();
|
||||||
@@ -1244,6 +1680,7 @@
|
@@ -1244,6 +1717,7 @@
|
||||||
|
|
||||||
if (blockposition.getY() <= i) {
|
if (blockposition.getY() <= i) {
|
||||||
if (this.awaitingPositionFromClient == null && worldserver.mayInteract(this.player, blockposition)) {
|
if (this.awaitingPositionFromClient == null && worldserver.mayInteract(this.player, blockposition)) {
|
||||||
@ -799,7 +840,7 @@
|
|||||||
InteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock);
|
InteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock);
|
||||||
|
|
||||||
if (enuminteractionresult.consumesAction()) {
|
if (enuminteractionresult.consumesAction()) {
|
||||||
@@ -1281,6 +1718,8 @@
|
@@ -1281,6 +1755,8 @@
|
||||||
@Override
|
@Override
|
||||||
public void handleUseItem(ServerboundUseItemPacket packet) {
|
public void handleUseItem(ServerboundUseItemPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -808,7 +849,7 @@
|
|||||||
if (this.player.hasClientLoaded()) {
|
if (this.player.hasClientLoaded()) {
|
||||||
this.ackBlockChangesUpTo(packet.getSequence());
|
this.ackBlockChangesUpTo(packet.getSequence());
|
||||||
ServerLevel worldserver = this.player.serverLevel();
|
ServerLevel worldserver = this.player.serverLevel();
|
||||||
@@ -1296,6 +1735,47 @@
|
@@ -1296,6 +1772,47 @@
|
||||||
this.player.absRotateTo(f, f1);
|
this.player.absRotateTo(f, f1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,7 +897,7 @@
|
|||||||
InteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand);
|
InteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand);
|
||||||
|
|
||||||
if (enuminteractionresult instanceof InteractionResult.Success) {
|
if (enuminteractionresult instanceof InteractionResult.Success) {
|
||||||
@@ -1321,7 +1801,7 @@
|
@@ -1321,7 +1838,7 @@
|
||||||
Entity entity = packet.getEntity(worldserver);
|
Entity entity = packet.getEntity(worldserver);
|
||||||
|
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
@ -865,7 +906,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1342,6 +1822,13 @@
|
@@ -1342,6 +1859,13 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect(DisconnectionDetails info) {
|
public void onDisconnect(DisconnectionDetails info) {
|
||||||
@ -879,7 +920,7 @@
|
|||||||
ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), info.reason().getString());
|
ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), info.reason().getString());
|
||||||
this.removePlayerFromWorld();
|
this.removePlayerFromWorld();
|
||||||
super.onDisconnect(info);
|
super.onDisconnect(info);
|
||||||
@@ -1349,10 +1836,20 @@
|
@@ -1349,10 +1873,20 @@
|
||||||
|
|
||||||
private void removePlayerFromWorld() {
|
private void removePlayerFromWorld() {
|
||||||
this.chatMessageChain.close();
|
this.chatMessageChain.close();
|
||||||
@ -902,7 +943,7 @@
|
|||||||
this.player.getTextFilter().leave();
|
this.player.getTextFilter().leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1367,7 +1864,16 @@
|
@@ -1367,7 +1901,16 @@
|
||||||
@Override
|
@Override
|
||||||
public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) {
|
public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -919,7 +960,7 @@
|
|||||||
if (this.player.getInventory().selected != packet.getSlot() && this.player.getUsedItemHand() == InteractionHand.MAIN_HAND) {
|
if (this.player.getInventory().selected != packet.getSlot() && this.player.getUsedItemHand() == InteractionHand.MAIN_HAND) {
|
||||||
this.player.stopUsingItem();
|
this.player.stopUsingItem();
|
||||||
}
|
}
|
||||||
@@ -1376,11 +1882,18 @@
|
@@ -1376,11 +1919,18 @@
|
||||||
this.player.resetLastActionTime();
|
this.player.resetLastActionTime();
|
||||||
} else {
|
} else {
|
||||||
ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
|
ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
|
||||||
@ -938,7 +979,7 @@
|
|||||||
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
|
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
|
||||||
|
|
||||||
if (!optional.isEmpty()) {
|
if (!optional.isEmpty()) {
|
||||||
@@ -1394,27 +1907,44 @@
|
@@ -1394,27 +1944,44 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,7 +1031,7 @@
|
|||||||
ParseResults<CommandSourceStack> parseresults = this.parseCommand(command);
|
ParseResults<CommandSourceStack> parseresults = this.parseCommand(command);
|
||||||
|
|
||||||
if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseresults)) {
|
if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseresults)) {
|
||||||
@@ -1431,19 +1961,37 @@
|
@@ -1431,19 +1998,37 @@
|
||||||
|
|
||||||
if (!optional.isEmpty()) {
|
if (!optional.isEmpty()) {
|
||||||
this.tryHandleChat(packet.command(), () -> {
|
this.tryHandleChat(packet.command(), () -> {
|
||||||
@ -1032,7 +1073,7 @@
|
|||||||
} catch (SignedMessageChain.DecodeException signedmessagechain_a) {
|
} catch (SignedMessageChain.DecodeException signedmessagechain_a) {
|
||||||
this.handleMessageDecodeFailure(signedmessagechain_a);
|
this.handleMessageDecodeFailure(signedmessagechain_a);
|
||||||
return;
|
return;
|
||||||
@@ -1451,10 +1999,10 @@
|
@@ -1451,10 +2036,10 @@
|
||||||
|
|
||||||
CommandSigningContext.SignedArguments commandsigningcontext_a = new CommandSigningContext.SignedArguments(map);
|
CommandSigningContext.SignedArguments commandsigningcontext_a = new CommandSigningContext.SignedArguments(map);
|
||||||
|
|
||||||
@ -1045,7 +1086,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) {
|
private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) {
|
||||||
@@ -1530,14 +2078,20 @@
|
@@ -1530,14 +2115,20 @@
|
||||||
return com_mojang_brigadier_commanddispatcher.parse(command, this.player.createCommandSourceStack());
|
return com_mojang_brigadier_commanddispatcher.parse(command, this.player.createCommandSourceStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,10 +1111,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1566,6 +2120,127 @@
|
@@ -1564,8 +2155,129 @@
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ // CraftBukkit start - add method
|
+ // CraftBukkit start - add method
|
||||||
+ public void chat(String s, PlayerChatMessage original, boolean async) {
|
+ public void chat(String s, PlayerChatMessage original, boolean async) {
|
||||||
+ if (s.isEmpty() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) {
|
+ if (s.isEmpty() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) {
|
||||||
@ -1166,8 +1209,8 @@
|
|||||||
+ this.server.console.sendMessage(s);
|
+ this.server.console.sendMessage(s);
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
+ private void handleCommand(String s) {
|
+ private void handleCommand(String s) {
|
||||||
+ org.spigotmc.AsyncCatcher.catchOp("Command Dispatched Async: " + s); // Paper - Add async catcher
|
+ org.spigotmc.AsyncCatcher.catchOp("Command Dispatched Async: " + s); // Paper - Add async catcher
|
||||||
+ if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
|
+ if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
|
||||||
@ -1198,7 +1241,7 @@
|
|||||||
private PlayerChatMessage getSignedMessage(ServerboundChatPacket packet, LastSeenMessages lastSeenMessages) throws SignedMessageChain.DecodeException {
|
private PlayerChatMessage getSignedMessage(ServerboundChatPacket packet, LastSeenMessages lastSeenMessages) throws SignedMessageChain.DecodeException {
|
||||||
SignedMessageBody signedmessagebody = new SignedMessageBody(packet.message(), packet.timeStamp(), packet.salt(), lastSeenMessages);
|
SignedMessageBody signedmessagebody = new SignedMessageBody(packet.message(), packet.timeStamp(), packet.salt(), lastSeenMessages);
|
||||||
|
|
||||||
@@ -1573,13 +2248,42 @@
|
@@ -1573,13 +2285,42 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private void broadcastChatMessage(PlayerChatMessage message) {
|
private void broadcastChatMessage(PlayerChatMessage message) {
|
||||||
@ -1246,7 +1289,7 @@
|
|||||||
this.disconnect((Component) Component.translatable("disconnect.spam"));
|
this.disconnect((Component) Component.translatable("disconnect.spam"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1601,7 +2305,33 @@
|
@@ -1601,7 +2342,33 @@
|
||||||
@Override
|
@Override
|
||||||
public void handleAnimate(ServerboundSwingPacket packet) {
|
public void handleAnimate(ServerboundSwingPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -1280,7 +1323,7 @@
|
|||||||
this.player.swing(packet.getHand());
|
this.player.swing(packet.getHand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1609,6 +2339,29 @@
|
@@ -1609,6 +2376,29 @@
|
||||||
public void handlePlayerCommand(ServerboundPlayerCommandPacket packet) {
|
public void handlePlayerCommand(ServerboundPlayerCommandPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
if (this.player.hasClientLoaded()) {
|
if (this.player.hasClientLoaded()) {
|
||||||
@ -1310,7 +1353,7 @@
|
|||||||
this.player.resetLastActionTime();
|
this.player.resetLastActionTime();
|
||||||
Entity entity;
|
Entity entity;
|
||||||
PlayerRideableJumping ijumpable;
|
PlayerRideableJumping ijumpable;
|
||||||
@@ -1616,6 +2369,11 @@
|
@@ -1616,6 +2406,11 @@
|
||||||
switch (packet.getAction()) {
|
switch (packet.getAction()) {
|
||||||
case PRESS_SHIFT_KEY:
|
case PRESS_SHIFT_KEY:
|
||||||
this.player.setShiftKeyDown(true);
|
this.player.setShiftKeyDown(true);
|
||||||
@ -1322,7 +1365,7 @@
|
|||||||
break;
|
break;
|
||||||
case RELEASE_SHIFT_KEY:
|
case RELEASE_SHIFT_KEY:
|
||||||
this.player.setShiftKeyDown(false);
|
this.player.setShiftKeyDown(false);
|
||||||
@@ -1691,6 +2449,12 @@
|
@@ -1691,6 +2486,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendPlayerChatMessage(PlayerChatMessage message, ChatType.Bound params) {
|
public void sendPlayerChatMessage(PlayerChatMessage message, ChatType.Bound params) {
|
||||||
@ -1335,7 +1378,7 @@
|
|||||||
this.send(new ClientboundPlayerChatPacket(message.link().sender(), message.link().index(), message.signature(), message.signedBody().pack(this.messageSignatureCache), message.unsignedContent(), message.filterMask(), params));
|
this.send(new ClientboundPlayerChatPacket(message.link().sender(), message.link().index(), message.signature(), message.signedBody().pack(this.messageSignatureCache), message.unsignedContent(), message.filterMask(), params));
|
||||||
this.addPendingMessage(message);
|
this.addPendingMessage(message);
|
||||||
}
|
}
|
||||||
@@ -1703,6 +2467,13 @@
|
@@ -1703,6 +2504,13 @@
|
||||||
return this.connection.getRemoteAddress();
|
return this.connection.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1349,7 +1392,7 @@
|
|||||||
public void switchToConfig() {
|
public void switchToConfig() {
|
||||||
this.waitingForSwitchToConfig = true;
|
this.waitingForSwitchToConfig = true;
|
||||||
this.removePlayerFromWorld();
|
this.removePlayerFromWorld();
|
||||||
@@ -1718,9 +2489,17 @@
|
@@ -1718,9 +2526,17 @@
|
||||||
@Override
|
@Override
|
||||||
public void handleInteract(ServerboundInteractPacket packet) {
|
public void handleInteract(ServerboundInteractPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -1367,7 +1410,7 @@
|
|||||||
|
|
||||||
this.player.resetLastActionTime();
|
this.player.resetLastActionTime();
|
||||||
this.player.setShiftKeyDown(packet.isUsingSecondaryAction());
|
this.player.setShiftKeyDown(packet.isUsingSecondaryAction());
|
||||||
@@ -1733,20 +2512,58 @@
|
@@ -1733,20 +2549,58 @@
|
||||||
|
|
||||||
if (this.player.canInteractWithEntity(axisalignedbb, 3.0D)) {
|
if (this.player.canInteractWithEntity(axisalignedbb, 3.0D)) {
|
||||||
packet.dispatch(new ServerboundInteractPacket.Handler() {
|
packet.dispatch(new ServerboundInteractPacket.Handler() {
|
||||||
@ -1383,7 +1426,7 @@
|
|||||||
+ ItemStack itemInHand = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand);
|
+ ItemStack itemInHand = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand);
|
||||||
+ boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob;
|
+ boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob;
|
||||||
+ Item origItem = ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null ? null : ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem();
|
+ Item origItem = ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null ? null : ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem();
|
||||||
+
|
|
||||||
+ ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event);
|
+ ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event);
|
||||||
+
|
+
|
||||||
+ // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a
|
+ // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a
|
||||||
@ -1412,7 +1455,7 @@
|
|||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+ InteractionResult enuminteractionresult = playerconnection_a.run(ServerGamePacketListenerImpl.this.player, entity, enumhand);
|
+ InteractionResult enuminteractionresult = playerconnection_a.run(ServerGamePacketListenerImpl.this.player, entity, enumhand);
|
||||||
|
+
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
|
+ if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
|
||||||
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote();
|
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote();
|
||||||
@ -1430,7 +1473,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1755,19 +2572,20 @@
|
@@ -1755,19 +2609,20 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInteraction(InteractionHand hand) {
|
public void onInteraction(InteractionHand hand) {
|
||||||
@ -1454,7 +1497,7 @@
|
|||||||
label23:
|
label23:
|
||||||
{
|
{
|
||||||
if (entity instanceof AbstractArrow) {
|
if (entity instanceof AbstractArrow) {
|
||||||
@@ -1785,6 +2603,11 @@
|
@@ -1785,6 +2640,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerGamePacketListenerImpl.this.player.attack(entity);
|
ServerGamePacketListenerImpl.this.player.attack(entity);
|
||||||
@ -1466,7 +1509,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1795,7 +2618,26 @@
|
@@ -1795,7 +2655,26 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1493,7 +1536,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1809,7 +2651,7 @@
|
@@ -1809,7 +2688,7 @@
|
||||||
case PERFORM_RESPAWN:
|
case PERFORM_RESPAWN:
|
||||||
if (this.player.wonGame) {
|
if (this.player.wonGame) {
|
||||||
this.player.wonGame = false;
|
this.player.wonGame = false;
|
||||||
@ -1502,7 +1545,7 @@
|
|||||||
this.resetPosition();
|
this.resetPosition();
|
||||||
CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD);
|
CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD);
|
||||||
} else {
|
} else {
|
||||||
@@ -1817,11 +2659,11 @@
|
@@ -1817,11 +2696,11 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1516,7 +1559,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1834,15 +2676,21 @@
|
@@ -1834,15 +2713,21 @@
|
||||||
@Override
|
@Override
|
||||||
public void handleContainerClose(ServerboundContainerClosePacket packet) {
|
public void handleContainerClose(ServerboundContainerClosePacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -1540,7 +1583,7 @@
|
|||||||
this.player.containerMenu.sendAllDataToRemote();
|
this.player.containerMenu.sendAllDataToRemote();
|
||||||
} else if (!this.player.containerMenu.stillValid(this.player)) {
|
} else if (!this.player.containerMenu.stillValid(this.player)) {
|
||||||
ServerGamePacketListenerImpl.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
|
ServerGamePacketListenerImpl.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
|
||||||
@@ -1855,7 +2703,284 @@
|
@@ -1855,7 +2740,284 @@
|
||||||
boolean flag = packet.getStateId() != this.player.containerMenu.getStateId();
|
boolean flag = packet.getStateId() != this.player.containerMenu.getStateId();
|
||||||
|
|
||||||
this.player.containerMenu.suppressRemoteUpdates();
|
this.player.containerMenu.suppressRemoteUpdates();
|
||||||
@ -1826,7 +1869,7 @@
|
|||||||
ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packet.getChangedSlots()).iterator();
|
ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packet.getChangedSlots()).iterator();
|
||||||
|
|
||||||
while (objectiterator.hasNext()) {
|
while (objectiterator.hasNext()) {
|
||||||
@@ -1901,8 +3026,22 @@
|
@@ -1901,8 +3063,22 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1850,7 +1893,7 @@
|
|||||||
if (containerrecipebook_a == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) {
|
if (containerrecipebook_a == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) {
|
||||||
this.player.connection.send(new ClientboundPlaceGhostRecipePacket(this.player.containerMenu.containerId, craftingmanager_d.display().display()));
|
this.player.connection.send(new ClientboundPlaceGhostRecipePacket(this.player.containerMenu.containerId, craftingmanager_d.display().display()));
|
||||||
}
|
}
|
||||||
@@ -1917,6 +3056,7 @@
|
@@ -1917,6 +3093,7 @@
|
||||||
@Override
|
@Override
|
||||||
public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) {
|
public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -1858,7 +1901,7 @@
|
|||||||
this.player.resetLastActionTime();
|
this.player.resetLastActionTime();
|
||||||
if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) {
|
if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) {
|
||||||
if (!this.player.containerMenu.stillValid(this.player)) {
|
if (!this.player.containerMenu.stillValid(this.player)) {
|
||||||
@@ -1945,7 +3085,44 @@
|
@@ -1945,7 +3122,44 @@
|
||||||
|
|
||||||
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
|
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
|
||||||
boolean flag2 = itemstack.isEmpty() || itemstack.getCount() <= itemstack.getMaxStackSize();
|
boolean flag2 = itemstack.isEmpty() || itemstack.getCount() <= itemstack.getMaxStackSize();
|
||||||
@ -1866,7 +1909,7 @@
|
|||||||
+ // CraftBukkit start - Call click event
|
+ // CraftBukkit start - Call click event
|
||||||
+ InventoryView inventory = this.player.inventoryMenu.getBukkitView();
|
+ InventoryView inventory = this.player.inventoryMenu.getBukkitView();
|
||||||
+ org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packet.itemStack());
|
+ org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packet.itemStack());
|
||||||
|
+
|
||||||
+ SlotType type = SlotType.QUICKBAR;
|
+ SlotType type = SlotType.QUICKBAR;
|
||||||
+ if (flag) {
|
+ if (flag) {
|
||||||
+ type = SlotType.OUTSIDE;
|
+ type = SlotType.OUTSIDE;
|
||||||
@ -1881,7 +1924,7 @@
|
|||||||
+ this.cserver.getPluginManager().callEvent(event);
|
+ this.cserver.getPluginManager().callEvent(event);
|
||||||
+
|
+
|
||||||
+ itemstack = CraftItemStack.asNMSCopy(event.getCursor());
|
+ itemstack = CraftItemStack.asNMSCopy(event.getCursor());
|
||||||
+
|
|
||||||
+ switch (event.getResult()) {
|
+ switch (event.getResult()) {
|
||||||
+ case ALLOW:
|
+ case ALLOW:
|
||||||
+ // Plugin cleared the id / stacksize checks
|
+ // Plugin cleared the id / stacksize checks
|
||||||
@ -1903,7 +1946,7 @@
|
|||||||
if (flag1 && flag2) {
|
if (flag1 && flag2) {
|
||||||
this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemstack);
|
this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemstack);
|
||||||
this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemstack);
|
this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemstack);
|
||||||
@@ -1972,6 +3149,7 @@
|
@@ -1972,6 +3186,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSignText(ServerboundSignUpdatePacket packet, List<FilteredText> signText) {
|
private void updateSignText(ServerboundSignUpdatePacket packet, List<FilteredText> signText) {
|
||||||
@ -1911,7 +1954,7 @@
|
|||||||
this.player.resetLastActionTime();
|
this.player.resetLastActionTime();
|
||||||
ServerLevel worldserver = this.player.serverLevel();
|
ServerLevel worldserver = this.player.serverLevel();
|
||||||
BlockPos blockposition = packet.getPos();
|
BlockPos blockposition = packet.getPos();
|
||||||
@@ -1993,7 +3171,17 @@
|
@@ -1993,7 +3208,17 @@
|
||||||
@Override
|
@Override
|
||||||
public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) {
|
public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) {
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||||
@ -1930,7 +1973,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2002,6 +3190,7 @@
|
@@ -2002,6 +3227,7 @@
|
||||||
boolean flag = this.player.isModelPartShown(PlayerModelPart.HAT);
|
boolean flag = this.player.isModelPartShown(PlayerModelPart.HAT);
|
||||||
|
|
||||||
this.player.updateOptions(packet.information());
|
this.player.updateOptions(packet.information());
|
||||||
@ -1938,7 +1981,7 @@
|
|||||||
if (this.player.isModelPartShown(PlayerModelPart.HAT) != flag) {
|
if (this.player.isModelPartShown(PlayerModelPart.HAT) != flag) {
|
||||||
this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player));
|
this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player));
|
||||||
}
|
}
|
||||||
@@ -2058,7 +3247,7 @@
|
@@ -2058,7 +3284,7 @@
|
||||||
if (!this.waitingForSwitchToConfig) {
|
if (!this.waitingForSwitchToConfig) {
|
||||||
throw new IllegalStateException("Client acknowledged config, but none was requested");
|
throw new IllegalStateException("Client acknowledged config, but none was requested");
|
||||||
} else {
|
} else {
|
||||||
@ -1947,7 +1990,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2083,8 +3272,10 @@
|
@@ -2083,8 +3309,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2297,7 +2297,7 @@ public final class CraftServer implements Server {
|
|||||||
offers = this.tabCompleteChat(player, message);
|
offers = this.tabCompleteChat(player, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers);
|
TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? io.papermc.paper.util.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), BlockPos.containing(pos)) : null); // Paper - AsyncTabCompleteEvent
|
||||||
this.getPluginManager().callEvent(tabEvent);
|
this.getPluginManager().callEvent(tabEvent);
|
||||||
|
|
||||||
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
||||||
|
@ -28,6 +28,61 @@ public class ConsoleCommandCompleter implements Completer {
|
|||||||
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
||||||
final CraftServer server = this.server.server;
|
final CraftServer server = this.server.server;
|
||||||
final String buffer = "/" + line.line();
|
final String buffer = "/" + line.line();
|
||||||
|
// Async Tab Complete
|
||||||
|
final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event =
|
||||||
|
new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), buffer, true, null);
|
||||||
|
event.callEvent();
|
||||||
|
final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions();
|
||||||
|
|
||||||
|
if (event.isCancelled() || event.isHandled()) {
|
||||||
|
// Still fire sync event with the provided completions, if someone is listening
|
||||||
|
if (!event.isCancelled() && TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||||
|
List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> finalCompletions = new java.util.ArrayList<>(completions);
|
||||||
|
Waitable<List<String>> syncCompletions = new Waitable<List<String>>() {
|
||||||
|
@Override
|
||||||
|
protected List<String> evaluate() {
|
||||||
|
org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer,
|
||||||
|
finalCompletions.stream()
|
||||||
|
.map(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion::suggestion)
|
||||||
|
.collect(java.util.stream.Collectors.toList()));
|
||||||
|
return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
server.getServer().processQueue.add(syncCompletions);
|
||||||
|
try {
|
||||||
|
final List<String> legacyCompletions = syncCompletions.get();
|
||||||
|
completions.removeIf(it -> !legacyCompletions.contains(it.suggestion())); // remove any suggestions that were removed
|
||||||
|
// add any new suggestions
|
||||||
|
for (final String completion : legacyCompletions) {
|
||||||
|
if (notNewSuggestion(completions, completion)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
completions.add(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion.completion(completion));
|
||||||
|
}
|
||||||
|
} catch (InterruptedException | ExecutionException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!completions.isEmpty()) {
|
||||||
|
for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion completion : completions) {
|
||||||
|
if (completion.suggestion().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
candidates.add(new Candidate(
|
||||||
|
completion.suggestion(),
|
||||||
|
completion.suggestion(),
|
||||||
|
null,
|
||||||
|
io.papermc.paper.adventure.PaperAdventure.PLAIN.serializeOr(completion.tooltip(), null),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Paper end
|
// Paper end
|
||||||
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
||||||
@Override
|
@Override
|
||||||
@ -73,4 +128,15 @@ public class ConsoleCommandCompleter implements Completer {
|
|||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
private boolean notNewSuggestion(final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions, final String completion) {
|
||||||
|
for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion it : completions) {
|
||||||
|
if (it.suggestion().equals(completion)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user