From 6a09b233312a93cf8d7cd96eaf5260981ab42f94 Mon Sep 17 00:00:00 2001 From: Seth <13510767+ZeroEpoch1969@users.noreply.github.com> Date: Fri, 29 Dec 2017 11:12:47 -0700 Subject: [PATCH] Added discord support (#11) --- pom.xml | 62 +++++++++--- .../totalfreedommod/TotalFreedomMod.java | 3 + .../totalfreedommod/admin/Admin.java | 8 +- .../command/Command_linkdiscord.java | 49 ++++++++++ .../command/Command_unlinkdiscord.java | 34 +++++++ .../command/Command_verify.java | 88 +++++++++++++++++ .../totalfreedommod/config/ConfigEntry.java | 2 + .../totalfreedommod/discord/Discord.java | 96 +++++++++++++++++++ .../discord/MessageListener.java | 29 ++++++ src/main/resources/config.yml | 15 ++- 10 files changed, 371 insertions(+), 15 deletions(-) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java diff --git a/pom.xml b/pom.xml index 987c429c..5e53cc9a 100644 --- a/pom.xml +++ b/pom.xml @@ -73,91 +73,98 @@ org.apache.commons commons-lang3 3.6 + provided commons-io commons-io 2.5 + provided org.projectlombok lombok 1.16.18 + provided org.spigotmc spigot-api 1.12-pre5-SNAPSHOT - compile + provided com.github.Pravian Aero 2.1-SNAPSHOT - system - ${project.basedir}/lib/aero-2.1-SNAPSHOT.jar + provided com.github.TotalFreedom BukkitTelnet 4.5-pre1 + provided net.ess3 Essentials 2.13.1 + provided com.sk89q worldguard 6.2 - system - ${project.basedir}/lib/worldguard-6.2.jar + provided com.github.TotalFreedom.TF-WorldEdit worldedit-bukkit 6.1.0-TF + provided com.github.TotalFreedom.TF-WorldEdit worldedit-core 6.1.0-TF + provided net.coreprotect CoreProtect 2.14.2 - system - ${project.basedir}/lib/CoreProtect_2.14.2.jar + provided me.libraryaddict LibsDisguise 9.4.0-SNAPSHOT - system - ${project.basedir}/lib/LibsDisguises.jar + provided minecraft.server Spigot 1.12 - system - ${project.basedir}/lib/minecraft_server.jar + provided + + + + net.dv8tion + JDA + 3.4.0_317-withDependencies - @@ -184,7 +191,7 @@ 1.7 - + maven-antrun-plugin @@ -294,6 +301,35 @@ + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + target/generated-sources + + + + + + org.apache.maven.plugins + maven-shade-plugin + 1.4 + + + package + + shade + + + target/${project.name}.jar + false + + + + diff --git a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java index 92fb548e..57b22c40 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java @@ -25,6 +25,7 @@ import me.totalfreedom.totalfreedommod.bridge.WorldEditBridge; import me.totalfreedom.totalfreedommod.caging.Cager; import me.totalfreedom.totalfreedommod.command.CommandLoader; import me.totalfreedom.totalfreedommod.config.MainConfig; +import me.totalfreedom.totalfreedommod.discord.Discord; import me.totalfreedom.totalfreedommod.freeze.Freezer; import me.totalfreedom.totalfreedommod.fun.ItemFun; import me.totalfreedom.totalfreedommod.fun.Jumppads; @@ -79,6 +80,7 @@ public class TotalFreedomMod extends AeroPlugin public PlayerList pl; public Announcer an; public ChatManager cm; + public Discord dc; public BanManager bm; public PermbanList pm; public ProtectArea pa; @@ -176,6 +178,7 @@ public class TotalFreedomMod extends AeroPlugin pl = services.registerService(PlayerList.class); an = services.registerService(Announcer.class); cm = services.registerService(ChatManager.class); + dc = services.registerService(Discord.class); bm = services.registerService(BanManager.class); pm = services.registerService(PermbanList.class); pa = services.registerService(ProtectArea.class); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java index e5ae049c..09be8ee9 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java @@ -40,6 +40,9 @@ public class Admin implements ConfigLoadable, ConfigSavable, Validatable @Getter @Setter private String loginMessage = null; + @Getter + @Setter + private String discordID = null; public static final String CONFIG_FILENAME = "admins.yml"; @@ -65,7 +68,8 @@ public class Admin implements ConfigLoadable, ConfigSavable, Validatable .append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n") .append("- Custom Login Message: ").append(loginMessage).append("\n") .append("- Rank: ").append(rank.getName()).append("\n") - .append("- Is Active: ").append(active); + .append("- Is Active: ").append(active).append("\n") + .append("- Discord ID: ").append(discordID).append("\n"); return output.toString(); } @@ -88,6 +92,7 @@ public class Admin implements ConfigLoadable, ConfigSavable, Validatable ips.addAll(cs.getStringList("ips")); lastLogin = FUtil.stringToDate(cs.getString("last_login")); loginMessage = cs.getString("login_message", null); + discordID = cs.getString("discord_id", null); } @Override @@ -100,6 +105,7 @@ public class Admin implements ConfigLoadable, ConfigSavable, Validatable cs.set("ips", Lists.newArrayList(ips)); cs.set("last_login", FUtil.dateToString(lastLogin)); cs.set("login_message", loginMessage); + cs.set("discord_id", discordID); } public boolean isAtLeast(Rank pRank) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java new file mode 100644 index 00000000..9cd1d5cd --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java @@ -0,0 +1,49 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.admin.Admin; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.ChatColor; +import java.util.Random; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Link your discord account to your minecraft account", usage = "/") +public class Command_linkdiscord extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!plugin.dc.enabled) + { + msg("The discord verification system is currently disabled.", ChatColor.RED); + return true; + } + + Admin admin = plugin.al.getAdmin(playerSender); + if (admin.getDiscordID() != null) + { + msg("Your minecraft account is already linked to a discord account.", ChatColor.RED); + return true; + } + + if (plugin.dc.LINK_CODES.containsValue(admin)) + { + msg("Your linking code is " + ChatColor.GREEN + plugin.dc.getCodeForAdmin(admin), ChatColor.AQUA); + } + else + { + String code = ""; + Random random = new Random(); + for (int i = 0; i < 5; i++) + { + code += random.nextInt(10); + } + plugin.dc.LINK_CODES.put(code, admin); + msg("Your linking code is " + ChatColor.GREEN + code, ChatColor.AQUA); + } + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java new file mode 100644 index 00000000..c263997b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java @@ -0,0 +1,34 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.admin.Admin; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.ChatColor; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Unlink your discord account to your minecraft account", usage = "/") +public class Command_unlinkdiscord extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!plugin.dc.enabled) + { + msg("The discord verification system is currently disabled.", ChatColor.RED); + return true; + } + + Admin admin = plugin.al.getAdmin(playerSender); + if (admin.getDiscordID() == null) + { + msg("Your minecraft account is not linked to a discord account.", ChatColor.RED); + return true; + } + admin.setDiscordID(null); + msg("Your minecraft account has been successfully unlinked from the discord account.", ChatColor.GREEN); + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java new file mode 100644 index 00000000..174309a2 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java @@ -0,0 +1,88 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.util.FUtil; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.ChatColor; +import java.util.Random; +import java.util.Date; +import net.pravian.aero.util.Ips; + +@CommandPermissions(level = Rank.IMPOSTOR, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Sends a verification code to the player, or the player can input the sent code.", usage = "/ [code]") +public class Command_verify extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!plugin.dc.enabled) + { + msg("The discord verification system is currently disabled", ChatColor.RED); + return true; + } + + if (!plugin.al.isAdminImpostor(playerSender)) + { + msg("You are not an imposter, therefore you do not need to verify.", ChatColor.RED); + return true; + } + + Admin admin = plugin.al.getEntryByName(playerSender.getName()); + + if (admin.getDiscordID() == null) + { + msg("You do not have a discord account linked to your minecraft account, please verify the manual way.", ChatColor.RED); + return true; + } + + if (args.length < 1) + { + String code = ""; + Random random = new Random(); + for (int i = 0; i < 10; i++) + { + code += random.nextInt(10); + } + plugin.dc.VERIFY_CODES.add(code); + plugin.dc.bot.getUserById(admin.getDiscordID()).openPrivateChannel().complete().sendMessage("A user with the ip `" + Ips.getIp(playerSender) + "` has sent a verification request. Please run the following in-game command: `/verify " + code + "`").complete(); + msg("A verification code has been sent to your account, please copy the code and run /verify ", ChatColor.GREEN); + } + else + { + String code = args[0]; + if (!plugin.dc.VERIFY_CODES.contains(code)) + { + msg("You have entered an invalid verification code", ChatColor.RED); + return true; + } + else + { + plugin.dc.VERIFY_CODES.remove(code); + FUtil.bcastMsg(playerSender.getName() + " has verified themself!", ChatColor.GOLD); + FUtil.adminAction(ConfigEntry.SERVER_NAME.getString(), "Readding " + admin.getName() + " to the staff list", true); + if (playerSender != null) + { + admin.setName(playerSender.getName()); + admin.addIp(Ips.getIp(playerSender)); + } + admin.setActive(true); + admin.setLastLogin(new Date()); + plugin.al.save(); + plugin.al.updateTables(); + final FPlayer fPlayer = plugin.pl.getPlayer(playerSender); + if (fPlayer.getFreezeData().isFrozen()) + { + fPlayer.getFreezeData().setFrozen(false); + msg("You have been unfrozen."); + } + } + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java b/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java index d0ecfb46..d42032a0 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java @@ -44,6 +44,8 @@ public enum ConfigEntry SERVER_BAN_URL(String.class, "server.ban_url"), SERVER_PERMBAN_URL(String.class, "server.permban_url"), // + DISCORD_TOKEN(String.class, "discord.token"), + // ADMINLIST_CLEAN_THESHOLD_HOURS(Integer.class, "adminlist.clean_threshold_hours"), ADMINLIST_CONSOLE_IS_SENIOR(Boolean.class, "adminlist.console_is_senior"), // diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java new file mode 100644 index 00000000..9a750325 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java @@ -0,0 +1,96 @@ +package me.totalfreedom.totalfreedommod.discord; + +import com.google.common.base.Strings; +import me.totalfreedom.totalfreedommod.discord.MessageListener; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import net.dv8tion.jda.core.JDA; +import net.dv8tion.jda.core.JDABuilder; +import net.dv8tion.jda.core.entities.MessageChannel; +import net.dv8tion.jda.core.AccountType; +import net.dv8tion.jda.core.exceptions.RateLimitedException; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import javax.security.auth.login.LoginException; + +public class Discord extends FreedomService +{ + public static HashMap LINK_CODES = new HashMap<>(); + public static List VERIFY_CODES = new ArrayList(); + public static JDA bot = null; + public static Boolean enabled = false; + + public Discord(TotalFreedomMod plugin) + { + super(plugin); + } + + public void startBot() + { + if (!Strings.isNullOrEmpty(ConfigEntry.DISCORD_TOKEN.getString())) + { + enabled = true; + } + else + { + enabled = false; + return; + } + if (bot != null) + { + for (Object object : bot.getRegisteredListeners()) + { + bot.removeEventListener(object); + } + } + try + { + bot = new JDABuilder(AccountType.BOT).setToken(ConfigEntry.DISCORD_TOKEN.getString()).addEventListener(new MessageListener()).setAudioEnabled(false).setAutoReconnect(true).buildBlocking(); + FLog.info("Discord verification bot has successfully enabled!"); + } + catch (LoginException e) + { + FLog.warning("An invalid token for the discord verification bot, the bot will not enable."); + } + catch (RateLimitedException e) + { + FLog.warning("The discord verification bot was ratelimited trying to login, please try again later."); + } + catch (IllegalArgumentException | InterruptedException e) + { + FLog.warning("Discord verification bot failed to start."); + } + } + + @Override + protected void onStart() + { + startBot(); + } + + public static String getCodeForAdmin(Admin admin) + { + for (String code: LINK_CODES.keySet()) + { + if (LINK_CODES.get(code).equals(admin)) + { + return code; + } + } + return null; + } + + @Override + protected void onStop() + { + if (bot != null) + { + bot.shutdown(); + } + FLog.info("Discord verification bot has successfully shutdown."); + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java new file mode 100644 index 00000000..f9412b7c --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java @@ -0,0 +1,29 @@ +package me.totalfreedom.totalfreedommod.discord; + +import me.totalfreedom.totalfreedommod.admin.Admin; +import net.dv8tion.jda.core.events.message.priv.PrivateMessageReceivedEvent; +import net.dv8tion.jda.core.hooks.ListenerAdapter; + +public class MessageListener extends ListenerAdapter +{ + public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) + { + if (!event.getAuthor().getId().equals(Discord.bot.getSelfUser().getId())) + { + + // Handle link code + if (event.getMessage().getContentRaw().matches("[0-9][0-9][0-9][0-9][0-9]")) + { + String code = event.getMessage().getRawContent(); + if (Discord.LINK_CODES.get(code) != null) + { + Admin admin = Discord.LINK_CODES.get(code); + admin.setDiscordID(event.getMessage().getAuthor().getId()); + Discord.LINK_CODES.remove(code); + event.getChannel().sendMessage("Link successful. Now this Discord account is linked with the Minecraft account `" + admin.getName() + "`.\n " + + "Now when you are an impostor on the server, you may use `/verify` to verify.").complete();; + } + } + } + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 46a3cb60..5e3c6289 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -27,6 +27,11 @@ server: # URL players should appeal for permanent bans at permban_url: http://bit.ly/TF_PermBan +# Discord +discord: + # If you do not have a token, make a bot account and get one at https://discordapp.com/developers/applications/me + token: '' + # Admin list adminlist: @@ -36,6 +41,12 @@ adminlist: # Give the default CONSOLE senior admin privileges. # Handy in development environments. console_is_senior: true + +# CoreProtect +coreprotect: + auto_wipe: false + + file_limit: 5000 # ForceIP configuration forceip: @@ -47,7 +58,6 @@ forceip: # The kick message sent to players when logging in with the wrong hostname kickmsg: You have been kicked from the server - Please connect using %address% - # Blocking certain events allow: fire_place: false @@ -58,6 +68,9 @@ allow: water_place: false tnt_minecarts: false explosions: false + redstone: true + fireworks: false + frostwalker: false # Blocked commands: #