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
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 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: 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";
}
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;
}
}
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