[JAVA] Ich habe versucht, den Chat mit dem Minecraft-Server mit der Discord-API zu verknüpfen

Einführung

** Bitte beachten Sie, dass dies der erste Qiita-Beitrag ist, daher kann es schwierig sein, ihn zu lesen. ** ** **

** Bitte beachten Sie, dass wir dieses Mal nicht vorstellen werden, wie Sie das Discord Bot API-Token erhalten. ** ** **

Minecraft BE Server Software Mit der Plug-In-Erweiterung von Nukkit Ich habe bis zur Implementierung der Funktion geschrieben, um den Chat auf dem Server in Echtzeit mit Discord's Bot anzuzeigen.

Löschen Sie die Bibliothek mit Maven

Fügen Sie diese zu pom.xml hinzu.

pom.xml


...
<repositories>
    ...
    <repository>
        <id>jcenter</id>
        <url>http://jcenter.bintray.com</url>
    </repository>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>
...

...
<dependencies>
    ...
    <dependency>
        <groupId>com.github.austinv11</groupId>
        <artifactId>Discord4J</artifactId>
        <version>2.10.1</version>
    </dependency>
</dependencies>
...

Wenn Sie es manuell löschen möchten, klicken Sie hier (https://discord4j.com/downloads.html).

Versuchen Sie es mit der Bibliothek

Anmeldung

DiscordChatService.java


public class DiscordChatService implements Listener {
    private final String Token = "API-Token erhalten";
    private IDiscordClient client;
    private IChannel chatChannel;

    //Fügen Sie eine Klasse, die PluginBase erbt, in den Konstruktor ein.
    //Dieses Mal verwende ich MyPlugin als Beispiel.
    public DiscordChatService(MyPlugin plugin) {
        this.login();

        Server.getInstance().getPluginManager().registerEvents(this, plugin);
    }

    private void login() {
        //Melden Sie sich mit dem von Discord erhaltenen API-Token an.
        this.client = new ClientBuilder().withToken(TOKEN).build();

        //Wenn ich das schreibe@EventSubscriber Ruft das angehängte Ereignis zurück.
        this.client.getDispatcher().registerListener(this);

        //Einloggen
        this.client.login();
    }
}

Implementieren Sie einen Rückruf zum Abschluss der Anmeldung

DiscordChatService.java


@EventSubscriber
public synchronized void onReady(ReadyEvent event) {
    Server.getInstance().getLogger().info("Bot hat sich angemeldet.");

    //Holen Sie sich den Kanal von Bot hier gepostet.
    this.chatChannel = this.client.getChannels().stream().filter(ch -> ch.getName().equals("chat")
        && ch.getCategory().getName().equals("SERVER")).findFirst().get();
}

Von hier aus das Hauptthema (Discord-> Server) Implementierung des Chats

DiscordChatService.java


@EventSubscriber
public synchronized void onMessage(MessageReceivedEvent event) throws RateLimitException, DiscordException, MissingPermissionsException {
    IMessage message = event.getMessage();
    IUser user = message.getAuthor();

    //Blockieren Sie den Bot-Chat.
    if (user.isBot()) return;

    //Holen Sie sich den Kanal aus der Nachricht.
    IChannel channel = message.getChannel();

    //Geben Sie Discord-Kanäle und -Kategorien an(Ohne sie erhalten Sie Nachrichten von allen Kanälen)
    //Sofern nicht anders angegeben, können Sie es löschen.
    if (channel.getCategory().getName().equals("SERVER")// "SERVER"Ist es eine Kategorie namens
            && channel.getName().equals("chat")) {// "chat"Ist es ein Kanal namens

        //Nachrichtentext.
        String mes = message.getContent();

        //Holen Sie sich den Benutzernamen.
        String name = user.getName();

        //Verketten Sie Zeichenfolgen und senden Sie den Chat auf dem Server.
        Server.getInstance().broadcastMessage("[" + name + "] " + mes);
    }
}

(Server-> Discord) Chat-Implementierung

Das war schwierig. Es gibt jedoch ein Problem mit diesem Code. Der Server friert kurz ein, da keine Chats asynchron gesendet werden.

DiscordChatService.java


@EventHandler
public void onPlayerChatEvent(PlayerChatEvent event) {
    Player player = event.getPlayer();
    String name = player.getName();
    String msg = "[" + name + "] " + event.getMessage();

    //Implementierung, die Ratenbeschränkungen berücksichtigt.(Wird ohne Erlaubnis erneut gesendet)
    //Wenn Sie es normal implementieren, erhalten Sie eine RateLimitException.
    RequestBuffer.request(() -> {
        //Auf Kanal posten.
        this.chatChannel.sendMessage(msg);
    });
}

Verbesserte Version

Hier kommt die Oreore-Implementierungsklasse

Oreore-Implementierungsklasse

ThreadPool.java



import java.util.HashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public final class ThreadPool {
    private static final HashMap<String, ActionThread> pool = new HashMap<>();

    static {
        registerThread("DiscordMassage");
    }

    public static void registerThread(String name) {
        Safe.nullCheck(name);

        ActionThread thread = new ActionThread(name);
        pool.put(name, thread);
        thread.start();
    }

    public static void addAction(String threadName, Runnable action) {
        ActionThread thread = pool.get(threadName);
        thread.addAction(action);
    }

    public static void close(String threadName) {
        ActionThread thread = pool.remove(threadName);
        thread.close();
    }

    private static class ActionThread extends Thread {
        private ConcurrentLinkedQueue<Runnable> actions = new ConcurrentLinkedQueue<>();
        private boolean isClose;

        public ActionThread(String name) {
            this.setName(name);
        }

        @Override
        public void run() {
            while (!this.isClose) {
                if (this.actions.isEmpty())
                    continue;
                this.actions.poll().run();
            }
        }

        public void addAction(Runnable action) {
            this.actions.offer(action);
        }

        public void close() {
            this.isClose = true;
        }
    }
}

Und verwenden Sie die Oleore-Implementierungsklasse

DiscordChatService.java


@EventHandler
public void onPlayerChatEvent(PlayerChatEvent event) {
    Player player = event.getPlayer();
    String name = player.getName();
    String msg = "[" + name + "] " + event.getMessage();

    //Verwenden Sie meine Implementierungsklasse
    ThreadPool.addAction("DiscordMassage", () -> {
        //Implementierung, die Ratenbeschränkungen berücksichtigt.(Wird ohne Erlaubnis erneut gesendet)
        RequestBuffer.request(() -> {
            //Auf Kanal posten.
            this.chatChannel.sendMessage(msg);
        });
    }
}

Verwenden Sie schwarze Magie, um das Discord 4J-Protokoll zu löschen

Weil es persönlich ein Hindernis war

DiscordChatService.java


public DiscordChatService(MyPlugin plugin) {
...
    try {
        Field f = Discord4J.class.getDeclaredField("LOGGER");//Holen Sie sich ein Feld namens Logger
        Field modifiersField = Field.class.getDeclaredField("modifiers");//Dunkle Klasse, die die Zugänglichkeit verwaltet
        modifiersField.setAccessible(true);
        modifiersField.setInt(f, f.getModifiers() & ~Modifier.PRIVATE & ~Modifier.FINAL);//Manipulationen
        f.set(null, new DummyLogger());//Stellen Sie einen Dummy-Logger ein
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }
}
Dummy-Klasse

DummyLogger


import org.slf4j.Logger;
import org.slf4j.Marker;

public class DummyLogger implements Logger {
    @Override
    public String getName() {
        return null;
    }

    @Override
    public boolean isTraceEnabled() {
        return false;
    }


    @Override
    public void trace(String s) {

    }

    @Override
    public void trace(String s, Object o) {

    }

    @Override
    public void trace(String s, Object o, Object o1) {

    }

    @Override
    public void trace(String s, Object... object) {

    }

    @Override
    public void trace(String s, Throwable throwable) {

    }

    @Override
    public boolean isTraceEnabled(Marker marker) {
        return false;
    }

    @Override
    public void trace(Marker marker, String s) {

    }

    @Override
    public void trace(Marker marker, String s, Object o) {

    }

    @Override
    public void trace(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void trace(Marker marker, String s, Object... object) {

    }

    @Override
    public void trace(Marker marker, String s, Throwable throwable) {

    }

    @Override
    public boolean isDebugEnabled() {
        return false;
    }

    @Override
    public void debug(String s) {

    }

    @Override
    public void debug(String s, Object o) {

    }

    @Override
    public void debug(String s, Object o, Object o1) {

    }

    @Override
    public void debug(String s, Object... object) {

    }

    @Override
    public void debug(String s, Throwable throwable) {

    }

    @Override
    public boolean isDebugEnabled(Marker marker) {
        return false;
    }

    @Override
    public void debug(Marker marker, String s) {

    }

    @Override
    public void debug(Marker marker, String s, Object o) {

    }

    @Override
    public void debug(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void debug(Marker marker, String s, Object... object) {

    }

    @Override
    public void debug(Marker marker, String s, Throwable throwable) {

    }

    @Override
    public boolean isInfoEnabled() {
        return false;
    }

    @Override
    public void info(String s) {

    }

    @Override
    public void info(String s, Object o) {

    }

    @Override
    public void info(String s, Object o, Object o1) {

    }

    @Override
    public void info(String s, Object... object) {

    }

    @Override
    public void info(String s, Throwable throwable) {

    }

    @Override
    public boolean isInfoEnabled(Marker marker) {
        return false;
    }

    @Override
    public void info(Marker marker, String s) {

    }

    @Override
    public void info(Marker marker, String s, Object o) {

    }

    @Override
    public void info(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void info(Marker marker, String s, Object... object) {

    }

    @Override
    public void info(Marker marker, String s, Throwable throwable) {

    }

    @Override
    public boolean isWarnEnabled() {
        return false;
    }

    @Override
    public void warn(String s) {

    }

    @Override
    public void warn(String s, Object o) {

    }

    @Override
    public void warn(String s, Object... object) {

    }

    @Override
    public void warn(String s, Object o, Object o1) {

    }

    @Override
    public void warn(String s, Throwable throwable) {

    }

    @Override
    public boolean isWarnEnabled(Marker marker) {
        return false;
    }

    @Override
    public void warn(Marker marker, String s) {

    }

    @Override
    public void warn(Marker marker, String s, Object o) {

    }

    @Override
    public void warn(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void warn(Marker marker, String s, Object... object) {

    }

    @Override
    public void warn(Marker marker, String s, Throwable throwable) {

    }

    @Override
    public boolean isErrorEnabled() {
        return false;
    }

    @Override
    public void error(String s) {

    }

    @Override
    public void error(String s, Object o) {

    }

    @Override
    public void error(String s, Object o, Object o1) {

    }

    @Override
    public void error(String s, Object... object) {

    }

    @Override
    public void error(String s, Throwable throwable) {

    }

    @Override
    public boolean isErrorEnabled(Marker marker) {
        return false;
    }

    @Override
    public void error(Marker marker, String s) {

    }

    @Override
    public void error(Marker marker, String s, Object o) {

    }

    @Override
    public void error(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void error(Marker marker, String s, Object... object) {

    }

    @Override
    public void error(Marker marker, String s, Throwable throwable) {

    }
}

Und Frieden ist gekommen ...

Zusammenfassung

Darüber hinaus ist es notwendig, Funktionen wie Längenbegrenzung und kollektive Chat-Übertragung zu implementieren, aber ich werde es schreiben, wenn es in Zukunft Zeit gibt.

Recommended Posts

Ich habe versucht, den Chat mit dem Minecraft-Server mit der Discord-API zu verknüpfen
Ich habe versucht, Animationen mit der Blazor + Canvas-API zu zeichnen
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, einen API-Server mit Go (Echo) x MySQL x Docker x Clean Architecture zu erstellen
Ich habe versucht, den Betrieb des gRPC-Servers mit grpcurl zu überprüfen
Ich habe versucht, mit Web Assembly zu beginnen
Ich habe versucht, die Stream-API zusammenzufassen
Ich habe versucht, eine Web-API zu erstellen, die mit Quarkus eine Verbindung zur Datenbank herstellt
Ich habe versucht, AdoptOpenJDK 11 (11.0.2) mit dem Docker-Image zu überprüfen
Ich habe versucht, eine Standardauthentifizierung mit Java durchzuführen
Ich habe versucht, die Federbeinkonfiguration mit Coggle zu verwalten
Ich habe versucht, Anmeldeinformationen mit JMX zu verwalten
Ich habe versucht, grafana und postgres [docker-compose] zu verknüpfen
Ich habe versucht, JavaFX und Spring Framework zu verknüpfen.
Ich habe versucht, einen Server mit Netty zu implementieren
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe versucht, ein Portfolio mit AWS, Docker, CircleCI, Laravel [mit Referenzlink] zu erstellen.
Ich habe versucht, was ich mit Stream leise versuchen wollte.
Ich habe versucht, das Hochladen von Dateien mit Spring MVC zu implementieren
Ich habe versucht, CSV mit Outsystems zu lesen und auszugeben
Ich habe versucht, TCP / IP + BIO mit JAVA zu implementieren
[Java 11] Ich habe versucht, Java auszuführen, ohne mit Javac zu kompilieren
Ich habe MySQL 5.7 mit Docker-Compose gestartet und versucht, eine Verbindung herzustellen
Ich habe versucht, mit Spring Data JPA zu beginnen
Ich habe versucht, Sterling Sort mit Java Collector zu implementieren
[Java] Ich habe versucht, die Yahoo API-Produktsuche zu implementieren
Ich habe versucht, den Betrieb der http-Anfrage (Put) mit dem Talented API Tester zu überprüfen
Ich habe versucht, eine Java EE-Anwendung mit OpenShift zu modernisieren.
Ich habe DI mit Ruby versucht
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit spiritueller Technik zu erhöhen
[Rails] Ich habe versucht, die Stapelverarbeitung mit der Rake-Task zu implementieren
Was ich mit der Redmine REST API süchtig gemacht habe
Ich habe UPSERT mit PostgreSQL ausprobiert.
API mit Spring + Vue.js verknüpfen
Ich habe BIND mit Docker ausprobiert
Ich habe versucht, yum-cron zu verifizieren
Ich habe versucht, mit Docker eine Padrino-Entwicklungsumgebung zu erstellen
Ich habe versucht, mit Swagger mit Spring Boot zu beginnen
Ich habe versucht, mit Ractor mehrere Objekte übergeben zu können
Ich habe versucht, das Problem der "mehrstufigen Auswahl" mit Ruby zu lösen
Ich habe versucht, mithilfe von JDBC Template mit Spring MVC eine Verbindung zu MySQL herzustellen
Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren
Ich habe versucht, mit Eclipse + Tomcat eine http2-Entwicklungsumgebung zu erstellen
Ich habe versucht, eine flexible ODER-Zuordnung mit MyBatis Dynamic SQL zu implementieren
Ich habe versucht, Ruby's Float (arg, Ausnahme: true) mit Builtin neu zu implementieren
Ich habe versucht, eine Android-Anwendung mit MVC zu erstellen (Java)
Ich habe versucht, mit Rails eine Gruppenfunktion (Bulletin Board) zu erstellen
Ich habe versucht, C # (Indexer) zu kauen.
Ich habe versucht, JOOQ mit Gradle zu verwenden
Ich habe eine morphologische Analyse mit MeCab versucht
Ich habe versucht, die Unterstützung für iOS 14 zusammenzufassen
Ich habe versucht, UDP mit Java zu kommunizieren
Ich habe versucht, die Methode zu erklären