[JAVA] [Minecraft] Fonctionnement du temps avec le plug-in Bukkit / Spigot


Notez la pierre d'achoppement au début de la création du plug-in Bukkit.

Que veux-tu faire

Lorsque vous entrez un mot spécifique dans le champ de discussion de Minecraft, un déclencheur est déclenché pour définir l'heure du jeu. Ici, par exemple, si vous entrez "matin", créez un plug-in qui passe à l'heure 0 (matin).

Mauvais exemple

main.java


//Instruction de package et instruction d'importation omises
public class main extends JavaPlugin{
    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new eventListener(this), this);
    }
}

eventListener.java


//Instruction de package et instruction d'importation omises
public class eventListener implements Listener {
    private final main m;
    public eventListener(main m_){m=m_;}

    @EventHandler
    public void onPlayerChat(AsyncPlayerChatEvent event){
        if(event.getMessage().equals("Matin")){
            event.getPlayer().getWorld().setTime(0L);
            event.getPlayer().sendMessage("Le mot «matin» a été détecté.");
            m.getLogger().info(event.getPlayer().getName()+"Dit le mot "matin"");
        }
    }
}

Les discussions envoyées par les joueurs peuvent être capturées avec ʻAsyncPlayerChatEventet peuvent être utilisées librement du côté du plug-in. De plus, [écrit ici](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/World.html), World est ʻevent.getPlayer (). GetWorld (dans le gestionnaire d'événements. Vous pouvez l'obtenir avec).

Le problème est que cela va compiler.

Pourquoi pas

La compilation a réussi et aucune erreur ne s'est produite lorsque je l'ai installé. Cependant, lorsque je tape "matin", j'obtiens deux erreurs côté serveur.

[00:00:00 ERROR]: Could not pass event AsyncPlayerChatEvent to hogehoge_plugin v1.0.0
org.bukkit.event.EventException: null
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:312) ~[craftbukkit-1.15.2.jar:git-Bukkit-8160e29]
	at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[craftbukkit-1.15.2.jar:git-Bukkit-8160e29]
~ Abréviation ~
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461) [craftbukkit-1.15.2.jar:git-Bukkit-8160e29]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [craftbukkit-1.15.2.jar:git-Bukkit-8160e29]
	at java.lang.Thread.run(Thread.java:830) [?:?]
Caused by: java.lang.IllegalStateException: TimeSkipEvent cannot be triggered asynchronously from another thread.
	at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:510) ~[craftbukkit-1.15.2.jar:git-Bukkit-8160e29]
	at org.bukkit.craftbukkit.v1_15_R1.CraftWorld.setFullTime(CraftWorld.java:803) ~[craftbukkit-1.15.2.jar:git-Bukkit-8160e29]
~ Abréviation ~

Comme décrit dans ce document, ʻAsyncPlayerChatEventest essentiellement exécuté de manière asynchrone. Cependant, ʻevent.getPlayer (). GetWorld (). SetTime (0L);doit être exécuté de manière synchrone.

Solution

Il existe plusieurs solutions, mais l'implémentation la plus simple de la classe anonyme évite l'erreur.

main.java


//Vous pouvez le laisser tel quel

eventListener.java


//Instruction de package et instruction d'importation omises
public class eventListener implements Listener {
    private final main m;
    public eventListener(main m_){m=m_;}

    @EventHandler
    public void onPlayerChat(AsyncPlayerChatEvent event){
        if(event.getMessage().equals("Matin")){
            m.getServer().getScheduler().runTask(m, new Runnable() {
                @Override
                public void run() {event.getPlayer().getWorld().setTime(0L);}
            });
            event.getPlayer().sendMessage("Le mot «matin» a été détecté.");
            m.getLogger().info(event.getPlayer().getName()+"Dit le mot "matin"");
        }
    }
}

J'utilise le planificateur de ʻorg.bukkit.scheduler pour appeler le traitement synchrone à partir de l'asynchrone ʻAsyncPlayerChatEvent. runTask exécute la classe enregistrée au prochain tick (tick du serveur). Si vous voulez attendre un peu, utilisez plutôt runTaskLater.



c'est tout.

Recommended Posts

[Minecraft] Fonctionnement du temps avec le plug-in Bukkit / Spigot
Développement de plug-in avec ImageJ