9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

添加clear指令

This commit is contained in:
XiaoMoMi
2025-11-18 17:59:24 +08:00
parent 691aed86dd
commit fca6090918
7 changed files with 126 additions and 4 deletions

View File

@@ -33,6 +33,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new ReloadCommand(this, plugin), new ReloadCommand(this, plugin),
new GetItemCommand(this, plugin), new GetItemCommand(this, plugin),
new GiveItemCommand(this, plugin), new GiveItemCommand(this, plugin),
new ClearItemCommand(this, plugin),
new ItemBrowserPlayerCommand(this, plugin), new ItemBrowserPlayerCommand(this, plugin),
new ItemBrowserAdminCommand(this, plugin), new ItemBrowserAdminCommand(this, plugin),
new SearchRecipePlayerCommand(this, plugin), new SearchRecipePlayerCommand(this, plugin),

View File

@@ -0,0 +1,98 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.util.ItemStackUtils;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import net.momirealms.craftengine.core.plugin.command.FlagKeys;
import net.momirealms.craftengine.core.plugin.locale.MessageConstants;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.bukkit.data.MultiplePlayerSelector;
import org.incendo.cloud.bukkit.parser.NamespacedKeyParser;
import org.incendo.cloud.bukkit.parser.selector.MultiplePlayerSelectorParser;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.parser.standard.IntegerParser;
import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.suggestion.SuggestionProvider;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
public class ClearItemCommand extends BukkitCommandFeature<CommandSender> {
public ClearItemCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.flag(FlagKeys.SILENT_FLAG)
.required("player", MultiplePlayerSelectorParser.multiplePlayerSelectorParser(true))
.required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
@Override
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
return CompletableFuture.completedFuture(plugin().itemManager().cachedCustomItemSuggestions());
}
}))
.optional("amount", IntegerParser.integerParser(0))
.handler(context -> {
MultiplePlayerSelector selector = context.get("player");
int amount = context.getOrDefault("amount", -1);
NamespacedKey namespacedKey = context.get("id");
Key itemId = Key.of(namespacedKey.namespace(), namespacedKey.value());
Predicate<Object> predicate = nmsStack -> {
Optional<Key> id = BukkitItemManager.instance().wrap(ItemStackUtils.asCraftMirror(nmsStack)).customId();
return id.isPresent() && id.get().equals(itemId);
};
int totalCount = 0;
Collection<Player> players = selector.values();
for (Player player : players) {
Object serverPlayer = FastNMS.INSTANCE.method$CraftPlayer$getHandle(player);
Object inventory = FastNMS.INSTANCE.method$Player$getInventory(serverPlayer);
Object inventoryMenu = FastNMS.INSTANCE.field$Player$inventoryMenu(serverPlayer);
totalCount += FastNMS.INSTANCE.method$Inventory$clearOrCountMatchingItems(inventory, predicate, amount, FastNMS.INSTANCE.method$InventoryMenu$getCraftSlots(inventoryMenu));
FastNMS.INSTANCE.method$AbstractContainerMenu$broadcastChanges(FastNMS.INSTANCE.field$Player$containerMenu(serverPlayer));
FastNMS.INSTANCE.method$InventoryMenu$slotsChanged(inventoryMenu, inventory);
}
if (totalCount == 0) {
if (players.size() == 1) {
handleFeedback(context, MessageConstants.COMMAND_ITEM_CLEAR_FAILED_SINGLE, Component.text(players.iterator().next().getName()));
} else {
handleFeedback(context, MessageConstants.COMMAND_ITEM_CLEAR_FAILED_MULTIPLE, Component.text(players.size()));
}
} else {
if (amount == 0) {
if (players.size() == 1) {
handleFeedback(context, MessageConstants.COMMAND_ITEM_CLEAR_TEST_SINGLE, Component.text(totalCount), Component.text(players.iterator().next().getName()));
} else {
handleFeedback(context, MessageConstants.COMMAND_ITEM_CLEAR_TEST_MULTIPLE, Component.text(totalCount), Component.text(players.size()));
}
} else {
if (players.size() == 1) {
handleFeedback(context, MessageConstants.COMMAND_ITEM_CLEAR_SUCCESS_SINGLE, Component.text(totalCount), Component.text(players.iterator().next().getName()));
} else {
handleFeedback(context, MessageConstants.COMMAND_ITEM_CLEAR_SUCCESS_MULTIPLE, Component.text(totalCount), Component.text(players.size()));
}
}
}
});
}
@Override
public String getFeatureID() {
return "clear_item";
}
}

View File

@@ -51,4 +51,8 @@ public final class ItemStackUtils {
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack); Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
return UniqueIdItem.of(wrappedItem); return UniqueIdItem.of(wrappedItem);
} }
public static ItemStack asCraftMirror(Object itemStack) {
return FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(itemStack);
}
} }

View File

@@ -43,6 +43,13 @@ give_item:
- /craftengine item give - /craftengine item give
- /ce item give - /ce item give
clear_item:
enable: true
permission: ce.command.admin.clear_item
usage:
- /craftengine item clear
- /ce item clear
item_browser_player: item_browser_player:
enable: true enable: true
permission: ce.command.player.item_browser permission: ce.command.player.item_browser

View File

@@ -49,6 +49,12 @@ command.item.get.failure.not_exist: "<red><lang:argument.item.id.invalid:'<arg:0
command.item.give.success.single: "<lang:commands.give.success.single:'<arg:0>':'<arg:1>':'<arg:2>'>" command.item.give.success.single: "<lang:commands.give.success.single:'<arg:0>':'<arg:1>':'<arg:2>'>"
command.item.give.success.multiple: "<lang:commands.give.success.multiple:'<arg:0>':'<arg:1>':'<arg:2>'>" command.item.give.success.multiple: "<lang:commands.give.success.multiple:'<arg:0>':'<arg:1>':'<arg:2>'>"
command.item.give.failure.not_exist: "<red><lang:argument.item.id.invalid:'<arg:0>'></red>" command.item.give.failure.not_exist: "<red><lang:argument.item.id.invalid:'<arg:0>'></red>"
command.item.clear.failed.single: "<red>No items were found on player <arg:0></red>"
command.item.clear.failed.multiple: "<red>No items were found on <arg:0> players</red>"
command.item.clear.success.single: "<white>Removed <arg:0> item(s) from player <arg:1></white>"
command.item.clear.success.multiple: "<white>Removed <arg:0> item(s) from <arg:1> players</white>"
command.item.clear.test.single: "<white>Found <arg:0> matching item(s) on player <arg:1></white>"
command.item.clear.test.multiple: "<white>Found <arg:0> matching item(s) on <arg:1> players</white>"
command.search_recipe.not_found: "<red>No recipe found for this item</red>" command.search_recipe.not_found: "<red>No recipe found for this item</red>"
command.search_usage.not_found: "<red>No usage found for this item</red>" command.search_usage.not_found: "<red>No usage found for this item</red>"
command.search_recipe.no_item: "<red>Please hold an item before running this command</red>" command.search_recipe.no_item: "<red>Please hold an item before running this command</red>"

View File

@@ -35,4 +35,10 @@ public interface MessageConstants {
TranslatableComponent.Builder COMMAND_LOCALE_SET_FAILURE = Component.translatable().key("command.locale.set.failure"); TranslatableComponent.Builder COMMAND_LOCALE_SET_FAILURE = Component.translatable().key("command.locale.set.failure");
TranslatableComponent.Builder COMMAND_LOCALE_SET_SUCCESS = Component.translatable().key("command.locale.set.success"); TranslatableComponent.Builder COMMAND_LOCALE_SET_SUCCESS = Component.translatable().key("command.locale.set.success");
TranslatableComponent.Builder COMMAND_LOCALE_UNSET_SUCCESS = Component.translatable().key("command.locale.unset.success"); TranslatableComponent.Builder COMMAND_LOCALE_UNSET_SUCCESS = Component.translatable().key("command.locale.unset.success");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_SUCCESS_SINGLE = Component.translatable().key("command.item.clear.success.single");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_SUCCESS_MULTIPLE = Component.translatable().key("command.item.clear.success.multiple");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_FAILED_SINGLE = Component.translatable().key("command.item.clear.failed.single");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_FAILED_MULTIPLE = Component.translatable().key("command.item.clear.failed.multiple");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_TEST_SINGLE = Component.translatable().key("command.item.clear.test.single");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_TEST_MULTIPLE = Component.translatable().key("command.item.clear.test.multiple");
} }

View File

@@ -1,9 +1,9 @@
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx1G
# Project settings # Project settings
project_version=0.0.65.8 project_version=0.0.65.9
config_version=55 config_version=56
lang_version=38 lang_version=39
project_group=net.momirealms project_group=net.momirealms
latest_supported_version=1.21.10 latest_supported_version=1.21.10
@@ -48,7 +48,7 @@ byte_buddy_version=1.17.8
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.5 snake_yaml_version=2.5
anti_grief_version=1.0.4 anti_grief_version=1.0.4
nms_helper_version=1.0.134 nms_helper_version=1.0.135
evalex_version=3.5.0 evalex_version=3.5.0
reactive_streams_version=1.0.4 reactive_streams_version=1.0.4
amazon_awssdk_version=2.34.5 amazon_awssdk_version=2.34.5