diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 9ec5deb..1d227f7 --- a/.gitignore +++ b/.gitignore @@ -131,7 +131,7 @@ publish/ *.publishproj # NuGet Packages Directory -## TODO: If you have NuGet Package Restore enabled, uncomment the next line +## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line #packages/ # Windows Azure Build Output diff --git a/.travis.yml b/.travis.yml old mode 100644 new mode 100755 diff --git a/License.md b/License.md old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/deploy.sh b/deploy.sh old mode 100644 new mode 100755 index 606423b..a40b486 --- a/deploy.sh +++ b/deploy.sh @@ -6,5 +6,5 @@ if [ $1 = 'production' ]; then echo Production mode echo $UPLOAD_KEY > upload_key chmod 400 upload_key -yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/plugins +yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/pluginupdates fi diff --git a/pom.xml b/pom.xml old mode 100644 new mode 100755 index a6477af..a6e0b14 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ org.spigotmc:spigot-api com.github.TBMCPlugins.ButtonCore:ButtonCore net.ess3:Essentials - + @@ -151,11 +151,11 @@ 1.12.2-R0.1-SNAPSHOT provided - + - com.discord4j - Discord4J - 2.10.1 + com.discord4j + Discord4J + 2.10.1 @@ -179,6 +179,7 @@ net.ess3 Essentials 2.13.1 + provided com.github.xaanit @@ -211,6 +212,10 @@ 2.6 test - + + com.vdurmont + emoji-java + 4.0.0 + diff --git a/src/main/java/buttondevteam/discordplugin/ChromaBot.java b/src/main/java/buttondevteam/discordplugin/ChromaBot.java old mode 100644 new mode 100755 index 0a4507a..e597095 --- a/src/main/java/buttondevteam/discordplugin/ChromaBot.java +++ b/src/main/java/buttondevteam/discordplugin/ChromaBot.java @@ -1,19 +1,18 @@ package buttondevteam.discordplugin; -import java.awt.Color; -import java.util.Arrays; -import java.util.stream.Collectors; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitScheduler; - import buttondevteam.discordplugin.listeners.MCChatListener; import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitScheduler; import sx.blah.discord.api.internal.json.objects.EmbedObject; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.util.EmbedBuilder; +import java.awt.*; +import java.util.Arrays; +import java.util.stream.Collectors; + public class ChromaBot { /** * May be null if it's not initialized. Initialization happens after the server is done loading (using {@link BukkitScheduler#runTaskAsynchronously(org.bukkit.plugin.Plugin, Runnable)}) @@ -47,7 +46,7 @@ public class ChromaBot { } /** - * Send a message to the chat channel and private chats. + * Send a message to the chat channels and private chats. * * @param message * The message to send, duh @@ -73,7 +72,7 @@ public class ChromaBot { } /** - * Send a fancy message to the chat channel. This will show a bold text with a colored line. + * Send a fancy message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh @@ -86,7 +85,7 @@ public class ChromaBot { } /** - * Send a fancy message to the chat channel. This will show a bold text with a colored line. + * Send a fancy message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh @@ -101,7 +100,7 @@ public class ChromaBot { } /** - * Send a fancy message to the chat channel. This will show a bold text with a colored line. + * Send a fancy message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh @@ -118,7 +117,7 @@ public class ChromaBot { } /** - * Send a message to the chat channel. This will show a bold text with a colored line. + * Send a message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java old mode 100644 new mode 100755 index 9cae322..abc1f8f --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -1,10 +1,15 @@ package buttondevteam.discordplugin; +import buttondevteam.lib.TBMCCoreAPI; +import org.bukkit.Bukkit; import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.RequestBuffer; import sx.blah.discord.util.RequestBuffer.IRequest; import sx.blah.discord.util.RequestBuffer.IVoidRequest; +import javax.annotation.Nullable; +import java.util.concurrent.TimeUnit; + public final class DPUtils { public static EmbedBuilder embedWithHead(EmbedBuilder builder, String playername) { @@ -33,13 +38,33 @@ public final class DPUtils { /** * Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode. */ - public static T perform(IRequest action) { - if (DiscordPlugin.SafeMode) - return null; - // if (Thread.currentThread() == DiscordPlugin.mainThread) - TODO: Ignore shutdown message <-- - // 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 - } + @Nullable + public static T perform(IRequest action, long timeout, TimeUnit unit) { + if (DiscordPlugin.SafeMode) + return null; + if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <-- + // 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!"); + try { + 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; + } + } + + /** + * Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode. + */ + @Nullable + public static T perform(IRequest action) { + if (DiscordPlugin.SafeMode) + return null; + if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <-- + // 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!"); + return RequestBuffer.request(action).get(); // Let the pros handle this + } /** * Performs Discord actions, retrying when ratelimited. diff --git a/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java b/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java old mode 100644 new mode 100755 index ef91b16..f5b779f --- a/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java @@ -1,13 +1,13 @@ package buttondevteam.discordplugin; -import java.util.UUID; - import buttondevteam.discordplugin.playerfaker.DiscordFakePlayer; import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; import lombok.Getter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.util.UUID; + public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlayer { private static int nextEntityId = 10000; private @Getter VanillaCommandListener vanillaCmdListener; diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlayer.java b/src/main/java/buttondevteam/discordplugin/DiscordPlayer.java old mode 100644 new mode 100755 diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java b/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java old mode 100644 new mode 100755 index 97c3aef..2c10314 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java @@ -1,13 +1,7 @@ package buttondevteam.discordplugin; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - +import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; +import lombok.Getter; import org.bukkit.*; import org.bukkit.advancement.Advancement; import org.bukkit.advancement.AdvancementProgress; @@ -24,18 +18,20 @@ import org.bukkit.inventory.*; import org.bukkit.inventory.InventoryView.Property; import org.bukkit.map.MapView; import org.bukkit.metadata.MetadataValue; -import org.bukkit.permissions.*; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.util.Vector; - -import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; -import lombok.Getter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.net.InetSocketAddress; +import java.util.*; + @SuppressWarnings("deprecation") public class DiscordPlayerSender extends DiscordSenderBase implements IMCPlayer { diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java old mode 100644 new mode 100755 index 5e1d8dc..170c789 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -1,8 +1,10 @@ package buttondevteam.discordplugin; +import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.discordplugin.listeners.*; import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase; import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.ChromaGamerBase; import com.google.common.io.Files; @@ -30,8 +32,9 @@ import sx.blah.discord.util.RequestBuffer; import java.awt.*; import java.io.File; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class DiscordPlugin extends JavaPlugin implements IListener { @@ -60,7 +63,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener { plugin = this; lastannouncementtime = getConfig().getLong("lastannouncementtime"); lastseentime = getConfig().getLong("lastseentime"); - GameRoles = (List) getConfig().getList("gameroles", new ArrayList()); ClientBuilder cb = new ClientBuilder(); cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8)); dc = cb.login(); @@ -77,6 +79,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { 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 */ @@ -109,6 +112,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { 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 @@ -119,6 +123,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { 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 @@ -129,6 +134,27 @@ public class DiscordPlugin extends JavaPlugin implements IListener { 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 dp = DiscordPlayer.getUser(Long.toString(did), DiscordPlayer.class); + val user = dc.fetchUser(did); + val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname")); + val groupid = chcon.getString("groupid"); + if (!mcch.isPresent() || ch == null || user == null || groupid == null) + continue; + MCChatListener.addCustomChat(ch, groupid, mcch.get(), dp, user, dcp); + } + } + + DiscordCommandBase.registerCommands(); if (getConfig().getBoolean("serverup", false)) { ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.YELLOW) .withTitle("Server recovered from a crash - chat connected.").build()); @@ -199,6 +225,14 @@ public class DiscordPlugin extends JavaPlugin implements IListener { } } + 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 */ @@ -211,8 +245,20 @@ public class DiscordPlugin extends JavaPlugin implements IListener { MCListener.callEventExcludingSome(new PlayerQuitEvent(entry.getValue(), "")); getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastseentime", lastseentime); - getConfig().set("gameroles", GameRoles); getConfig().set("serverup", false); + + val chcons = MCChatListener.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); + } + saveConfig(); MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannelWait(ch, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED) @@ -225,10 +271,11 @@ public class DiscordPlugin extends JavaPlugin implements IListener { + (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ") + "asked *politely* to leave the server for a bit.") : "") - .build())); + .build(), 5, TimeUnit.SECONDS)); ChromaBot.getInstance().updatePlayerList(); try { SafeMode = true; // Stop interacting with Discord + MCChatListener.stop(); ChromaBot.delete(); dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing dc.logout(); @@ -323,7 +370,15 @@ public class DiscordPlugin extends JavaPlugin implements IListener { return sendMessageToChannel(channel, message, embed, true); } + public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed, long timeout, TimeUnit unit) { + return sendMessageToChannel(channel, message, embed, true, timeout, unit); + } + private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) { + return sendMessageToChannel(channel, message, embed, wait, -1, null); + } + + private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) { if (message.length() > 1980) { message = message.substring(0, 1980); Bukkit.getLogger() @@ -337,10 +392,16 @@ public class DiscordPlugin extends JavaPlugin implements IListener { final String content = message; RequestBuffer.IRequest r = () -> embed == null ? channel.sendMessage(content) : channel.sendMessage(content, embed, false); - if (wait) - return DPUtils.perform(r); - else { - DPUtils.performNoWait(r); + 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 (Exception e) { diff --git a/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java b/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java old mode 100644 new mode 100755 diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSender.java b/src/main/java/buttondevteam/discordplugin/DiscordSender.java old mode 100644 new mode 100755 index 81a414b..f2f829b --- a/src/main/java/buttondevteam/discordplugin/DiscordSender.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordSender.java @@ -1,15 +1,18 @@ package buttondevteam.discordplugin; -import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.command.CommandSender; -import org.bukkit.permissions.*; +import org.bukkit.permissions.PermissibleBase; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; - import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.util.Set; + public class DiscordSender extends DiscordSenderBase implements CommandSender { private PermissibleBase perm = new PermissibleBase(this); diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java old mode 100644 new mode 100755 index 6da2ff4..0a6e392 --- a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java @@ -1,20 +1,19 @@ package buttondevteam.discordplugin; -import java.util.Arrays; -import java.util.stream.Collectors; - -import org.bukkit.Bukkit; -import org.bukkit.scheduler.BukkitTask; - import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.IDiscordSender; import lombok.Getter; import lombok.NonNull; import lombok.Setter; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.util.Arrays; +import java.util.stream.Collectors; + public abstract class DiscordSenderBase implements IDiscordSender { /** * May be null. diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSupplier.java b/src/main/java/buttondevteam/discordplugin/DiscordSupplier.java old mode 100644 new mode 100755 diff --git a/src/main/java/buttondevteam/discordplugin/IMCPlayer.java b/src/main/java/buttondevteam/discordplugin/IMCPlayer.java old mode 100644 new mode 100755 index e52539d..854db2b --- a/src/main/java/buttondevteam/discordplugin/IMCPlayer.java +++ b/src/main/java/buttondevteam/discordplugin/IMCPlayer.java @@ -1,8 +1,7 @@ package buttondevteam.discordplugin; -import org.bukkit.entity.Player; - import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; +import org.bukkit.entity.Player; public interface IMCPlayer> extends Player { VanillaCommandListener getVanillaCmdListener(); diff --git a/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java b/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java old mode 100644 new mode 100755 index 365e1be..e056737 --- a/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java +++ b/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java @@ -1,10 +1,10 @@ package buttondevteam.discordplugin; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.List; -import java.util.UUID; - +import buttondevteam.discordplugin.listeners.MCChatListener; +import buttondevteam.lib.TBMCCoreAPI; +import com.mojang.authlib.GameProfile; +import lombok.val; +import net.minecraft.server.v1_12_R1.*; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v1_12_R1.CraftServer; @@ -12,33 +12,10 @@ import org.bukkit.craftbukkit.v1_12_R1.util.CraftChatMessage; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.objenesis.ObjenesisStd; -import com.mojang.authlib.GameProfile; - -import buttondevteam.discordplugin.listeners.MCChatListener; -import buttondevteam.lib.TBMCCoreAPI; -import lombok.val; -import net.minecraft.server.v1_12_R1.AdvancementDataPlayer; -import net.minecraft.server.v1_12_R1.ChatMessageType; -import net.minecraft.server.v1_12_R1.DedicatedPlayerList; -import net.minecraft.server.v1_12_R1.DedicatedServer; -import net.minecraft.server.v1_12_R1.Entity; -import net.minecraft.server.v1_12_R1.EntityHuman; -import net.minecraft.server.v1_12_R1.EntityPlayer; -import net.minecraft.server.v1_12_R1.GameProfileBanList; -import net.minecraft.server.v1_12_R1.IChatBaseComponent; -import net.minecraft.server.v1_12_R1.IpBanList; -import net.minecraft.server.v1_12_R1.LoginListener; -import net.minecraft.server.v1_12_R1.MinecraftServer; -import net.minecraft.server.v1_12_R1.NBTTagCompound; -import net.minecraft.server.v1_12_R1.NetworkManager; -import net.minecraft.server.v1_12_R1.OpList; -import net.minecraft.server.v1_12_R1.Packet; -import net.minecraft.server.v1_12_R1.PacketPlayOutChat; -import net.minecraft.server.v1_12_R1.ScoreboardServer; -import net.minecraft.server.v1_12_R1.ServerStatisticManager; -import net.minecraft.server.v1_12_R1.WhiteList; -import net.minecraft.server.v1_12_R1.World; -import net.minecraft.server.v1_12_R1.WorldServer; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.UUID; public class PlayerListWatcher extends DedicatedPlayerList { private DedicatedPlayerList plist; diff --git a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java new file mode 100644 index 0000000..d9a1c8f --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java @@ -0,0 +1,83 @@ +package buttondevteam.discordplugin.commands; + +import buttondevteam.discordplugin.DiscordConnectedPlayer; +import buttondevteam.discordplugin.DiscordPlayer; +import buttondevteam.discordplugin.listeners.MCChatListener; +import buttondevteam.lib.TBMCChannelConnectFakeEvent; +import buttondevteam.lib.chat.Channel; +import buttondevteam.lib.player.TBMCPlayer; +import lombok.val; +import org.bukkit.Bukkit; +import sx.blah.discord.handle.obj.IMessage; +import sx.blah.discord.handle.obj.Permissions; +import sx.blah.discord.util.PermissionUtils; + +import java.util.Arrays; + +public class ChannelconCommand extends DiscordCommandBase { + @Override + public String getCommandName() { + return "channelcon"; + } + + @Override + public boolean run(IMessage message, String args) { + if (args.length() == 0) + return false; + if (!PermissionUtils.hasPermissions(message.getChannel(), message.getAuthor(), Permissions.MANAGE_CHANNEL)) { + message.reply("you need to have manage permissions for this channel!"); + return true; + } + if (MCChatListener.hasCustomChat(message.getChannel())) { + if (args.equalsIgnoreCase("remove")) { + if (MCChatListener.removeCustomChat(message.getChannel())) + message.reply("channel connection removed."); + else + message.reply("wait what, couldn't remove channel connection."); + return true; + } + 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(); + 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; + } + 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 "); + return true; + } + DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName()); + val ev = new TBMCChannelConnectFakeEvent(dcp, chan.get()); + //Using a fake player with no login/logout, should be fine for this event + String groupid = ev.getGroupID(ev.getSender()); //We're not trying to send in a specific group, we want to know which group the user belongs to (so not getGroupID()) + if (groupid == null) { + message.reply("sorry, that didn't work. You cannot use that Minecraft channel."); + return true; + } + if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) { + message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm."); + return true; + } + MCChatListener.addCustomChat(message.getChannel(), groupid, ev.getChannel(), dp, message.getAuthor(), dcp); + message.reply("alright, connection made to group `" + groupid + "`!"); + return true; + } + + @Override + public String[] getHelpText() { + return new String[]{ // + "---- 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 /connect .", // + "Call this command from the channel you want to use. Usage: @ChromaBot channelcon ", // + "To remove a connection use @ChromaBot channelcon remove in the channel.", // + "Mentioning the bot is needed in this case because the / prefix only works in #bot.", // + "Invite link: " // + }; + } +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java old mode 100644 new mode 100755 index 0eb837e..670b522 --- a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java @@ -1,16 +1,14 @@ package buttondevteam.discordplugin.commands; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; - -import com.google.common.collect.HashBiMap; - import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayerBase; +import com.google.common.collect.HashBiMap; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; import sx.blah.discord.handle.obj.IMessage; public class ConnectCommand extends DiscordCommandBase { @@ -27,15 +25,13 @@ public class ConnectCommand extends DiscordCommandBase { public static HashBiMap WaitingToConnect = HashBiMap.create(); @Override - public void run(IMessage message, String args) { - if (args.length() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "Usage: connect "); - return; - } + public boolean run(IMessage message, String args) { + if (args.length() == 0) + return true; if (args.contains(" ")) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "Too many arguments.\nUsage: connect "); - return; + return true; } if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) { DiscordPlugin.sendMessageToChannel(message.getChannel(), @@ -46,13 +42,13 @@ public class ConnectCommand extends DiscordCommandBase { OfflinePlayer p = Bukkit.getOfflinePlayer(args); if (p == null) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found"); - return; + return true; } try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) { DiscordPlayer dp = pl.getAs(DiscordPlayer.class); if (dp != null && message.getAuthor().getStringID().equals(dp.getDiscordID())) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected."); - return; + return true; } } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e); @@ -60,11 +56,12 @@ public class ConnectCommand extends DiscordCommandBase { } WaitingToConnect.put(p.getName(), message.getAuthor().getStringID()); DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Pending connection - accept connection in Minecraft from the account " + args - + " before the server gets restarted. You can also adjust the Minecraft name you want to connect to with the same command."); + "Alright! Now accept the connection in Minecraft from the account " + args + + " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command."); if (p.isOnline()) ((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#" + message.getAuthor().getDiscriminator() + " do /discord accept"); + return true; } @Override diff --git a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java new file mode 100644 index 0000000..1b6a605 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java @@ -0,0 +1,26 @@ +package buttondevteam.discordplugin.commands; + +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.discordplugin.listeners.CommandListener; +import sx.blah.discord.handle.obj.IMessage; + +public class DebugCommand extends DiscordCommandBase { + @Override + public String getCommandName() { + return "debug"; + } + + @Override + public boolean run(IMessage message, String args) { + if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L))) + message.reply("Debug " + (CommandListener.debug() ? "enabled" : "disabled")); + else + message.reply("You need to be a moderator to use this command."); + return true; + } + + @Override + public String[] getHelpText() { + return new String[]{"Switches debug mode."}; + } +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java old mode 100644 new mode 100755 index 2cfe732..8fd3145 --- a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java @@ -1,29 +1,36 @@ package buttondevteam.discordplugin.commands; -import java.util.HashMap; - import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import sx.blah.discord.handle.obj.IMessage; +import java.util.Arrays; +import java.util.HashMap; +import java.util.stream.Collectors; + +import static buttondevteam.discordplugin.listeners.CommandListener.debug; + public abstract class DiscordCommandBase { public abstract String getCommandName(); - public abstract void run(IMessage message, String args); + public abstract boolean run(IMessage message, String args); public abstract String[] getHelpText(); static final HashMap commands = new HashMap(); - static { + public static void registerCommands() { commands.put("connect", new ConnectCommand()); // TODO: API for adding commands? commands.put("userinfo", new UserinfoCommand()); commands.put("help", new HelpCommand()); commands.put("role", new RoleCommand()); commands.put("mcchat", new MCChatCommand()); + commands.put("channelcon", new ChannelconCommand()); + commands.put("debug", new DebugCommand()); } public static void runCommand(String cmd, String args, IMessage message) { + debug("F"); //Not sure if needed DiscordCommandBase command = commands.get(cmd); if (command == null) { DiscordPlugin.sendMessageToChannel(message.getChannel(), @@ -32,12 +39,19 @@ public abstract class DiscordCommandBase { + "help' for help"); return; } + debug("G"); try { - command.run(message, args); + if (!command.run(message, args)) + DiscordPlugin.sendMessageToChannel(message.getChannel(), Arrays.stream(command.getHelpText()).collect(Collectors.joining("\n"))); } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while executing command " + cmd + "!", e); DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured while executing this command. For more technical details see the server-issues channel on the dev Discord."); } + debug("H"); + } + + protected String[] splitargs(String args) { + return args.split("\\s+"); } } diff --git a/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java b/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java old mode 100644 new mode 100755 index f4b1cb5..29aff28 --- a/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java @@ -1,11 +1,11 @@ package buttondevteam.discordplugin.commands; -import java.util.Arrays; -import java.util.stream.Collectors; - import buttondevteam.discordplugin.DiscordPlugin; import sx.blah.discord.handle.obj.IMessage; +import java.util.Arrays; +import java.util.stream.Collectors; + public class HelpCommand extends DiscordCommandBase { @Override @@ -14,7 +14,7 @@ public class HelpCommand extends DiscordCommandBase { } @Override - public void run(IMessage message, String args) { + public boolean run(IMessage message, String args) { DiscordCommandBase argdc; if (args.length() == 0) DiscordPlugin.sendMessageToChannel(message.getChannel(), @@ -24,6 +24,7 @@ public class HelpCommand extends DiscordCommandBase { DiscordPlugin.sendMessageToChannel(message.getChannel(), (argdc = DiscordCommandBase.commands.get(args)) == null ? "Command not found: " + args : Arrays.stream(argdc.getHelpText()).collect(Collectors.joining("\n"))); + return true; } @Override diff --git a/src/main/java/buttondevteam/discordplugin/commands/MCChatCommand.java b/src/main/java/buttondevteam/discordplugin/commands/MCChatCommand.java old mode 100644 new mode 100755 index a629eda..e2ca2ca --- a/src/main/java/buttondevteam/discordplugin/commands/MCChatCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/MCChatCommand.java @@ -14,23 +14,23 @@ public class MCChatCommand extends DiscordCommandBase { } @Override - public void run(IMessage message, String args) { + public boolean run(IMessage message, String args) { if (!message.getChannel().isPrivate()) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "This command can only be issued in a direct message with the bot."); - return; + return true; } try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) { boolean mcchat = !user.isMinecraftChatEnabled(); MCChatListener.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user); DiscordPlugin.sendMessageToChannel(message.getChannel(), "Minecraft chat " + (mcchat // - ? "enabled. Use '" + message.getClient().getOurUser().mention() - + " mcchat' (with the mention) to disable." // + ? "enabled. Use '/mcchat' again to turn it off." // : "disabled.")); } catch (Exception e) { TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e); } + return true; } @Override diff --git a/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java b/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java old mode 100644 new mode 100755 index f1cf584..dbe8988 --- a/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java @@ -6,115 +6,88 @@ import buttondevteam.lib.TBMCCoreAPI; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IRole; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class RoleCommand extends DiscordCommandBase { - @Override - public String getCommandName() { - return "role"; - } + @Override + public String getCommandName() { + return "role"; + } - @Override - public void run(IMessage message, String args) { - final String usagemsg = "Subcommands: add, remove, list"; - if (args.length() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), usagemsg); - return; - } - String[] argsa = args.split(" "); - if (argsa[0].equalsIgnoreCase("add")) { - final IRole role = checkAndGetRole(message, argsa, "This command adds a game role to your account."); - if (role == null) - return; - try { - DPUtils.perform(() -> message.getAuthor().addRole(role)); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added game role."); - } catch (Exception e) { - TBMCCoreAPI.SendException("Error while adding role!", e); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role."); - } - } else if (argsa[0].equalsIgnoreCase("remove")) { - final IRole role = checkAndGetRole(message, argsa, "This command removes a game role from your account."); - if (role == null) - return; - try { - DPUtils.perform(() -> message.getAuthor().removeRole(role)); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed game role."); - } catch (Exception e) { - TBMCCoreAPI.SendException("Error while removing role!", e); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role."); - } - } else if (argsa[0].equalsIgnoreCase("list")) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "List of game roles:\n" + DiscordPlugin.GameRoles.stream().collect(Collectors.joining("\n"))); - } else if (argsa[0].equalsIgnoreCase("admin") && argsa.length > 1 && argsa[1].equalsIgnoreCase("addrole")) { - if (message.getAuthor().getRolesForGuild(DiscordPlugin.mainServer).stream() - .noneMatch(r -> r.getLongID() == 126030201472811008L)) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "You need to be a moderator to use this command."); - return; - } - if (argsa.length < 3) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Add a role to the game role list.\nUsage: " + argsa[0] + " "); - return; - } - String rolename = Arrays.stream(argsa).skip(2).collect(Collectors.joining(" ")); - final List roles = (TBMCCoreAPI.IsTestServer() ? DiscordPlugin.devServer : DiscordPlugin.mainServer) - .getRolesByName(rolename); - if (roles.size() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "That role cannot be found on Discord."); - return; - } - if (roles.size() > 1) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "There are more roles with this name. Why are there more roles with this name?"); - return; - } - DiscordPlugin.GameRoles.add(roles.get(0).getName()); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "Game role added."); - } - } + @Override + public boolean run(IMessage message, String args) { + if (args.length() == 0) + return false; + String[] argsa = splitargs(args); + if (argsa[0].equalsIgnoreCase("add")) { + final IRole role = checkAndGetRole(message, argsa, "This command adds a game role to your account."); + if (role == null) + return true; + try { + DPUtils.perform(() -> message.getAuthor().addRole(role)); + DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added game role."); + } catch (Exception e) { + TBMCCoreAPI.SendException("Error while adding role!", e); + DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role."); + } + } else if (argsa[0].equalsIgnoreCase("remove")) { + final IRole role = checkAndGetRole(message, argsa, "This command removes a game role from your account."); + if (role == null) + return true; + try { + DPUtils.perform(() -> message.getAuthor().removeRole(role)); + DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed game role."); + } catch (Exception e) { + TBMCCoreAPI.SendException("Error while removing role!", e); + DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role."); + } + } else if (argsa[0].equalsIgnoreCase("list")) { + listRoles(message); + } else return false; + return true; + } - private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) { - if (argsa.length < 2) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), usage + "\nUsage: " + argsa[0] + " "); - return null; - } - String rolename = argsa[1]; - for (int i = 2; i < argsa.length; i++) - rolename += " " + argsa[i]; - if (!DiscordPlugin.GameRoles.contains(rolename)) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "That game role cannot be found.\nList of game roles:\n" - + DiscordPlugin.GameRoles.stream().collect(Collectors.joining("\n"))); - return null; - } - final List roles = (TBMCCoreAPI.IsTestServer() ? DiscordPlugin.devServer : DiscordPlugin.mainServer) - .getRolesByName(rolename); - if (roles.size() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The specified role cannot be found on Discord! Removing from the list."); - DiscordPlugin.GameRoles.remove(rolename); - return null; - } - if (roles.size() > 1) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "There are more roles with this name. Why are there more roles with this name?"); - return null; - } - return roles.get(0); - } + private void listRoles(IMessage message) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "List of game roles:\n" + DiscordPlugin.GameRoles.stream().sorted().collect(Collectors.joining("\n"))); + } - @Override - public String[] getHelpText() { - return new String[] { // - "Add or remove game roles from yourself.", // - "Usage: role add|remove or role list", // - "Mods can use role addrole to add a role as a game role" }; - } + private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) { + if (argsa.length < 2) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), usage + "\nUsage: " + argsa[0] + " "); + return null; + } + String rolename = argsa[1]; + for (int i = 2; i < argsa.length; i++) + rolename += " " + argsa[i]; + if (!DiscordPlugin.GameRoles.contains(rolename)) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), "That game role cannot be found."); + listRoles(message); + return null; + } + final List roles = DiscordPlugin.mainServer.getRolesByName(rolename); + if (roles.size() == 0) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "The specified role cannot be found on Discord! Removing from the list."); + DiscordPlugin.GameRoles.remove(rolename); + return null; + } + if (roles.size() > 1) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "There are more roles with this name. Why are there more roles with this name?"); + return null; + } + return roles.get(0); + } + + @Override + public String[] getHelpText() { + return new String[]{ // + "Add or remove game roles from yourself.", // + "Usage: role add|remove or role list", // + }; + } } diff --git a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java old mode 100644 new mode 100755 index b5a7ad2..b0608ed --- a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java @@ -1,8 +1,5 @@ package buttondevteam.discordplugin.commands; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; @@ -11,6 +8,10 @@ import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IUser; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + public class UserinfoCommand extends DiscordCommandBase { @Override @@ -19,12 +20,7 @@ public class UserinfoCommand extends DiscordCommandBase { } @Override - public void run(IMessage message, String args) { - if (args.contains(" ")) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Too many arguments.\nUsage: userinfo [username/nickname[#tag]/ping]\nExamples:\nuserinfo ChromaBot\nuserinfo ChromaBot#6338\nuserinfo @ChromaBot#6338"); - return; - } + public boolean run(IMessage message, String args) { IUser target = null; if (args.length() == 0) target = message.getAuthor(); @@ -39,7 +35,7 @@ public class UserinfoCommand extends DiscordCommandBase { if (targets.size() == 0) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "The user cannot be found (by name): " + args); - return; + return true; } for (IUser ptarget : targets) { if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) { @@ -51,19 +47,19 @@ public class UserinfoCommand extends DiscordCommandBase { DiscordPlugin.sendMessageToChannel(message.getChannel(), "The user cannot be found (by discriminator): " + args + "(Found " + targets.size() + " users with the name.)"); - return; + return true; } } else { final List targets = getUsers(message, args); if (targets.size() == 0) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "The user cannot be found on Discord: " + args); - return; + return true; } if (targets.size() > 1) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping."); - return; + return true; } target = targets.get(0); } @@ -76,6 +72,7 @@ public class UserinfoCommand extends DiscordCommandBase { DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while getting the user!"); TBMCCoreAPI.SendException("Error while getting info about " + target.getName() + "!", e); } + return true; } private List getUsers(IMessage message, String args) { @@ -93,7 +90,8 @@ public class UserinfoCommand extends DiscordCommandBase { return new String[] { // "---- User information ----", // "Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.", // - "Usage: userinfo " // + "If used without args, shows your info.", // + "Usage: userinfo [username/nickname[#tag]/ping]\nExamples:\nuserinfo ChromaBot\nuserinfo ChromaBot#6338\nuserinfo @ChromaBot#6338" // }; } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java b/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java old mode 100644 new mode 100755 index cc8593a..a6d0150 --- a/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java @@ -1,12 +1,11 @@ package buttondevteam.discordplugin.listeners; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - import buttondevteam.discordplugin.DPUtils; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.PluginUpdater; import buttondevteam.lib.TBMCCoreAPI; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; public class AutoUpdaterListener implements Listener { @EventHandler diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java old mode 100644 new mode 100755 index c4c9e33..76ae457 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -5,9 +5,13 @@ import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.lib.TBMCCoreAPI; import lombok.val; +import org.bukkit.Bukkit; import sx.blah.discord.api.events.IListener; import sx.blah.discord.handle.impl.events.guild.channel.message.MentionEvent; 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.IChannel; import sx.blah.discord.handle.obj.IMessage; @@ -22,158 +26,202 @@ import java.util.concurrent.TimeUnit; public class CommandListener { - private static final String[] serverReadyStrings = new String[] { "In one week from now", // Ali - "Between now and the heat-death of the universe.", // Ghostise - "Soon™", "Ask again this time next month", // Ghostise - "In about 3 seconds", // Nicolai - "After we finish 8 plugins", // Ali - "Tomorrow.", // Ali - "After one tiiiny feature", // Ali - "Next commit", // Ali - "After we finish strangling Towny", // Ali - "When we kill every *fucking* bug", // Ali - "Once the server stops screaming.", // Ali - "After HL3 comes out", // Ali - "Next time you ask", // Ali - "When will *you* be open?" // Ali - }; + private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali + "Between now and the heat-death of the universe.", // Ghostise + "Soon™", "Ask again this time next month", // Ghostise + "In about 3 seconds", // Nicolai + "After we finish 8 plugins", // Ali + "Tomorrow.", // Ali + "After one tiiiny feature", // Ali + "Next commit", // Ali + "After we finish strangling Towny", // Ali + "When we kill every *fucking* bug", // Ali + "Once the server stops screaming.", // Ali + "After HL3 comes out", // Ali + "Next time you ask", // Ali + "When will *you* be open?" // Ali + }; - private static final String[] serverReadyQuestions = new String[] { "when will the server be open", - "when will the server be ready", "when will the server be done", "when will the server be complete", - "when will the server be finished", "when's the server ready", "when's the server open", - "Vhen vill ze server be open?" }; + private static final String[] serverReadyQuestions = new String[]{"when will the server be open", + "when will the server be ready", "when will the server be done", "when will the server be complete", + "when will the server be finished", "when's the server ready", "when's the server open", + "Vhen vill ze server be open?"}; - private static final Random serverReadyRandom = new Random(); - private static final ArrayList usableServerReadyStrings = new ArrayList(serverReadyStrings.length) { - private static final long serialVersionUID = 2213771460909848770L; - { - createUsableServerReadyStrings(this); - } - }; + private static final Random serverReadyRandom = new Random(); + private static final ArrayList usableServerReadyStrings = new ArrayList(serverReadyStrings.length) { + private static final long serialVersionUID = 2213771460909848770L; - private static void createUsableServerReadyStrings(ArrayList list) { - for (short i = 0; i < serverReadyStrings.length; i++) - list.add(i); - } + { + createUsableServerReadyStrings(this); + } + }; - private static long lasttime = 0; + private static void createUsableServerReadyStrings(ArrayList list) { + for (short i = 0; i < serverReadyStrings.length; i++) + list.add(i); + } - public static IListener[] getListeners() { - return new IListener[] { new IListener() { - @Override - public void handle(MentionEvent event) { - if (DiscordPlugin.SafeMode) - return; - if (event.getMessage().getAuthor().isBot()) - return; - final IChannel channel = event.getMessage().getChannel(); - if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID())) - return; - if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID())) - return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel - event.getMessage().getChannel().setTypingStatus(true); // Fun - runCommand(event.getMessage(), true); - } - }, new IListener() { - @Override - public void handle(MessageReceivedEvent event) { - if (DiscordPlugin.SafeMode) - return; - final String msglowercase = event.getMessage().getContent().toLowerCase(); - if (!TBMCCoreAPI.IsTestServer() - && Arrays.stream(serverReadyQuestions).anyMatch(s -> msglowercase.contains(s))) { - int next; - if (usableServerReadyStrings.size() == 0) - createUsableServerReadyStrings(usableServerReadyStrings); - next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size())); - DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), serverReadyStrings[next]); - return; - } - if (!event.getMessage().getChannel().isPrivate()) // - return; - if (DiscordPlayer.getUser(event.getAuthor().getStringID(), DiscordPlayer.class) - .isMinecraftChatEnabled()) - if (!event.getMessage().getContent().equalsIgnoreCase("mcchat")) - return; - if (event.getMessage().getAuthor().isBot()) - return; - runCommand(event.getMessage(), false); - } - }, new IListener() { - @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()); - } - } - } }; - } + private static long lasttime = 0; - /** - * Runs a ChromaBot command. + public static IListener[] getListeners() { + return new IListener[]{new IListener() { + @Override + public void handle(MentionEvent event) { + if (DiscordPlugin.SafeMode) + return; + if (event.getMessage().getAuthor().isBot()) + return; + final IChannel channel = event.getMessage().getChannel(); + if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID()) + && (!event.getMessage().getContent().contains("channelcon") || MCChatListener.hasCustomChat(channel))) //Allow channelcon in other servers but avoid double handling when it's enabled + return; + if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID())) + return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel + event.getMessage().getChannel().setTypingStatus(true); // Fun + runCommand(event.getMessage(), true); + } + }, new IListener() { + @Override + public void handle(MessageReceivedEvent event) { + if (DiscordPlugin.SafeMode) + return; + final String msglowercase = event.getMessage().getContent().toLowerCase(); + if (!TBMCCoreAPI.IsTestServer() + && Arrays.stream(serverReadyQuestions).anyMatch(s -> msglowercase.contains(s))) { + int next; + if (usableServerReadyStrings.size() == 0) + createUsableServerReadyStrings(usableServerReadyStrings); + next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size())); + DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), serverReadyStrings[next]); + return; + } + if (!event.getMessage().getChannel().isPrivate() + && !(event.getMessage().getContent().startsWith("/") + && event.getChannel().getStringID().equals(DiscordPlugin.botchannel.getStringID()))) // + return; + if (DiscordPlayer.getUser(event.getAuthor().getStringID(), DiscordPlayer.class) + .isMinecraftChatEnabled()) + if (!event.getMessage().getContent().equalsIgnoreCase("mcchat")) + return; + if (event.getMessage().getAuthor().isBot()) + return; + runCommand(event.getMessage(), false); + } + }, new IListener() { + @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) 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) event -> { + if (DiscordPlugin.GameRoles.remove(event.getRole().getName())) + DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role."); + }, (IListener) 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 { + 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."); + } + }}; + } + + /** + * Runs a ChromaBot command. * - * @param message - * The Discord message - * @param mentionedonly - * Only run the command if ChromaBot is mentioned at the start of the message - * @return Whether it ran the command (always true if mentionedonly is false) - */ - public static boolean runCommand(IMessage message, boolean mentionedonly) { - if (DiscordPlugin.SafeMode) - return true; - final StringBuilder cmdwithargs = new StringBuilder(message.getContent()); - final String mention = DiscordPlugin.dc.getOurUser().mention(false); - final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true); - boolean gotmention = checkanddeletemention(cmdwithargs, mention, message); - gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention; + * @param message The Discord message + * @param mentionedonly Only run the command if ChromaBot is mentioned at the start of the message + * @return Whether it ran the command (always true if mentionedonly is false) + */ + public static boolean runCommand(IMessage message, boolean mentionedonly) { + debug("A"); + if (DiscordPlugin.SafeMode) + return true; + debug("B"); + final StringBuilder cmdwithargs = new StringBuilder(message.getContent()); + final String mention = DiscordPlugin.dc.getOurUser().mention(false); + final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true); + boolean gotmention = checkanddeletemention(cmdwithargs, mention, message); + gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention; for (String mentionRole : (Iterable) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(r -> r.mention())::iterator) - gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions - if (mentionedonly && !gotmention) { - message.getChannel().setTypingStatus(false); - return false; - } - message.getChannel().setTypingStatus(true); - int index = cmdwithargs.indexOf(" "); - String cmd; - String args; - if (index == -1) { - cmd = cmdwithargs.toString(); - args = ""; - } else { - cmd = cmdwithargs.substring(0, index); - args = cmdwithargs.substring(index + 1); - } - DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message); - message.getChannel().setTypingStatus(false); - return true; - } + gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions + debug("C"); + if (mentionedonly && !gotmention) { + message.getChannel().setTypingStatus(false); + return false; + } + debug("D"); + message.getChannel().setTypingStatus(true); + String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command + int index = cmdwithargsString.indexOf(" "); + String cmd; + String args; + if (index == -1) { + cmd = cmdwithargsString; + args = ""; + } else { + cmd = cmdwithargsString.substring(0, index); + args = cmdwithargsString.substring(index + 1).trim(); //In case there are multiple spaces + } + debug("E"); + DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message); + message.getChannel().setTypingStatus(false); + return true; + } - private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) { - if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text - if (cmdwithargs.length() > mention.length() + 1) - cmdwithargs = cmdwithargs.delete(0, - cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length()); - else - cmdwithargs.replace(0, cmdwithargs.length(), "help"); - else - return false; - if (cmdwithargs.length() == 0) - cmdwithargs.replace(0, cmdwithargs.length(), "help"); - return true; - } + private static boolean debug = false; + + public static void debug(String debug) { + if (CommandListener.debug) //Debug + System.out.println(debug); + } + + public static boolean debug() { + return debug = !debug; + } + + private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) { + if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text + if (cmdwithargs.length() > mention.length() + 1) + cmdwithargs = cmdwithargs.delete(0, + cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length()); + else + cmdwithargs.replace(0, cmdwithargs.length(), "help"); + else { + if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/') + cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat + return false; + } + if (cmdwithargs.length() == 0) + cmdwithargs.replace(0, cmdwithargs.length(), "help"); + return true; + } } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/DebugMessageListener.java b/src/main/java/buttondevteam/discordplugin/listeners/DebugMessageListener.java old mode 100644 new mode 100755 index 220ff45..1e163c4 --- a/src/main/java/buttondevteam/discordplugin/listeners/DebugMessageListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/DebugMessageListener.java @@ -1,9 +1,9 @@ package buttondevteam.discordplugin.listeners; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCDebugMessageEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; public class DebugMessageListener implements Listener{ @EventHandler diff --git a/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java b/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java old mode 100644 new mode 100755 index 1712e0d..549bb97 --- a/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java @@ -23,8 +23,8 @@ public class ExceptionListener implements Listener { return; if (lastthrown.stream() .anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace()) - && e.getException().getMessage() == null ? ex.getMessage() == null - : e.getException().getMessage().equals(ex.getMessage())) // e.Exception.Message==ex.Message + && (e.getException().getMessage() == null ? ex.getMessage() == null + : e.getException().getMessage().equals(ex.getMessage()))) // e.Exception.Message==ex.Message && lastsourcemsg.contains(e.getSourceMessage())) return; SendException(e.getException(), e.getSourceMessage()); diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java old mode 100644 new mode 100755 index df1bf12..d4a3ce9 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -10,6 +10,8 @@ import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.ChatRoom; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.TBMCPlayer; +import com.vdurmont.emoji.EmojiParser; +import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.val; import org.bukkit.Bukkit; @@ -33,9 +35,10 @@ import sx.blah.discord.util.MissingPermissionsException; import java.awt.*; import java.time.Instant; import java.util.*; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; -import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -45,6 +48,7 @@ public class MCChatListener implements Listener, IListener private BukkitTask sendtask; private LinkedBlockingQueue> sendevents = new LinkedBlockingQueue<>(); private Runnable sendrunnable; + private static Thread sendthread; @EventHandler // Minecraft public void onMCChat(TBMCChatEvent ev) { @@ -54,8 +58,10 @@ public class MCChatListener implements Listener, IListener if (sendtask != null) return; sendrunnable = () -> { + sendthread = Thread.currentThread(); processMCToDiscord(); - sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); + if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down + sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); }; sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); } @@ -117,27 +123,41 @@ public class MCChatListener implements Listener, IListener } }; // Checks if the given channel is different than where the message was sent from + // Or if it was from MC Predicate isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase) || ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID(); if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp")) - && isdifferentchannel.test(DiscordPlugin.chatchannel)) + && (e.isFromcmd() || isdifferentchannel.test(DiscordPlugin.chatchannel))) doit.accept(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) : lastmsgdata); for (LastMsgData data : lastmsgPerUser) { - if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel) - && e.shouldSendTo(getSender(data.channel, data.user, data.dp))) + if (data.dp.isMinecraftChatEnabled() && (e.isFromcmd() || isdifferentchannel.test(data.channel)) + && e.shouldSendTo(getSender(data.channel, data.user))) doit.accept(data); } + + val iterator = lastmsgCustom.iterator(); + while (iterator.hasNext()) { //TODO: Add cmd to fix mcchat + val lmd = iterator.next(); + 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 + if (e.shouldSendTo(lmd.dcp) && e.getGroupID().equals(lmd.groupID)) //Check original user's permissions + doit.accept(lmd); + else { + 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."); + } + } } catch (Exception ex) { TBMCCoreAPI.SendException("Error while sending message to Discord!", ex); } } @RequiredArgsConstructor - private static class LastMsgData { + public static class LastMsgData { public IMessage message; public long time; public String content; @@ -147,6 +167,20 @@ public class MCChatListener implements Listener, IListener public final DiscordPlayer dp; } + public static class CustomLMD extends LastMsgData { + public final String groupID; + public final Channel mcchannel; + public final DiscordConnectedPlayer dcp; + + public CustomLMD(@NonNull IChannel channel, @NonNull IUser user, @NonNull DiscordPlayer dp, + @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp) { + super(channel, user, dp); + groupID = groupid; + this.mcchannel = mcchannel; + this.dcp = dcp; + } + } + @EventHandler public void onChatPreprocess(TBMCChatPreprocessEvent event) { int start = -1; @@ -168,7 +202,7 @@ public class MCChatListener implements Listener, IListener } private static final String[] UnconnectedCmds = new String[]{"list", "u", "shrug", "tableflip", "unflip", "mwiki", - "yeehaw"}; + "yeehaw", "lenny", "rp", "plugins"}; private static LastMsgData lastmsgdata; private static short lastlist = 0; @@ -177,6 +211,10 @@ public class MCChatListener implements Listener, IListener * Used for messages in PMs (mcchat). */ private static ArrayList lastmsgPerUser = new ArrayList(); + /** + * Used for town or nation chats or anything else + */ + private static ArrayList lastmsgCustom = new ArrayList<>(); public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) { TBMCPlayer mcp = dp.getAs(TBMCPlayer.class); @@ -220,6 +258,27 @@ public class MCChatListener implements Listener, IListener .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did)); } + public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, DiscordPlayer dp, IUser user, DiscordConnectedPlayer dcp) { + val lmd = new CustomLMD(channel, user, dp, groupid, mcchannel, dcp); + lastmsgCustom.add(lmd); + } + + public static boolean hasCustomChat(IChannel channel) { + return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID()); + } + + public static CustomLMD getCustomChat(IChannel channel) { + return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null); + } + + public static boolean removeCustomChat(IChannel channel) { + return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); + } + + public static List getCustomChats() { + return Collections.unmodifiableList(lastmsgCustom); + } + /** * May contain P<DiscordID> as key for public chat */ @@ -242,6 +301,12 @@ public class MCChatListener implements Listener, IListener data.message = null; // Since only private channels are stored, only those will work anyways } + public static void resetLastMessageCustom(IChannel channel) { + for (LastMsgData data : lastmsgCustom) + if (data.channel.getLongID() == channel.getLongID()) + data.message = null; + } + /** * This overload sends it to the global chat. */ @@ -258,37 +323,50 @@ public class MCChatListener implements Listener, IListener action.accept(DiscordPlugin.chatchannel); for (LastMsgData data : lastmsgPerUser) action.accept(data.channel); + lastmsgCustom.forEach(cc -> action.accept(cc.channel)); } private static void forAllowedMCChat(Consumer action, TBMCSystemChatEvent event) { if (Channel.GlobalChat.ID.equals(event.getChannel().ID)) action.accept(DiscordPlugin.chatchannel); for (LastMsgData data : lastmsgPerUser) - if (event.shouldSendTo(getSender(data.channel, data.user, data.dp))) + if (event.shouldSendTo(getSender(data.channel, data.user))) action.accept(data.channel); + lastmsgCustom.stream().filter(data -> event.shouldSendTo(data.dcp)) + .map(data -> data.channel).forEach(action); + } + + public static void stop() { + if (sendthread != null) sendthread.interrupt(); + if (recthread != null) recthread.interrupt(); } private BukkitTask rectask; private LinkedBlockingQueue recevents = new LinkedBlockingQueue<>(); private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks private Runnable recrun; + private static Thread recthread; @Override // Discord public void handle(MessageReceivedEvent ev) { if (DiscordPlugin.SafeMode) return; val author = ev.getMessage().getAuthor(); - if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID()) - && !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID()))) - return; if (author.isBot()) return; + final boolean hasCustomChat = hasCustomChat(ev.getChannel()); + if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID()) + && !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID())) + && !hasCustomChat) + return; if (ev.getMessage().getContent().equalsIgnoreCase("mcchat")) return; // Race condition: If it gets here after it enabled mcchat it says it - I might as well allow disabling with this (CommandListener) if (CommandListener.runCommand(ev.getMessage(), true)) return; if (!ev.getMessage().getChannel().isPrivate()) resetLastMessage(); + else if (hasCustomChat) + resetLastMessageCustom(ev.getChannel()); else resetLastMessage(ev.getMessage().getChannel()); lastlist++; @@ -296,8 +374,10 @@ public class MCChatListener implements Listener, IListener if (rectask != null) return; recrun = () -> { //Don't return in a while loop next time + recthread = Thread.currentThread(); processDiscordToMC(); - rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing + if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down + rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing }; rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing } @@ -315,7 +395,7 @@ public class MCChatListener implements Listener, IListener val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class); String dmessage = event.getMessage().getContent(); try { - final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender, user); + final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender); for (IUser u : event.getMessage().getMentions()) { dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting @@ -323,11 +403,15 @@ public class MCChatListener implements Listener, IListener dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName())); } - BiConsumer sendChatMessage = (channel, msg) -> // - TBMCChatAPI.SendChatMessage(channel, dsender, - msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() + dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?) + dmessage = dmessage.replaceAll(":(\\S+)\\|type_(?:(\\d)|(1)_2):", ":$1::skin-tone-$2:"); //Convert to Discord's format so it still shows up + + Function getChatMessage = msg -> // + msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) - : "")); + : ""); + + CustomLMD clmd = getCustomChat(event.getChannel()); boolean react = false; @@ -336,40 +420,46 @@ public class MCChatListener implements Listener, IListener if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) event.getMessage().delete(); }); - final String cmd = dmessage.substring(1).toLowerCase(); + //preprocessChat(dsender, dmessage); - Same is done below + final String cmdlowercased = dmessage.substring(1).toLowerCase(); if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds) - .noneMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) { + .noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) { // Command not whitelisted dsender.sendMessage("Sorry, you can only access these commands:\n" + Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc) .collect(Collectors.joining(", ")) + (user.getConnectedID(TBMCPlayer.class) == null - ? "\nTo access your commands, first please connect your accounts, using @ChromaBot connect in " + ? "\nTo access your commands, first please connect your accounts, using /connect in " + DiscordPlugin.botchannel.mention() - + "\nThen you can access all of your regular commands (even offline) in private chat: DM me `mcchat`!" - : "\nYou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!")); + + "\nThen y" + : "\nY") + + "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"); return; } if (lastlist > 5) { ListC = 0; lastlist = 0; } - if (cmd.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already + if (cmdlowercased.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already { dsender.sendMessage("Stop it. You know the answer."); lastlist = 0; } else { - int spi = cmd.indexOf(' '); - final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi); + int spi = cmdlowercased.indexOf(' '); + final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi); Optional ch = Channel.getChannels().stream() - .filter(c -> c.ID.equalsIgnoreCase(topcmd)).findAny(); + .filter(c -> c.ID.equalsIgnoreCase(topcmd) + || (c.IDs != null && c.IDs.length > 0 + && Arrays.stream(c.IDs).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny(); if (!ch.isPresent()) Bukkit.getScheduler().runTask(DiscordPlugin.plugin, - () -> VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd)); + () -> { + VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmdlowercased); + Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased); + }); else { Channel chc = ch.get(); - if (!chc.ID.equals(Channel.GlobalChat.ID) - && !event.getMessage().getChannel().isPrivate()) + if (!chc.ID.equals(Channel.GlobalChat.ID) && !chc.ID.equals("rp") && !event.getMessage().getChannel().isPrivate()) dsender.sendMessage( "You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels."); else { @@ -387,7 +477,11 @@ public class MCChatListener implements Listener, IListener dsender.sendMessage("You're now talking in: " + DPUtils.sanitizeString(dsender.getMcchannel().DisplayName)); } else { // Send single message - sendChatMessage.accept(chc, cmd.substring(spi + 1)); + final String msg = event.getMessage().getContent().substring(spi + 2); + if (clmd == null) + TBMCChatAPI.SendChatMessage(chc, dsender, getChatMessage.apply(msg), true); + else + TBMCChatAPI.SendChatMessageDontCheckSender(chc, dsender, getChatMessage.apply(msg), true, clmd.dcp); react = true; } } @@ -396,21 +490,20 @@ public class MCChatListener implements Listener, IListener lastlistp = (short) Bukkit.getOnlinePlayers().size(); } else {// Not a command if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 - && !event.getChannel().isPrivate()) - TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0, + && !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) + TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0, "everyone", (dsender instanceof Player ? ((Player) dsender).getDisplayName() : dsender.getName()) + " pinned a message on Discord."); else { - sendChatMessage.accept(dsender.getMcchannel(), dmessage); + if (clmd != null) + TBMCChatAPI.SendChatMessageDontCheckSender(clmd.mcchannel, dsender, getChatMessage.apply(dmessage), false, clmd.dcp); + else + TBMCChatAPI.SendChatMessage(dsender.getMcchannel(), dsender, getChatMessage.apply(dmessage)); react = true; } } if (react) { try { - /* - * System.out.println("Got message: " + m.getContent() + " with embeds: " + m.getEmbeds().stream().map(e -> e.getTitle() + " " + e.getDescription()) - * .collect(Collectors.joining("\n"))); - */ if (lastmsgfromd != null) { DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(), DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time @@ -426,10 +519,46 @@ public class MCChatListener implements Listener, IListener } } + private boolean preprocessChat(DiscordSenderBase dsender, String dmessage) { + if (dmessage.length() < 2) + return false; + int index = dmessage.indexOf(" "); + String cmd; + if (index == -1) { // Only the command is run + cmd = dmessage; + for (Channel channel : Channel.getChannels()) { + if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) { + Channel oldch = dsender.getMcchannel(); + if (oldch instanceof ChatRoom) + ((ChatRoom) oldch).leaveRoom(dsender); + if (oldch.equals(channel)) + dsender.setMcchannel(Channel.GlobalChat); + else { + dsender.setMcchannel(channel); + if (channel instanceof ChatRoom) + ((ChatRoom) channel).joinRoom(dsender); + } + dsender.sendMessage("You are now talking in: " + dsender.getMcchannel().DisplayName); + return true; + } + } + } else { // We have arguments + cmd = dmessage.substring(0, index); + for (Channel channel : Channel.getChannels()) { + if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) { + TBMCChatAPI.SendChatMessage(channel, dsender, dmessage.substring(index + 1)); + return true; + } + } + // TODO: Target selectors + } + return false; + } + /** * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. */ - private static DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) { + private static DiscordSenderBase getSender(IChannel channel, final IUser author) { val key = (channel.isPrivate() ? "" : "P") + author.getStringID(); return Stream.>>of( // https://stackoverflow.com/a/28833677/2703239 () -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java old mode 100644 new mode 100755 index 42e85a0..74ee6a2 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java @@ -45,26 +45,28 @@ public class MCListener implements Listener { public void onPlayerJoin(TBMCPlayerJoinEvent e) { if (e.getPlayer() instanceof DiscordConnectedPlayer) return; // Don't show the joined message for the fake player - final Player p = e.getPlayer(); - DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); - if (dp != null) { - val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); - MCChatListener.OnlineSenders.put(dp.getDiscordID(), - new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); - MCChatListener.OnlineSenders.put("P" + dp.getDiscordID(), - new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); - } - if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { - IUser user = DiscordPlugin.dc - .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); - p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() - + " do /discord accept"); - p.sendMessage("§bIf it wasn't you, do /discord decline"); - } - if (!DiscordPlugin.hooked) - MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game"); - MCChatListener.ListC = 0; - ChromaBot.getInstance().updatePlayerList(); + Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { + final Player p = e.getPlayer(); + DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); + if (dp != null) { + val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); + MCChatListener.OnlineSenders.put(dp.getDiscordID(), + new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); + MCChatListener.OnlineSenders.put("P" + dp.getDiscordID(), + new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); + } + if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { + IUser user = DiscordPlugin.dc + .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); + p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() + + " do /discord accept"); + p.sendMessage("§bIf it wasn't you, do /discord decline"); + } + if (!DiscordPlugin.hooked) + MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game"); + MCChatListener.ListC = 0; + ChromaBot.getInstance().updatePlayerList(); + }); } @EventHandler(priority = EventPriority.HIGHEST) @@ -93,7 +95,7 @@ public class MCListener implements Listener { if (DiscordPlugin.SafeMode) return; DiscordPlayer dp = e.getPlayer().getAs(DiscordPlayer.class); - if (dp == null || dp.getDiscordID() == null || dp.getDiscordID() == "") + if (dp == null || dp.getDiscordID() == null || dp.getDiscordID().equals("")) return; IUser user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); e.addInfo("Discord tag: " + user.getName() + "#" + user.getDiscriminator()); diff --git a/src/main/java/buttondevteam/discordplugin/mccommands/AcceptMCCommand.java b/src/main/java/buttondevteam/discordplugin/mccommands/AcceptMCCommand.java old mode 100644 new mode 100755 index abe8723..13b3095 --- a/src/main/java/buttondevteam/discordplugin/mccommands/AcceptMCCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mccommands/AcceptMCCommand.java @@ -1,7 +1,5 @@ package buttondevteam.discordplugin.mccommands; -import org.bukkit.entity.Player; - import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.commands.ConnectCommand; import buttondevteam.discordplugin.listeners.MCChatListener; @@ -9,6 +7,7 @@ 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 { @@ -18,7 +17,7 @@ public class AcceptMCCommand extends DiscordMCCommandBase { return new String[] { // "§6---- Accept Discord connection ----", // "Accept a pending connection between your Discord and Minecraft account.", // - "To start the connection process, do §b@ChromaBot connect §r in the #bot channel on Discord", // + "To start the connection process, do §b/connect §r in the #bot channel on Discord", // "Usage: /" + alias + " accept" // }; } diff --git a/src/main/java/buttondevteam/discordplugin/mccommands/DeclineMCCommand.java b/src/main/java/buttondevteam/discordplugin/mccommands/DeclineMCCommand.java old mode 100644 new mode 100755 index 813cc3a..831ad89 --- a/src/main/java/buttondevteam/discordplugin/mccommands/DeclineMCCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mccommands/DeclineMCCommand.java @@ -1,9 +1,8 @@ package buttondevteam.discordplugin.mccommands; -import org.bukkit.entity.Player; - 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 { @@ -13,7 +12,7 @@ public class DeclineMCCommand extends DiscordMCCommandBase { return new String[] { // "§6---- Decline Discord connection ----", // "Decline a pending connection between your Discord and Minecraft account.", // - "To start the connection process, do §b@ChromaBot connect §r in the #bot channel on Discord", // + "To start the connection process, do §b/connect §r in the #bot channel on Discord", // "Usage: /" + alias + " decline" // }; } diff --git a/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommandBase.java b/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommandBase.java old mode 100644 new mode 100755 diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java old mode 100644 new mode 100755 index 7bdda8e..6ce85f8 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java @@ -1,7 +1,8 @@ package buttondevteam.discordplugin.playerfaker; -import java.util.*; - +import buttondevteam.discordplugin.DiscordSenderBase; +import lombok.Getter; +import lombok.Setter; import org.bukkit.*; import org.bukkit.block.PistonMoveReaction; import org.bukkit.entity.Entity; @@ -10,13 +11,11 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import org.bukkit.util.Vector; - -import buttondevteam.discordplugin.DiscordSenderBase; -import lombok.Getter; -import lombok.Setter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.util.*; + @Getter @Setter @SuppressWarnings("deprecated") diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java old mode 100644 new mode 100755 index 8943970..c5b2c5c --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java @@ -1,25 +1,27 @@ package buttondevteam.discordplugin.playerfaker; -import java.net.InetSocketAddress; -import java.util.*; +import buttondevteam.discordplugin.DiscordPlugin; +import lombok.Getter; +import lombok.experimental.Delegate; import org.bukkit.*; import org.bukkit.advancement.Advancement; import org.bukkit.advancement.AdvancementProgress; import org.bukkit.conversations.Conversation; import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.entity.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.map.MapView; import org.bukkit.permissions.PermissibleBase; import org.bukkit.plugin.Plugin; import org.bukkit.scoreboard.Scoreboard; - -import buttondevteam.discordplugin.DiscordPlugin; -import lombok.experimental.Delegate; -import lombok.Getter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.net.InetSocketAddress; +import java.util.*; + public class DiscordFakePlayer extends DiscordHumanEntity implements Player { protected DiscordFakePlayer(IUser user, IChannel channel, int entityId, UUID uuid, String mcname) { super(user, channel, entityId, uuid); diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java old mode 100644 new mode 100755 index 26d220f..c1522f1 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java @@ -1,7 +1,5 @@ package buttondevteam.discordplugin.playerfaker; -import java.util.UUID; - import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -10,10 +8,11 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Villager; import org.bukkit.inventory.*; import org.bukkit.inventory.InventoryView.Property; - import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.util.UUID; + public abstract class DiscordHumanEntity extends DiscordLivingEntity implements HumanEntity { protected DiscordHumanEntity(IUser user, IChannel channel, int entityId, UUID uuid) { super(user, channel, entityId, uuid); diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordInventory.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordInventory.java old mode 100644 new mode 100755 index f8f9886..a97f715 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordInventory.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordInventory.java @@ -1,12 +1,5 @@ package buttondevteam.discordplugin.playerfaker; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; @@ -14,6 +7,13 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + public class DiscordInventory implements Inventory { public DiscordInventory(DiscordHumanEntity holder) { this.holder = holder; diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java old mode 100644 new mode 100755 index d4e78c1..f261de4 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java @@ -1,12 +1,7 @@ package buttondevteam.discordplugin.playerfaker; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; - +import lombok.Getter; +import lombok.Setter; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.attribute.Attribute; @@ -21,12 +16,11 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; - -import lombok.Getter; -import lombok.Setter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; +import java.util.*; + public abstract class DiscordLivingEntity extends DiscordEntity implements LivingEntity { protected DiscordLivingEntity(IUser user, IChannel channel, int entityId, UUID uuid) { diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordPlayerInventory.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordPlayerInventory.java old mode 100644 new mode 100755 diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/VanillaCommandListener.java b/src/main/java/buttondevteam/discordplugin/playerfaker/VanillaCommandListener.java old mode 100644 new mode 100755 index 3355478..29f3a13 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/VanillaCommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/VanillaCommandListener.java @@ -1,7 +1,10 @@ package buttondevteam.discordplugin.playerfaker; -import java.util.Arrays; - +import buttondevteam.discordplugin.DiscordSenderBase; +import buttondevteam.discordplugin.IMCPlayer; +import lombok.Getter; +import lombok.val; +import net.minecraft.server.v1_12_R1.*; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_12_R1.CraftServer; import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; @@ -9,17 +12,7 @@ import org.bukkit.craftbukkit.v1_12_R1.command.VanillaCommandWrapper; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Player; -import buttondevteam.discordplugin.DiscordSenderBase; -import buttondevteam.discordplugin.IMCPlayer; -import lombok.Getter; -import lombok.val; -import net.minecraft.server.v1_12_R1.ChatMessage; -import net.minecraft.server.v1_12_R1.CommandException; -import net.minecraft.server.v1_12_R1.EnumChatFormat; -import net.minecraft.server.v1_12_R1.IChatBaseComponent; -import net.minecraft.server.v1_12_R1.ICommandListener; -import net.minecraft.server.v1_12_R1.MinecraftServer; -import net.minecraft.server.v1_12_R1.World; +import java.util.Arrays; public class VanillaCommandListener> implements ICommandListener { private @Getter T player; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml old mode 100644 new mode 100755 diff --git a/src/test/java/buttondevteam/DiscordPlugin/AppTest.java b/src/test/java/buttondevteam/DiscordPlugin/AppTest.java old mode 100644 new mode 100755