** Please note that it may be difficult to read because it is the first post on qiita. ** **
** Please note that we will not introduce how to get the API token of Discord Bot this time. ** **
Minecraft BE server software With the plugin extension of Nukkit I wrote up to the implementation of the function to display the chat in the server in real time with Discord Bot.
Add these to pom.xml.
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>
...
If you want to drop it manually, click here (https://discord4j.com/downloads.html)
DiscordChatService.java
public class DiscordChatService implements Listener {
private final String Token = "Obtained API token";
private IDiscordClient client;
private IChannel chatChannel;
//Put a class that inherits PluginBase into the constructor.
//This time, I use MyPlugin as an example.
public DiscordChatService(MyPlugin plugin) {
this.login();
Server.getInstance().getPluginManager().registerEvents(this, plugin);
}
private void login() {
//Log in using the API token obtained from Discord.
this.client = new ClientBuilder().withToken(TOKEN).build();
//When I write this@EventSubscriber Calls back the event that was attached.
this.client.getDispatcher().registerListener(this);
//Login
this.client.login();
}
}
DiscordChatService.java
@EventSubscriber
public synchronized void onReady(ReadyEvent event) {
Server.getInstance().getLogger().info("The bot has logged in.");
//Get the channel posted by the bot here.
this.chatChannel = this.client.getChannels().stream().filter(ch -> ch.getName().equals("chat")
&& ch.getCategory().getName().equals("SERVER")).findFirst().get();
}
DiscordChatService.java
@EventSubscriber
public synchronized void onMessage(MessageReceivedEvent event) throws RateLimitException, DiscordException, MissingPermissionsException {
IMessage message = event.getMessage();
IUser user = message.getAuthor();
//Block bot chat.
if (user.isBot()) return;
//Get the channel from the message.
IChannel channel = message.getChannel();
//Specify Discord channels and categories(Without it, you will receive messages from all channels)
//Unless otherwise specified, you can delete it.
if (channel.getCategory().getName().equals("SERVER")// "SERVER"Is it a category named
&& channel.getName().equals("chat")) {// "chat"Is it a channel named
//Message body.
String mes = message.getContent();
//Get the user name.
String name = user.getName();
//Concatenate strings and broadcast chat within the server.
Server.getInstance().broadcastMessage("[" + name + "] " + mes);
}
}
This was difficult. However, there is a problem with this code. The server freezes momentarily because chats are not sent asynchronously.
DiscordChatService.java
@EventHandler
public void onPlayerChatEvent(PlayerChatEvent event) {
Player player = event.getPlayer();
String name = player.getName();
String msg = "[" + name + "] " + event.getMessage();
//Implementation that takes rate limiting into consideration.(Will resend without permission)
//If you implement it normally, you will get a RateLimitException.
RequestBuffer.request(() -> {
//Post to the channel.
this.chatChannel.sendMessage(msg);
});
}
Here comes the Oreore implementation class
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;
}
}
}
And use the oleore implementation class
DiscordChatService.java
@EventHandler
public void onPlayerChatEvent(PlayerChatEvent event) {
Player player = event.getPlayer();
String name = player.getName();
String msg = "[" + name + "] " + event.getMessage();
//Use my implementation class
ThreadPool.addAction("DiscordMassage", () -> {
//Implementation that takes rate limiting into consideration.(Will resend without permission)
RequestBuffer.request(() -> {
//Post to the channel.
this.chatChannel.sendMessage(msg);
});
}
}
Because it was an obstacle personally
DiscordChatService.java
public DiscordChatService(MyPlugin plugin) {
...
try {
Field f = Discord4J.class.getDeclaredField("LOGGER");//Get a field called Logger
Field modifiersField = Field.class.getDeclaredField("modifiers");//Darkness class that manages accessibility
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~Modifier.PRIVATE & ~Modifier.FINAL);//Tampering
f.set(null, new DummyLogger());//Set a dummy Logger
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
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) {
}
}
And peace has come ...
In addition to this, it is necessary to implement functions such as length limit and batch chat transmission, but I will write it if there is time in the future.
Recommended Posts