From 3576a9bb6ec37a264ee5320e596580e47c62bead Mon Sep 17 00:00:00 2001 From: Lemon Date: Sat, 24 Mar 2018 20:41:45 +0500 Subject: [PATCH] [UNTESTED] implement player verification system --- .../totalfreedommod/TotalFreedomMod.java | 3 + .../command/Command_linkdiscord.java | 62 ++++--- .../command/Command_playerverify.java | 96 +++++++++++ .../command/Command_saconfig.java | 5 +- .../command/Command_verify.java | 134 ++++++++------- .../command/Command_verifyplayer.java | 33 ++++ .../totalfreedommod/config/ConfigEntry.java | 6 +- .../totalfreedommod/discord/Discord.java | 11 ++ .../discord/MessageListener.java | 14 +- .../PlayerVerification.java | 152 ++++++++++++++++++ .../playerverification/VPlayer.java | 134 +++++++++++++++ .../totalfreedommod/rank/RankManager.java | 8 +- 12 files changed, 568 insertions(+), 90 deletions(-) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_playerverify.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifyplayer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/playerverification/PlayerVerification.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/playerverification/VPlayer.java diff --git a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java index c03a6c0c..fe1522f1 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java @@ -15,6 +15,7 @@ import me.totalfreedom.totalfreedommod.freeze.Freezer; import me.totalfreedom.totalfreedommod.fun.*; import me.totalfreedom.totalfreedommod.httpd.HTTPDaemon; import me.totalfreedom.totalfreedommod.player.PlayerList; +import me.totalfreedom.totalfreedommod.playerverification.PlayerVerification; import me.totalfreedom.totalfreedommod.punishments.PunishmentList; import me.totalfreedom.totalfreedommod.rank.RankManager; import me.totalfreedom.totalfreedommod.rollback.RollbackManager; @@ -97,6 +98,7 @@ public class TotalFreedomMod extends AeroPlugin public Trailer tr; public HTTPDaemon hd; public SignBlocker snp; + public PlayerVerification pv; // // Bridges public ServiceManager bridges; @@ -198,6 +200,7 @@ public class TotalFreedomMod extends AeroPlugin ew = services.registerService(EntityWiper.class); fd = services.registerService(FrontDoor.class); sp = services.registerService(ServerPing.class); + pv = services.registerService(PlayerVerification.class); // Fun it = services.registerService(ItemFun.class); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java index 9cd1d5cd..ff4715e2 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java @@ -1,14 +1,17 @@ package me.totalfreedom.totalfreedommod.command; -import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.discord.Discord; +import me.totalfreedom.totalfreedommod.playerverification.VPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.ChatColor; 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) +@CommandPermissions(level = Rank.NON_OP, source = SourceType.ONLY_IN_GAME) @CommandParameters(description = "Link your discord account to your minecraft account", usage = "/") public class Command_linkdiscord extends FreedomCommand { @@ -21,28 +24,45 @@ public class Command_linkdiscord extends FreedomCommand 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); + + if (plugin.al.isAdmin(playerSender)) { + 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 (Discord.LINK_CODES.containsValue(admin)) { + msg("Your linking code is " + ChatColor.GREEN + Discord.getCodeForAdmin(admin), ChatColor.AQUA); + } else { + String code = ""; + Random random = new Random(); + for (int i = 0; i < 5; i++) { + code += random.nextInt(10); + } + Discord.LINK_CODES.put(code, admin); + msg("Your linking code is " + ChatColor.GREEN + code, ChatColor.AQUA); + } } else { - String code = ""; - Random random = new Random(); - for (int i = 0; i < 5; i++) - { - code += random.nextInt(10); + VPlayer data = plugin.pv.getVerificationPlayer(playerSender); + if (data.getDiscordID() != null) { + msg("Your minecraft account is already linked to a discord account.", ChatColor.RED); + return true; + } + + if (Discord.PLAYER_LINK_CODES.containsValue(data)) { + msg("Your linking code is " + ChatColor.GREEN + Discord.getCodeForPlayer(data), ChatColor.AQUA); + } else { + String code = ""; + Random random = new Random(); + for (int i = 0; i < 5; i++) { + code += random.nextInt(10); + } + Discord.PLAYER_LINK_CODES.put(code, data); + msg("Your linking code is " + ChatColor.GREEN + code, ChatColor.AQUA); } - 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_playerverify.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_playerverify.java new file mode 100644 index 00000000..a180e22c --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_playerverify.java @@ -0,0 +1,96 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.playerverification.VPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import net.pravian.aero.util.Ips; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Manage your verification", usage = "/ ", aliases = "playerverification, opverification, opverify, opv") +public class Command_playerverify extends FreedomCommand { + @Override + protected boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { + if (args.length < 2) { + return false; + } + if (plugin.al.isAdmin(sender)) { + msg("This command is only for OP's.", ChatColor.RED); + return true; + } + switch (args[0].toLowerCase()) { + case "enable": + switch (args[1].toLowerCase()) { + case "discord": + if (!plugin.dc.enabled) { + msg("The discord verification system is currently disabled.", ChatColor.RED); + return true; + } + VPlayer data = plugin.pv.getVerificationPlayer(playerSender); + if (data.isDiscordVerificationEnabled()) { + msg("Discord verification is already enabled for you.", ChatColor.RED); + return true; + } + data.setDiscordVerificationEnabled(true); + plugin.pv.saveVerificationData(data); + msg("Enabled discord verification. Please type /linkdiscord to link a discord account.", ChatColor.AQUA); + return true; + case "forum": + msg("TODO. This will be enabled in a later update. Please use discord verification instead."); + return true; + default: + return false; + } + case "disable": + switch (args[1].toLowerCase()) { + case "discord": + VPlayer data = plugin.pv.getVerificationPlayer(playerSender); + if (!data.isDiscordVerificationEnabled()) { + msg("Discord verification is already disabled for you.", ChatColor.RED); + return true; + } + data.setDiscordVerificationEnabled(false); + plugin.pv.saveVerificationData(data); + msg("Disabled discord verification.", ChatColor.AQUA); + return true; + case "forum": + msg("TODO. Forum verification will be enabled in a later update."); + return true; + default: + return false; + } + case "status": + switch (args[1].toLowerCase()) { + case "discord": + VPlayer data = plugin.pv.getVerificationPlayer(playerSender); + boolean enabled = data.isDiscordVerificationEnabled(); + boolean specified = data.getDiscordID() != null; + msg(ChatColor.GRAY + "Discord Verification Enabled: " + (enabled ? ChatColor.AQUA + "true" : ChatColor.RED + "false")); + msg(ChatColor.GRAY + "Discord ID: " + (specified ? ChatColor.AQUA + data.getDiscordID() : ChatColor.RED + "not set")); + return true; + case "forum": + msg("TODO. Forum verification will be enabled in a later update."); + return true; + default: + return false; + } + case "clearips": + VPlayer data = plugin.pv.getVerificationPlayer(playerSender); + int cleared = 0; + for (String ip : data.getIPs()) { + if (!ip.equals(Ips.getIp(playerSender))) { + data.removeIp(ip); + cleared++; + } + } + msg("Cleared all IP's except your current IP \"" + Ips.getIp(playerSender) + "\""); + msg("Cleared " + cleared + " IP's."); + plugin.pv.saveVerificationData(data); + return true; + default: + return false; + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java index f3d00f9d..b4fc9c9d 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java @@ -1,6 +1,5 @@ package me.totalfreedom.totalfreedommod.command; -import java.util.Date; import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.rank.Rank; @@ -12,6 +11,8 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.Date; + @CommandPermissions(level = Rank.OP, source = SourceType.BOTH) @CommandParameters(description = "Manage admins.", usage = "/ | >") public class Command_saconfig extends FreedomCommand @@ -220,8 +221,8 @@ public class Command_saconfig extends FreedomCommand player.setOp(true); player.sendMessage(YOU_ARE_OP); } + plugin.pv.removeEntry(player.getName()); // admins can't have player verification entries } - 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 index 0d8ddcf4..3bda4d41 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java @@ -1,88 +1,100 @@ 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 me.totalfreedom.totalfreedommod.discord.Discord; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.util.Ips; +import org.bukkit.ChatColor; 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; +import java.util.Random; @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 -{ +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) - { + 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)) - { + + if (!plugin.al.isAdminImpostor(playerSender) && !plugin.pv.isPlayerImpostor(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); + + String discordId = ""; + + if (plugin.al.isAdminImpostor(playerSender)) { + 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; } - 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 admin list", true); - if (playerSender != null) - { - admin.setName(playerSender.getName()); - admin.addIp(Ips.getIp(playerSender)); + discordId = admin.getDiscordID(); + } else { + if (plugin.pv.isPlayerImpostor(playerSender)) { + if (plugin.pv.getVerificationPlayer(playerSender).getDiscordID() == null) { + msg("You do not have a discord account linked to your minecraft account, please verify the manual way.", ChatColor.RED); + return true; } - admin.setActive(true); - admin.setLastLogin(new Date()); - plugin.al.save(); - plugin.al.updateTables(); - plugin.rm.updateDisplay(playerSender); - final FPlayer fPlayer = plugin.pl.getPlayer(playerSender); - if (fPlayer.getFreezeData().isFrozen()) - { - fPlayer.getFreezeData().setFrozen(false); - msg("You have been unfrozen."); + discordId = plugin.pv.getVerificationPlayer(playerSender).getDiscordID(); + } + } + + if (args.length < 1) { + String code = ""; + Random random = new Random(); + for (int i = 0; i < 10; i++) { + code += random.nextInt(10); + } + Discord.VERIFY_CODES.add(code); + Discord.bot.getUserById(discordId).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 (!Discord.VERIFY_CODES.contains(code)) { + msg("You have entered an invalid verification code", ChatColor.RED); + return true; + } else { + if (plugin.al.isAdminImpostor(playerSender)) { + Admin admin = plugin.al.getEntryByName(playerSender.getName()); + Discord.VERIFY_CODES.remove(code); + FUtil.bcastMsg(playerSender.getName() + " has verified themself!", ChatColor.GOLD); + FUtil.adminAction(ConfigEntry.SERVER_NAME.getString(), "Readding " + admin.getName() + " to the admin 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(); + plugin.rm.updateDisplay(playerSender); + final FPlayer fPlayer = plugin.pl.getPlayer(playerSender); + if (fPlayer.getFreezeData().isFrozen()) { + fPlayer.getFreezeData().setFrozen(false); + msg("You have been unfrozen."); + } + } else { + final FPlayer fPlayer = plugin.pl.getPlayer(playerSender); + if (fPlayer.getFreezeData().isFrozen()) { + fPlayer.getFreezeData().setFrozen(false); + msg("You have been unfrozen."); + } + plugin.pv.verifyPlayer(playerSender); } } + return true; } return true; } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifyplayer.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifyplayer.java new file mode 100644 index 00000000..404eb145 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifyplayer.java @@ -0,0 +1,33 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Manually verifies a player", usage = "/ ") +public class Command_verifyplayer extends FreedomCommand { + + @Override + public boolean run(final CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { + if (args.length == 0) { + return false; + } + final Player player = getPlayer(args[0]); + if (player == null) { + msg(FreedomCommand.PLAYER_NOT_FOUND, ChatColor.RED); + return true; + } + if (!plugin.pv.isPlayerImpostor(player)) { + msg("That player is not an impostor."); + return true; + } + FUtil.adminAction(sender.getName(), "Manually verifying player " + player.getName(), true); + plugin.pv.verifyPlayer(player); + + 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 edcc15cc..48383a44 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java @@ -1,12 +1,15 @@ package me.totalfreedom.totalfreedommod.config; import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import org.bukkit.potion.PotionEffectType; import java.util.List; + public enum ConfigEntry { + FORCE_IP_ENABLED(Boolean.class, "forceip.enabled"), FORCE_IP_PORT(Integer.class, "forceip.port"), FORCE_IP_KICKMSG(String.class, "forceip.kickmsg"), @@ -106,7 +109,7 @@ public enum ConfigEntry private final Class type; private final String configName; - private ConfigEntry(Class type, String configName) + ConfigEntry(Class type, String configName) { this.type = type; this.configName = configName; @@ -130,6 +133,7 @@ public enum ConfigEntry public String setString(String value) { getConfig().setString(this, value); + PotionEffectType type = PotionEffectType.ABSORPTION; return value; } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java index bbc2ad88..b371ddb4 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java @@ -5,6 +5,7 @@ import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.playerverification.VPlayer; import me.totalfreedom.totalfreedommod.util.FLog; import net.dv8tion.jda.core.AccountType; import net.dv8tion.jda.core.JDA; @@ -18,6 +19,7 @@ import java.util.List; public class Discord extends FreedomService { public static HashMap LINK_CODES = new HashMap<>(); + public static HashMap PLAYER_LINK_CODES = new HashMap(); public static List VERIFY_CODES = new ArrayList(); public static JDA bot = null; public Boolean enabled = false; @@ -74,6 +76,15 @@ public class Discord extends FreedomService return null; } + public static String getCodeForPlayer(VPlayer playerData) { + for (String code : PLAYER_LINK_CODES.keySet()) { + if (PLAYER_LINK_CODES.get(code).equals(playerData)) { + return code; + } + } + return null; + } + @Override protected void onStop() { diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java index c63d6a3a..474e0675 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageListener.java @@ -1,6 +1,8 @@ package me.totalfreedom.totalfreedommod.discord; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.playerverification.VPlayer; import net.dv8tion.jda.core.events.message.priv.PrivateMessageReceivedEvent; import net.dv8tion.jda.core.hooks.ListenerAdapter; @@ -15,14 +17,22 @@ public class MessageListener extends ListenerAdapter if (event.getMessage().getContentRaw().matches("[0-9][0-9][0-9][0-9][0-9]")) { String code = event.getMessage().getContentRaw(); - if (Discord.LINK_CODES.get(code) != null) - { + 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(); } + if (Discord.PLAYER_LINK_CODES.get(code) != null) { + VPlayer player = Discord.PLAYER_LINK_CODES.get(code); + player.setDiscordID(event.getMessage().getAuthor().getId()); + + TotalFreedomMod.plugin().pv.saveVerificationData(player); + Discord.PLAYER_LINK_CODES.remove(code); + event.getChannel().sendMessage("Link successful. Now this Discord account is linked with the Minecraft account `" + player.getName() + "`.\n " + + "Now when you are an impostor on the server, you may use `/verify` to verify.").complete(); + } } } } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/playerverification/PlayerVerification.java b/src/main/java/me/totalfreedom/totalfreedommod/playerverification/PlayerVerification.java new file mode 100644 index 00000000..6a1c0f2d --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/playerverification/PlayerVerification.java @@ -0,0 +1,152 @@ +package me.totalfreedom.totalfreedommod.playerverification; + +import com.google.common.collect.Maps; +import lombok.Getter; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FLog; +import net.pravian.aero.config.YamlConfig; +import net.pravian.aero.util.Ips; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.io.File; +import java.util.Map; + +public class PlayerVerification extends FreedomService { + + @Getter + public final Map dataMap = Maps.newHashMap(); // username, data + private File configFolder; + + public PlayerVerification(TotalFreedomMod plugin) { + super(plugin); + this.configFolder = new File(plugin.getDataFolder(), "playerverification"); + } + + @Override + protected void onStart() { + dataMap.clear(); + } + + public void save(VPlayer data) { + YamlConfig config = getConfig(data); + data.saveTo(config); + config.save(); + } + + @Override + protected void onStop() { + //save all (should be saved in theory but to be safe) + for (VPlayer player : dataMap.values()) { + save(player); + } + } + + public Boolean isPlayerImpostor(Player player) { + VPlayer vplayer = getVerificationPlayer(player.getName()); + return !plugin.al.isAdmin(player) && vplayer != null && (vplayer.getForumVerificationEnabled() || vplayer.getDiscordVerificationEnabled()) && !vplayer.getIPs().contains(Ips.getIp(player)); + } + + public void verifyPlayer(Player player) { + if (!isPlayerImpostor(player)) { + return; + } + VPlayer vplayer = getVerificationPlayer(player.getName()); + vplayer.addIp(Ips.getIp(player)); + saveVerificationData(vplayer); + } + + public void saveVerificationData(VPlayer player) { + if (dataMap.containsKey(player.getName())) { + dataMap.remove(player.getName()); + } + dataMap.put(player.getName(), player); + save(player); + } + + //may not return null + public VPlayer getVerificationPlayer(Player player) { + VPlayer data = getVerificationPlayer(player.getName()); + if (data != null) { + return data; + } + // Create new entry. + FLog.info("Creating new player verification entry for " + player.getName()); + + // Create new player data + VPlayer newEntry = new VPlayer(player.getName()); + newEntry.addIp(Ips.getIp(player)); + saveVerificationData(newEntry); + return newEntry; + } + + //may return null + public VPlayer getVerificationPlayer(String username) { + if (dataMap.containsKey(username)) { + return dataMap.get(username); + } + VPlayer player = loadData(username); + if (player != null) { + return player; + } + + return null; + } + + public VPlayer loadData(String username) { + final File configFile = getConfigFile(username); + if (!configFile.exists()) { + return null; + } + + final VPlayer data = new VPlayer(username); + data.loadFrom(getConfig(data)); + + if (!data.isValid()) { + FLog.warning("Could not load player verification entry: " + username + ". Entry is not valid!"); + configFile.delete(); + return null; + } + + + // Only store data in map if the player is online + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + if (onlinePlayer.getName().equals(username)) { + dataMap.put(username, data); + return data; + } + } + return data; + } + + public void removeEntry(String username) { + if (getVerificationPlayer(username) != null) { + getConfigFile(username).delete(); + if (dataMap.containsKey(username)) { + dataMap.remove(username); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerQuit(PlayerQuitEvent event) { + if (dataMap.containsKey(event.getPlayer().getName())) { + saveVerificationData(dataMap.get(event.getPlayer().getName())); + dataMap.remove(event.getPlayer().getName()); + } + } + + protected File getConfigFile(String name) { + return new File(configFolder, name + ".yml"); + } + + protected YamlConfig getConfig(VPlayer data) { + final YamlConfig config = new YamlConfig(plugin, getConfigFile(data.getName().toLowerCase()), false); + config.load(); + return config; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/playerverification/VPlayer.java b/src/main/java/me/totalfreedom/totalfreedommod/playerverification/VPlayer.java new file mode 100644 index 00000000..8b91b9df --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/playerverification/VPlayer.java @@ -0,0 +1,134 @@ +package me.totalfreedom.totalfreedommod.playerverification; + +import com.google.common.collect.Lists; +import lombok.Getter; +import lombok.Setter; +import net.pravian.aero.base.ConfigLoadable; +import net.pravian.aero.base.ConfigSavable; +import net.pravian.aero.base.Validatable; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +import java.util.List; + +public class VPlayer implements ConfigLoadable, ConfigSavable, Validatable { + + private final List ips = Lists.newArrayList(); + @Getter + @Setter + private String name; + @Getter + @Setter + private String forumUsername = null; + @Getter + @Setter + private String discordID = null; + @Getter + @Setter + private Boolean discordVerificationEnabled = false; + @Getter + @Setter + private Boolean forumVerificationEnabled = false; + + + public VPlayer(String username) { + this.name = username; + } + + public void loadFrom(Player player) { + name = player.getName(); + ips.clear(); + ips.add(Ips.getIp(player)); + } + + @Override + public void loadFrom(ConfigurationSection cs) { + name = cs.getString("username", null); + ips.clear(); + ips.addAll(cs.getStringList("ips")); + forumUsername = cs.getString("forum_username", null); + discordID = cs.getString("discord_id", null); + discordVerificationEnabled = cs.getBoolean("discord_verification_enabled", false); + forumVerificationEnabled = cs.getBoolean("forum_verification_enabled", false); + } + + @Override + public void saveTo(ConfigurationSection cs) { + Validate.isTrue(isValid(), "Could not save player veirfication entry: " + name + ". Entry not valid!"); + cs.set("username", name); + cs.set("forum_username", forumUsername); + cs.set("discord_id", discordID); + cs.set("ips", Lists.newArrayList(ips)); + cs.set("discord_verification_enabled", discordVerificationEnabled); + cs.set("forum_verification_enabled", forumVerificationEnabled); + } + + // Util IP methods + public void addIp(String ip) { + if (!ips.contains(ip)) { + ips.add(ip); + } + } + + public void addIps(List ips) { + for (String ip : ips) { + addIp(ip); + } + } + + + public void removeIp(String ip) { + if (ips.contains(ip)) { + ips.remove(ip); + } + } + + public List getIPs() { + return ips; + } + + public void clearIPs() { + ips.clear(); + } + + public Boolean isDiscordVerificationEnabled() { + return discordVerificationEnabled; + } + + public Boolean isForumVerificationEnabled() { + return forumVerificationEnabled; + } + + public void setDiscordVerificationEnabled(boolean enabled) { + this.discordVerificationEnabled = enabled; + } + + public void setForumVerificationEnabled(boolean enabled) { + this.forumVerificationEnabled = enabled; + } + + public String getDiscordID() { + return discordID; + } + + public void setDiscordID(String discordID) { + this.discordID = discordID; + } + + public String getForumUsername() { + return forumUsername; + } + + public void setForumUsername(String forumUsername) { + this.forumUsername = forumUsername; + } + + + @Override + public boolean isValid() { + return name != null + && !ips.isEmpty(); + } +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java index f6c059b4..563d51a4 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java @@ -98,7 +98,7 @@ public class RankManager extends FreedomService public Rank getRank(Player player) { - if (plugin.al.isAdminImpostor(player)) + if (plugin.al.isAdminImpostor(player) || plugin.pv.isPlayerImpostor(player)) { return Rank.IMPOSTOR; } @@ -158,11 +158,13 @@ public class RankManager extends FreedomService } // Handle impostors - Boolean isImposter = plugin.al.isAdminImpostor(player); + Boolean isImposter = plugin.al.isAdminImpostor(player) || plugin.pv.isPlayerImpostor(player); if (isImposter) { FUtil.bcastMsg(ChatColor.AQUA + player.getName() + " is " + Rank.IMPOSTOR.getColoredLoginMessage()); - FUtil.bcastMsg("Warning: " + player.getName() + " has been flagged as an impostor and has been frozen!", ChatColor.RED); + if (plugin.al.isAdminImpostor(player)) { + FUtil.bcastMsg("Warning: " + player.getName() + " has been flagged as an impostor and has been frozen!", ChatColor.RED); + } String displayName = Rank.IMPOSTOR.getColor() + player.getName(); player.setPlayerListName(StringUtils.substring(displayName, 0, 16)); player.getInventory().clear();