package fr.luc.bettermccommands.repeat; import fr.luc.bettermccommands.api.CommandContext; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitTask; import java.time.Duration; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; /** * Utilitaire permettant d'exécuter une commande ou une action associée de manière répétée / cadencée dans le temps. */ public class CommandRepeater { /** * Répète une action liée au contexte de commande à intervalle régulier. * * @param plugin Le plugin Bukkit gérant les tâches. * @param context Le contexte de la commande. * @param totalRuns Le nombre total de répétitions. * @param interval L'intervalle de temps entre chaque exécution. * @param onRun L'action à exécuter à chaque itération. * @return L'instance de {@link BukkitTask} créée. */ public static BukkitTask repeat(Plugin plugin, CommandContext context, int totalRuns, Duration interval, Consumer onRun) { return repeat(plugin, context, totalRuns, interval, onRun, null); } /** * Répète une action avec rappel final à l'issue de toutes les répétitions. * * @param plugin Le plugin Bukkit gérant les tâches. * @param context Le contexte de la commande. * @param totalRuns Le nombre total d'exécutions (ex: 5). * @param interval La durée entre deux itérations. * @param onRun L'action exécutée à chaque itération. * @param onComplete L'action finale appelée lorsque toutes les répétitions sont terminées (ou null). * @return L'instance de {@link BukkitTask} correspondante. */ public static BukkitTask repeat(Plugin plugin, CommandContext context, int totalRuns, Duration interval, Consumer onRun, Runnable onComplete) { Objects.requireNonNull(plugin, "plugin cannot be null"); Objects.requireNonNull(context, "context cannot be null"); Objects.requireNonNull(onRun, "onRun cannot be null"); long ticks = Math.max(1, (interval != null ? interval.toMillis() : 1000) / 50); AtomicInteger runCount = new AtomicInteger(0); final BukkitTask[] taskHolder = new BukkitTask[1]; taskHolder[0] = Bukkit.getScheduler().runTaskTimer(plugin, () -> { int current = runCount.incrementAndGet(); CommandRepeatProgress progress = new CommandRepeatProgress(context, current, totalRuns); try { onRun.accept(progress); } catch (Exception e) { context.replyError("Erreur lors de l'exécution répétée : " + e.getMessage()); e.printStackTrace(); progress.cancel(); } if (progress.isCancelled() || current >= totalRuns) { if (taskHolder[0] != null) { taskHolder[0].cancel(); } if (!progress.isCancelled() && onComplete != null) { try { onComplete.run(); } catch (Exception e) { e.printStackTrace(); } } } }, 0L, ticks); return taskHolder[0]; } }