001package com.mrivanplays.commandworker.bukkit; 002 003import com.mrivanplays.commandworker.bukkit.argtypes.MinecraftArgumentTypesAccessor; 004import com.mrivanplays.commandworker.bukkit.internal.BukkitBridgeCommand; 005import com.mrivanplays.commandworker.bukkit.registry.CmdRegistry; 006import com.mrivanplays.commandworker.bukkit.registry.CmdRegistryHandler; 007import com.mrivanplays.commandworker.core.Command; 008import com.mrivanplays.commandworker.core.CommandManager; 009import com.mrivanplays.commandworker.core.RegisteredCommand; 010import java.lang.reflect.Field; 011import java.util.ArrayList; 012import java.util.Collections; 013import java.util.List; 014import java.util.Objects; 015import java.util.function.Predicate; 016import org.bukkit.Bukkit; 017import org.bukkit.command.CommandMap; 018import org.bukkit.command.CommandSender; 019import org.bukkit.plugin.java.JavaPlugin; 020import org.jetbrains.annotations.NotNull; 021import org.jetbrains.annotations.Nullable; 022 023public class BukkitCommandManager implements CommandManager<CommandSender> { 024 025 private List<RegisteredCommand<CommandSender>> registeredCommands; 026 027 private final JavaPlugin plugin; 028 029 private boolean shouldFallback = true; 030 031 public BukkitCommandManager(JavaPlugin plugin) { 032 this.plugin = plugin; 033 this.registeredCommands = new ArrayList<>(); 034 if (CmdRegistryHandler.isSupported()) { 035 MinecraftArgumentTypesAccessor.ensureSetup(); 036 } 037 } 038 039 @Override 040 public void register( 041 @NotNull Command<CommandSender> command, 042 @Nullable Predicate<CommandSender> permissionCheck, 043 @NotNull String... aliases) { 044 Objects.requireNonNull(command, "command"); 045 if (permissionCheck == null) { 046 permissionCheck = (sender) -> true; 047 } 048 Objects.requireNonNull(aliases, "aliases"); 049 String[] populatedAliases = CommandManager.getAliases(plugin.getName(), aliases); 050 if (!aliasesFree(registeredCommands, populatedAliases)) { 051 return; 052 } 053 RegisteredCommand<CommandSender> registeredCommand = 054 new RegisteredCommand<>(populatedAliases, command, permissionCheck); 055 registeredCommands.add(registeredCommand); 056 CmdRegistry registry = CmdRegistryHandler.getRegistry(); 057 if (!isBrigadierSupported()) { 058 if (shouldFallback) { 059 // fallback to registering with bukkit 060 getBukkitCommandMap() 061 .register( 062 aliases[0], plugin.getName(), new BukkitBridgeCommand(registeredCommand, aliases)); 063 } 064 } else { 065 registry.register(registeredCommand); 066 } 067 } 068 069 @Override 070 public boolean shouldFallback() { 071 return shouldFallback; 072 } 073 074 @Override 075 public void setShouldFallback(boolean shouldFallback) { 076 this.shouldFallback = shouldFallback; 077 } 078 079 @Override 080 public boolean isBrigadierSupported() { 081 return CmdRegistryHandler.isSupported(); 082 } 083 084 private CommandMap getBukkitCommandMap() { 085 try { 086 Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap"); 087 field.setAccessible(true); 088 return (CommandMap) field.get(Bukkit.getServer()); 089 } catch (IllegalAccessException | NoSuchFieldException e) { 090 throw new RuntimeException(e); 091 } 092 } 093 094 @Override 095 @NotNull 096 public List<RegisteredCommand<CommandSender>> getRegisteredCommands() { 097 return Collections.unmodifiableList(registeredCommands); 098 } 099 100 @Override 101 public String toString() { 102 return "BukkitCommandManager(plugin=" 103 + plugin 104 + ", shouldFallback=" 105 + shouldFallback 106 + ", brigadierSupported=" 107 + isBrigadierSupported() 108 + ", registeredCommands=" 109 + registeredCommands; 110 } 111}