Merge branch 'master' into acquirable

This commit is contained in:
TheMode 2021-04-26 16:15:42 +02:00
commit 79d936936e
36 changed files with 256 additions and 36 deletions

View File

@ -8,13 +8,16 @@ import net.minestom.server.command.builder.arguments.ArgumentDynamicWord;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
import net.minestom.server.command.builder.condition.CommandCondition;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* Represents a command which has suggestion/auto-completion.
@ -42,6 +45,7 @@ public class Command {
private final String name;
private final String[] aliases;
private final String[] names;
private CommandExecutor defaultExecutor;
private CommandCondition condition;
@ -59,6 +63,7 @@ public class Command {
public Command(@NotNull String name, @Nullable String... aliases) {
this.name = name;
this.aliases = aliases;
this.names = Stream.concat(Arrays.stream(aliases), Stream.of(name)).toArray(String[]::new);
this.subcommands = new ArrayList<>();
this.syntaxes = new ArrayList<>();
@ -223,8 +228,7 @@ public class Command {
*
* @return the main command's name
*/
@NotNull
public String getName() {
public @NotNull String getName() {
return name;
}
@ -233,11 +237,21 @@ public class Command {
*
* @return the command aliases, can be null or empty
*/
@Nullable
public String[] getAliases() {
public @Nullable String[] getAliases() {
return aliases;
}
/**
* Gets all the possible names for this command.
* <p>
* Include {@link #getName()} and {@link #getAliases()}.
*
* @return this command names
*/
public @NotNull String[] getNames() {
return names;
}
/**
* Gets the default {@link CommandExecutor} which is called when there is no argument
* or if no corresponding syntax has been found.
@ -266,8 +280,7 @@ public class Command {
* @return a collection containing all this command syntaxes
* @see #addSyntax(CommandExecutor, Argument[])
*/
@NotNull
public Collection<CommandSyntax> getSyntaxes() {
public @NotNull Collection<CommandSyntax> getSyntaxes() {
return syntaxes;
}
@ -280,8 +293,7 @@ public class Command {
* @param text the whole player's text
* @return the array containing all the suggestion for the current arg (split SPACE), can be null
*/
@Nullable
public String[] onDynamicWrite(@NotNull CommandSender sender, @NotNull String text) {
public @Nullable String[] onDynamicWrite(@NotNull CommandSender sender, @NotNull String text) {
return null;
}
@ -300,15 +312,29 @@ public class Command {
public void globalListener(@NotNull CommandSender sender, @NotNull CommandContext context, @NotNull String command) {
}
@Beta
public @NotNull Set<String> getSyntaxesStrings() {
Set<String> syntaxes = new HashSet<>();
Consumer<String> syntaxConsumer = syntaxString -> {
for (String name : getNames()) {
final String syntax = name + StringUtils.SPACE + syntaxString;
syntaxes.add(syntax);
}
};
this.subcommands.forEach(subcommand -> subcommand.getSyntaxesStrings().forEach(syntaxConsumer));
this.syntaxes.forEach(commandSyntax -> syntaxConsumer.accept(commandSyntax.getSyntaxString()));
return syntaxes;
}
public static boolean isValidName(@NotNull Command command, @NotNull String name) {
if (command.getName().equals(name))
return true;
final String[] aliases = command.getAliases();
if (aliases == null)
return false;
for (String alias : aliases) {
if (alias.equals(name))
for (String commandName : command.getNames()) {
if (commandName.equals(name)) {
return true;
}
}
return false;
}

View File

@ -3,6 +3,7 @@ package net.minestom.server.command.builder;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.condition.CommandCondition;
import net.minestom.server.entity.Player;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -103,4 +104,13 @@ public class CommandSyntax {
public boolean hasSuggestion() {
return suggestion;
}
public @NotNull String getSyntaxString() {
StringBuilder builder = new StringBuilder();
for (Argument<?> argument : args) {
builder.append(argument.toString())
.append(StringUtils.SPACE);
}
return builder.toString().trim();
}
}

View File

@ -37,4 +37,8 @@ public class ArgumentBoolean extends Argument<Boolean> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Boolean<%s>", getId());
}
}

View File

@ -74,4 +74,9 @@ public class ArgumentCommand extends Argument<CommandResult> {
this.shortcut = shortcut;
return this;
}
@Override
public String toString() {
return String.format("Command<%s>", getId());
}
}

View File

@ -68,4 +68,8 @@ public class ArgumentEnum<E extends Enum> extends Argument<E> {
}
}
@Override
public String toString() {
return String.format("Enum<%s>", getId());
}
}

View File

@ -31,4 +31,9 @@ public class ArgumentLiteral extends Argument<String> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{literalNode});
}
@Override
public String toString() {
return String.format("Literal<%s>", getId());
}
}

View File

@ -77,4 +77,9 @@ public class ArgumentString extends Argument<String> {
return StringEscapeUtils.unescapeJava(input);
}
@Override
public String toString() {
return String.format("String<%s>", getId());
}
}

View File

@ -36,4 +36,9 @@ public class ArgumentStringArray extends Argument<String[]> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("StringArray<%s>", getId());
}
}

View File

@ -116,4 +116,9 @@ public class ArgumentWord extends Argument<String> {
public String[] getRestrictions() {
return restrictions;
}
@Override
public String toString() {
return String.format("Word<%s>", getId());
}
}

View File

@ -47,4 +47,9 @@ public class ArgumentColor extends Argument<Style> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Color<%s>", getId());
}
}

