00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Comandi Custom

Introduzione ai Comandi

I comandi permettono ai giocatori e agli admin di interagire con il tuo plugin. Spigot/Paper offre un sistema flessibile per creare comandi con argomenti, tab completion e permessi.

Creare un Comando Base

1. Dichiarare il Comando in plugin.yml

```yaml commands: heal: description: Cura il giocatore usage: / [player] permission: myplugin.heal ```

2. Creare il Command Executor

```java public class HealCommand implements CommandExecutor {

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    // Controlla se il sender è un giocatore
    if (!(sender instanceof Player)) {
        sender.sendMessage("§cQuesto comando può essere usato solo da un giocatore!");
        return true;
    }
    
    Player player = (Player) sender;
    
    // Cura il giocatore
    player.setHealth(20.0);
    player.setFoodLevel(20);
    player.sendMessage("§aSei stato curato!");
    
    return true;
}

} ```

3. Registrare il Comando

Nella classe principale:

```java public class MyPlugin extends JavaPlugin {

@Override
public void onEnable() {
    // Registra il comando
    getCommand("heal").setExecutor(new HealCommand());
}

} ```

Gestire Argomenti

```java public class TeleportCommand implements CommandExecutor {

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    if (!(sender instanceof Player)) {
        sender.sendMessage("§cSolo giocatori!");
        return true;
    }
    
    Player player = (Player) sender;
    
    // /tp <x> <y> <z>
    if (args.length != 3) {
        player.sendMessage("§cUso: /tp <x> <y> <z>");
        return true;
    }
    
    try {
        double x = Double.parseDouble(args[0]);
        double y = Double.parseDouble(args[1]);
        double z = Double.parseDouble(args[2]);
        
        Location location = new Location(player.getWorld(), x, y, z);
        player.teleport(location);
        player.sendMessage("§aTeletrasportato a " + x + ", " + y + ", " + z);
        
    } catch (NumberFormatException e) {
        player.sendMessage("§cCoordinate non valide!");
    }
    
    return true;
}

} ```

Comandi con Target

Curare altri giocatori:

```java public class HealCommand implements CommandExecutor {

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    // /heal (cura se stesso)
    if (args.length == 0) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("§cSpecifica un giocatore!");
            return true;
        }
        
        Player player = (Player) sender;
        healPlayer(player);
        player.sendMessage("§aSei stato curato!");
        return true;
    }
    
    // /heal <player> (cura un altro giocatore)
    if (args.length == 1) {
        if (!sender.hasPermission("myplugin.heal.others")) {
            sender.sendMessage("§cNon hai il permesso!");
            return true;
        }
        
        Player target = Bukkit.getPlayer(args[0]);
        
        if (target == null) {
            sender.sendMessage("§cGiocatore non trovato!");
            return true;
        }
        
        healPlayer(target);
        sender.sendMessage("§aHai curato " + target.getName());
        target.sendMessage("§aSei stato curato da " + sender.getName());
        return true;
    }
    
    sender.sendMessage("§cUso: /heal [player]");
    return true;
}

private void healPlayer(Player player) {
    player.setHealth(20.0);
    player.setFoodLevel(20);
    player.setSaturation(20);
}

} ```

Tab Completion

Suggerimenti quando il giocatore preme TAB:

```java public class HealCommand implements CommandExecutor, TabCompleter {

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    // ... codice comando ...
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
    List<String> completions = new ArrayList<>();
    
    // /heal <TAB> -> suggerisci nomi giocatori
    if (args.length == 1) {
        String partial = args[0].toLowerCase();
        
        for (Player player : Bukkit.getOnlinePlayers()) {
            if (player.getName().toLowerCase().startsWith(partial)) {
                completions.add(player.getName());
            }
        }
    }
    
    return completions;
}

} ```

Registrare Tab Completer

```java @Override public void onEnable() { PluginCommand command = getCommand(“heal”); HealCommand executor = new HealCommand();

command.setExecutor(executor);
command.setTabCompleter(executor); // Registra tab completer

} ```

Comandi con Subcomandi

