BukkitWiki

Welcome to the BukkitWiki!

This Wiki is home to Bukkit's documentation and regulations surrounding the Bukkit Project and it's services. Want to help out? We would love to have you! Signup to get started!

READ MORE

BukkitWiki
m (ouuups)
Xbony2 (talk | contribs)
m (Undo revision 13411 by 112.98.19.201 (talk))
 
(41 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{Box|
 
BORDER = #FF8000|
 
BACKGROUND = #FF8000|
 
WIDTH = 100%|
 
HEADING = '''Réécriture totale''' |
 
CONTENT = Cette page est en train d'être entièrement refaite avec les informations à jour et les dernières fonctionnalités, et notamment avec des liens vers des tutos français et non anglais. La version définitive ne sera plus vraiment sur la base de [http://forums.bukkit.org/threads/plugin-development-a-huge-tutorial-status-under-development.15167/ l'article anglais]. MERCI DE NE PAS REMETTRE CE QU'IL Y AVAIT AVANT. }}
 
 
{{Box|
 
BORDER = #FF8000|
 
BACKGROUND = #FF8000|
 
WIDTH = 100%|
 
ICON = [[File:TODOIcon.png|32px]]|
 
HEADING = '''Travail en cours...''' |
 
CONTENT = Cette page est toujours en cours de rédaction. Revenez bientôt pour voir du contenu supplémentaire}}
 
 
<br />
 
 
 
== Apprendre à programmer en Java ==
 
== Apprendre à programmer en Java ==
 
Avant de commencer à créer des plugins bukkit, il est '''nécessaire''' d'avoir '''suffisamment''' de connaissances en programmation en général, et plus particulièrement en Java.
 
Avant de commencer à créer des plugins bukkit, il est '''nécessaire''' d'avoir '''suffisamment''' de connaissances en programmation en général, et plus particulièrement en Java.
Line 42: Line 25:
 
* '''Eclipse''' - Gratuit, le plus utilisé
 
* '''Eclipse''' - Gratuit, le plus utilisé
 
* '''NetBeans''' - Gratuit, aussi très utilisé
 
* '''NetBeans''' - Gratuit, aussi très utilisé
* '''IntelliJ Idea''' - Payant, objectivement le meilleur IDE. Sa version gratuite est un peu moins complète qu'Eclipse ou NetBeans.
+
* '''IntelliJ Idea''' - Payant, avec une version gratuite. Sa version gratuite est un peu moins complète qu'Eclipse ou NetBeans.
 
Si vous êtes débutant "total", choisissez Eclipse. Il est le plus utilisé, et donc le plus représenté dans les tutoriels, comme celui-ci !
 
Si vous êtes débutant "total", choisissez Eclipse. Il est le plus utilisé, et donc le plus représenté dans les tutoriels, comme celui-ci !
   
Line 53: Line 36:
   
 
=== L'API bukkit ===
 
=== L'API bukkit ===
Le système de plugins des serveurs CraftBukkit utilise une API (Application Programming Interface ou "Interface de Programmation Applicative") nommée Bukkit. Lorsque vous créez un plugin pour les serveurs utilisant CraftBukkit, vous utilisez des classes, interfaces et méthodes de l'API Bukkit. Si vous lisez ceci, vous êtes censé connaître Java et la programmation, vous comprendrez donc cette phrase : on dit que CraftBukkit ''implémente'' Bukkit.
+
Le système de plugins des serveurs CraftBukkit utilise une API (Application Programming Interface ou "Interface de Programmation Applicative") nommée Bukkit. Lorsque vous créez un plugin pour les serveurs utilisant CraftBukkit, vous utilisez des classes, interfaces et méthodes de l'API Bukkit. Si vous lisez ceci, vous êtes censé connaître Java et la programmation, vous comprendrez donc cette phrase: on dit que CraftBukkit ''implémente'' Bukkit.
 
Pour pouvoir utiliser tout cela dans votre projet Eclipse, il faut spécifier que le projet utilisera l'API Bukkit.
 
Pour pouvoir utiliser tout cela dans votre projet Eclipse, il faut spécifier que le projet utilisera l'API Bukkit.
   
L'API bukkit se présente sous la forme d'un fichier JAR non éxécutable. téléchargeable ici:
+
L'API bukkit se présente sous la forme d'un fichier JAR non éxécutable. => [http://dl.bukkit.org/downloads/bukkit/ Télécharger l'API Bukkit] (Ne fonctionne plus).
  +
<br><br>
=> [http://dl.bukkit.org/downloads/bukkit/ Télécharger l'API Bukkit]
 
 
{{ warning | Vous ne devez JAMAIS utiliser CraftBukkit à la place de Bukkit lorsque vous développez. Vous seriez tenté d'utiliser des classes, interfaces et méthodes de CraftBukkit '''qui ne font pas partie de l'API'''. Au final, vous aurez un "plugin-mod" qui devra être recompilé à chaque mise à jour du projet Bukkit. }}
 
 
{{ note | Vous trouverez tout de même des plugins plutôt importants qui utilisent CraftBukkit pour étendre l'API Bukkit, tel que''TagAPI'' ou ''ProtocolLib''}}
{{ warning | Vous ne devez JAMAIS utiliser CraftBukkit à la place de Bukkit lorsque vous développez. Vous seriez tenté d'utiliser des classes, interfaces et méthodes de CraftBukkit '''qui ne font pas partie de l'API'''. Au final, vous aurez un "plugin-mod" qui devra être recompilé pour chaque mise à jour du projet Bukkit. }}
 
{{ note | Vous trouverez tout de même des plugins plutôt importants qui utilisent CraftBukkit pour étendre l'API Bukkit (Ex: ''TagAPI'', ''ProtocolLib''), ou pour des raisons de performances (Ex: ''WorldEdit''). }}
 
   
 
=== Un serveur CraftBukkit ===
 
=== Un serveur CraftBukkit ===
Line 70: Line 52:
 
== Création du projet ==
 
== Création du projet ==
 
Maintenant que vous avez tout ce qu'il faut, vous pouvez commencer la partie intéressante : le développement du plugin lui-même.
 
Maintenant que vous avez tout ce qu'il faut, vous pouvez commencer la partie intéressante : le développement du plugin lui-même.
Pour commencer, vous allez créer un nouveau projet dans Eclipse que vous appellerez comme votre plugin :<br />
+
Pour commencer, vous allez créer un nouveau projet dans Eclipse que vous appellerez comme votre plugin :<br>
   
[[File:nouveau projet.png|500px]]<br />
+
[[File:nouveau projet.png|500px]]<br>
   
 
=== Utiliser l'API bukkit ===
 
=== Utiliser l'API bukkit ===
 
Je vous avais dit plus haut que, pour pouvoir utiliser l'API Bukkit afin de créer votre plugin, il fallait le spécifier à Eclipse.
 
Je vous avais dit plus haut que, pour pouvoir utiliser l'API Bukkit afin de créer votre plugin, il fallait le spécifier à Eclipse.
Pour cela, allez dans les propriétés de votre projet (clic droit sur votre projet > Properties) :<br /><br />
+
Pour cela, allez dans les propriétés de votre projet (clic droit sur votre projet > Properties) :<br><br>
   
   
[[File:properties.png|300px]]<br /><br /><br />
+
[[File:properties.png|300px]]<br><br><br>
   
[[File:properties fenetre.png|800px]]<br />
+
[[File:properties fenetre.png|800px]]<br>
   
 
Dans cette fenêtre, cliquez sur le bouton '''Add external jar''' et sélectionnez le bukkit.jar que vous avez téléchargé.
 
Dans cette fenêtre, cliquez sur le bouton '''Add external jar''' et sélectionnez le bukkit.jar que vous avez téléchargé.
   
Ensuite, cliquez sur la petite flèche à gauche de "bukkit.jar" pour dérouler un menu :<br />
+
Ensuite, cliquez sur la petite flèche à gauche de "bukkit.jar" pour dérouler un menu :<br>
   
[[File:properties - javadoc location 1.png|300px]]<br />
+
[[File:properties - javadoc location 1.png|300px]]<br>
   
   
Double-cliquez sur '''JavaDoc Location''' afin de faire apparaître cette fenêtre :<br />
+
Double-cliquez sur '''JavaDoc Location''' afin de faire apparaître cette fenêtre :<br>
   
[[File:properties - set javadoc.png|700px]]<br />
+
[[File:properties - set javadoc.png|700px]]<br>
   
   
 
Dans le premier cadre "JavaDoc Location Path", entrez ceci:
 
Dans le premier cadre "JavaDoc Location Path", entrez ceci:
'''<nowiki>http://jd.bukkit.org/apidocs</nowiki>'''<br />
+
'''<nowiki>http://jd.bukkit.org/apidocs</nowiki>'''
  +
  +
Pour les versions plus récentes de Bukkit (1.8 et plus), la JavaDoc est disponible ici : '''<nowiki>https://hub.spigotmc.org/javadocs/bukkit/</nowiki>'''<br>
   
   
Line 106: Line 90:
 
=== Création ===
 
=== Création ===
 
Créez tout d'abord un nouveau paquet ("package") dans votre projet en cliquant sur le bouton [[File:nouveau paquet.png|40px]] qui se trouve en haut de la fenêtre d'Eclipse, dans cette barre de menus:
 
Créez tout d'abord un nouveau paquet ("package") dans votre projet en cliquant sur le bouton [[File:nouveau paquet.png|40px]] qui se trouve en haut de la fenêtre d'Eclipse, dans cette barre de menus:
<br />
+
<br>
<br />
+
<br>
   
 
[[File:barre de menu.png|1000px]]
 
[[File:barre de menu.png|1000px]]
<br />
+
<br>
<br />
+
<br>
   
Vous devez suivre certaines conventions lors du choix du nom de votre package :<br />
+
Vous devez suivre certaines conventions lors du choix du nom de votre package :<br>
  +
* Il ne doit '''PAS''' contenir de majuscule, ni de caractères spéciaux
* Si vous possédez un nom de domaine, le nom du package doit commencer par ce nom de domaine à l'envers.
 
  +
* Il devrait contenir le nom de votre plugin
** Exemple : '''mondomaine.fr''' => Votre package sera préfixé par '''fr.mondomaine''' ([http://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html source])
 
 
* Si vous possédez un nom de domaine, le nom du package peut commencer par ce nom de domaine à l'envers. Par exemple, si vous possédez '''mondomaine.com''', votre package commencera par '''com.mondomaine'''
** N'utilisez surtout pas de domaine que vous ne possédez pas.
 
* Si vous ne possédez pas de nom de domaine, il y a plusieurs alternatives possibles :
+
* Si vous ne possédez pas de nom de domaine, vous pouvez simplement utiliser ce que vous voulez, tant que ce n'est pas déjà utilisé. On pourra conseiller '''me.<votrePseudo>.<votrePlugin>''' ou '''fr.<votrePseudo>.<votrePlugin>'''
  +
* Il ne doit absolument '''PAS''' commencer par l'un des noms suivants:
*# Créez un compte sur un site de gestion de sources comme GitHub ou SourceForge
 
 
** org.bukkit
*#* Pour GitHub, suivez [http://pages.github.com/ ces instructions] et vous aurez un sous-domaine, donc votre package serait préfixé par '''com.github.<votrePseudo>'''<br />
 
 
** net.bukkit
*# Utilisez votre addresse mail. Exemple : '''<votrePseudo>@gmail.com''' donne '''com.gmail.<votrePseudo>'''<br />
 
 
** com.bukkit
*# Et voici la méthode déconseillée, si vous n'avez ni nom de domaine, ni l'envie de faire un compte GitHub, ni même d'addresse mail (!) : utilisez ce que vous voulez, tant que ce n'est pas un nom déjà utilisé. On pourra conseiller '''me.<votrePseudo>'''.
 
 
** net.minecraft
 
 
<br>
Voici ce par quoi votre nom de package ne doit absolument pas commencer :
 
 
Par exemple: ''sk89q'', l'auteur de ''WorldEdit'', possède le nom de domaine ''sk89q.com''. Le nom du package contenant le code de WorldEdit est donc '''com.sk89q.worldedit'''.
* org.bukkit
 
 
<br>
* net.bukkit
 
 
<br>
* com.bukkit
 
* net.minecraft
 
 
Maintenant que vous avez un "préfix" de package, vous pouvez lui ajouter le nom de votre plugin. Par exemple, ''sk89q'', l'auteur de ''WorldEdit'', possède le nom de domain ''sk89q.com''. Le nom du package contenant l'ensemble du cote de WorldEdit est '''com.sk89q.worldedit'''.
 
 
{{ note | Il est très important que votre nom de package ne contienne aucune lettre majuscule. }}
 
<br />
 
<br />
 
   
 
Ensuite, créez une nouvelle Classe dans ce package en cliquant sur le bouton [[File:nouvelle classe.png|40px]] qui se trouve également dans la barre de menus.<br>
 
Ensuite, créez une nouvelle Classe dans ce package en cliquant sur le bouton [[File:nouvelle classe.png|40px]] qui se trouve également dans la barre de menus.<br>
   
Généralement, on appelle la classe principale du plugin par le nom du plugin.
+
On appelle généralement la classe principale du plugin par le nom du plugin.
   
 
=== JavaPlugin ===
 
=== JavaPlugin ===
Line 162: Line 139:
 
La classe JavaPlugin possède une méthode '''onEnable()''' qui est appellée à chaque lancement du plugin.
 
La classe JavaPlugin possède une méthode '''onEnable()''' qui est appellée à chaque lancement du plugin.
 
Afin de pouvoir effectuer vos propre actions au démarrage du plugin, vous devez redéfinir la méthode onEnable() dans la classe principale de votre plugin:
 
Afin de pouvoir effectuer vos propre actions au démarrage du plugin, vous devez redéfinir la méthode onEnable() dans la classe principale de votre plugin:
<br />
+
<br>
   
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
Line 179: Line 156:
 
La classe JavaPlugin possède aussi une méthode '''onDisable()''' qui, vous l'avez sûrement deviné, est appellée à chaque fois que le plugin est désactivé.
 
La classe JavaPlugin possède aussi une méthode '''onDisable()''' qui, vous l'avez sûrement deviné, est appellée à chaque fois que le plugin est désactivé.
 
Comme pour onEnable(), vous devez redéfinir la méthode onDisable() dans la classe principale de votre plugin:
 
Comme pour onEnable(), vous devez redéfinir la méthode onDisable() dans la classe principale de votre plugin:
<br />
+
<br>
   
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
Line 210: Line 187:
 
}
 
}
 
</source>
 
</source>
  +
<br>
  +
 
== Le fichier plugin.yml ==
 
== Le fichier plugin.yml ==
 
Lorsque CraftBukkit démarre, il va regarder à l'intérieur de tous les fichiers JAR dans le dossier /plugins et y chercher un fichier plugin.yml. Ce fichier plugin.yml contient des informations sur le plugin, telles que:
 
Lorsque CraftBukkit démarre, il va regarder à l'intérieur de tous les fichiers JAR dans le dossier /plugins et y chercher un fichier plugin.yml. Ce fichier plugin.yml contient des informations sur le plugin, telles que:
Line 220: Line 199:
 
* Le site de l'auteur du plugin
 
* Le site de l'auteur du plugin
 
* etc...
 
* etc...
<br />
+
<br>
   
 
=> Voir [[Plugin_YAML/fr|Référence plugin.yml]]
 
=> Voir [[Plugin_YAML/fr|Référence plugin.yml]]
<br /><br />
+
<br><br>
   
 
=== Création ===
 
=== Création ===
Line 241: Line 220:
 
</source></blockquote>
 
</source></blockquote>
 
{{ warning | Les 3 premières informations sont cruciales. '''Sans elles, CraftBukkit refusera de lancer le plugin.'''}}
 
{{ warning | Les 3 premières informations sont cruciales. '''Sans elles, CraftBukkit refusera de lancer le plugin.'''}}
  +
{{ warning | '''Ne mettez pas d'accents dans plugin.yml'''}}
 
<br>
 
<br>
 
Voici un exemple, le début du '''plugin.yml''' de WorldEdit 5.5.7:
 
Voici un exemple, le début du '''plugin.yml''' de WorldEdit 5.5.7:
Line 263: Line 243:
 
</source></blockquote>
 
</source></blockquote>
 
* '''exemple''': le nom de la commande
 
* '''exemple''': le nom de la commande
* '''usage''': (uniquement à tire d'information)comment votre commande doit être exécutée, avec quels paramètres<br>
+
* '''usage''': (uniquement à titre d'information)comment votre commande doit être exécutée, avec quels paramètres<br>
 
* '''permission''': (uniquement à titre d'information)la permission requise pour effectuer cette commande<br>
 
* '''permission''': (uniquement à titre d'information)la permission requise pour effectuer cette commande<br>
 
* '''aliases''': la liste des "alias" de la commande. Au lieu de taper le nom complet de la commande pour l'utiliser, vous pouvez taper le nom d'un des alias.
 
* '''aliases''': la liste des "alias" de la commande. Au lieu de taper le nom complet de la commande pour l'utiliser, vous pouvez taper le nom d'un des alias.
Line 301: Line 281:
 
*** '''true''': Si on donne à un joueur la permission parent, il aura cette permission enfant selon ce qui est précisé pour celle-ci ("true", "false", "op" ou "not op")
 
*** '''true''': Si on donne à un joueur la permission parent, il aura cette permission enfant selon ce qui est précisé pour celle-ci ("true", "false", "op" ou "not op")
 
*** '''false''': Si on donne à un joueur la permission parent, il aura cette permission enfant selon '''l'inverse''' de ce qui est précisé pour celle-ci.
 
*** '''false''': Si on donne à un joueur la permission parent, il aura cette permission enfant selon '''l'inverse''' de ce qui est précisé pour celle-ci.
  +
<br>
   
 
== Les fichiers de configuration ==
 
== Les fichiers de configuration ==
Line 335: Line 316:
 
@Overrride
 
@Overrride
 
public void onEnable() {
 
public void onEnable() {
this.saveDefaultConfig();
+
saveDefaultConfig();
 
}
 
}
 
</source>
 
</source>
Line 376: Line 357:
 
@Override
 
@Override
 
public void onEnable() {
 
public void onEnable() {
this.saveDefaultConfig();//On sauvegarde la configuration par défaut si la configuration principale n'existe pas
+
saveDefaultConfig();//On sauvegarde la configuration par défaut si la configuration principale n'existe pas
  +
if(this.getConfig().getBoolean("plugin.optionA")) {//On vérifie si la valeur du booléen plugin.optionA dans la configuration principale est "true"
 
this.getConfig().set("plugin.optionB", 127);//Si c'est le cas on met la valeur plugin.optionB à 127
+
if(getConfig().getBoolean("plugin.optionA")) {//Si la valeur du booléen plugin.optionA dans la configuration principale est "true"
  +
getConfig().set("plugin.optionB", 127);//... alors on met la valeur plugin.optionB à 127
this.saveConfig();//Et on sauvegarde la configuration principale
+
saveConfig();//Et on sauvegarde la configuration principale
 
}
 
}
  +
 
File otherConfigFile = new File("plugins/MonPlugin/configB.yml");//Fichier de l'autre configuration
 
File otherConfigFile = new File("plugins/MonPlugin/configB.yml");//Fichier de l'autre configuration
 
if(!otherConfigFile.exists()) {
 
if(!otherConfigFile.exists()) {
 
otherConfigFile.createNewFile();//On crée ce fichier s'il n'existe pas
 
otherConfigFile.createNewFile();//On crée ce fichier s'il n'existe pas
 
}
 
}
  +
 
FileConfiguration otherConfig = YamlConfiguration.loadConfiguration(otherConfigFile);//On charge l'autre configuration
 
FileConfiguration otherConfig = YamlConfiguration.loadConfiguration(otherConfigFile);//On charge l'autre configuration
 
otherConfig.set("plugin.test.infos", "Phrase de test !");//On met la valeur plugin.test.infos à "Plugin de test !"
 
otherConfig.set("plugin.test.infos", "Phrase de test !");//On met la valeur plugin.test.infos à "Plugin de test !"
Line 390: Line 374:
 
}
 
}
 
</source>
 
</source>
  +
<br>
  +
  +
== Les commandes ==
  +
Vous savez définir des commandes dans plugin.yml, mais si ces commandes pouvaient faire quelque chose, ça serait bien ! Pour cela vous avez deux solutions:
  +
{{note | Dans les deux cas, mettez vos commandes dans le fichier plugin.yml }}
  +
  +
=== Dans la classe principale ===
  +
Vous pouvez programmer les actions déclenchées par une commande directement dans la classe principale de votre plugin. Cette méthode convient très bien si vous avez peu de commandes et si elles ne sont pas très compliquées. Il vous suffit alors de surcharger la méthode onCommand:
  +
<source lang="java">
  +
@Override
  +
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
  +
if (cmd.getName().equalsIgnoreCase("exemple")) { // Si c'est la commande "exemple" qui a été tapée:
  +
// On fait quelque chose
  +
return true;//On renvoie "true" pour dire que la commande était valide
  +
}
  +
return false;//Si une autre commande a été tapée on renvoie "false" pour dire qu'elle n'était pas valide.
  +
}
  +
</source>
  +
<br>
  +
=== Dans une classe à part ===
  +
Si vous avez pas mal de commandes et si elles sont assez longues, il est préférable de mettre la méthode onCommand dans une classe à part. On crée couramment une classe différente par commande. Ces classes doivent implémenter l'interface '''CommandExecutor'''. On les appelle donc avec le nom de la commande suivi de "CommandExecutor":
  +
<source lang="java">
  +
public class ExempleCommandExecutor implements CommandExecutor {
  +
@Override
  +
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
  +
//On fait quelque chose
  +
return true;
  +
}
  +
}
  +
</source>
  +
<br>
  +
Ce n'est pas tout ! Pour que votre plugin sache que faire pour telle commande, il faut le lui dire lors de son lancement. Pour cela on récupère la commande avec '''getCommand(String)'''' et on lui dit quel CommandExecutor utiliser avec '''setExecutor(CommandExecutor)''':
  +
<source lang="java">
  +
@Override
  +
public void onEnable() {
  +
CommandExecutor exempleExecutor = new ExempleCommandExecutor();
  +
getCommand("exemple").setExecutor(exempleExecutor);
  +
}
  +
</source>
  +
  +
<br>
  +
  +
=== Savoir qui effectue la commande ===
  +
Vous pouvez savoir qui effectue la commande avec le paramètre de type '''CommandSender''' de la méthode onCommand. Il est souvent utile de vérifier s'il s'agit d'un joueur ou de la console du serveur:
  +
<source lang="java">
  +
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
  +
if(sender instanceof Player) {
  +
// C'est un joueur qui a effectué la commande
  +
Player p = (Player)sender;// On récupère le joueur.
  +
} else {
  +
// C'est la console du serveur qui a effectuée la commande.
  +
}
  +
return true;
  +
}
  +
</source>
  +
<br>
  +
  +
== Les évènements ==
  +
L'api bukkit dispose d'un système d'évènements permettant aux plugins d'écouter et de réagir à ce qui se passe sur le serveur.<br>
  +
=> Voir [[Event API Reference/fr|Référence API des événements]]
  +
<br>
  +
  +
=== Listener ===
  +
L'écoute des évènements passe par l'interface '''Listener'''. Il vous faut donc une classe qui implémente cette interface. Comme pour les commandes, si vous écoutez peu d'évènements et que vous faites des choses simples, vous pouvez tout à fait utiliser votre classe principale, comme ceci:
  +
<source lang="java">
  +
public class Plugin extends JavaPlugin implements Listener {
  +
}
  +
</source>
  +
<br>
  +
Mais si vous avez plus d'évènements et si ils sont assez longs, il est préférable de créer une classe à part, comme cela:
  +
<source lang="java">
  +
public class PluginListener implements Listener {
  +
}
  +
</source>
  +
{{ note | N'oubliez pas d'importer '''org.bukkit.event.Listener''' si votre IDE ne le fait pas tout seul}}
  +
  +
=== La méthode onXXX(Event) ===
  +
L'interface Listener ne propose pas de méthodes toutes prêtes pour écouter les évènements du serveur. C'est à vous de créer une méthode dans votre Listener pour chaque évènement que vous voulez écouter.<br>
  +
Ces méthodes '''doivent''' être de la forme suivante, et '''doivent''' comporter l'annotation '''@EventHandler''':
  +
<source lang="java">
  +
@EventHandler
  +
public void onXXX(Event e) {
  +
//Action à effectuer quand l'évènement e survient
  +
}
  +
</source>
  +
* '''onXXX''': le nom de la méthode devrait être "on" suivi du nom de l'évènement, par exemple "onPlayerJoin"
  +
* '''Event''': la classe de l'évènement à écouter.
  +
<br>
  +
Ce n'est pas tout ! Pour que le serveur appelle votre méthode à chaque fois que l'évènement correspondant survient, il faut le lui dire lors du lancement de votre plugin. Pour cela on passe par le '''PluginManager''' et on utilise '''registerEvents(Listener, JavaPlugin)''':
  +
<source lang="java">
  +
@Override
  +
public void onEnable() {
  +
Listener l = new PluginListener();
  +
PluginManager pm = getServer().getPluginManager();
  +
pm.registerEvents(l, this);
  +
}
  +
</source>
  +
<br>
  +
Si vous utilisez votre classe principale en tant que Listener, faites simplement:
  +
<source lang="java">
  +
@Override
  +
public void onEnable() {
  +
PluginManager pm = getServer().getPluginManager();
  +
pm.registerEvents(this, this);
  +
}
  +
</source>
  +
  +
=== Exemple ===
  +
Classe qui implémente Listener:
  +
<source lang="java">
  +
import org.bukkit.event.Listener;
  +
import org.bukkit.event.player.PlayerJoinEvent;
  +
  +
public class PluginListener implements Listener {
  +
@EvantHandler
  +
public void onPlayerJoin(PlayerJoinEvent e) {//PlayerJoinEvent est l'évènement de connexion d'un joueur sur le serveur
  +
Player p = e.getPlayer();//On récupère le joueur qui vient de se connecter à partir de l'évènement
  +
p.sendMessage("Bienvenue sur le serveur !");//On lui envoie un message
  +
}
  +
}
  +
</source>
  +
<br>
  +
Classe principale du plugin:
  +
<source lang="java">
  +
import org.bukkit.plugin.java.JavaPlugin;
  +
import org.bukkit.plugin.PluginManager;
  +
import org.bukkit.event.Listener;
  +
  +
public class Plugin extends JavaPlugin {
  +
@Override
  +
public void onEnable() {
  +
Listener l = new PluginListener();//On crée une instance de notre classe qui implémente Listener
  +
PluginManager pm = getServer().getPluginManager();//On récupère le PluginManager du serveur
  +
pm.registerEvents(l, this);//On enregistre notre instance de Listener et notre plugin auprès du PluginManager
  +
}
  +
}
  +
</source>
  +
<br>
  +
== La planification des tâches ==
  +
L'api bukkit dispose également d'un système de planification des tâches. Il permet aux plugins d'exécuter du code, de façon synchrone ou asynchrone (dans un Thread différent de celui du serveur), après un certain temps et/ou à intervalles réguliers.<br>
  +
=> Voir [[Scheduler API Reference/fr|Référence Scheduler]]
  +
  +
=== BukkitRunnable ===
  +
La méthode la plus simple et la plus recommandée est de créer une classe héritant de '''BukkitRunnable''', et de mettre dans la méthode '''run()''' le code que vous voulez exécuter:
  +
<source lang="java">
  +
public class ExempleTask extends BukkitRunnable {
  +
@Override
  +
public void run() {
  +
//Code a exécuter
  +
}
  +
}
  +
</source>
  +
  +
=== Planification ===
  +
Une fois que vous avez votre tâche, vous pouvez planifier son lancement avec les méthodes héritées de BukkitRunnable. En voici quelques unes:
  +
* '''runTask(Plugin plugin)''': exécute la tâche immédiatement
  +
* '''runTaskAsynchronously(Plugin plugin)''': exécute la tâche de façon asynchrone (dans un autre Thread)
  +
* '''runTaskLater(Plugin plugin, long delay)''': exécute la tâche après un certains nombres de ticks
  +
* '''runTaskTimer(Plugin plugin, long delay, long period)''': exécute la tâche tous les ''period'' ticks, après ''delay'' ticks.
  +
<br>
  +
{{Warning|Les tâches asynchrones (exécutées dans un autre Thread) ne doivent utiliser AUCUNE api bukkit durant leur exécution}}
  +
{{Note|Sur un serveur sans lag, 20 ticks durent 1 seconde}}
  +
<br>
  +
Exemple au lancement du plugin:
  +
<source lang="java">
  +
@Override
  +
public void onEnable() {
  +
BukkitRunnable task = new ExempleTask();
  +
task.runTaskLater(this, 200);//On lance la tâche dans 10 secondes
  +
}
  +
</source>
  +
<br>
  +
  +
== Vérifier si votre plugin est à jour ==
  +
Si vous mettez votre plugin sur dev.bukkit.org, vous vous demandez peut-être s'il est possible de vérifier si le serveur dispose de la dernière version, en se connectant à internet. Cela est tout à fait possible via l'api "ServersMods", qui permet de récupérer des infos sur les projets du site !<br>
  +
=> Voir [[ServerMods API/fr|Référence de l'api ServersMods]]<br>
  +
{{Warning|Les autres méthodes pour vérifier les mises à jour '''ne sont plus autorisées par devBukkit'''}}
  +
<br>
  +
{{Languages|Plugin Tutorial}}
  +
[[Category:Tutorials/fr]]

Latest revision as of 14:36, 25 June 2017

Apprendre à programmer en Java

Avant de commencer à créer des plugins bukkit, il est nécessaire d'avoir suffisamment de connaissances en programmation en général, et plus particulièrement en Java. Si les mots IDE, JDK, fonction, variable, main, classe, jar, package, etc… vous sont inconnus, ou si vous avez encore du mal avec le langage Java, voici quelques pistes :

Il y a aussi la solution des tutoriaux en vidéo. Privilégiez tout de même les tutoriaux écris.

Si vous souhaitez vraiment devenir développeur, suivez bien le tutoriel du site du zéro, en prenant bien le temps de comprendre chaque notion. Cela vous aidera énormément pour la suite.

Outils du développeur

Java

Vous aurez bien sûr besoin de Java, c'est-à-dire d'un JRE (Java Runtime Environment ou "Environnement d'Exécution Java" c'est ce qu'on appelle communément "Java" et qui permet d'utiliser des programmes Java compilés, comme par exemple Minecraft) ou d'un JDK (Java Development Kit, des outils qui permettent de créer des programmes Java et de les déboguer. Contient le JRE). Il est préférable d'utiliser le JDK pour programmer, même si certains IDE comme Eclipse peuvent s'en passer, d'autres l'utilisent.

=> Télécharger le dernier JRE ou JDK

Un IDE

Un IDE, Integrated Development Environment (ou "Environnement de Développement Intégré"), est un outil qui va permettre d'écrire le code du programme, de le compiler pour en faire un fichier utilisable par l'ordinateur, et de le déboguer, c'est-à-dire de trouver où se trouvent les bogues (ou "bugs" en anglais) pour les corriger rapidement. Le tout-en-un du développeur.

Il existe différents IDE. Voici les principaux qu'on observe dans l'environnement Bukkit, ceux que l'on peut croiser :

  • Eclipse - Gratuit, le plus utilisé
  • NetBeans - Gratuit, aussi très utilisé
  • IntelliJ Idea - Payant, avec une version gratuite. Sa version gratuite est un peu moins complète qu'Eclipse ou NetBeans.

Si vous êtes débutant "total", choisissez Eclipse. Il est le plus utilisé, et donc le plus représenté dans les tutoriels, comme celui-ci !

=> Téléchargez la dernière version d'Eclipse IDE

Sur cette page, vous trouverez toutes les dernières versions d'Eclipse. Pour développer en Java, vous pouvez utiliser Eclipse IDE for Java Developers ou Eclipse Standard. Si vous avez un ordinateur 64 bits, prenez la version 64 bits. Eclipse, tout comme NetBeans, est plutôt lourd, autant utiliser une version plus rapide si vous le pouvez.

Lightbulb Note: Si vous avez un vieux Mac à processeur PowerPC, vous devrez télécharger une version plus ancienne d'Eclipse telle que Indigo ou Juno

L'API bukkit

Le système de plugins des serveurs CraftBukkit utilise une API (Application Programming Interface ou "Interface de Programmation Applicative") nommée Bukkit. Lorsque vous créez un plugin pour les serveurs utilisant CraftBukkit, vous utilisez des classes, interfaces et méthodes de l'API Bukkit. Si vous lisez ceci, vous êtes censé connaître Java et la programmation, vous comprendrez donc cette phrase: on dit que CraftBukkit implémente Bukkit. Pour pouvoir utiliser tout cela dans votre projet Eclipse, il faut spécifier que le projet utilisera l'API Bukkit.

L'API bukkit se présente sous la forme d'un fichier JAR non éxécutable. => Télécharger l'API Bukkit (Ne fonctionne plus).

Warning Warning: Vous ne devez JAMAIS utiliser CraftBukkit à la place de Bukkit lorsque vous développez. Vous seriez tenté d'utiliser des classes, interfaces et méthodes de CraftBukkit qui ne font pas partie de l'API. Au final, vous aurez un "plugin-mod" qui devra être recompilé à chaque mise à jour du projet Bukkit.
Lightbulb Note: Vous trouverez tout de même des plugins plutôt importants qui utilisent CraftBukkit pour étendre l'API Bukkit, tel queTagAPI ou ProtocolLib

Un serveur CraftBukkit

Si vous voulez tester votre plugin, il vous faudra un serveur Minecraft CraftBukkit fonctionnel. Vous DEVEZ tester votre plugin avant de le publier.

=> Voir wiki.bukkit.org/Setting_up_a_server/fr

Création du projet

Maintenant que vous avez tout ce qu'il faut, vous pouvez commencer la partie intéressante : le développement du plugin lui-même. Pour commencer, vous allez créer un nouveau projet dans Eclipse que vous appellerez comme votre plugin :

Nouveau projet

Utiliser l'API bukkit

Je vous avais dit plus haut que, pour pouvoir utiliser l'API Bukkit afin de créer votre plugin, il fallait le spécifier à Eclipse. Pour cela, allez dans les propriétés de votre projet (clic droit sur votre projet > Properties) :


Properties


Properties fenetre

Dans cette fenêtre, cliquez sur le bouton Add external jar et sélectionnez le bukkit.jar que vous avez téléchargé.

Ensuite, cliquez sur la petite flèche à gauche de "bukkit.jar" pour dérouler un menu :

Properties - javadoc location 1


Double-cliquez sur JavaDoc Location afin de faire apparaître cette fenêtre :

Properties - set javadoc


Dans le premier cadre "JavaDoc Location Path", entrez ceci: http://jd.bukkit.org/apidocs

Pour les versions plus récentes de Bukkit (1.8 et plus), la JavaDoc est disponible ici : https://hub.spigotmc.org/javadocs/bukkit/


Puis cliquez sur "Ok" et encore sur "Ok" dans la fenêtre des propriétés ("Properties").

La classe principale

Tous les plugins disposent d'une classe principale. Cette classe sera utilisée au démarrage du plugin et vous permet donc de lancer certaines actions.

Création

Créez tout d'abord un nouveau paquet ("package") dans votre projet en cliquant sur le bouton Nouveau paquet qui se trouve en haut de la fenêtre d'Eclipse, dans cette barre de menus:

Barre de menu

Vous devez suivre certaines conventions lors du choix du nom de votre package :

  • Il ne doit PAS contenir de majuscule, ni de caractères spéciaux
  • Il devrait contenir le nom de votre plugin
  • Si vous possédez un nom de domaine, le nom du package peut commencer par ce nom de domaine à l'envers. Par exemple, si vous possédez mondomaine.com, votre package commencera par com.mondomaine
  • Si vous ne possédez pas de nom de domaine, vous pouvez simplement utiliser ce que vous voulez, tant que ce n'est pas déjà utilisé. On pourra conseiller me.<votrePseudo>.<votrePlugin> ou fr.<votrePseudo>.<votrePlugin>
  • Il ne doit absolument PAS commencer par l'un des noms suivants:
    • org.bukkit
    • net.bukkit
    • com.bukkit
    • net.minecraft


Par exemple: sk89q, l'auteur de WorldEdit, possède le nom de domaine sk89q.com. Le nom du package contenant le code de WorldEdit est donc com.sk89q.worldedit.

Ensuite, créez une nouvelle Classe dans ce package en cliquant sur le bouton Nouvelle classe qui se trouve également dans la barre de menus.

On appelle généralement la classe principale du plugin par le nom du plugin.

JavaPlugin

Cette classe principale doit hériter de la classe JavaPlugin de l'API Bukkit afin d'être vraiment considérée comme la classe principale d'un plugin par le serveur CraftBukkit.

Vous pouvez donc modifier

public class Plugin {
}

en

public class Plugin extends JavaPlugin {
}

Eclipse, comme tout IDE, devrait vous proposer d'importer org.bukkit.plugin.java.JavaPlugin. Vous devriez donc avoir ceci en haut de votre classe.

import org.bukkit.plugin.java.JavaPlugin;

La méthode onEnable()

La classe JavaPlugin possède une méthode onEnable() qui est appellée à chaque lancement du plugin. Afin de pouvoir effectuer vos propre actions au démarrage du plugin, vous devez redéfinir la méthode onEnable() dans la classe principale de votre plugin:

public class Plugin extends JavaPlugin {
    @Override
    public void onEnable(){
        // Actions à effectuer au démarrage du plugin, c'est-à-dire :
        //   - Au démarrage du serveur
        //   - Après un /reload
    }

}

La méthode onDisable()

La classe JavaPlugin possède aussi une méthode onDisable() qui, vous l'avez sûrement deviné, est appellée à chaque fois que le plugin est désactivé. Comme pour onEnable(), vous devez redéfinir la méthode onDisable() dans la classe principale de votre plugin:

public class Plugin extends JavaPlugin {
    @Override
    public void onDisable(){
        // Actions à effectuer à la désactivation du plugin
        //   - A l'extinction du serveur
        //   - Pendant un /reload
    }

}
Lightbulb Note: Pour faire simple, la commande /reload appelle les méthodes onDisable() de chacun des plugins actifs, puis les méthodes onEnable().

Affichage de messages

Un plugin peut afficher des messages dans la console et le log du serveur avec les méthodes du Logger associé au plugin. La méthode getLogger() permet de le récupérer.
Il y'a trois types de messages, chacun pouvant être affiché avec une méthode différente du logger:

  • Message d'information, commençant par [INFO] dans la console: méthode info(String)
  • Message d'avertissement, commençant par [WARNING] dans la console: méthode warning(String)
  • Message d'erreur, commençant par [SEVERE] dans la console: méthode severe(String)

Ces trois méthodes prennent comme paramètre le message à afficher.
Voici un exemple:

@Override
public void onEnable() {
    getLogger().info("Plugin démarré !");
}


Le fichier plugin.yml

Lorsque CraftBukkit démarre, il va regarder à l'intérieur de tous les fichiers JAR dans le dossier /plugins et y chercher un fichier plugin.yml. Ce fichier plugin.yml contient des informations sur le plugin, telles que:

  • Le nom du plugin
  • La version du plugin
  • Le chemin de la classe principale
  • Les commandes du plugin
  • Les permissions du plugin
  • Le nom de l'auteur du plugin
  • Le site de l'auteur du plugin
  • etc...


=> Voir Référence plugin.yml

Création

Faites un clic droit sur votre projet > New > File
Nouveau fichier

Appelez le fichier plugin.yml et mettez-y ceci :

name: <nomDuPlugin>
main: <votrePackage>.<VotreClassePrincipale>
version: <versionDuPlugin>
description: <Description du plugin>
author: <votreNom>
Warning Warning: Les 3 premières informations sont cruciales. Sans elles, CraftBukkit refusera de lancer le plugin.
Warning Warning: Ne mettez pas d'accents dans plugin.yml


Voici un exemple, le début du plugin.yml de WorldEdit 5.5.7:

name: WorldEdit
main: com.sk89q.worldedit.bukkit.WorldEditPlugin
version: 5.5.7

Les commandes

Il est conseillé de mettre les commandes de votre plugin dans le fichier plugin.yml. Pour cela, ajoutez-y un tag "commands":

commands:
  exemple:
    description: Description de la commande.
    usage: /exemple [parametre1] [parametre2]
    permission: permission.exemple
    aliases:
    - ex
    - e
  • exemple: le nom de la commande
  • usage: (uniquement à titre d'information)comment votre commande doit être exécutée, avec quels paramètres
  • permission: (uniquement à titre d'information)la permission requise pour effectuer cette commande
  • aliases: la liste des "alias" de la commande. Au lieu de taper le nom complet de la commande pour l'utiliser, vous pouvez taper le nom d'un des alias.

Les permissions

Il est conseillé d'ajouter les permissions que votre plugin utilise dans le fichier plugin.yml. Pour cela, ajoutez-y un tag "permissions":

permissions:
  plugin.exemple:
    description: permet d'utiliser la commande exemple
    default: op
  • plugin.exemple: le nom de la permission
  • description: description de la commande
  • default: qui par défaut a cette permission. 4 valeurs sont possibles:
    • true: par défaut, tout le monde a cette permission
    • false: par défaut, personne n'a cette permission
    • op: par défaut, seuls les admins (OP) du serveur ont cette permission
    • not op: par défaut, seuls ceux qui ne sont PAS admins du serveur ont cette permission



Il est possible de définir des permissions "parents" et "enfants" avec le tag children:

permissions:
  plugin.*:
    description: donne acces a toutes les permissions enfants
    children:
      plugin.exemple: true   
  plugin.exemple:
    description: permet d'utiliser la commande exemple
    default: op
  • plugin.*: nom de la permission parent. Généralement on utilise le signe * pour remplacer la/les dernière(s) partie(s) de la permission parent, selon ce qui change chez les enfants.
  • children: en dessous on va mettre toutes les permissions enfants.
    • plugin.exemple: nom de la permission enfant. 2 valeurs sont possibles:
      • true: Si on donne à un joueur la permission parent, il aura cette permission enfant selon ce qui est précisé pour celle-ci ("true", "false", "op" ou "not op")
      • false: Si on donne à un joueur la permission parent, il aura cette permission enfant selon l'inverse de ce qui est précisé pour celle-ci.


Les fichiers de configuration

L'api bukkit met à disposition des outils pour gérer facilement des fichiers de configuration. Le fichier de configuration principal d'un plugin se trouve toujours ici: dossier du serveur/plugins/NomDuPlugin/config.yml.

Le fichier config.yml par défaut

Il est conseillé d'avoir un fichier config.yml par défaut dans le .jar du plugin. Cela servira notamment à créer le fichier de configuration principal s'il n'existe pas.
Pour créer ce fichier, faites un clic droit sur votre projet > New > File et appelez-le "config.yml". Dans ce fichier vous pouvez mettre:

  • De simples valeurs:
nom: valeur
  • Des listes:
nom:
  - élément 1
  - élément 2
  • Des groupes de valeurs, avec des parents et des enfants:
parent:
  enfant1: valeur
  enfant2:
    sousEnfant:
      - élément
  • Des commentaires: en ajoutant le signe # en début de ligne:
#Ceci est un commentaire


Afin de sauvegarder cette configuration par défaut dans dossier du serveur/plugins/NomDuPlugin/config.yml lorsque ce dernier n'existe pas, utilisez la méthode saveDefaultConfig(). Exemple au chargement du plugin:

@Overrride
public void onEnable() {
    saveDefaultConfig();
}

Accéder un fichier de configuration

Afin d'accéder, d'écrire ou de lire des fichiers de configuration, on utilise l'objet FileConfiguration de l'api bukkit. Il y'a plusieurs façons de récupérer une instance de FileConfiguration:

  • Si vous voulez accéder à dossier du serveur/plugins/NomDuPlugin/config.yml, utilisez la méthode getConfig() de JavaPlugin.
  • Si vous voulez accéder au fichier de configuration par défaut stocké dans le .jar du plugin, utilisez getConfig().getDefault()
  • Pour tout autre fichier de configuration, faites comme ceci:
File configFile = new File("plugin/NomDuPlugin/monFichierConfig.yml");
FileConfiguration config = YamlConfiguration.loadConfiguration(configFile);


Vous devez aussi savoir qu'une valeur dans un fichier de configuration est identifiée grâce à son chemin, qui est construit de la façon suivante: parent.enfant.sousEnfant.nomDeLaValeur

Lire des valeurs

Les méthodes getXXX(String) de la classe FileConfiguration permettent de récupérer une valeur de type XXX. Elles prennent comme paramètre le chemin de la valeur. Voici les méthodes les plus utilisées:

  • getBoolean(String): donne un booléen (true/false)
  • getInt(String): donne un nombre entier
  • getFloat(String): donne un nombre à virgule
  • getString(String): donne une chaîne de caractère
  • getStringList(String): donne une liste de chaînes de caractères
  • getList(String): donne une liste d'éléments divers


Modifier des valeurs

La méthode set(String, Object) permet de modifier une valeur dans la configuration. Elle prend comme paramètre le chemin de la valeur, et la valeur elle-même. Exemple:

getConfig().set("parent.enfant1", "Salut !");


Warning Warning: Une fois que vous avez modifié une configuration, pensez à la sauvegarder !
  • Si c'est la configuration principale du plugin, utilisez la méthode saveConfig() de la classe JavaPlugin.
  • Sinon, utilisez la méthode save(File), de la classe FileConfiguration, qui prend en paramètre le fichier dans lequel la config sera enregistrée.

Exemple

Un petit exemple, lors du lancement du plugin:

@Override
public void onEnable() {
    saveDefaultConfig();//On sauvegarde la configuration par défaut si la configuration principale n'existe pas

    if(getConfig().getBoolean("plugin.optionA")) {//Si la valeur du booléen plugin.optionA dans la configuration principale est "true"
        getConfig().set("plugin.optionB", 127);//... alors on met la valeur plugin.optionB à 127
        saveConfig();//Et on sauvegarde la configuration principale
    }

    File otherConfigFile = new File("plugins/MonPlugin/configB.yml");//Fichier de l'autre configuration
    if(!otherConfigFile.exists()) {
        otherConfigFile.createNewFile();//On crée ce fichier s'il n'existe pas
    }

    FileConfiguration otherConfig = YamlConfiguration.loadConfiguration(otherConfigFile);//On charge l'autre configuration
    otherConfig.set("plugin.test.infos", "Phrase de test !");//On met la valeur plugin.test.infos à "Plugin de test !"
    otherConfig.save(otherConfigFile);//On sauvegarde l'autre configuration dans son fichier
}


Les commandes

Vous savez définir des commandes dans plugin.yml, mais si ces commandes pouvaient faire quelque chose, ça serait bien ! Pour cela vous avez deux solutions:

Lightbulb Note: Dans les deux cas, mettez vos commandes dans le fichier plugin.yml

Dans la classe principale

Vous pouvez programmer les actions déclenchées par une commande directement dans la classe principale de votre plugin. Cette méthode convient très bien si vous avez peu de commandes et si elles ne sont pas très compliquées. Il vous suffit alors de surcharger la méthode onCommand:

@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
	if (cmd.getName().equalsIgnoreCase("exemple")) { // Si c'est la commande "exemple" qui a été tapée:
		// On fait quelque chose
		return true;//On renvoie "true" pour dire que la commande était valide
	}
	return false;//Si une autre commande a été tapée on renvoie "false" pour dire qu'elle n'était pas valide.
}


Dans une classe à part

Si vous avez pas mal de commandes et si elles sont assez longues, il est préférable de mettre la méthode onCommand dans une classe à part. On crée couramment une classe différente par commande. Ces classes doivent implémenter l'interface CommandExecutor. On les appelle donc avec le nom de la commande suivi de "CommandExecutor":

public class ExempleCommandExecutor implements CommandExecutor {
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
	//On fait quelque chose
	return true;
   } 
}


Ce n'est pas tout ! Pour que votre plugin sache que faire pour telle commande, il faut le lui dire lors de son lancement. Pour cela on récupère la commande avec getCommand(String)' et on lui dit quel CommandExecutor utiliser avec setExecutor(CommandExecutor):

@Override
public void onEnable() {
   CommandExecutor exempleExecutor = new ExempleCommandExecutor();
   getCommand("exemple").setExecutor(exempleExecutor);
}


Savoir qui effectue la commande

Vous pouvez savoir qui effectue la commande avec le paramètre de type CommandSender de la méthode onCommand. Il est souvent utile de vérifier s'il s'agit d'un joueur ou de la console du serveur:

public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    if(sender instanceof Player) {
        // C'est un joueur qui a effectué la commande
        Player p = (Player)sender;// On récupère le joueur.
    } else {
        // C'est la console du serveur qui a effectuée la commande.
    }
    return true;
}


Les évènements

L'api bukkit dispose d'un système d'évènements permettant aux plugins d'écouter et de réagir à ce qui se passe sur le serveur.
=> Voir Référence API des événements

Listener

L'écoute des évènements passe par l'interface Listener. Il vous faut donc une classe qui implémente cette interface. Comme pour les commandes, si vous écoutez peu d'évènements et que vous faites des choses simples, vous pouvez tout à fait utiliser votre classe principale, comme ceci:

public class Plugin extends JavaPlugin implements Listener {
}


Mais si vous avez plus d'évènements et si ils sont assez longs, il est préférable de créer une classe à part, comme cela:

public class PluginListener implements Listener {
}
Lightbulb Note: N'oubliez pas d'importer org.bukkit.event.Listener si votre IDE ne le fait pas tout seul

La méthode onXXX(Event)

L'interface Listener ne propose pas de méthodes toutes prêtes pour écouter les évènements du serveur. C'est à vous de créer une méthode dans votre Listener pour chaque évènement que vous voulez écouter.
Ces méthodes doivent être de la forme suivante, et doivent comporter l'annotation @EventHandler:

@EventHandler
public void onXXX(Event e) {
    //Action à effectuer quand l'évènement e survient
}
  • onXXX: le nom de la méthode devrait être "on" suivi du nom de l'évènement, par exemple "onPlayerJoin"
  • Event: la classe de l'évènement à écouter.


Ce n'est pas tout ! Pour que le serveur appelle votre méthode à chaque fois que l'évènement correspondant survient, il faut le lui dire lors du lancement de votre plugin. Pour cela on passe par le PluginManager et on utilise registerEvents(Listener, JavaPlugin):

@Override
public void onEnable() {
   Listener l = new PluginListener();
   PluginManager pm = getServer().getPluginManager();
   pm.registerEvents(l, this);
}


Si vous utilisez votre classe principale en tant que Listener, faites simplement:

@Override
public void onEnable() {
   PluginManager pm = getServer().getPluginManager();
   pm.registerEvents(this, this);
}

Exemple

Classe qui implémente Listener:

import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class PluginListener implements Listener {
   @EvantHandler
   public void onPlayerJoin(PlayerJoinEvent e) {//PlayerJoinEvent est l'évènement de connexion d'un joueur sur le serveur
      Player p = e.getPlayer();//On récupère le joueur qui vient de se connecter à partir de l'évènement
      p.sendMessage("Bienvenue sur le serveur !");//On lui envoie un message
   }
}


Classe principale du plugin:

import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.event.Listener;

public class Plugin extends JavaPlugin {
   @Override
   public void onEnable() {
      Listener l = new PluginListener();//On crée une instance de notre classe qui implémente Listener
      PluginManager pm = getServer().getPluginManager();//On récupère le PluginManager du serveur
      pm.registerEvents(l, this);//On enregistre notre instance de Listener et notre plugin auprès du PluginManager
   }
}


La planification des tâches

L'api bukkit dispose également d'un système de planification des tâches. Il permet aux plugins d'exécuter du code, de façon synchrone ou asynchrone (dans un Thread différent de celui du serveur), après un certain temps et/ou à intervalles réguliers.
=> Voir Référence Scheduler

BukkitRunnable

La méthode la plus simple et la plus recommandée est de créer une classe héritant de BukkitRunnable, et de mettre dans la méthode run() le code que vous voulez exécuter:

public class ExempleTask extends BukkitRunnable {
   @Override
   public void run() {
      //Code a exécuter
   }
}

Planification

Une fois que vous avez votre tâche, vous pouvez planifier son lancement avec les méthodes héritées de BukkitRunnable. En voici quelques unes:

  • runTask(Plugin plugin): exécute la tâche immédiatement
  • runTaskAsynchronously(Plugin plugin): exécute la tâche de façon asynchrone (dans un autre Thread)
  • runTaskLater(Plugin plugin, long delay): exécute la tâche après un certains nombres de ticks
  • runTaskTimer(Plugin plugin, long delay, long period): exécute la tâche tous les period ticks, après delay ticks.


Warning Warning: Les tâches asynchrones (exécutées dans un autre Thread) ne doivent utiliser AUCUNE api bukkit durant leur exécution
Lightbulb Note: Sur un serveur sans lag, 20 ticks durent 1 seconde


Exemple au lancement du plugin:

@Override
public void onEnable() {
   BukkitRunnable task = new ExempleTask();
   task.runTaskLater(this, 200);//On lance la tâche dans 10 secondes
}


Vérifier si votre plugin est à jour

Si vous mettez votre plugin sur dev.bukkit.org, vous vous demandez peut-être s'il est possible de vérifier si le serveur dispose de la dernière version, en se connectant à internet. Cela est tout à fait possible via l'api "ServersMods", qui permet de récupérer des infos sur les projets du site !
=> Voir Référence de l'api ServersMods

Warning Warning: Les autres méthodes pour vérifier les mises à jour ne sont plus autorisées par devBukkit


Language   EnglishбеларускаяDeutschespañolsuomifrançaisitaliano한국어Nederlandsnorskpolskiportuguêsрусскийlietuviųčeština