View File

@ -35,4 +35,9 @@ public class ArgumentComponent extends Argument<Component> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Component<%s>", getId());
}
}

View File

@ -269,6 +269,20 @@ public class ArgumentEntity extends Argument<EntityFinder> {
return onlyPlayers;
}
@Override
public String toString() {
if (onlySingleEntity) {
if (onlyPlayers) {
return String.format("Player<%s>", getId());
}
return String.format("Entity<%s>", getId());
}
if (onlyPlayers) {
return String.format("Players<%s>", getId());
}
return String.format("Entities<%s>", getId());
}
private static EntityFinder.TargetSelector toTargetSelector(@NotNull String selectorVariable) {
if (selectorVariable.equals("@p"))
return EntityFinder.TargetSelector.NEAREST_PLAYER;

View File

@ -62,4 +62,9 @@ public class ArgumentFloatRange extends ArgumentRange<FloatRange> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("FloatRange<%s>", getId());
}
}

View File

@ -67,4 +67,9 @@ public class ArgumentIntRange extends ArgumentRange<IntRange> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("IntRange<%s>", getId());
}
}

View File

@ -33,6 +33,18 @@ public class ArgumentItemStack extends Argument<ItemStack> {
@NotNull
@Override
public ItemStack parse(@NotNull String input) throws ArgumentSyntaxException {
return staticParse(input);
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false);
argumentNode.parser = "minecraft:item_stack";
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
public static ItemStack staticParse(@NotNull String input) throws ArgumentSyntaxException {
final int nbtIndex = input.indexOf("{");
if (nbtIndex == 0)
@ -61,10 +73,7 @@ public class ArgumentItemStack extends Argument<ItemStack> {
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false);
argumentNode.parser = "minecraft:item_stack";
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
public String toString() {
return String.format("ItemStack<%s>", getId());
}
}

View File

@ -47,4 +47,9 @@ public class ArgumentNbtCompoundTag extends Argument<NBTCompound> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("NbtCompound<%s>", getId());
}
}

View File

@ -43,4 +43,9 @@ public class ArgumentNbtTag extends Argument<NBT> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("NBT<%s>", getId());
}
}

View File

@ -31,4 +31,9 @@ public class ArgumentResourceLocation extends Argument<String> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("ResourceLocation<%s>", getId());
}
}

View File

@ -66,4 +66,9 @@ public class ArgumentTime extends Argument<UpdateOption> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Time<%s>", getId());
}
}

View File

@ -33,4 +33,9 @@ public class ArgumentUUID extends Argument<UUID> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("UUID<%s>", getId());
}
}

View File

@ -24,4 +24,9 @@ public class ArgumentBlockState extends ArgumentRegistry<Block> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("BlockState<%s>", getId());
}
}

View File

@ -27,4 +27,9 @@ public class ArgumentEnchantment extends ArgumentRegistry<Enchantment> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Enchantment<%s>", getId());
}
}

View File

@ -29,4 +29,9 @@ public class ArgumentEntityType extends ArgumentRegistry<EntityType> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("EntityType<%s>", getId());
}
}

View File

@ -27,4 +27,9 @@ public class ArgumentParticle extends ArgumentRegistry<Particle> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Particle<%s>", getId());
}
}

View File

@ -27,4 +27,9 @@ public class ArgumentPotionEffect extends ArgumentRegistry<PotionEffect> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Potion<%s>", getId());
}
}

View File

@ -57,4 +57,8 @@ public class ArgumentDouble extends ArgumentNumber<Double> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Double<%s>", getId());
}
}

View File

@ -57,4 +57,8 @@ public class ArgumentFloat extends ArgumentNumber<Float> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Float<%s>", getId());
}
}

View File

@ -48,4 +48,8 @@ public class ArgumentInteger extends ArgumentNumber<Integer> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("Integer<%s>", getId());
}
}

View File

@ -88,4 +88,9 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("RelativeBlockPosition<%s>", getId());
}
}

View File

@ -77,4 +77,8 @@ public class ArgumentRelativeVec2 extends ArgumentRelative<RelativeVec> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("RelativeVec2<%s>", getId());
}
}

View File

@ -83,4 +83,9 @@ public class ArgumentRelativeVec3 extends ArgumentRelative<RelativeVec> {
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
@Override
public String toString() {
return String.format("RelativeVec3<%s>", getId());
}
}

View File

