diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml
index 1e4acc716..1e959b731 100644
--- a/bukkit/loader/src/main/resources/commands.yml
+++ b/bukkit/loader/src/main/resources/commands.yml
@@ -69,6 +69,13 @@ search_recipe_admin:
- /craftengine item search-recipe
- /ce item search-recipe
+totem:
+ enable: true
+ permission: ce.command.admin.totem
+ usage:
+ - /craftengine totem
+ - /ce totem
+
# Debug commands
debug_set_block:
enable: true
diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml
index eab86ce3f..7ddd21f54 100644
--- a/bukkit/loader/src/main/resources/translations/en.yml
+++ b/bukkit/loader/src/main/resources/translations/en.yml
@@ -52,4 +52,5 @@ command.item.give.failure.not_exist: "No recipe found for this item"
command.search_usage.not_found: "No usage found for this item"
command.search_recipe.no_item: "Please hold an item before running this command"
-command.search_usage.no_item: "Please hold an item before running this command"
\ No newline at end of file
+command.search_usage.no_item: "Please hold an item before running this command"
+command.totem.not_totem: "'' is not type of totem_of_undying"
\ No newline at end of file
diff --git a/bukkit/loader/src/main/resources/translations/es.yml b/bukkit/loader/src/main/resources/translations/es.yml
index b716978d9..23de3a017 100644
--- a/bukkit/loader/src/main/resources/translations/es.yml
+++ b/bukkit/loader/src/main/resources/translations/es.yml
@@ -52,4 +52,5 @@ command.item.give.failure.not_exist: "No se encontró ninguna receta para este objeto"
command.search_usage.not_found: "No se encontró ningún uso para este objeto"
command.search_recipe.no_item: "Por favor, sostén un objeto antes de ejecutar este comando"
-command.search_usage.no_item: "Por favor, sostén un objeto antes de ejecutar este comando"
\ No newline at end of file
+command.search_usage.no_item: "Por favor, sostén un objeto antes de ejecutar este comando"
+command.totem.not_totem: "'' no es del tipo totem_of_undying"
\ No newline at end of file
diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml
index 3de54b7d3..29cb7a370 100644
--- a/bukkit/loader/src/main/resources/translations/zh_cn.yml
+++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml
@@ -52,4 +52,5 @@ command.item.give.failure.not_exist: "找不到此物品的配方"
command.search_usage.not_found: "找不到此物品的用途"
command.search_recipe.no_item: "请手持物品后再执行此命令"
-command.search_usage.no_item: "请手持物品后再执行此命令"
\ No newline at end of file
+command.search_usage.no_item: "请手持物品后再执行此命令"
+command.totem.not_totem: "'' 不是 totem_of_undying 类型"
\ No newline at end of file
diff --git a/bukkit/loader/src/main/resources/translations/zh_tw.yml b/bukkit/loader/src/main/resources/translations/zh_tw.yml
index 8a48c57d8..37aae210f 100644
--- a/bukkit/loader/src/main/resources/translations/zh_tw.yml
+++ b/bukkit/loader/src/main/resources/translations/zh_tw.yml
@@ -52,4 +52,5 @@ command.item.give.failure.not_exist: "找不到此物品的配方"
command.search_usage.not_found: "找不到此物品的用途"
command.search_recipe.no_item: "執行此命令前請手持物品"
-command.search_usage.no_item: "執行此命令前請手持物品"
\ No newline at end of file
+command.search_usage.no_item: "執行此命令前請手持物品"
+command.totem.not_totem: "'' 不是 totem_of_undying 類型"
\ No newline at end of file
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java
index bba404771..ef2df937e 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java
@@ -256,6 +256,8 @@ public class BukkitItemManager extends AbstractItemManager {
CustomItem customItem = itemBuilder.build();
this.customItems.put(id, customItem);
this.cachedSuggestions.add(Suggestion.suggestion(id.toString()));
+ if (material == Material.TOTEM_OF_UNDYING)
+ this.cachedTotemSuggestions.add(Suggestion.suggestion(id.toString()));
// post process
// register tags
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java
index ec38a6f81..f83af185c 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java
@@ -45,7 +45,8 @@ public class BukkitCommandManager extends AbstractCommandManager
new DebugItemDataCommand(this, plugin),
new DebugSetBlockCommand(this, plugin),
new DebugSpawnFurnitureCommand(this, plugin),
- new DebugTargetBlockCommand(this, plugin)
+ new DebugTargetBlockCommand(this, plugin),
+ new TotemCommand(this, plugin)
));
final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager();
manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true);
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemCommand.java
new file mode 100644
index 000000000..72e8a64db
--- /dev/null
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemCommand.java
@@ -0,0 +1,73 @@
+package net.momirealms.craftengine.bukkit.plugin.command.feature;
+
+import net.kyori.adventure.text.Component;
+import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
+import net.momirealms.craftengine.bukkit.util.MaterialUtils;
+import net.momirealms.craftengine.bukkit.util.PlayerUtils;
+import net.momirealms.craftengine.core.item.CustomItem;
+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.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+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.suggestion.Suggestion;
+import org.incendo.cloud.suggestion.SuggestionProvider;
+
+import java.util.concurrent.CompletableFuture;
+
+public class TotemCommand extends BukkitCommandFeature {
+
+ public TotemCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) {
+ super(commandManager, plugin);
+ }
+
+ @Override
+ public Command.Builder extends CommandSender> assembleCommand(CommandManager manager, Command.Builder builder) {
+ return builder
+ .flag(FlagKeys.SILENT_FLAG)
+ .required("players", MultiplePlayerSelectorParser.multiplePlayerSelectorParser())
+ .required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() {
+ @Override
+ public @NonNull CompletableFuture extends @NonNull Iterable extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext