[JAVA] [Minecraft] Zeitbetrieb mit Bukkit / Spigot-Plug-In


Beachten Sie den Stolperstein zu Beginn der Erstellung des Bukkit-Plug-Ins.

Was willst du tun

Wenn Sie ein bestimmtes Wort in das Chatfeld von Minecraft eingeben, wird ein Auslöser ausgelöst, um die Zeit im Spiel festzulegen. Wenn Sie hier beispielsweise "Morgen" eingeben, erstellen Sie ein Plug-In, das sich auf die Zeit 0 (Morgen) ändert.

Schlechtes Beispiel

main.java


//Paketanweisung und Importanweisung weggelassen
public class main extends JavaPlugin{
    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new eventListener(this), this);
    }
}

eventListener.java


//Paketanweisung und Importanweisung weggelassen
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("Morgen")){
            event.getPlayer().getWorld().setTime(0L);
            event.getPlayer().sendMessage("Das Wort "Morgen" wurde erkannt.");
            m.getLogger().info(event.getPlayer().getName()+"Sagte das Wort "Morgen"");
        }
    }
}

Von Spielern gesendete Chats können mit "AsyncPlayerChatEvent" abgefangen und auf der Plug-In-Seite frei betrieben werden. Außerdem ist hier geschrieben World event.getPlayer (). GetWorld () im Ereignishandler. Sie können es mit) bekommen.

Das Problem ist, dass dies kompiliert wird.

Warum nicht

Die Kompilierung war erfolgreich und es ist kein Fehler aufgetreten, als ich sie tatsächlich installiert habe. Wenn ich jedoch tatsächlich "Morgen" eingebe, werden auf der Serverseite zwei Fehler angezeigt.

[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]
~ Abkürzung ~
	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]
~ Abkürzung ~

Wie in [diesem Dokument] beschrieben (https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/player/AsyncPlayerChatEvent.html), wird "AsyncPlayerChatEvent" grundsätzlich asynchron ausgeführt. Event.getPlayer (). GetWorld (). SetTime (0L); muss jedoch synchron ausgeführt werden.

Lösungen

Es gibt verschiedene Lösungen, aber die einfachste Implementierung der anonymen Klasse vermeidet den Fehler.

main.java


//Sie können es so lassen, wie es ist

eventListener.java


//Paketanweisung und Importanweisung weggelassen
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("Morgen")){
            m.getServer().getScheduler().runTask(m, new Runnable() {
                @Override
                public void run() {event.getPlayer().getWorld().setTime(0L);}
            });
            event.getPlayer().sendMessage("Das Wort "Morgen" wurde erkannt.");
            m.getLogger().info(event.getPlayer().getName()+"Sagte das Wort "Morgen"");
        }
    }
}

Ich verwende den Scheduler "org.bukkit.scheduler", um die synchrone Verarbeitung vom asynchronen "AsyncPlayerChatEvent" aufzurufen. runTask führt die registrierte Klasse beim nächsten Tick (Server Tick) aus. Wenn Sie etwas warten möchten, verwenden Sie stattdessen "runTaskLater".



das ist alles.

Recommended Posts

[Minecraft] Zeitbetrieb mit Bukkit / Spigot-Plug-In
Plug-In-Entwicklung mit ImageJ