Plugin Délais entre l'utilisation d'une commande

  • Auteur de la discussion Auteur de la discussion PsYZiiK
  • Date de début Date de début

PsYZiiK

Bucheron
26 Avril 2016
42
0
11
22
Bonjour,

Je viens de débuter en création de plugin. J'ai bien dit "débuter".

Alors voici mon soucis,
J'ai créer une commande dans mon plugin, mais je voudrais mettre un délai entre l'utilisation de cette commande. Par exemple, on aura accès à cette commande toutes les 24H.

Je ne veux surtout pas d'autres plugins ! Je veux que ce soit moi qui crée mes propres plugins.

J'ai été voir un tutoriel sur les Bukkit Scheduler mais je n'ai pas compris. Merci de me donner une solution^^ !
 
Bonjour,

Je viens de débuter en création de plugin. J'ai bien dit "débuter".

Alors voici mon soucis,
J'ai créer une commande dans mon plugin, mais je voudrais mettre un délai entre l'utilisation de cette commande. Par exemple, on aura accès à cette commande toutes les 24H.

Je ne veux surtout pas d'autres plugins ! Je veux que ce soit moi qui crée mes propres plugins.

J'ai été voir un tutoriel sur les Bukkit Scheduler mais je n'ai pas compris. Merci de me donner une solution^^ !

Hey!

je veux bien t'aider mais il va me falloir une partie de ton code pour voir comme tu développes.

PS: Pour ajouter du code dans les messages appuie du + dans la barre du haut et clique sur Code
 
Bonjour,

Voici un de mes exemples de codes :

Code:
package fr.psyziik.MonPlugin;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;

public class MesCommandes implements Listener {

    public MesCommandes(MonPlugin monPlugin) {
    }

    @EventHandler
    public void onTestCommande(PlayerCommandPreprocessEvent e){
   
        Player p = e.getPlayer();
        String msg = e.getMessage();
        String[] args = msg.split(" ");
       
        if (args[0].equalsIgnoreCase("/monkit")){
            ItemStack épée = new ItemStack(Material.DIAMOND_SWORD, 1);
            p.getInventory().addItem(épée);
            p.sendMessage(ChatColor.RED+"[Kit]"+ChatColor.GREEN+" Vous venez de recevoir votre Kit !");
            e.setCancelled(true);
        }
       
        if (args[0].equalsIgnoreCase("/monbroadcast")){
            if(p.hasPermission("testbroadcast.use")){
            p.sendMessage(ChatColor.RED+"Bravo, tu as réussi le test !");
            p.getServer().broadcastMessage(ChatColor.DARK_PURPLE+"[Annonce]"+ChatColor.GREEN+" Bonjour le serveur !");
            }else{
                p.sendMessage(ChatColor.RED+"Vous n'avez pas la permission de faire ceci !");
            }
            e.setCancelled(true);
   
        }

    }
   
}

On peut voir que j'ai créer une commande (/monkit). J'aimerais juste savoir comment faire pour que les joueurs ne puissent utiliser cette comande que toutes les 24H.
Parce que là, les joueurs peuvent utiliser la commande n'importe quand^^ !

Merci à toi !
 
Bonjour,

Voici un de mes exemples de codes :

Code:
package fr.psyziik.MonPlugin;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;

public class MesCommandes implements Listener {

    public MesCommandes(MonPlugin monPlugin) {
    }

    @EventHandler
    public void onTestCommande(PlayerCommandPreprocessEvent e){
 
        Player p = e.getPlayer();
        String msg = e.getMessage();
        String[] args = msg.split(" ");
     
        if (args[0].equalsIgnoreCase("/monkit")){
            ItemStack épée = new ItemStack(Material.DIAMOND_SWORD, 1);
            p.getInventory().addItem(épée);
            p.sendMessage(ChatColor.RED+"[Kit]"+ChatColor.GREEN+" Vous venez de recevoir votre Kit !");
            e.setCancelled(true);
        }
     
        if (args[0].equalsIgnoreCase("/monbroadcast")){
            if(p.hasPermission("testbroadcast.use")){
            p.sendMessage(ChatColor.RED+"Bravo, tu as réussi le test !");
            p.getServer().broadcastMessage(ChatColor.DARK_PURPLE+"[Annonce]"+ChatColor.GREEN+" Bonjour le serveur !");
            }else{
                p.sendMessage(ChatColor.RED+"Vous n'avez pas la permission de faire ceci !");
            }
            e.setCancelled(true);
 
        }

    }
 
}

