Skip to main content

Registering Custom Commands

SuperiorSkyblock2 provides a flexible command system through the SuperiorCommand interface. Commands can be registered as player commands (/is <command>) or admin commands (/is admin <command>).

Command Interface

Implement the SuperiorCommand interface to create custom commands:
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblock;
import com.bgsoftware.superiorskyblock.api.commands.SuperiorCommand;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

public class RewardsCommand implements SuperiorCommand {
    
    @Override
    public List<String> getAliases() {
        return Arrays.asList("rewards", "reward", "prizes");
    }
    
    @Override
    public String getPermission() {
        return "superiorskyblock.rewards";
    }
    
    @Override
    public String getUsage(Locale locale) {
        return "rewards";
    }
    
    @Override
    public String getDescription(Locale locale) {
        return "View your available rewards";
    }
    
    @Override
    public int getMinArgs() {
        return 1; // /is rewards
    }
    
    @Override
    public int getMaxArgs() {
        return 1; // No additional arguments
    }
    
    @Override
    public boolean canBeExecutedByConsole() {
        return false; // Players only
    }
    
    @Override
    public boolean displayCommand() {
        return true; // Show in /is help
    }
    
    @Override
    public void execute(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
        Player player = (Player) sender;
        // Command logic here
        player.sendMessage("Opening rewards menu...");
    }
    
    @Override
    public List<String> tabComplete(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
        return null; // No tab completion
    }
}

Command Properties

1

Aliases

Define command aliases. First alias is the primary command name.
@Override
public List<String> getAliases() {
    return Arrays.asList("top", "topten", "leaderboard");
}
Players can use: /is top, /is topten, or /is leaderboard
2

Permission

Set the permission node required to execute the command.
@Override
public String getPermission() {
    return "superiorskyblock.island.top";
}
Return empty string for no permission requirement:
return "";
3

Usage and Description

Provide localized usage and description strings.
@Override
public String getUsage(Locale locale) {
    return "top [category]";
}

@Override
public String getDescription(Locale locale) {
    return "View the island leaderboard";
}
4

Argument Count

Define minimum and maximum argument counts.
@Override
public int getMinArgs() {
    return 1; // /is command (command name counts as 1)
}

@Override
public int getMaxArgs() {
    return 3; // /is command arg1 arg2
}
The command name itself counts as argument 1. Additional arguments start at index 1 in the args array.

Command Execution

Implement command logic in the execute() method:
@Override
public void execute(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
    // Check if sender is a player
    if (!(sender instanceof Player)) {
        sender.sendMessage("This command can only be used by players!");
        return;
    }
    
    Player player = (Player) sender;
    
    // Get the SuperiorPlayer wrapper
    SuperiorPlayer superiorPlayer = plugin.getPlayers().getSuperiorPlayer(player);
    
    // Get player's island
    Island island = superiorPlayer.getIsland();
    if (island == null) {
        player.sendMessage("You don't have an island!");
        return;
    }
    
    // Execute command logic
    if (args.length > 1) {
        String subCommand = args[1];
        // Handle sub-command
    }
    
    player.sendMessage("Command executed successfully!");
}

Console Execution

Allow or disallow console execution:
@Override
public boolean canBeExecutedByConsole() {
    return true; // Console can execute
}

@Override
public void execute(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
    if (sender instanceof Player) {
        Player player = (Player) sender;
        // Player-specific logic
    } else {
        // Console-specific logic
        sender.sendMessage("Executing from console...");
    }
}
If canBeExecutedByConsole() returns false, you can safely cast sender to Player in execute().

Tab Completion

Provide smart tab completion for better user experience:
@Override
public List<String> tabComplete(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
    if (args.length == 2) {
        // Tab complete for first argument
        return Arrays.asList("create", "delete", "list", "info");
    }
    
    if (args.length == 3 && args[1].equalsIgnoreCase("delete")) {
        // Tab complete player names
        return plugin.getPlayers().getAllPlayers().stream()
            .map(sp -> sp.getName())
            .collect(Collectors.toList());
    }
    
    return null; // No suggestions
}