```java public class KitCommand implements CommandExecutor, TabCompleter {

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    if (!(sender instanceof Player)) {
        sender.sendMessage("§cSolo giocatori!");
        return true;
    }
    
    Player player = (Player) sender;
    
    if (args.length == 0) {
        player.sendMessage("§cUso: /kit <starter|pvp|builder>");
        return true;
    }
    
    String subcommand = args[0].toLowerCase();
    
    switch (subcommand) {
        case "starter":
            giveStarterKit(player);
            break;
        case "pvp":
            if (!player.hasPermission("myplugin.kit.pvp")) {
                player.sendMessage("§cNon hai il permesso!");
                return true;
            }
            givePvPKit(player);
            break;
        case "builder":
            giveBuilderKit(player);
            break;
        default:
            player.sendMessage("§cKit non valido!");
            return true;
    }
    
    return true;
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
    if (args.length == 1) {
        return Arrays.asList("starter", "pvp", "builder");
    }
    return null;
}

private void giveStarterKit(Player player) {
    player.getInventory().addItem(
        new ItemStack(Material.WOODEN_SWORD),
        new ItemStack(Material.BREAD, 16)
    );
    player.sendMessage("§aKit starter ricevuto!");
}

private void givePvPKit(Player player) {
    player.getInventory().addItem(
        new ItemStack(Material.DIAMOND_SWORD),
        new ItemStack(Material.DIAMOND_CHESTPLATE),
        new ItemStack(Material.GOLDEN_APPLE, 5)
    );
    player.sendMessage("§aKit PvP ricevuto!");
}

private void giveBuilderKit(Player player) {
    player.getInventory().addItem(
        new ItemStack(Material.STONE, 64),
        new ItemStack(Material.OAK_PLANKS, 64),
        new ItemStack(Material.GLASS, 32)
    );
    player.sendMessage("§aKit builder ricevuto!");
}

} ```

Comandi dalla Console

Permettere l’esecuzione dalla console:

```java @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { // Funziona sia per giocatori che console if (args.length == 0) { sender.sendMessage(“§cSpecifica un giocatore!”); return true; }

Player target = Bukkit.getPlayer(args[0]);

if (target == null) {
    sender.sendMessage("§cGiocatore non trovato!");
    return true;
}

target.setHealth(20.0);
sender.sendMessage("§a" + target.getName() + " è stato curato!");

return true;

} ```

Permessi nei Comandi

```java @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { // Controlla permesso if (!sender.hasPermission(“myplugin.admin”)) { sender.sendMessage(“§cNon hai il permesso!”); return true; }

// Codice del comando...
return true;

} ```

Best Practices

  • Ritorna sempre true: Se gestisci l’errore, ritorna true per evitare che venga mostrato l’usage
  • Valida gli input: Controlla sempre che gli argomenti siano validi
  • Messaggi chiari: Usa colori e messaggi descrittivi
  • Tab completion: Migliora l’UX suggerendo opzioni valide
  • Permessi granulari: Crea permessi separati per ogni funzionalità

Comandi Avanzati: Brigadier (Paper)

Paper supporta Brigadier per comandi più avanzati:

```java public class BrigadierExample implements CommandExecutor {

public void registerBrigadier() {
    LiteralCommandNode<CommandSourceStack> node = Commands.literal("example")
        .then(Commands.argument("player", ArgumentTypes.player())
            .executes(context -> {
                Player player = context.getArgument("player", Player.class);
                player.sendMessage("Hello!");
                return 1;
            })
        )
        .build();
    
    // Registra con Brigadier
}

} ```

Errori Comuni

Comando non registrato

// SBAGLIATO: dimenticato di registrare
new HealCommand(); // Non fa nulla!

// CORRETTO
getCommand("heal").setExecutor(new HealCommand());

Nome comando non corrisponde

// plugin.yml
commands:
  heal: ...

// SBAGLIATO
getCommand("cure").setExecutor(...); // Nome diverso!

// CORRETTO
getCommand("heal").setExecutor(...);

Non controllare null

// SBAGLIATO
Player target = Bukkit.getPlayer(args[0]);
target.sendMessage("Hi!"); // NullPointerException se offline!

// CORRETTO
Player target = Bukkit.getPlayer(args[0]);
if (target == null) {
    sender.sendMessage("Giocatore non trovato!");
    return true;
}
target.sendMessage("Hi!");

Conclusione

I comandi sono l’interfaccia principale tra i giocatori e il tuo plugin. Un sistema di comandi ben progettato, con tab completion e messaggi chiari, rende il plugin intuitivo e piacevole da usare.