On peut voir que j'ai créer une commande (/monkit). J'aimerais juste savoir comment faire pour que les joueurs ne puissent utiliser cette comande que toutes les 24H.
Parce que là, les joueurs peuvent utiliser la commande n'importe quand^^ !

Merci à toi !

Tu développes sous quoi Bukkit, Sponge, Spigot, cette méthode pour les commandes n'est pas si bien
 
J'ai pu faire sa, ça fonctionne sauf erreur de ma part!

PHP:
    int timer;
    public int task;
  
    public void kittimer(Player p){
        if(MFR.kit.containsKey(p)){
          
            task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Bukkit.getPluginManager().getPlugin("Minecraft.fr"), new Runnable() {
              
                @Override
                public void run() {
                    timer= 86401-1;
                    //86400 correspond n'a pu être identifié." style="margin: 0px; padding: 0px; border: 0px; border-image-source: initial; border-image-slice: initial; border-image-width: initial; border-image-outset: initial; border-image-repeat: initial; outline: 0px; vertical-align: baseline; cursor: pointer; font-family: Arial, serif; font-size: 14px; line-height: 16.8px; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">Corresponds a pourrait être confondu avec son homophone à." style="margin: 0px; padding: 0px; border: 0px; border-image-source: initial; border-image-slice: initial; border-image-width: initial; border-image-outset: initial; border-image-repeat: initial; outline: 0px; vertical-align: baseline; cursor: pointer; font-family: Arial, serif; font-size: 14px; line-height: 16.8px; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">à 24h en seconde + 1 attention si tu reload : mot inconnu de nos dictionnaires automatiquement remplacé par Reload." class="sac" style="margin: 0px; padding: 0px; border: 0px; border-image-source: initial; border-image-slice: initial; border-image-width: initial; border-image-outset: initial; border-image-repeat: initial; outline: 0px; vertical-align: baseline; cursor: pointer; font-family: Arial, serif; font-size: 14px; line-height: 16.8px; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">Reload sa repart est masculin singulier." style="margin: 0px; padding: 0px; border: 0px; border-image-source: initial; border-image-slice: initial; border-image-width: initial; border-image-outset: initial; border-image-repeat: initial; outline: 0px; vertical-align: baseline; cursor: pointer; font-family: Arial, serif; font-size: 14px; line-height: 16.8px; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">son repart a pourrait être confondu avec son homophone à." style="margin: 0px; padding: 0px; border: 0px; border-image-source: initial; border-image-slice: initial; border-image-width: initial; border-image-outset: initial; border-image-repeat: initial; outline: 0px; vertical-align: baseline; cursor: pointer; font-family: Arial, serif; font-size: 14px; line-height: 16.8px; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">à 86400 
                    if(timer == 0){
                        // tu peut faire la commande
                    }else{
                        // tu peut pas faire la commande
                    }
                }
            }, 20, 20); // Je ne sais plus à quoi sa correspond mais laisse comme ça
        }
    }
 
Euh, j'ai pas trop compris de ce que tu as essayé de dire, peux tu m'expliquer ?
 
Euh, j'ai pas trop compris de ce que tu as essayé de dire, peux tu m'expliquer ?

En simple tu fait un système que quand le joueur fait la commande sa l'ajoute dans une HashMap;

PHP:
public static HashMap<Player, String> kit = new HashMap<>();

       if(sender instanceof Player){
            Player p = (Player) sender;
            ItemStack item = new ItemStack(Material.DIAMOND_SWORD, 1);
          
            p.getInventory().addItem(item);
            p.sendMessage("&c[Kit] &2Vous venez de recevoir votre kit !");
          
            MFR.kit.put(p, p.getDisplayName())
        }

Et tu entoure if(...){} en faisant le test de la réponse que tu as mit la:

PHP:
public void kittimer(Player p){
        if(MFR.kit.containsKey(p)){
           
            task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Bukkit.getPluginManager().getPlugin("Minecraft.fr"), new Runnable() {
               
                @Override
                public void run() {
                    timer= 86401-1;
                    //86400 correspond a 24h en seconde + 1 attention si tu reload sa repart a 86400
                    if(timer == 0){
                        // tu peut faire la commande
                    }else{
                        // tu peut pas faire la commande
                    }
                }
            }, 20, 20);
        }
    }