@ -1931,9 +1931,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
InventoryOpenEvent inventoryOpenEvent = new InventoryOpenEvent(inventory, this);
callCancellableEvent(InventoryOpenEvent.class, inventoryOpenEvent, () -> {
if (getOpenInventory() != null) {
getOpenInventory().removeViewer(this);
Inventory openInventory = getOpenInventory();
if (openInventory != null) {
openInventory.removeViewer(this);
}
Inventory newInventory = inventoryOpenEvent.getInventory();

View File

@ -128,7 +128,7 @@ public class Section implements PublicCloneable<Section> {
section.paletteBlockMap = paletteBlockMap;
section.blockPaletteMap = blockPaletteMap;
for (int y = 0; y < Chunk.CHUNK_SIZE_Y; y++) {
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
final short blockId = getBlockAt(x, y, z);

View File

@ -174,7 +174,7 @@ public class Inventory extends AbstractInventory implements Viewable {
@Override
public boolean removeViewer(@NotNull Player player) {
final boolean result = this.viewers.remove(player);
this.cursorPlayersItem.remove(player);
setCursorItem(player, ItemStack.AIR);
this.clickProcessor.clearCache(player);
return result;
}
@ -198,18 +198,19 @@ public class Inventory extends AbstractInventory implements Viewable {
* @param cursorItem the new player cursor item
*/
public void setCursorItem(@NotNull Player player, @NotNull ItemStack cursorItem) {
if (!isViewer(player))
return;
final ItemStack currentCursorItem = cursorPlayersItem.get(player);
final boolean similar = currentCursorItem != null && currentCursorItem.isSimilar(cursorItem);
final ItemStack currentCursorItem = cursorPlayersItem.getOrDefault(player, ItemStack.AIR);
final boolean similar = currentCursorItem.isSimilar(cursorItem);
if (!similar) {
final SetSlotPacket setSlotPacket = SetSlotPacket.createCursorPacket(cursorItem);
player.getPlayerConnection().sendPacket(setSlotPacket);
}
this.cursorPlayersItem.put(player, cursorItem);
if (!cursorItem.isAir()) {
this.cursorPlayersItem.put(player, cursorItem);
} else {
this.cursorPlayersItem.remove(player);
}
}
/**
@ -351,6 +352,10 @@ public class Inventory extends AbstractInventory implements Viewable {
playerInventory.setItemStack(clickSlot, clickResult.getClicked());
}
if(clickResult.doRefresh()){
update(player);
}
refreshPlayerCursorItem(player, clickResult.getCursor());
return !clickResult.isCancel();

View File

@ -186,8 +186,12 @@ public class InventoryClickProcessor {
return null;
var pair = TransactionType.ADD.process(targetInventory, clicked, (index, itemStack) -> {
InventoryClickResult result = startCondition(inventory, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
return !result.isCancel();
InventoryClickResult result = startCondition(targetInventory, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
if(result.isCancel()){
clickResult.setRefresh(true);
return false;
}
return true;
});
ItemStack itemResult = TransactionOption.ALL.fill(targetInventory, pair.left(), pair.right());
@ -209,8 +213,12 @@ public class InventoryClickProcessor {
var pair = TransactionType.ADD.process(targetInventory, clicked, (index, itemStack) -> {
if (index == slot) // Prevent item lose/duplication
return false;
InventoryClickResult result = startCondition(null, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
return !result.isCancel();
InventoryClickResult result = startCondition(targetInventory, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
if(result.isCancel()){
clickResult.setRefresh(true);
return false;
}
return true;
}, start, end, step);
ItemStack itemResult = TransactionOption.ALL.fill(targetInventory, pair.left(), pair.right());
@ -547,6 +555,13 @@ public class InventoryClickProcessor {
return startCondition(clickResult, inventory, player, slot, clickType);
}
@NotNull
private InventoryClickResult startCondition(@Nullable AbstractInventory inventory, @NotNull Player player, int slot,
@NotNull ClickType clickType, @NotNull ItemStack clicked, @NotNull ItemStack cursor) {
return startCondition(inventory instanceof Inventory ? (Inventory) inventory : null,
player, slot, clickType, clicked, cursor);
}
private void callClickEvent(@NotNull Player player, @Nullable Inventory inventory, int slot,
@NotNull ClickType clickType, @NotNull ItemStack clicked, @NotNull ItemStack cursor) {
InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(inventory, player, slot, clickType, clicked, cursor);

View File

@ -12,6 +12,8 @@ import net.minestom.server.network.packet.client.play.ClientWindowConfirmationPa
import net.minestom.server.network.packet.server.play.SetSlotPacket;
import net.minestom.server.network.packet.server.play.WindowConfirmationPacket;
import java.util.Objects;
public class WindowListener {
public static void clickWindowListener(ClientClickWindowPacket packet, Player player) {
@ -86,7 +88,17 @@ public class WindowListener {
}
// Prevent the player from picking a ghost item in cursor
refreshCursorItem(player, inventory);
if (Objects.equals(player.getOpenInventory(), inventory)) {
refreshCursorItem(player, inventory);
}
// Prevent ghost item when the click is cancelled
if (!successful) {
player.getInventory().update();
if (inventory != null) {
inventory.update(player);
}
}
WindowConfirmationPacket windowConfirmationPacket = new WindowConfirmationPacket();
windowConfirmationPacket.windowId = windowId;