Smart Tab Completion Example

@Override
public List<String> tabComplete(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
    List<String> suggestions = new ArrayList<>();
    
    if (args.length == 2) {
        // Suggest sub-commands
        suggestions.add("worth");
        suggestions.add("level");
        suggestions.add("top");
        
        // Filter based on partial input
        String input = args[1].toLowerCase();
        return suggestions.stream()
            .filter(s -> s.startsWith(input))
            .collect(Collectors.toList());
    }
    
    if (args.length == 3) {
        // Suggest island names or players
        return plugin.getGrid().getIslands().stream()
            .map(Island::getName)
            .filter(name -> name.toLowerCase().startsWith(args[2].toLowerCase()))
            .collect(Collectors.toList());
    }
    
    return null;
}

Registering Commands

Register commands through your module:
public class MyModule extends PluginModule {
    
    @Override
    public SuperiorCommand[] getSuperiorCommands(SuperiorSkyblock plugin) {
        // Player commands: /is <command>
        return new SuperiorCommand[] {
            new RewardsCommand(),
            new StatsCommand(),
            new WarpsCommand()
        };
    }
    
    @Override
    public SuperiorCommand[] getSuperiorAdminCommands(SuperiorSkyblock plugin) {
        // Admin commands: /is admin <command>
        return new SuperiorCommand[] {
            new SetRewardCommand(),
            new ResetStatsCommand()
        };
    }
}

Advanced Command Example

public class IslandUpgradeCommand implements SuperiorCommand {
    
    private final UpgradeManager upgradeManager;
    
    public IslandUpgradeCommand(UpgradeManager upgradeManager) {
        this.upgradeManager = upgradeManager;
    }
    
    @Override
    public List<String> getAliases() {
        return Arrays.asList("upgrade", "upgrades", "up");
    }
    
    @Override
    public String getPermission() {
        return "superiorskyblock.island.upgrade";
    }
    
    @Override
    public String getUsage(Locale locale) {
        return "upgrade [upgrade-name]";
    }
    
    @Override
    public String getDescription(Locale locale) {
        return "Upgrade your island";
    }
    
    @Override
    public int getMinArgs() {
        return 1;
    }
    
    @Override
    public int getMaxArgs() {
        return 2;
    }
    
    @Override
    public boolean canBeExecutedByConsole() {
        return false;
    }
    
    @Override
    public boolean displayCommand() {
        return true;
    }
    
    @Override
    public void execute(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
        Player player = (Player) sender;
        SuperiorPlayer superiorPlayer = plugin.getPlayers().getSuperiorPlayer(player);
        Island island = superiorPlayer.getIsland();
        
        if (island == null) {
            player.sendMessage("§cYou must be on an island to use this command!");
            return;
        }
        
        // Open upgrade menu or process specific upgrade
        if (args.length == 1) {
            upgradeManager.openUpgradeMenu(player, island);
        } else {
            String upgradeName = args[1];
            upgradeManager.processUpgrade(player, island, upgradeName);
        }
    }
    
    @Override
    public List<String> tabComplete(SuperiorSkyblock plugin, CommandSender sender, String[] args) {
        if (args.length == 2) {
            // Suggest available upgrades
            return upgradeManager.getAvailableUpgrades().stream()
                .map(Upgrade::getName)
                .filter(name -> name.toLowerCase().startsWith(args[1].toLowerCase()))
                .collect(Collectors.toList());
        }
        return null;
    }
}

Help Menu Display

Control whether commands appear in help menus:
@Override
public boolean displayCommand() {
    return true; // Shows in /is help
}
Set to false for hidden commands:
@Override
public boolean displayCommand() {
    return false; // Hidden from help, but still executable
}

Best Practices

  • Always validate arguments before processing
  • Provide clear error messages for invalid input
  • Use permissions to restrict access appropriately
  • Implement tab completion for better UX
  • Check if players have islands before island-specific commands
  • Use SuperiorPlayer wrapper instead of raw Bukkit Player when possible
  • Return descriptive usage strings
  • Consider console execution for administrative commands
  • Use argument count validation to handle variable arguments