PS: Je suis null en tuto
 
Salut,

}, 20, 20); // Je ne sais plus à quoi sa correspond mais laisse comme ça
LEL !

Bon... Quand vous voulez développer avec une API (ce qui est le cas ici vu qu'on va développer avec spigot/bukkit) il ne faut pas avoir peur d'aller voir la documentation. Et il faut surtout savoir la lire !
Pour spigot, la doc est ici: https://hub.spigotmc.org/javadocs/spigot/
Pour bukkit, la doc est ici: https://hub.spigotmc.org/javadocs/bukkit/
Très peu de différence entre les deux (surtout dans quelque chose d'aussi basique).

Quelques notions tout d'abord sur le scheduler. Commençons par un lien vers la doc: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/scheduler/BukkitScheduler.html Je n'ai pas étudier en détail comment il fonctionne mais pour donner une image c'est comme si on lançais un thread. Celui-ci pourra être exécuter plus tard (runTaskLater) ou de manière récurrente (runTaskTimer). Pour plus d'informations sur les scheduler, je vous invite à venir voir ce tutoriel: http://wiki.bukkit.org/Scheduler_Programming (cette page existe en français mais je le trouve moins précise ;) ).

Bien maintenant regardons le problème de plus près. On veut interdire une commande durant un certains délais. A-t-on vraiment besoin d'un scheduler ? Si j'ai bien compris l'idée de Device, il veut mettre les joueurs dans une liste (jusque la je suis d'accord), lancer une tache scheduler et ensuite les retirer de la liste ? Non c'est pas vraiment ça que tu veux faire... mais je vois pas où tu veux aller.

Bref, voici ce que je propose:
  • Lorque le joueur fait la commande et qu'il a le droit (que cela fait 24h qu'il ne l'a pas fait) on le rajoute dans la liste (on va enregistré son uuid) mais on va également enregistrer le timestamp (codification du moment présent sous forme de chiffre) actuel.
  • Dès qu'un joueur fera la commande, on va commencer par vérifier si il est dans la liste. Si n'est pas dedans, tout est bon, il peut faire la commande. Si il est dans la liste, on va regarder si le timestamp enregistré est plus grand que le timestamp actuel + 24h. Si c'est le cas, il peut faire la commande, sinon on lui dit qu'il ne peut pas.
Attention, en faisant ce système alors que tu as beaucoup de joueur, tu as des risque de saturation de mémoire. Mais le système des schedulers est encore plus coûteux en ressource (d'un côté on a une liste, de l'autre on à des taches avec tout le contexte qu'il y a autour).
De plus, si ton serveur redémarre, tout sera remis à 0. Si tu veux conserver ces informations il faudra faire un système qui enregistrera cette liste dans un fichier et qui chargera ce fichier au démarrage.

Petite remarque en passant, je ne suis pas fan du PlayerCommandPreprocessEvent (même si Richie3366 adore ça), je trouve que le onPlayerCommand marche très bien ;) )
Pourquoi prendre l'UUID et non pas l'objet Player ou son pseudo ? Tout simplement parce que l'objet Player il est supprimé lors de la déconnexion (et un nouvel objet est créé) et le pseudo quand à lui peux-être modifié depuis le site de Mojang (même si c'est limité à un changement tous les 20 jours à peu près).

Concrètement en code ça donne ceci:
PHP:
private static HashMap<UUID, Long> playerCommand = new HashMap<UUID, Long>();
private static int DELAY = 86400000; // 60000 = 1 sec; 3600000 = 1h; 86400000 = 24h

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

    // Vérification que c'est la bonne commande, ect, ect....
    // Je vais quand même pas tout écrire xD

    if (sender instanceof Player) {
        Player player = ((Player) sender);
        UUID uuid = player.getUniqueId();
        long tempsActuel = (new Timestamp(System.currentTimeMillis())).getTime();


        if(!playerCommand.containsKey(uuid) ||  // Si il n'est pas dans la liste
            (playerCommand.get(uuid) - tempsActuel) > DELAY) { // Ou que le temps est suppérieur

            // La commande ici
            playerCommand.put(uuid, tempsActuel);

        } else {
            player.sendMessage(ChatColor.RED +
                       "Vous devez encore attendre avant de pouvoir faire cette commande");
        }
    }
}



Cordialement,
Detobel36