Added reset command and fixes #69
5 changed files with 155 additions and 67 deletions
|
@ -1,6 +1,5 @@
|
||||||
package buttondevteam.discordplugin;
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import sx.blah.discord.util.EmbedBuilder;
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
import sx.blah.discord.util.RequestBuffer;
|
import sx.blah.discord.util.RequestBuffer;
|
||||||
|
@ -9,6 +8,7 @@ import sx.blah.discord.util.RequestBuffer.IVoidRequest;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
public final class DPUtils {
|
public final class DPUtils {
|
||||||
|
|
||||||
|
@ -39,18 +39,13 @@ public final class DPUtils {
|
||||||
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
|
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T> T perform(IRequest<T> action, long timeout, TimeUnit unit) {
|
public static <T> T perform(IRequest<T> action, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
||||||
if (DiscordPlugin.SafeMode)
|
if (DiscordPlugin.SafeMode)
|
||||||
return null;
|
return null;
|
||||||
if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <--
|
if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <--
|
||||||
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
|
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
|
||||||
try {
|
return RequestBuffer.request(action).get(timeout, unit); // Let the pros handle this
|
||||||
return RequestBuffer.request(action).get(timeout, unit); // Let the pros handle this
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("Couldn't perform Discord action!", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +55,7 @@ public final class DPUtils {
|
||||||
public static <T> T perform(IRequest<T> action) {
|
public static <T> T perform(IRequest<T> action) {
|
||||||
if (DiscordPlugin.SafeMode)
|
if (DiscordPlugin.SafeMode)
|
||||||
return null;
|
return null;
|
||||||
if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <--
|
if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <--
|
||||||
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
|
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
|
||||||
return RequestBuffer.request(action).get(); // Let the pros handle this
|
return RequestBuffer.request(action).get(); // Let the pros handle this
|
||||||
|
@ -72,7 +67,7 @@ public final class DPUtils {
|
||||||
public static Void perform(IVoidRequest action) {
|
public static Void perform(IVoidRequest action) {
|
||||||
if (DiscordPlugin.SafeMode)
|
if (DiscordPlugin.SafeMode)
|
||||||
return null;
|
return null;
|
||||||
if (Thread.currentThread() == DiscordPlugin.mainThread)
|
if (Bukkit.isPrimaryThread())
|
||||||
throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
return RequestBuffer.request(action).get(); // Let the pros handle this
|
return RequestBuffer.request(action).get(); // Let the pros handle this
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package buttondevteam.discordplugin;
|
||||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||||
import buttondevteam.discordplugin.listeners.*;
|
import buttondevteam.discordplugin.listeners.*;
|
||||||
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
|
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
|
||||||
|
import buttondevteam.discordplugin.mccommands.ResetMCCommand;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.lib.chat.Channel;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
|
@ -15,6 +16,7 @@ import com.google.gson.JsonParser;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
@ -35,12 +37,12 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
||||||
private static boolean stop = false;
|
private static boolean stop = false;
|
||||||
static Thread mainThread;
|
|
||||||
public static IDiscordClient dc;
|
public static IDiscordClient dc;
|
||||||
public static DiscordPlugin plugin;
|
public static DiscordPlugin plugin;
|
||||||
public static boolean SafeMode = true;
|
public static boolean SafeMode = true;
|
||||||
|
@ -50,6 +52,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
stop = false; //If not the first time
|
||||||
try {
|
try {
|
||||||
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
||||||
try {
|
try {
|
||||||
|
@ -67,7 +70,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
||||||
dc = cb.login();
|
dc = cb.login();
|
||||||
dc.getDispatcher().registerListener(this);
|
dc.getDispatcher().registerListener(this);
|
||||||
mainThread = Thread.currentThread();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
@ -103,7 +105,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
}
|
}
|
||||||
if (mainServer == null || devServer == null)
|
if (mainServer == null || devServer == null)
|
||||||
return; // Retry
|
return; // Retry
|
||||||
if (!TBMCCoreAPI.IsTestServer()) {
|
if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable()
|
||||||
botchannel = mainServer.getChannelByID(209720707188260864L); // bot
|
botchannel = mainServer.getChannelByID(209720707188260864L); // bot
|
||||||
annchannel = mainServer.getChannelByID(126795071927353344L); // announcements
|
annchannel = mainServer.getChannelByID(126795071927353344L); // announcements
|
||||||
genchannel = mainServer.getChannelByID(125813020357165056L); // general
|
genchannel = mainServer.getChannelByID(125813020357165056L); // general
|
||||||
|
@ -155,7 +157,10 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscordCommandBase.registerCommands();
|
DiscordCommandBase.registerCommands();
|
||||||
if (getConfig().getBoolean("serverup", false)) {
|
if (ResetMCCommand.resetting)
|
||||||
|
ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.CYAN)
|
||||||
|
.withTitle("Discord plugin restarted - chat connected.").build()); //Really important to note the chat, hmm
|
||||||
|
else if (getConfig().getBoolean("serverup", false)) {
|
||||||
ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.YELLOW)
|
ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.YELLOW)
|
||||||
.withTitle("Server recovered from a crash - chat connected.").build());
|
.withTitle("Server recovered from a crash - chat connected.").build());
|
||||||
val thr = new Throwable(
|
val thr = new Throwable(
|
||||||
|
@ -165,6 +170,9 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
} else
|
} else
|
||||||
ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.GREEN)
|
ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.GREEN)
|
||||||
.withTitle("Server started - chat connected.").build());
|
.withTitle("Server started - chat connected.").build());
|
||||||
|
|
||||||
|
ResetMCCommand.resetting = false; //This is the last event handling this flag
|
||||||
|
|
||||||
getConfig().set("serverup", true);
|
getConfig().set("serverup", true);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
DPUtils.performNoWait(() -> {
|
DPUtils.performNoWait(() -> {
|
||||||
|
@ -212,14 +220,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
||||||
new Thread(this::AnnouncementGetterThreadMethod).start();
|
new Thread(this::AnnouncementGetterThreadMethod).start();
|
||||||
setupProviders();
|
setupProviders();
|
||||||
/*
|
|
||||||
* IDiscordOAuth doa = new DiscordOAuthBuilder(dc).withClientID("226443037893591041") .withClientSecret(getConfig().getString("appsecret")) .withRedirectUrl("https://" +
|
|
||||||
* (TBMCCoreAPI.IsTestServer() ? "localhost" : "server.figytuna.com") + ":8081/callback") .withScopes(Scope.IDENTIFY).withHttpServerOptions(new HttpServerOptions().setPort(8081))
|
|
||||||
* .withSuccessHandler((rc, user) -> { rc.response().headers().add("Location", "https://" + (TBMCCoreAPI.IsTestServer() ? "localhost" : "server.figytuna.com") + ":8080/login?type=discord&"
|
|
||||||
* + rc.request().query()); rc.response().setStatusCode(303); rc.response().end("Redirecting"); rc.response().close(); }).withFailureHandler(rc -> { rc.response().headers().add("Location",
|
|
||||||
* "https://" + (TBMCCoreAPI.IsTestServer() ? "localhost" : "server.figytuna.com") + ":8080/login?type=discord&" + rc.request().query()); rc.response().setStatusCode(303);
|
|
||||||
* rc.response().end("Redirecting"); rc.response().close(); }).build(); getLogger().info("Auth URL: " + doa.buildAuthUrl());
|
|
||||||
*/
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e);
|
TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e);
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
stop = true;
|
stop = true;
|
||||||
for (val entry : MCChatListener.ConnectedSenders.entrySet())
|
for (val entry : MCChatListener.ConnectedSenders.entrySet())
|
||||||
MCListener.callEventExcludingSome(new PlayerQuitEvent(entry.getValue(), ""));
|
MCListener.callEventExcludingSome(new PlayerQuitEvent(entry.getValue(), ""));
|
||||||
|
MCChatListener.ConnectedSenders.clear();
|
||||||
getConfig().set("lastannouncementtime", lastannouncementtime);
|
getConfig().set("lastannouncementtime", lastannouncementtime);
|
||||||
getConfig().set("lastseentime", lastseentime);
|
getConfig().set("lastseentime", lastseentime);
|
||||||
getConfig().set("serverup", false);
|
getConfig().set("serverup", false);
|
||||||
|
@ -260,25 +261,37 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfig();
|
saveConfig();
|
||||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannelWait(ch, "",
|
MCChatListener.forAllMCChat(ch -> {
|
||||||
new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
|
try {
|
||||||
.withTitle(Restart ? "Server restarting" : "Server stopping")
|
if (ResetMCCommand.resetting)
|
||||||
.withDescription(
|
DiscordPlugin.sendMessageToChannelWait(ch, "",
|
||||||
Bukkit.getOnlinePlayers().size() > 0
|
new EmbedBuilder().withColor(Color.ORANGE).withTitle("Discord plugin restarting").build());
|
||||||
? (DPUtils
|
else
|
||||||
.sanitizeString(Bukkit.getOnlinePlayers().stream()
|
DiscordPlugin.sendMessageToChannelWait(ch, "",
|
||||||
.map(p -> p.getDisplayName()).collect(Collectors.joining(", ")))
|
new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
|
||||||
+ (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ")
|
.withTitle(Restart ? "Server restarting" : "Server stopping")
|
||||||
+ "asked *politely* to leave the server for a bit.")
|
.withDescription(
|
||||||
: "")
|
Bukkit.getOnlinePlayers().size() > 0
|
||||||
.build(), 5, TimeUnit.SECONDS));
|
? (DPUtils
|
||||||
|
.sanitizeString(Bukkit.getOnlinePlayers().stream()
|
||||||
|
.map(Player::getDisplayName).collect(Collectors.joining(", ")))
|
||||||
|
+ (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ")
|
||||||
|
+ "asked *politely* to leave the server for a bit.")
|
||||||
|
: "")
|
||||||
|
.build(), 5, TimeUnit.SECONDS);
|
||||||
|
} catch (TimeoutException | InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
ChromaBot.getInstance().updatePlayerList();
|
ChromaBot.getInstance().updatePlayerList();
|
||||||
try {
|
try {
|
||||||
SafeMode = true; // Stop interacting with Discord
|
SafeMode = true; // Stop interacting with Discord
|
||||||
MCChatListener.stop();
|
MCChatListener.stop(true);
|
||||||
ChromaBot.delete();
|
ChromaBot.delete();
|
||||||
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
||||||
dc.logout();
|
dc.logout();
|
||||||
|
mainServer = devServer = null; //Fetch servers and channels again
|
||||||
|
sent = false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e);
|
TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e);
|
||||||
}
|
}
|
||||||
|
@ -359,26 +372,30 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendMessageToChannel(IChannel channel, String message, EmbedObject embed) {
|
public static void sendMessageToChannel(IChannel channel, String message, EmbedObject embed) {
|
||||||
sendMessageToChannel(channel, message, embed, false);
|
try {
|
||||||
|
sendMessageToChannel(channel, message, embed, false);
|
||||||
|
} catch (TimeoutException | InterruptedException e) {
|
||||||
|
e.printStackTrace(); //Shouldn't happen, as we're not waiting on the result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMessage sendMessageToChannelWait(IChannel channel, String message) {
|
public static IMessage sendMessageToChannelWait(IChannel channel, String message) throws TimeoutException, InterruptedException {
|
||||||
return sendMessageToChannelWait(channel, message, null);
|
return sendMessageToChannelWait(channel, message, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed) {
|
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed) throws TimeoutException, InterruptedException {
|
||||||
return sendMessageToChannel(channel, message, embed, true);
|
return sendMessageToChannel(channel, message, embed, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed, long timeout, TimeUnit unit) {
|
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
||||||
return sendMessageToChannel(channel, message, embed, true, timeout, unit);
|
return sendMessageToChannel(channel, message, embed, true, timeout, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) {
|
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) throws TimeoutException, InterruptedException {
|
||||||
return sendMessageToChannel(channel, message, embed, wait, -1, null);
|
return sendMessageToChannel(channel, message, embed, wait, -1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) {
|
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
||||||
if (message.length() > 1980) {
|
if (message.length() > 1980) {
|
||||||
message = message.substring(0, 1980);
|
message = message.substring(0, 1980);
|
||||||
Bukkit.getLogger()
|
Bukkit.getLogger()
|
||||||
|
@ -404,6 +421,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
DPUtils.performNoWait(r);
|
DPUtils.performNoWait(r);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} catch (TimeoutException | InterruptedException e) {
|
||||||
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Bukkit.getLogger().warning(
|
Bukkit.getLogger().warning(
|
||||||
"Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message);
|
"Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class ConnectCommand extends DiscordCommandBase {
|
||||||
@Override
|
@Override
|
||||||
public boolean run(IMessage message, String args) {
|
public boolean run(IMessage message, String args) {
|
||||||
if (args.length() == 0)
|
if (args.length() == 0)
|
||||||
return true;
|
return false;
|
||||||
if (args.contains(" ")) {
|
if (args.contains(" ")) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||||
"Too many arguments.\nUsage: connect <Minecraftname>");
|
"Too many arguments.\nUsage: connect <Minecraftname>");
|
||||||
|
|
|
@ -7,10 +7,12 @@ import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.lib.chat.Channel;
|
||||||
|
import buttondevteam.lib.chat.ChatMessage;
|
||||||
import buttondevteam.lib.chat.ChatRoom;
|
import buttondevteam.lib.chat.ChatRoom;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
import com.vdurmont.emoji.EmojiParser;
|
import com.vdurmont.emoji.EmojiParser;
|
||||||
|
import io.netty.util.collection.LongObjectHashMap;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
@ -37,6 +39,7 @@ import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -52,7 +55,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
|
|
||||||
@EventHandler // Minecraft
|
@EventHandler // Minecraft
|
||||||
public void onMCChat(TBMCChatEvent ev) {
|
public void onMCChat(TBMCChatEvent ev) {
|
||||||
if (ev.isCancelled())
|
if (DiscordPlugin.SafeMode || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown
|
||||||
return;
|
return;
|
||||||
sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now()));
|
sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now()));
|
||||||
if (sendtask != null)
|
if (sendtask != null)
|
||||||
|
@ -70,15 +73,10 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
try {
|
try {
|
||||||
TBMCChatEvent e;
|
TBMCChatEvent e;
|
||||||
Instant time;
|
Instant time;
|
||||||
try {
|
val se = sendevents.take(); // Wait until an element is available
|
||||||
val se = sendevents.take(); // Wait until an element is available
|
e = se.getKey();
|
||||||
e = se.getKey();
|
time = se.getValue();
|
||||||
time = se.getValue();
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
sendtask.cancel();
|
|
||||||
sendtask = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String authorPlayer = "[" + DPUtils.sanitizeString(e.getChannel().DisplayName) + "] " //
|
final String authorPlayer = "[" + DPUtils.sanitizeString(e.getChannel().DisplayName) + "] " //
|
||||||
+ (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") //
|
+ (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") //
|
||||||
+ (DPUtils.sanitizeString(e.getSender() instanceof Player //
|
+ (DPUtils.sanitizeString(e.getSender() instanceof Player //
|
||||||
|
@ -101,7 +99,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
// embed.withFooterText(e.getChannel().DisplayName);
|
// embed.withFooterText(e.getChannel().DisplayName);
|
||||||
embed.withTimestamp(time);
|
embed.withTimestamp(time);
|
||||||
final long nanoTime = System.nanoTime();
|
final long nanoTime = System.nanoTime();
|
||||||
Consumer<LastMsgData> doit = lastmsgdata -> {
|
InterruptibleConsumer<LastMsgData> doit = lastmsgdata -> {
|
||||||
final EmbedObject embedObject = embed.build();
|
final EmbedObject embedObject = embed.build();
|
||||||
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
||||||
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
||||||
|
@ -140,17 +138,22 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
}
|
}
|
||||||
|
|
||||||
val iterator = lastmsgCustom.iterator();
|
val iterator = lastmsgCustom.iterator();
|
||||||
while (iterator.hasNext()) { //TODO: Add cmd to fix mcchat
|
while (iterator.hasNext()) {
|
||||||
val lmd = iterator.next();
|
val lmd = iterator.next();
|
||||||
if ((e.isFromcmd() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
|
if ((e.isFromcmd() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
|
||||||
&& e.getChannel().ID.equals(lmd.mcchannel.ID)) //If it's from a command, the command msg has been deleted, so we need to send it
|
&& e.getChannel().ID.equals(lmd.mcchannel.ID) //If it's from a command, the command msg has been deleted, so we need to send it
|
||||||
if (e.shouldSendTo(lmd.dcp) && e.getGroupID().equals(lmd.groupID)) //Check original user's permissions
|
&& e.getGroupID().equals(lmd.groupID)) { //Check if this is the group we want to test - #58
|
||||||
|
if (e.shouldSendTo(lmd.dcp)) //Check original user's permissions
|
||||||
doit.accept(lmd);
|
doit.accept(lmd);
|
||||||
else {
|
else {
|
||||||
iterator.remove(); //If the user no longer has permission, remove the connection
|
iterator.remove(); //If the user no longer has permission, remove the connection
|
||||||
DiscordPlugin.sendMessageToChannel(lmd.channel, "The user no longer has permission to view the channel, connection removed.");
|
DiscordPlugin.sendMessageToChannel(lmd.channel, "The user no longer has permission to view the channel, connection removed.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException ex) { //Stop if interrupted anywhere
|
||||||
|
sendtask.cancel();
|
||||||
|
sendtask = null;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
TBMCCoreAPI.SendException("Error while sending message to Discord!", ex);
|
TBMCCoreAPI.SendException("Error while sending message to Discord!", ex);
|
||||||
}
|
}
|
||||||
|
@ -215,6 +218,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
* Used for town or nation chats or anything else
|
* Used for town or nation chats or anything else
|
||||||
*/
|
*/
|
||||||
private static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
private static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
||||||
|
private static LongObjectHashMap<IMessage> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
|
||||||
|
|
||||||
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
|
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
|
||||||
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
|
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
|
||||||
|
@ -232,6 +236,8 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, ""));
|
MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!start)
|
||||||
|
lastmsgfromd.remove(channel.getLongID());
|
||||||
return start //
|
return start //
|
||||||
? lastmsgPerUser.add(new LastMsgData(channel, user, dp)) // Doesn't support group DMs
|
? lastmsgPerUser.add(new LastMsgData(channel, user, dp)) // Doesn't support group DMs
|
||||||
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||||
|
@ -272,6 +278,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean removeCustomChat(IChannel channel) {
|
public static boolean removeCustomChat(IChannel channel) {
|
||||||
|
lastmsgfromd.remove(channel.getLongID());
|
||||||
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,14 +343,40 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
.map(data -> data.channel).forEach(action);
|
.map(data -> data.channel).forEach(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void stop() {
|
/**
|
||||||
|
* Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode.
|
||||||
|
*
|
||||||
|
* @param wait Wait 5 seconds for the threads to stop
|
||||||
|
*/
|
||||||
|
public static void stop(boolean wait) {
|
||||||
if (sendthread != null) sendthread.interrupt();
|
if (sendthread != null) sendthread.interrupt();
|
||||||
if (recthread != null) recthread.interrupt();
|
if (recthread != null) recthread.interrupt();
|
||||||
|
try {
|
||||||
|
if (sendthread != null) {
|
||||||
|
sendthread.interrupt();
|
||||||
|
if (wait)
|
||||||
|
sendthread.join(5000);
|
||||||
|
}
|
||||||
|
if (recthread != null) {
|
||||||
|
recthread.interrupt();
|
||||||
|
if (wait)
|
||||||
|
recthread.join(5000);
|
||||||
|
}
|
||||||
|
lastmsgdata = null;
|
||||||
|
lastmsgPerUser.clear();
|
||||||
|
lastmsgCustom.clear();
|
||||||
|
lastmsgfromd.clear();
|
||||||
|
ConnectedSenders.clear();
|
||||||
|
lastlist = lastlistp = ListC = 0;
|
||||||
|
UnconnectedSenders.clear();
|
||||||
|
recthread = sendthread = null;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace(); //This thread shouldn't be interrupted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BukkitTask rectask;
|
private BukkitTask rectask;
|
||||||
private LinkedBlockingQueue<MessageReceivedEvent> recevents = new LinkedBlockingQueue<>();
|
private LinkedBlockingQueue<MessageReceivedEvent> recevents = new LinkedBlockingQueue<>();
|
||||||
private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks
|
|
||||||
private Runnable recrun;
|
private Runnable recrun;
|
||||||
private static Thread recthread;
|
private static Thread recthread;
|
||||||
|
|
||||||
|
@ -478,10 +511,11 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
|
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
|
||||||
} else { // Send single message
|
} else { // Send single message
|
||||||
final String msg = event.getMessage().getContent().substring(spi + 2);
|
final String msg = event.getMessage().getContent().substring(spi + 2);
|
||||||
|
val cmb = ChatMessage.builder(chc, dsender, user, getChatMessage.apply(msg)).fromCommand(true);
|
||||||
if (clmd == null)
|
if (clmd == null)
|
||||||
TBMCChatAPI.SendChatMessage(chc, dsender, getChatMessage.apply(msg), true);
|
TBMCChatAPI.SendChatMessage(cmb.build());
|
||||||
else
|
else
|
||||||
TBMCChatAPI.SendChatMessageDontCheckSender(chc, dsender, getChatMessage.apply(msg), true, clmd.dcp);
|
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build());
|
||||||
react = true;
|
react = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,23 +529,25 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||||
: dsender.getName()) + " pinned a message on Discord.");
|
: dsender.getName()) + " pinned a message on Discord.");
|
||||||
else {
|
else {
|
||||||
|
val cmb = ChatMessage.builder(dsender.getMcchannel(), dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
||||||
if (clmd != null)
|
if (clmd != null)
|
||||||
TBMCChatAPI.SendChatMessageDontCheckSender(clmd.mcchannel, dsender, getChatMessage.apply(dmessage), false, clmd.dcp);
|
TBMCChatAPI.SendChatMessage(cmb.channel(clmd.mcchannel).permCheck(clmd.dcp).build());
|
||||||
else
|
else
|
||||||
TBMCChatAPI.SendChatMessage(dsender.getMcchannel(), dsender, getChatMessage.apply(dmessage));
|
TBMCChatAPI.SendChatMessage(cmb.build());
|
||||||
react = true;
|
react = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (react) {
|
if (react) {
|
||||||
try {
|
try {
|
||||||
if (lastmsgfromd != null) {
|
val lmfd = lastmsgfromd.get(event.getChannel().getLongID());
|
||||||
DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(),
|
if (lmfd != null) {
|
||||||
|
DPUtils.perform(() -> lmfd.removeReaction(DiscordPlugin.dc.getOurUser(),
|
||||||
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
|
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
||||||
}
|
}
|
||||||
lastmsgfromd = event.getMessage();
|
lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage());
|
||||||
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -546,7 +582,8 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
cmd = dmessage.substring(0, index);
|
cmd = dmessage.substring(0, index);
|
||||||
for (Channel channel : Channel.getChannels()) {
|
for (Channel channel : Channel.getChannels()) {
|
||||||
if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) {
|
if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) {
|
||||||
TBMCChatAPI.SendChatMessage(channel, dsender, dmessage.substring(index + 1));
|
val dp = DiscordPlayer.getUser(dsender.getUser().getStringID(), DiscordPlayer.class);
|
||||||
|
TBMCChatAPI.SendChatMessage(ChatMessage.builder(channel, dsender, dp, dmessage.substring(index + 1)).build());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,4 +606,9 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
return Optional.of(dsender);
|
return Optional.of(dsender);
|
||||||
}).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
}).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
private interface InterruptibleConsumer<T> {
|
||||||
|
void accept(T value) throws TimeoutException, InterruptedException;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package buttondevteam.discordplugin.mccommands;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
@CommandClass(path = "discord reset", modOnly = true)
|
||||||
|
public class ResetMCCommand extends TBMCCommandBase { //Not player-only, so not using DiscordMCCommandBase
|
||||||
|
public static boolean resetting = false;
|
||||||
|
@Override
|
||||||
|
public boolean OnCommand(CommandSender sender, String s, String[] strings) {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
|
||||||
|
resetting = true; //Turned off after sending enable message (ReadyEvent)
|
||||||
|
sender.sendMessage("§bDisabling DiscordPlugin...");
|
||||||
|
Bukkit.getPluginManager().disablePlugin(DiscordPlugin.plugin);
|
||||||
|
sender.sendMessage("§bEnabling DiscordPlugin...");
|
||||||
|
Bukkit.getPluginManager().enablePlugin(DiscordPlugin.plugin);
|
||||||
|
sender.sendMessage("§bReset finished!");
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] GetHelpText(String s) {
|
||||||
|
return new String[]{ //
|
||||||
|
"§6---- Reset ChromaBot ----", //
|
||||||
|
"This command disables and then enables the plugin." //
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue