Waiting less on MC command responses, some fixes #88
14 changed files with 726 additions and 678 deletions
19
.editorconfig
Normal file
19
.editorconfig
Normal file
|
@ -0,0 +1,19 @@
|
|||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = false
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
|
||||
[{*.yml, *.yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.architecture.IHaveConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IIDLinkedObject;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
import sx.blah.discord.util.RequestBuffer;
|
||||
import sx.blah.discord.util.RequestBuffer.IRequest;
|
||||
|
@ -103,4 +107,18 @@ public final class DPUtils {
|
|||
return DiscordPlugin.plugin.getLogger();
|
||||
}
|
||||
|
||||
public static ConfigData<IChannel> channelData(IHaveConfig config, String key, long defID) {
|
||||
return config.getDataPrimDef(key, defID, id -> DiscordPlugin.dc.getChannelByID((long) id), IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mentions the <b>bot channel</b>. Useful for help texts.
|
||||
*
|
||||
* @return The string for mentioning the channel
|
||||
*/
|
||||
public static String botmention() {
|
||||
if (DiscordPlugin.plugin == null) return "#bot";
|
||||
return DiscordPlugin.plugin.CommandChannel().get().mention();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,450 +1,460 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||
import buttondevteam.discordplugin.exceptions.ExceptionListenerModule;
|
||||
import buttondevteam.discordplugin.listeners.CommonListeners;
|
||||
import buttondevteam.discordplugin.listeners.MCListener;
|
||||
import buttondevteam.discordplugin.mcchat.*;
|
||||
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
|
||||
import buttondevteam.discordplugin.mccommands.ResetMCCommand;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import lombok.val;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import sx.blah.discord.api.ClientBuilder;
|
||||
import sx.blah.discord.api.IDiscordClient;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
import sx.blah.discord.handle.impl.events.ReadyEvent;
|
||||
import sx.blah.discord.handle.impl.obj.ReactionEmoji;
|
||||
import sx.blah.discord.handle.obj.*;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
import sx.blah.discord.util.RequestBuffer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent> {
|
||||
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
||||
private static boolean stop = false;
|
||||
public static IDiscordClient dc;
|
||||
public static DiscordPlugin plugin;
|
||||
public static boolean SafeMode = true;
|
||||
public static List<String> GameRoles;
|
||||
|
||||
public ConfigData<Character> Prefix() {
|
||||
return getData("prefix", '/');
|
||||
}
|
||||
|
||||
public static char getPrefix() {
|
||||
if (plugin == null) return '/';
|
||||
return plugin.Prefix().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pluginEnable() {
|
||||
stop = false; //If not the first time
|
||||
try {
|
||||
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
||||
plugin = this;
|
||||
lastannouncementtime = getConfig().getLong("lastannouncementtime");
|
||||
lastseentime = getConfig().getLong("lastseentime");
|
||||
ClientBuilder cb = new ClientBuilder();
|
||||
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
||||
dc = cb.login();
|
||||
dc.getDispatcher().registerListener(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static IChannel botchannel;
|
||||
public static IChannel annchannel;
|
||||
public static IChannel genchannel;
|
||||
public static IChannel chatchannel;
|
||||
public static IChannel botroomchannel;
|
||||
public static IChannel modlogchannel;
|
||||
/**
|
||||
* Don't send messages, just receive, the same channel is used when testing
|
||||
*/
|
||||
public static IChannel officechannel;
|
||||
public static IChannel updatechannel;
|
||||
public static IChannel devofficechannel;
|
||||
public static IGuild mainServer;
|
||||
public static IGuild devServer;
|
||||
|
||||
private static volatile BukkitTask task;
|
||||
private static volatile boolean sent = false;
|
||||
|
||||
@Override
|
||||
public void handle(ReadyEvent event) {
|
||||
try {
|
||||
dc.changePresence(StatusType.DND, ActivityType.PLAYING, "booting");
|
||||
task = Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
|
||||
if (mainServer == null || devServer == null) {
|
||||
mainServer = event.getClient().getGuildByID(125813020357165056L);
|
||||
devServer = event.getClient().getGuildByID(219529124321034241L);
|
||||
}
|
||||
if (mainServer == null || devServer == null)
|
||||
return; // Retry
|
||||
if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable()
|
||||
botchannel = mainServer.getChannelByID(209720707188260864L); // bot
|
||||
annchannel = mainServer.getChannelByID(126795071927353344L); // announcements
|
||||
genchannel = mainServer.getChannelByID(125813020357165056L); // general
|
||||
chatchannel = mainServer.getChannelByID(249663564057411596L); // minecraft_chat
|
||||
botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room
|
||||
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
|
||||
updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates
|
||||
devofficechannel = officechannel; // developers-office
|
||||
modlogchannel = mainServer.getChannelByID(283840717275791360L); // modlog
|
||||
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Chromacraft");
|
||||
} else {
|
||||
botchannel = devServer.getChannelByID(239519012529111040L); // bot-room
|
||||
annchannel = botchannel; // bot-room
|
||||
genchannel = botchannel; // bot-room
|
||||
botroomchannel = botchannel;// bot-room
|
||||
chatchannel = botchannel;// bot-room
|
||||
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
|
||||
updatechannel = botchannel;
|
||||
devofficechannel = botchannel;// bot-room
|
||||
modlogchannel = botchannel; // bot-room
|
||||
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing");
|
||||
}
|
||||
if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null
|
||||
|| chatchannel == null || officechannel == null || updatechannel == null)
|
||||
return; // Retry
|
||||
SafeMode = false;
|
||||
if (task != null)
|
||||
task.cancel();
|
||||
if (!sent) {
|
||||
new ChromaBot(this).updatePlayerList();
|
||||
GameRoles = mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList());
|
||||
|
||||
val chcons = getConfig().getConfigurationSection("chcons");
|
||||
if (chcons != null) {
|
||||
val chconkeys = chcons.getKeys(false);
|
||||
for (val chconkey : chconkeys) {
|
||||
val chcon = chcons.getConfigurationSection(chconkey);
|
||||
val mcch = Channel.getChannels().stream().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny();
|
||||
val ch = dc.getChannelByID(chcon.getLong("chid"));
|
||||
val did = chcon.getLong("did");
|
||||
val user = dc.fetchUser(did);
|
||||
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
||||
val groupid = chcon.getString("groupid");
|
||||
val toggles = chcon.getInt("toggles");
|
||||
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
|
||||
continue;
|
||||
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
|
||||
}
|
||||
}
|
||||
|
||||
DiscordCommandBase.registerCommands();
|
||||
if (ResetMCCommand.resetting)
|
||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN)
|
||||
.withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm
|
||||
else if (getConfig().getBoolean("serverup", false)) {
|
||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.YELLOW)
|
||||
.withTitle("Server recovered from a crash - chat connected.").build(), ChannelconBroadcast.RESTART);
|
||||
val thr = new Throwable(
|
||||
"The server shut down unexpectedly. See the log of the previous run for more details.");
|
||||
thr.setStackTrace(new StackTraceElement[0]);
|
||||
TBMCCoreAPI.SendException("The server crashed!", thr);
|
||||
} else
|
||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.GREEN)
|
||||
.withTitle("Server started - chat connected.").build(), ChannelconBroadcast.RESTART);
|
||||
|
||||
ResetMCCommand.resetting = false; //This is the last event handling this flag
|
||||
|
||||
getConfig().set("serverup", true);
|
||||
saveConfig();
|
||||
DPUtils.performNoWait(() -> {
|
||||
try {
|
||||
List<IMessage> msgs = genchannel.getPinnedMessages();
|
||||
for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10
|
||||
genchannel.unpin(msgs.get(i));
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
});
|
||||
sent = true;
|
||||
if (TBMCCoreAPI.IsTestServer() && !dc.getOurUser().getName().toLowerCase().contains("test")) {
|
||||
TBMCCoreAPI.SendException(
|
||||
"Won't load because we're in testing mode and not using a separate account.",
|
||||
new Exception(
|
||||
"The plugin refuses to load until you change the token to a testing account."));
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
TBMCCoreAPI.SendUnsentExceptions();
|
||||
TBMCCoreAPI.SendUnsentDebugMessages();
|
||||
/*if (!TBMCCoreAPI.IsTestServer()) {
|
||||
final Calendar currentCal = Calendar.getInstance();
|
||||
final Calendar newCal = Calendar.getInstance();
|
||||
currentCal.set(currentCal.get(Calendar.YEAR), currentCal.get(Calendar.MONTH),
|
||||
currentCal.get(Calendar.DAY_OF_MONTH), 4, 10);
|
||||
if (currentCal.get(Calendar.DAY_OF_MONTH) % 9 == 0 && currentCal.before(newCal)) {
|
||||
Random rand = new Random();
|
||||
sendMessageToChannel(dc.getChannels().get(rand.nextInt(dc.getChannels().size())),
|
||||
"You could make a religion out of this");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}, 0, 10);
|
||||
for (IListener<?> listener : CommonListeners.getListeners())
|
||||
dc.getDispatcher().registerListener(listener);
|
||||
Component.registerComponent(this, new GeneralEventBroadcasterModule());
|
||||
Component.registerComponent(this, new MinecraftChatModule());
|
||||
Component.registerComponent(this, new ExceptionListenerModule());
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
|
||||
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
|
||||
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
||||
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof DiscordSenderBase
|
||||
? ((DiscordSenderBase) sender).getChromaUser() : null));
|
||||
new Thread(this::AnnouncementGetterThreadMethod).start();
|
||||
setupProviders();
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isGameRole(IRole r) {
|
||||
if (r.getGuild().getLongID() != mainServer.getLongID())
|
||||
return false; //Only allow on the main server
|
||||
val rc = new Color(149, 165, 166, 0);
|
||||
return r.getColor().equals(rc)
|
||||
&& r.getPosition() < mainServer.getRoleByID(234343495735836672L).getPosition(); //Below the ChromaBot role
|
||||
}
|
||||
|
||||
/**
|
||||
* Always true, except when running "stop" from console
|
||||
*/
|
||||
public static boolean Restart;
|
||||
|
||||
@Override
|
||||
public void pluginDisable() {
|
||||
stop = true;
|
||||
MCChatPrivate.logoutAll();
|
||||
getConfig().set("lastannouncementtime", lastannouncementtime);
|
||||
getConfig().set("lastseentime", lastseentime);
|
||||
getConfig().set("serverup", false);
|
||||
|
||||
val chcons = MCChatCustom.getCustomChats();
|
||||
val chconsc = getConfig().createSection("chcons");
|
||||
for (val chcon : chcons) {
|
||||
val chconc = chconsc.createSection(chcon.channel.getStringID());
|
||||
chconc.set("mcchid", chcon.mcchannel.ID);
|
||||
chconc.set("chid", chcon.channel.getLongID());
|
||||
chconc.set("did", chcon.user.getLongID());
|
||||
chconc.set("mcuid", chcon.dcp.getUniqueId().toString());
|
||||
chconc.set("mcname", chcon.dcp.getName());
|
||||
chconc.set("groupid", chcon.groupID);
|
||||
chconc.set("toggles", chcon.toggles);
|
||||
}
|
||||
|
||||
saveConfig();
|
||||
EmbedObject embed;
|
||||
if (ResetMCCommand.resetting)
|
||||
embed = new EmbedBuilder().withColor(Color.ORANGE).withTitle("Discord plugin restarting").build();
|
||||
else
|
||||
embed = new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
|
||||
.withTitle(Restart ? "Server restarting" : "Server stopping")
|
||||
.withDescription(
|
||||
Bukkit.getOnlinePlayers().size() > 0
|
||||
? (DPUtils
|
||||
.sanitizeString(Bukkit.getOnlinePlayers().stream()
|
||||
.map(Player::getDisplayName).collect(Collectors.joining(", ")))
|
||||
+ (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ")
|
||||
+ "kicked the hell out.") //TODO: Make configurable
|
||||
: "") //If 'restart' is disabled then this isn't shown even if joinleave is enabled
|
||||
.build();
|
||||
MCChatUtils.forCustomAndAllMCChat(ch -> {
|
||||
try {
|
||||
DiscordPlugin.sendMessageToChannelWait(ch, "",
|
||||
embed, 5, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, ChannelconBroadcast.RESTART, false);
|
||||
ChromaBot.getInstance().updatePlayerList();
|
||||
try {
|
||||
SafeMode = true; // Stop interacting with Discord
|
||||
MCChatListener.stop(true);
|
||||
ChromaBot.delete();
|
||||
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
||||
dc.logout();
|
||||
mainServer = devServer = null; //Fetch servers and channels again
|
||||
sent = false;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private long lastannouncementtime = 0;
|
||||
private long lastseentime = 0;
|
||||
public static final ReactionEmoji DELIVERED_REACTION = ReactionEmoji.of("✅");
|
||||
|
||||
private void AnnouncementGetterThreadMethod() {
|
||||
while (!stop) {
|
||||
try {
|
||||
if (SafeMode) {
|
||||
Thread.sleep(10000);
|
||||
continue;
|
||||
}
|
||||
String body = TBMCCoreAPI.DownloadString(SubredditURL + "/new/.json?limit=10");
|
||||
JsonArray json = new JsonParser().parse(body).getAsJsonObject().get("data").getAsJsonObject()
|
||||
.get("children").getAsJsonArray();
|
||||
StringBuilder msgsb = new StringBuilder();
|
||||
StringBuilder modmsgsb = new StringBuilder();
|
||||
long lastanntime = lastannouncementtime;
|
||||
for (int i = json.size() - 1; i >= 0; i--) {
|
||||
JsonObject item = json.get(i).getAsJsonObject();
|
||||
final JsonObject data = item.get("data").getAsJsonObject();
|
||||
String author = data.get("author").getAsString();
|
||||
JsonElement distinguishedjson = data.get("distinguished");
|
||||
String distinguished;
|
||||
if (distinguishedjson.isJsonNull())
|
||||
distinguished = null;
|
||||
else
|
||||
distinguished = distinguishedjson.getAsString();
|
||||
String permalink = "https://www.reddit.com" + data.get("permalink").getAsString();
|
||||
long date = data.get("created_utc").getAsLong();
|
||||
if (date > lastseentime)
|
||||
lastseentime = date;
|
||||
else if (date > lastannouncementtime) {
|
||||
do {
|
||||
val reddituserclass = ChromaGamerBase.getTypeForFolder("reddit");
|
||||
if (reddituserclass == null)
|
||||
break;
|
||||
val user = ChromaGamerBase.getUser(author, reddituserclass);
|
||||
String id = user.getConnectedID(DiscordPlayer.class);
|
||||
if (id != null)
|
||||
author = "<@" + id + ">";
|
||||
} while (false);
|
||||
if (!author.startsWith("<"))
|
||||
author = "/u/" + author;
|
||||
(distinguished != null && distinguished.equals("moderator") ? modmsgsb : msgsb)
|
||||
.append("A new post was submitted to the subreddit by ").append(author).append("\n")
|
||||
.append(permalink).append("\n");
|
||||
lastanntime = date;
|
||||
}
|
||||
}
|
||||
if (msgsb.length() > 0)
|
||||
genchannel.pin(sendMessageToChannelWait(genchannel, msgsb.toString()));
|
||||
if (modmsgsb.length() > 0)
|
||||
sendMessageToChannel(annchannel, modmsgsb.toString());
|
||||
if (lastannouncementtime != lastanntime) {
|
||||
lastannouncementtime = lastanntime; // If sending succeeded
|
||||
getConfig().set("lastannouncementtime", lastannouncementtime);
|
||||
getConfig().set("lastseentime", lastseentime);
|
||||
saveConfig();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendMessageToChannel(IChannel channel, String message) {
|
||||
sendMessageToChannel(channel, message, null);
|
||||
}
|
||||
|
||||
public static void sendMessageToChannel(IChannel channel, String message, EmbedObject embed) {
|
||||
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) throws TimeoutException, InterruptedException {
|
||||
return sendMessageToChannelWait(channel, message, null);
|
||||
}
|
||||
|
||||
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed) throws TimeoutException, InterruptedException {
|
||||
return sendMessageToChannel(channel, message, embed, true);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) throws TimeoutException, InterruptedException {
|
||||
return sendMessageToChannel(channel, message, embed, wait, -1, null);
|
||||
}
|
||||
|
||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
||||
if (message.length() > 1980) {
|
||||
message = message.substring(0, 1980);
|
||||
Bukkit.getLogger()
|
||||
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
||||
}
|
||||
try {
|
||||
MCChatUtils.resetLastMessage(channel); // If this is a chat message, it'll be set again
|
||||
final String content = message;
|
||||
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
|
||||
: channel.sendMessage(content, embed, false);
|
||||
if (wait) {
|
||||
if (unit != null)
|
||||
return DPUtils.perform(r, timeout, unit);
|
||||
else
|
||||
return DPUtils.perform(r);
|
||||
} else {
|
||||
if (unit != null)
|
||||
plugin.getLogger().warning("Tried to set timeout for non-waiting call.");
|
||||
else
|
||||
DPUtils.performNoWait(r);
|
||||
return null;
|
||||
}
|
||||
} catch (TimeoutException | InterruptedException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().warning(
|
||||
"Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Permission perms;
|
||||
|
||||
public boolean setupProviders() {
|
||||
try {
|
||||
Class.forName("net.milkbowl.vault.permission.Permission");
|
||||
Class.forName("net.milkbowl.vault.chat.Chat");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisteredServiceProvider<Permission> permsProvider = Bukkit.getServer().getServicesManager()
|
||||
.getRegistration(Permission.class);
|
||||
perms = permsProvider.getProvider();
|
||||
return perms != null;
|
||||
}
|
||||
}
|
||||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.component.channel.Channel;
|
||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||
import buttondevteam.discordplugin.exceptions.ExceptionListenerModule;
|
||||
import buttondevteam.discordplugin.listeners.CommonListeners;
|
||||
import buttondevteam.discordplugin.listeners.MCListener;
|
||||
import buttondevteam.discordplugin.mcchat.*;
|
||||
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
|
||||
import buttondevteam.discordplugin.mccommands.ResetMCCommand;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import lombok.val;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import sx.blah.discord.api.ClientBuilder;
|
||||
import sx.blah.discord.api.IDiscordClient;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
import sx.blah.discord.handle.impl.events.ReadyEvent;
|
||||
import sx.blah.discord.handle.impl.obj.ReactionEmoji;
|
||||
import sx.blah.discord.handle.obj.*;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
import sx.blah.discord.util.RequestBuffer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent> {
|
||||
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
||||
private static boolean stop = false;
|
||||
public static IDiscordClient dc;
|
||||
public static DiscordPlugin plugin;
|
||||
public static boolean SafeMode = true;
|
||||
public static List<String> GameRoles;
|
||||
|
||||
public ConfigData<Character> Prefix() {
|
||||
return getIConfig().getData("prefix", '/', str -> ((String) str).charAt(0), Object::toString);
|
||||
}
|
||||
|
||||
public static char getPrefix() {
|
||||
if (plugin == null) return '/';
|
||||
return plugin.Prefix().get();
|
||||
}
|
||||
|
||||
public ConfigData<IGuild> MainServer() {
|
||||
return getIConfig().getDataPrimDef("mainServer", 219529124321034241L, id -> dc.getGuildByID((long) id), IIDLinkedObject::getLongID);
|
||||
}
|
||||
|
||||
public ConfigData<IChannel> CommandChannel() {
|
||||
return DPUtils.channelData(getIConfig(), "commandChannel", 239519012529111040L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pluginEnable() {
|
||||
stop = false; //If not the first time
|
||||
try {
|
||||
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
||||
plugin = this;
|
||||
lastannouncementtime = getConfig().getLong("lastannouncementtime");
|
||||
lastseentime = getConfig().getLong("lastseentime");
|
||||
ClientBuilder cb = new ClientBuilder();
|
||||
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
||||
dc = cb.login();
|
||||
dc.getDispatcher().registerListener(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static IChannel botchannel; //Can be removed
|
||||
public static IChannel annchannel;
|
||||
public static IChannel genchannel;
|
||||
public static IChannel chatchannel;
|
||||
public static IChannel botroomchannel;
|
||||
public static IChannel modlogchannel;
|
||||
/**
|
||||
* Don't send messages, just receive, the same channel is used when testing
|
||||
*/
|
||||
public static IChannel officechannel;
|
||||
public static IChannel updatechannel;
|
||||
public static IChannel devofficechannel;
|
||||
public static IGuild mainServer;
|
||||
public static IGuild devServer;
|
||||
|
||||
private static volatile BukkitTask task;
|
||||
private static volatile boolean sent = false;
|
||||
|
||||
@Override
|
||||
public void handle(ReadyEvent event) {
|
||||
try {
|
||||
dc.changePresence(StatusType.DND, ActivityType.PLAYING, "booting");
|
||||
task = Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
|
||||
if (mainServer == null || devServer == null) {
|
||||
mainServer = event.getClient().getGuildByID(125813020357165056L);
|
||||
devServer = event.getClient().getGuildByID(219529124321034241L);
|
||||
}
|
||||
if (mainServer == null || devServer == null)
|
||||
return; // Retry
|
||||
if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable()
|
||||
botchannel = mainServer.getChannelByID(209720707188260864L); // bot
|
||||
annchannel = mainServer.getChannelByID(126795071927353344L); // announcements
|
||||
genchannel = mainServer.getChannelByID(125813020357165056L); // general
|
||||
chatchannel = mainServer.getChannelByID(249663564057411596L); // minecraft_chat
|
||||
botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room
|
||||
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
|
||||
updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates
|
||||
devofficechannel = officechannel; // developers-office
|
||||
modlogchannel = mainServer.getChannelByID(283840717275791360L); // modlog
|
||||
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Chromacraft");
|
||||
} else {
|
||||
botchannel = devServer.getChannelByID(239519012529111040L); // bot-room
|
||||
annchannel = botchannel; // bot-room
|
||||
genchannel = botchannel; // bot-room
|
||||
botroomchannel = botchannel;// bot-room
|
||||
chatchannel = botchannel;// bot-room
|
||||
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
|
||||
updatechannel = botchannel;
|
||||
devofficechannel = botchannel;// bot-room
|
||||
modlogchannel = botchannel; // bot-room
|
||||
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing");
|
||||
}
|
||||
if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null
|
||||
|| chatchannel == null || officechannel == null || updatechannel == null)
|
||||
return; // Retry
|
||||
SafeMode = false;
|
||||
if (task != null)
|
||||
task.cancel();
|
||||
if (!sent) {
|
||||
new ChromaBot(this).updatePlayerList();
|
||||
GameRoles = mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList());
|
||||
|
||||
val chcons = getConfig().getConfigurationSection("chcons");
|
||||
if (chcons != null) {
|
||||
val chconkeys = chcons.getKeys(false);
|
||||
for (val chconkey : chconkeys) {
|
||||
val chcon = chcons.getConfigurationSection(chconkey);
|
||||
val mcch = Channel.getChannels().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny();
|
||||
val ch = dc.getChannelByID(chcon.getLong("chid"));
|
||||
val did = chcon.getLong("did");
|
||||
val user = dc.fetchUser(did);
|
||||
val groupid = chcon.getString("groupid");
|
||||
val toggles = chcon.getInt("toggles");
|
||||
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
|
||||
continue;
|
||||
Bukkit.getScheduler().runTask(this, () -> { //<-- Needed because of occasional ConcurrentModificationExceptions when creating the player (PermissibleBase)
|
||||
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
||||
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
DiscordCommandBase.registerCommands();
|
||||
if (ResetMCCommand.resetting)
|
||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN)
|
||||
.withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm
|
||||
else if (getConfig().getBoolean("serverup", false)) {
|
||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.YELLOW)
|
||||
.withTitle("Server recovered from a crash - chat connected.").build(), ChannelconBroadcast.RESTART);
|
||||
val thr = new Throwable(
|
||||
"The server shut down unexpectedly. See the log of the previous run for more details.");
|
||||
thr.setStackTrace(new StackTraceElement[0]);
|
||||
TBMCCoreAPI.SendException("The server crashed!", thr);
|
||||
} else
|
||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.GREEN)
|
||||
.withTitle("Server started - chat connected.").build(), ChannelconBroadcast.RESTART);
|
||||
|
||||
ResetMCCommand.resetting = false; //This is the last event handling this flag
|
||||
|
||||
getConfig().set("serverup", true);
|
||||
saveConfig();
|
||||
DPUtils.performNoWait(() -> {
|
||||
try {
|
||||
List<IMessage> msgs = genchannel.getPinnedMessages();
|
||||
for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10
|
||||
genchannel.unpin(msgs.get(i));
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
});
|
||||
sent = true;
|
||||
if (TBMCCoreAPI.IsTestServer() && !dc.getOurUser().getName().toLowerCase().contains("test")) {
|
||||
TBMCCoreAPI.SendException(
|
||||
"Won't load because we're in testing mode and not using a separate account.",
|
||||
new Exception(
|
||||
"The plugin refuses to load until you change the token to a testing account. (The account needs to have \"test\" in it's name.)"));
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
TBMCCoreAPI.SendUnsentExceptions();
|
||||
TBMCCoreAPI.SendUnsentDebugMessages();
|
||||
/*if (!TBMCCoreAPI.IsTestServer()) {
|
||||
final Calendar currentCal = Calendar.getInstance();
|
||||
final Calendar newCal = Calendar.getInstance();
|
||||
currentCal.set(currentCal.get(Calendar.YEAR), currentCal.get(Calendar.MONTH),
|
||||
currentCal.get(Calendar.DAY_OF_MONTH), 4, 10);
|
||||
if (currentCal.get(Calendar.DAY_OF_MONTH) % 9 == 0 && currentCal.before(newCal)) {
|
||||
Random rand = new Random();
|
||||
sendMessageToChannel(dc.getChannels().get(rand.nextInt(dc.getChannels().size())),
|
||||
"You could make a religion out of this");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}, 0, 10);
|
||||
for (IListener<?> listener : CommonListeners.getListeners())
|
||||
dc.getDispatcher().registerListener(listener);
|
||||
Component.registerComponent(this, new GeneralEventBroadcasterModule());
|
||||
Component.registerComponent(this, new MinecraftChatModule());
|
||||
Component.registerComponent(this, new ExceptionListenerModule());
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
|
||||
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
|
||||
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
||||
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof DiscordSenderBase
|
||||
? ((DiscordSenderBase) sender).getChromaUser() : null));
|
||||
new Thread(this::AnnouncementGetterThreadMethod).start();
|
||||
setupProviders();
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isGameRole(IRole r) {
|
||||
if (r.getGuild().getLongID() != mainServer.getLongID())
|
||||
return false; //Only allow on the main server
|
||||
val rc = new Color(149, 165, 166, 0);
|
||||
return r.getColor().equals(rc)
|
||||
&& r.getPosition() < mainServer.getRoleByID(234343495735836672L).getPosition(); //Below the ChromaBot role
|
||||
}
|
||||
|
||||
/**
|
||||
* Always true, except when running "stop" from console
|
||||
*/
|
||||
public static boolean Restart;
|
||||
|
||||
@Override
|
||||
public void pluginDisable() {
|
||||
stop = true;
|
||||
MCChatPrivate.logoutAll();
|
||||
getConfig().set("lastannouncementtime", lastannouncementtime);
|
||||
getConfig().set("lastseentime", lastseentime);
|
||||
getConfig().set("serverup", false);
|
||||
|
||||
val chcons = MCChatCustom.getCustomChats();
|
||||
val chconsc = getConfig().createSection("chcons");
|
||||
for (val chcon : chcons) {
|
||||
val chconc = chconsc.createSection(chcon.channel.getStringID());
|
||||
chconc.set("mcchid", chcon.mcchannel.ID);
|
||||
chconc.set("chid", chcon.channel.getLongID());
|
||||
chconc.set("did", chcon.user.getLongID());
|
||||
chconc.set("mcuid", chcon.dcp.getUniqueId().toString());
|
||||
chconc.set("mcname", chcon.dcp.getName());
|
||||
chconc.set("groupid", chcon.groupID);
|
||||
chconc.set("toggles", chcon.toggles);
|
||||
}
|
||||
|
||||
saveConfig();
|
||||
EmbedObject embed;
|
||||
if (ResetMCCommand.resetting)
|
||||
embed = new EmbedBuilder().withColor(Color.ORANGE).withTitle("Discord plugin restarting").build();
|
||||
else
|
||||
embed = new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
|
||||
.withTitle(Restart ? "Server restarting" : "Server stopping")
|
||||
.withDescription(
|
||||
Bukkit.getOnlinePlayers().size() > 0
|
||||
? (DPUtils
|
||||
.sanitizeString(Bukkit.getOnlinePlayers().stream()
|
||||
.map(Player::getDisplayName).collect(Collectors.joining(", ")))
|
||||
+ (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ")
|
||||
+ "kicked the hell out.") //TODO: Make configurable
|
||||
: "") //If 'restart' is disabled then this isn't shown even if joinleave is enabled
|
||||
.build();
|
||||
MCChatUtils.forCustomAndAllMCChat(ch -> {
|
||||
try {
|
||||
DiscordPlugin.sendMessageToChannelWait(ch, "",
|
||||
embed, 5, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, ChannelconBroadcast.RESTART, false);
|
||||
ChromaBot.getInstance().updatePlayerList();
|
||||
try {
|
||||
SafeMode = true; // Stop interacting with Discord
|
||||
MCChatListener.stop(true);
|
||||
ChromaBot.delete();
|
||||
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
||||
dc.logout();
|
||||
mainServer = devServer = null; //Fetch servers and channels again
|
||||
sent = false;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private long lastannouncementtime = 0;
|
||||
private long lastseentime = 0;
|
||||
public static final ReactionEmoji DELIVERED_REACTION = ReactionEmoji.of("✅");
|
||||
|
||||
private void AnnouncementGetterThreadMethod() {
|
||||
while (!stop) {
|
||||
try {
|
||||
if (SafeMode) {
|
||||
Thread.sleep(10000);
|
||||
continue;
|
||||
}
|
||||
String body = TBMCCoreAPI.DownloadString(SubredditURL + "/new/.json?limit=10");
|
||||
JsonArray json = new JsonParser().parse(body).getAsJsonObject().get("data").getAsJsonObject()
|
||||
.get("children").getAsJsonArray();
|
||||
StringBuilder msgsb = new StringBuilder();
|
||||
StringBuilder modmsgsb = new StringBuilder();
|
||||
long lastanntime = lastannouncementtime;
|
||||
for (int i = json.size() - 1; i >= 0; i--) {
|
||||
JsonObject item = json.get(i).getAsJsonObject();
|
||||
final JsonObject data = item.get("data").getAsJsonObject();
|
||||
String author = data.get("author").getAsString();
|
||||
JsonElement distinguishedjson = data.get("distinguished");
|
||||
String distinguished;
|
||||
if (distinguishedjson.isJsonNull())
|
||||
distinguished = null;
|
||||
else
|
||||
distinguished = distinguishedjson.getAsString();
|
||||
String permalink = "https://www.reddit.com" + data.get("permalink").getAsString();
|
||||
long date = data.get("created_utc").getAsLong();
|
||||
if (date > lastseentime)
|
||||
lastseentime = date;
|
||||
else if (date > lastannouncementtime) {
|
||||
do {
|
||||
val reddituserclass = ChromaGamerBase.getTypeForFolder("reddit");
|
||||
if (reddituserclass == null)
|
||||
break;
|
||||
val user = ChromaGamerBase.getUser(author, reddituserclass);
|
||||
String id = user.getConnectedID(DiscordPlayer.class);
|
||||
if (id != null)
|
||||
author = "<@" + id + ">";
|
||||
} while (false);
|
||||
if (!author.startsWith("<"))
|
||||
author = "/u/" + author;
|
||||
(distinguished != null && distinguished.equals("moderator") ? modmsgsb : msgsb)
|
||||
.append("A new post was submitted to the subreddit by ").append(author).append("\n")
|
||||
.append(permalink).append("\n");
|
||||
lastanntime = date;
|
||||
}
|
||||
}
|
||||
if (msgsb.length() > 0)
|
||||
genchannel.pin(sendMessageToChannelWait(genchannel, msgsb.toString()));
|
||||
if (modmsgsb.length() > 0)
|
||||
sendMessageToChannel(annchannel, modmsgsb.toString());
|
||||
if (lastannouncementtime != lastanntime) {
|
||||
lastannouncementtime = lastanntime; // If sending succeeded
|
||||
getConfig().set("lastannouncementtime", lastannouncementtime);
|
||||
getConfig().set("lastseentime", lastseentime);
|
||||
saveConfig();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendMessageToChannel(IChannel channel, String message) {
|
||||
sendMessageToChannel(channel, message, null);
|
||||
}
|
||||
|
||||
public static void sendMessageToChannel(IChannel channel, String message, EmbedObject embed) {
|
||||
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) throws TimeoutException, InterruptedException {
|
||||
return sendMessageToChannelWait(channel, message, null);
|
||||
}
|
||||
|
||||
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed) throws TimeoutException, InterruptedException {
|
||||
return sendMessageToChannel(channel, message, embed, true);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) throws TimeoutException, InterruptedException {
|
||||
return sendMessageToChannel(channel, message, embed, wait, -1, null);
|
||||
}
|
||||
|
||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
||||
if (message.length() > 1980) {
|
||||
message = message.substring(0, 1980);
|
||||
Bukkit.getLogger()
|
||||
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
||||
}
|
||||
try {
|
||||
MCChatUtils.resetLastMessage(channel); // If this is a chat message, it'll be set again
|
||||
final String content = message;
|
||||
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
|
||||
: channel.sendMessage(content, embed, false);
|
||||
if (wait) {
|
||||
if (unit != null)
|
||||
return DPUtils.perform(r, timeout, unit);
|
||||
else
|
||||
return DPUtils.perform(r);
|
||||
} else {
|
||||
if (unit != null)
|
||||
plugin.getLogger().warning("Tried to set timeout for non-waiting call.");
|
||||
else
|
||||
DPUtils.performNoWait(r);
|
||||
return null;
|
||||
}
|
||||
} catch (TimeoutException | InterruptedException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().warning(
|
||||
"Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Permission perms;
|
||||
|
||||
public boolean setupProviders() {
|
||||
try {
|
||||
Class.forName("net.milkbowl.vault.permission.Permission");
|
||||
Class.forName("net.milkbowl.vault.chat.Chat");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisteredServiceProvider<Permission> permsProvider = Bukkit.getServer().getServicesManager()
|
||||
.getRegistration(Permission.class);
|
||||
perms = permsProvider.getProvider();
|
||||
return perms != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public abstract class DiscordSenderBase implements CommandSender {
|
|||
(!broadcast && user != null ? user.mention() + "\n" : "") + msgtosend.trim());
|
||||
sendtask = null;
|
||||
msgtosend = "";
|
||||
}, 10); // Waits a half second to gather all/most of the different messages
|
||||
}, 4); // Waits a 0.2 second to gather all/most of the different messages
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while sending message to DiscordSender", e);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package buttondevteam.discordplugin.commands;
|
||||
|
||||
import buttondevteam.discordplugin.ChannelconBroadcast;
|
||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.component.channel.Channel;
|
||||
import buttondevteam.discordplugin.*;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatCustom;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -67,7 +64,7 @@ public class ChannelconCommand extends DiscordCommandBase {
|
|||
message.reply("this channel is already connected to a Minecraft channel. Use `@ChromaBot channelcon remove` to remove it.");
|
||||
return true;
|
||||
}
|
||||
val chan = Channel.getChannels().stream().filter(ch -> ch.ID.equalsIgnoreCase(args) || (ch.IDs != null && Arrays.stream(ch.IDs).anyMatch(cid -> cid.equalsIgnoreCase(args)))).findAny();
|
||||
val chan = Channel.getChannels().filter(ch -> ch.ID.equalsIgnoreCase(args) || (Arrays.stream(ch.IDs().get()).anyMatch(cid -> cid.equalsIgnoreCase(args)))).findAny();
|
||||
if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW)
|
||||
message.reply("MC channel with ID '" + args + "' not found! The ID is the command for it without the /.");
|
||||
return true;
|
||||
|
@ -75,7 +72,7 @@ public class ChannelconCommand extends DiscordCommandBase {
|
|||
val dp = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class);
|
||||
val chp = dp.getAs(TBMCPlayer.class);
|
||||
if (chp == null) {
|
||||
message.reply("you need to connect your Minecraft account. On our server in #bot do /connect <MCname>");
|
||||
message.reply("you need to connect your Minecraft account. On our server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect <MCname>");
|
||||
return true;
|
||||
}
|
||||
DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName());
|
||||
|
@ -100,12 +97,12 @@ public class ChannelconCommand extends DiscordCommandBase {
|
|||
"---- Channel connect ---", //
|
||||
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
|
||||
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
|
||||
"You also need to have your Minecraft account connected. In #bot use " + DiscordPlugin.getPrefix() + "connect <mcname>.", //
|
||||
"You also need to have your Minecraft account connected. In " + DPUtils.botmention() + " use " + DiscordPlugin.getPrefix() + "connect <mcname>.", //
|
||||
"Call this command from the channel you want to use.", //
|
||||
"Usage: @" + DiscordPlugin.dc.getOurUser().getName() + " channelcon <mcchannel>", //
|
||||
"Use the ID (command) of the channel, for example `g` for the global chat.", //
|
||||
"To remove a connection use @ChromaBot channelcon remove in the channel.", //
|
||||
"Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in #bot.", //
|
||||
"Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in " + DPUtils.botmention() + ".", //
|
||||
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=226443037893591041&scope=bot&permissions=268509264>" //
|
||||
};
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@ public class FunModule extends Component {
|
|||
};
|
||||
|
||||
private ConfigData<Boolean> serverReady() {
|
||||
return getData("serverReady", true);
|
||||
return getConfig().getData("serverReady", true);
|
||||
}
|
||||
|
||||
private ConfigData<List<String>> serverReadyAnswers() {
|
||||
return getData("serverReadyAnswers", Arrays.asList(serverReadyStrings),
|
||||
return getConfig().getData("serverReadyAnswers", Arrays.asList(serverReadyStrings),
|
||||
data -> (List<String>) data, data -> data); //TODO: Test
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ public class CommandListener {
|
|||
if (!mentionedonly) { //mentionedonly conditions are in CommonListeners
|
||||
if (!message.getChannel().isPrivate()
|
||||
&& !(message.getContent().charAt(0) == DiscordPlugin.getPrefix()
|
||||
&& channel.getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
|
||||
&& channel.getStringID().equals(DiscordPlugin.plugin.CommandChannel().get().getStringID()))) //
|
||||
return false;
|
||||
message.getChannel().setTypingStatus(true); // Fun
|
||||
}
|
||||
|
|
|
@ -1,128 +1,128 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
|
||||
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
|
||||
import sx.blah.discord.handle.obj.StatusType;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CommonListeners {
|
||||
|
||||
/*private static ArrayList<Object> dcListeners=new ArrayList<>();
|
||||
|
||||
public static void registerDiscordListener(DiscordListener listener) {
|
||||
//Step 1: Get all events that are handled by us
|
||||
//Step 2: Find methods that handle these
|
||||
//...or just simply call the methods in the right order
|
||||
}
|
||||
|
||||
private static void callDiscordEvent(Event event) {
|
||||
String name=event.getClass().getSimpleName();
|
||||
name=Character.toLowerCase(name.charAt(0))+name.substring(1);
|
||||
for (Object listener : dcListeners) {
|
||||
listener.getClass().getMethods(name, AsyncDiscordEvent.class);
|
||||
}
|
||||
}*/
|
||||
|
||||
private static long lasttime = 0;
|
||||
|
||||
/*
|
||||
MentionEvent:
|
||||
- CommandListener (starts with mention, only 'channelcon' and not in #bot)
|
||||
|
||||
MessageReceivedEvent:
|
||||
- v CommandListener (starts with mention, in #bot or a connected chat)
|
||||
- Minecraft chat (is enabled in the channel and message isn't [/]mcchat)
|
||||
- CommandListener (with the correct prefix in #bot, or in private)
|
||||
*/
|
||||
public static IListener<?>[] getListeners() {
|
||||
return new IListener[]{new IListener<MessageReceivedEvent>() {
|
||||
@Override
|
||||
public void handle(MessageReceivedEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
if (event.getMessage().getAuthor().isBot())
|
||||
return;
|
||||
boolean handled = false;
|
||||
if (event.getChannel().getLongID() == DiscordPlugin.botchannel.getLongID() //If mentioned, that's higher than chat
|
||||
|| event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels
|
||||
handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here
|
||||
if (handled) return;
|
||||
val mcchat = Component.getComponents().get(MinecraftChatModule.class);
|
||||
if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again
|
||||
handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels
|
||||
if (!handled)
|
||||
handled = CommandListener.runCommand(event.getMessage(), false);
|
||||
}
|
||||
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
|
||||
@Override
|
||||
public void handle(PresenceUpdateEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
val devrole = DiscordPlugin.devServer.getRolesByName("Developer").get(0);
|
||||
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
|
||||
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
||||
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
|
||||
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
||||
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
||||
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
|
||||
new EmbedBuilder()
|
||||
.withImage(
|
||||
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
|
||||
.build());
|
||||
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
|
||||
}
|
||||
}
|
||||
}, (IListener<RoleCreateEvent>) event -> {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole()))
|
||||
return; //Deleted or not a game role
|
||||
DiscordPlugin.GameRoles.add(event.getRole().getName());
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
|
||||
}, 100);
|
||||
}, (IListener<RoleDeleteEvent>) event -> {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role.");
|
||||
}, (IListener<RoleUpdateEvent>) event -> { //Role update event
|
||||
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
|
||||
} else {
|
||||
if (DiscordPlugin.GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
|
||||
return;
|
||||
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
|
||||
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
|
||||
if (removed)
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
|
||||
else
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
private static boolean debug = false;
|
||||
|
||||
public static void debug(String debug) {
|
||||
if (CommonListeners.debug) //Debug
|
||||
DPUtils.getLogger().info(debug);
|
||||
}
|
||||
|
||||
public static boolean debug() {
|
||||
return debug = !debug;
|
||||
}
|
||||
}
|
||||
package buttondevteam.discordplugin.listeners;
|
||||
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
|
||||
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
|
||||
import sx.blah.discord.handle.obj.StatusType;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CommonListeners {
|
||||
|
||||
/*private static ArrayList<Object> dcListeners=new ArrayList<>();
|
||||
|
||||
public static void registerDiscordListener(DiscordListener listener) {
|
||||
//Step 1: Get all events that are handled by us
|
||||
//Step 2: Find methods that handle these
|
||||
//...or just simply call the methods in the right order
|
||||
}
|
||||
|
||||
private static void callDiscordEvent(Event event) {
|
||||
String name=event.getClass().getSimpleName();
|
||||
name=Character.toLowerCase(name.charAt(0))+name.substring(1);
|
||||
for (Object listener : dcListeners) {
|
||||
listener.getClass().getMethods(name, AsyncDiscordEvent.class);
|
||||
}
|
||||
}*/
|
||||
|
||||
private static long lasttime = 0;
|
||||
|
||||
/*
|
||||
MentionEvent:
|
||||
- CommandListener (starts with mention, only 'channelcon' and not in #bot)
|
||||
|
||||
MessageReceivedEvent:
|
||||
- v CommandListener (starts with mention, in #bot or a connected chat)
|
||||
- Minecraft chat (is enabled in the channel and message isn't [/]mcchat)
|
||||
- CommandListener (with the correct prefix in #bot, or in private)
|
||||
*/
|
||||
public static IListener<?>[] getListeners() {
|
||||
return new IListener[]{new IListener<MessageReceivedEvent>() {
|
||||
@Override
|
||||
public void handle(MessageReceivedEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
if (event.getMessage().getAuthor().isBot())
|
||||
return;
|
||||
boolean handled = false;
|
||||
if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat
|
||||
|| event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels
|
||||
handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here
|
||||
if (handled) return;
|
||||
val mcchat = Component.getComponents().get(MinecraftChatModule.class);
|
||||
if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again
|
||||
handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels
|
||||
if (!handled)
|
||||
handled = CommandListener.runCommand(event.getMessage(), false);
|
||||
}
|
||||
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
|
||||
@Override
|
||||
public void handle(PresenceUpdateEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
val devrole = DiscordPlugin.devServer.getRolesByName("Developer").get(0);
|
||||
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
|
||||
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
||||
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
|
||||
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
||||
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
||||
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
|
||||
new EmbedBuilder()
|
||||
.withImage(
|
||||
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
|
||||
.build());
|
||||
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
|
||||
}
|
||||
}
|
||||
}, (IListener<RoleCreateEvent>) event -> {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole()))
|
||||
return; //Deleted or not a game role
|
||||
DiscordPlugin.GameRoles.add(event.getRole().getName());
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
|
||||
}, 100);
|
||||
}, (IListener<RoleDeleteEvent>) event -> {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role.");
|
||||
}, (IListener<RoleUpdateEvent>) event -> { //Role update event
|
||||
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
|
||||
} else {
|
||||
if (DiscordPlugin.GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
|
||||
return;
|
||||
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
|
||||
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
|
||||
if (removed)
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
|
||||
else
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
private static boolean debug = false;
|
||||
|
||||
public static void debug(String debug) {
|
||||
if (CommonListeners.debug) //Debug
|
||||
DPUtils.getLogger().info(debug);
|
||||
}
|
||||
|
||||
public static boolean debug() {
|
||||
return debug = !debug;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.component.channel.Channel;
|
||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import lombok.NonNull;
|
||||
import lombok.val;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.component.channel.Channel;
|
||||
import buttondevteam.component.channel.ChatRoom;
|
||||
import buttondevteam.core.ComponentManager;
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
|
@ -10,9 +12,7 @@ import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
|||
import buttondevteam.lib.TBMCChatEvent;
|
||||
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.ChatMessage;
|
||||
import buttondevteam.lib.chat.ChatRoom;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
|
@ -72,14 +72,15 @@ public class MCChatListener implements Listener {
|
|||
e = se.getKey();
|
||||
time = se.getValue();
|
||||
|
||||
final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName) + "] " //
|
||||
final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName().get()) + "] " //
|
||||
+ ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") //
|
||||
+ (DPUtils.sanitizeStringNoEscape(e.getSender() instanceof Player //
|
||||
? ((Player) e.getSender()).getDisplayName() //
|
||||
: e.getSender().getName()));
|
||||
val color = e.getChannel().Color().get();
|
||||
final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
||||
.withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(),
|
||||
e.getChannel().color.getGreen(), e.getChannel().color.getBlue()));
|
||||
.withDescription(e.getMessage()).withColor(new Color(color.getRed(),
|
||||
color.getGreen(), color.getBlue()));
|
||||
// embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "")
|
||||
// + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false);
|
||||
if (e.getSender() instanceof Player)
|
||||
|
@ -313,7 +314,7 @@ public class MCChatListener implements Listener {
|
|||
.collect(Collectors.joining(", "))
|
||||
+ (user.getConnectedID(TBMCPlayer.class) == null
|
||||
? "\nTo access your commands, first please connect your accounts, using /connect in "
|
||||
+ DiscordPlugin.botchannel.mention()
|
||||
+ DPUtils.botmention()
|
||||
+ "\nThen y"
|
||||
: "\nY")
|
||||
+ "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!");
|
||||
|
@ -330,10 +331,10 @@ public class MCChatListener implements Listener {
|
|||
} else {
|
||||
int spi = cmdlowercased.indexOf(' ');
|
||||
final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi);
|
||||
Optional<Channel> ch = Channel.getChannels().stream()
|
||||
Optional<Channel> ch = Channel.getChannels()
|
||||
.filter(c -> c.ID.equalsIgnoreCase(topcmd)
|
||||
|| (c.IDs != null && c.IDs.length > 0
|
||||
&& Arrays.stream(c.IDs).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny();
|
||||
|| (c.IDs().get().length > 0
|
||||
&& Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny();
|
||||
if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one
|
||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync
|
||||
() -> { //TODO: Better handling...
|
||||
|
@ -366,7 +367,7 @@ public class MCChatListener implements Listener {
|
|||
} else
|
||||
channel.set(Channel.GlobalChat);
|
||||
dsender.sendMessage("You're now talking in: "
|
||||
+ DPUtils.sanitizeString(channel.get().DisplayName));
|
||||
+ DPUtils.sanitizeString(channel.get().DisplayName().get()));
|
||||
} else { // Send single message
|
||||
final String msg = cmd.substring(spi + 1);
|
||||
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true);
|
||||
|
|
|
@ -59,7 +59,8 @@ public class MCChatPrivate {
|
|||
public static void logoutAll() {
|
||||
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
|
||||
for (val valueEntry : entry.getValue().entrySet())
|
||||
callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
|
||||
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
|
||||
callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
|
||||
MCChatUtils.ConnectedSenders.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.component.channel.Channel;
|
||||
import buttondevteam.core.ComponentManager;
|
||||
import buttondevteam.discordplugin.*;
|
||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import io.netty.util.collection.LongObjectHashMap;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.var;
|
||||
|
|
|
@ -1,43 +1,44 @@
|
|||
package buttondevteam.discordplugin.mccommands;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandClass(modOnly = false, path = "accept")
|
||||
public class AcceptMCCommand extends DiscordMCCommandBase {
|
||||
|
||||
@Override
|
||||
public String[] GetHelpText(String alias) {
|
||||
return new String[] { //
|
||||
"§6---- Accept Discord connection ----", //
|
||||
"Accept a pending connection between your Discord and Minecraft account.", //
|
||||
"To start the connection process, do §b/connect <MCname>§r in the #bot channel on Discord", //
|
||||
"Usage: /" + alias + " accept" //
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean OnCommand(Player player, String alias, String[] args) {
|
||||
String did = ConnectCommand.WaitingToConnect.get(player.getName());
|
||||
if (did == null) {
|
||||
player.sendMessage("§cYou don't have a pending connection to Discord.");
|
||||
return true;
|
||||
}
|
||||
DiscordPlayer dp = ChromaGamerBase.getUser(did, DiscordPlayer.class);
|
||||
TBMCPlayer mcp = TBMCPlayerBase.getPlayer(player.getUniqueId(), TBMCPlayer.class);
|
||||
dp.connectWith(mcp);
|
||||
dp.save();
|
||||
mcp.save();
|
||||
ConnectCommand.WaitingToConnect.remove(player.getName());
|
||||
MCChatUtils.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
|
||||
player.sendMessage("§bAccounts connected.");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
package buttondevteam.discordplugin.mccommands;
|
||||
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandClass(modOnly = false, path = "accept")
|
||||
public class AcceptMCCommand extends DiscordMCCommandBase {
|
||||
|
||||
@Override
|
||||
public String[] GetHelpText(String alias) {
|
||||
return new String[] { //
|
||||
"§6---- Accept Discord connection ----", //
|
||||
"Accept a pending connection between your Discord and Minecraft account.", //
|
||||
"To start the connection process, do §b/connect <MCname>§r in the " + DPUtils.botmention() + " channel on Discord", //
|
||||
"Usage: /" + alias + " accept" //
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean OnCommand(Player player, String alias, String[] args) {
|
||||
String did = ConnectCommand.WaitingToConnect.get(player.getName());
|
||||
if (did == null) {
|
||||
player.sendMessage("§cYou don't have a pending connection to Discord.");
|
||||
return true;
|
||||
}
|
||||
DiscordPlayer dp = ChromaGamerBase.getUser(did, DiscordPlayer.class);
|
||||
TBMCPlayer mcp = TBMCPlayerBase.getPlayer(player.getUniqueId(), TBMCPlayer.class);
|
||||
dp.connectWith(mcp);
|
||||
dp.save();
|
||||
mcp.save();
|
||||
ConnectCommand.WaitingToConnect.remove(player.getName());
|
||||
MCChatUtils.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
|
||||
player.sendMessage("§bAccounts connected.");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,31 +1,32 @@
|
|||
package buttondevteam.discordplugin.mccommands;
|
||||
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandClass(modOnly = false, path = "decline")
|
||||
public class DeclineMCCommand extends DiscordMCCommandBase {
|
||||
|
||||
@Override
|
||||
public String[] GetHelpText(String alias) {
|
||||
return new String[] { //
|
||||
"§6---- Decline Discord connection ----", //
|
||||
"Decline a pending connection between your Discord and Minecraft account.", //
|
||||
"To start the connection process, do §b/connect <MCname>§r in the #bot channel on Discord", //
|
||||
"Usage: /" + alias + " decline" //
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean OnCommand(Player player, String alias, String[] args) {
|
||||
String did = ConnectCommand.WaitingToConnect.remove(player.getName());
|
||||
if (did == null) {
|
||||
player.sendMessage("§cYou don't have a pending connection to Discord.");
|
||||
return true;
|
||||
}
|
||||
player.sendMessage("§bPending connection declined.");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
package buttondevteam.discordplugin.mccommands;
|
||||
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandClass(modOnly = false, path = "decline")
|
||||
public class DeclineMCCommand extends DiscordMCCommandBase {
|
||||
|
||||
@Override
|
||||
public String[] GetHelpText(String alias) {
|
||||
return new String[] { //
|
||||
"§6---- Decline Discord connection ----", //
|
||||
"Decline a pending connection between your Discord and Minecraft account.", //
|
||||
"To start the connection process, do §b/connect <MCname>§r in the " + DPUtils.botmention() + " channel on Discord", //
|
||||
"Usage: /" + alias + " decline" //
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean OnCommand(Player player, String alias, String[] args) {
|
||||
String did = ConnectCommand.WaitingToConnect.remove(player.getName());
|
||||
if (did == null) {
|
||||
player.sendMessage("§cYou don't have a pending connection to Discord.");
|
||||
return true;
|
||||
}
|
||||
player.sendMessage("§bPending connection declined.");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue