>")
-public class Command_verify extends FreedomCommand
-{
-
- @Override
- public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
- {
- boolean verificationEnabled = ConfigEntry.DISCORD_VERIFICATION.getBoolean();
- if (!plugin.dc.enabled)
- {
- msg("The Discord verification system is currently disabled.", ChatColor.RED);
- return true;
- }
-
- if (!verificationEnabled)
- {
- msg("The Discord verification system is currently disabled.", ChatColor.RED);
- return true;
- }
-
- if (senderIsConsole)
- {
- msg("/manuallyverify ", ChatColor.WHITE);
- return true;
- }
-
- if (!plugin.pl.IsImpostor(playerSender))
- {
- msg("You are not an impostor, therefore you do not need to verify.", ChatColor.RED);
- return true;
- }
-
- PlayerData playerData = plugin.pl.getData(playerSender);
- String discordId = playerData.getDiscordID();
-
- if (playerData.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 == 0)
- {
- String code = plugin.dc.generateCode(10);
- plugin.dc.addVerificationCode(code, playerData);
- plugin.dc.getUser(discordId).openPrivateChannel().complete().sendMessage("A user with the IP `" + FUtil.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);
- return true;
- }
-
- String code = args[0];
- String backupCode = null;
-
- if (plugin.pl.IsImpostor(playerSender))
- {
- PlayerData mapPlayer = plugin.dc.getVerificationCodes().get(code);
- if (mapPlayer == null)
- {
- if (!playerData.getBackupCodes().contains(Discord.getMD5(code)))
- {
- msg("You have entered an invalid verification code", ChatColor.RED);
- return true;
- }
- else
- {
- backupCode = Discord.getMD5(code);
- }
- }
- else
- {
- plugin.dc.removeVerificationCode(code);
- }
-
- final FPlayer fPlayer = plugin.pl.getPlayer(playerSender);
- if (fPlayer.getFreezeData().isFrozen())
- {
- fPlayer.getFreezeData().setFrozen(false);
- msg("You have been unfrozen.");
- }
- FUtil.bcastMsg(playerSender.getName() + " has verified!", ChatColor.GOLD);
- playerSender.setOp(true);
- plugin.pl.verify(playerSender, backupCode);
- return true;
- }
- return true;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifynoadmin.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifynoadmin.java
deleted file mode 100644
index 426566f1..00000000
--- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verifynoadmin.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package me.totalfreedom.totalfreedommod.command;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import me.totalfreedom.totalfreedommod.player.FPlayer;
-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.ADMIN, source = SourceType.BOTH)
-@CommandParameters(description = "Verify an admin without giving them admin permissions.", usage = "/ ", aliases = "vns,verifynostaff,vna")
-public class Command_verifynoadmin extends FreedomCommand
-{
-
- @Override
- public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
- {
- if (args.length < 1)
- {
- return false;
- }
-
- Player player = getPlayer(args[0]);
-
- if (player == null)
- {
- msg(PLAYER_NOT_FOUND);
- return true;
- }
-
- if (plugin.al.isAdminImpostor(player))
- {
- String ip = FUtil.getIp(player);
- if (!plugin.al.verifiedNoAdmin.containsKey(player.getName()))
- {
- List ips = new ArrayList<>();
- ips.add(ip);
- plugin.al.verifiedNoAdmin.put(player.getName(), ips);
- }
- else
- {
- List ips = plugin.al.verifiedNoAdmin.get(player.getName());
- if (!ips.contains(ip))
- {
- ips.add(ip);
- plugin.al.verifiedNoAdmin.remove(player.getName());
- plugin.al.verifiedNoAdmin.put(player.getName(), ips);
- }
- }
- plugin.rm.updateDisplay(player);
- FUtil.adminAction(sender.getName(), "Verified " + player.getName() + ", without admin permissions.", true);
- player.setOp(true);
- msg(player, YOU_ARE_OP);
- final FPlayer fPlayer = plugin.pl.getPlayer(player);
- if (fPlayer.getFreezeData().isFrozen())
- {
- fPlayer.getFreezeData().setFrozen(false);
- msg(player, "You have been unfrozen.");
- }
- msg("Verified " + player.getName() + " but didn't give them admin permissions", ChatColor.GREEN);
- }
- else
- {
- msg(player.getName() + " is not an admin imposter.", ChatColor.RED);
- }
-
- return true;
- }
-
- @Override
- public List getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
- {
- if (args.length == 1)
- {
- List adminImposters = new ArrayList<>();
- for (Player player : server.getOnlinePlayers())
- {
- if (plugin.al.isAdminImpostor(player))
- {
- adminImposters.add(player.getName());
- }
- }
- return adminImposters;
- }
-
- return Collections.emptyList();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_whitelist.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_whitelist.java
index b07356e7..693c7cf9 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_whitelist.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_whitelist.java
@@ -5,7 +5,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import me.totalfreedom.totalfreedommod.rank.Rank;
-import me.totalfreedom.totalfreedommod.util.DepreciationAggregator;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
@@ -95,7 +94,7 @@ public class Command_whitelist extends FreedomCommand
if (player == null)
{
- player = DepreciationAggregator.getOfflinePlayer(server, search_name);
+ player = server.getOfflinePlayer(search_name);
}
FUtil.adminAction(sender.getName(), "Adding " + player.getName() + " to the whitelist", false);
@@ -117,7 +116,7 @@ public class Command_whitelist extends FreedomCommand
if (player == null)
{
- player = DepreciationAggregator.getOfflinePlayer(server, search_name);
+ player = server.getOfflinePlayer(search_name);
}
if (player.isWhitelisted())
@@ -158,7 +157,7 @@ public class Command_whitelist extends FreedomCommand
if (args[0].equalsIgnoreCase("purge"))
{
FUtil.adminAction(sender.getName(), "Removing all players from the whitelist", false);
- msg("Removed " + plugin.si.purgeWhitelist() + " players from the whitelist.");
+ msg("Removed " + purge() + " players from the whitelist.");
return true;
}
return false;
@@ -198,10 +197,21 @@ public class Command_whitelist extends FreedomCommand
public List getWhitelistedNames()
{
List names = new ArrayList<>();
- for (Object name : plugin.si.getWhitelisted())
+ for (OfflinePlayer player : server.getWhitelistedPlayers())
{
- names.add(String.valueOf(name));
+ names.add(player.getName());
}
return names;
}
+
+ public int purge()
+ {
+ int removed = 0;
+ for (OfflinePlayer player : server.getWhitelistedPlayers())
+ {
+ player.setWhitelisted(false);
+ removed++;
+ }
+ return removed;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java b/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java
index 8d2dd093..ed826d46 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java
@@ -1,33 +1,27 @@
package me.totalfreedom.totalfreedommod.command;
import com.google.common.collect.Lists;
+
import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
+import java.util.*;
+
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.rank.Rank;
+import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
+import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandMap;
-import org.bukkit.command.CommandSender;
-import org.bukkit.command.ConsoleCommandSender;
-import org.bukkit.command.PluginCommand;
-import org.bukkit.command.TabCompleter;
+import org.bukkit.command.*;
import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public abstract class FreedomCommand implements CommandExecutor, TabCompleter
{
@@ -40,7 +34,6 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
public static final String NO_PERMISSION = ChatColor.RED + "You do not have permission to execute this command.";
public static final Timer timer = new Timer();
public static final Map COOLDOWN_TIMERS = new HashMap<>();
- private static CommandMap commandMap;
protected final TotalFreedomMod plugin = TotalFreedomMod.getPlugin();
protected final Server server = plugin.getServer();
private final String name;
@@ -69,34 +62,22 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
this.cooldown = perms.cooldown();
}
- public static CommandMap getCommandMap()
- {
- if (commandMap == null)
- {
- try
- {
- final Field f = Bukkit.getServer().getPluginManager().getClass().getDeclaredField("commandMap");
- f.setAccessible(true);
- commandMap = (CommandMap)f.get(Bukkit.getServer().getPluginManager());
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- return commandMap;
- }
-
public static FreedomCommand getFrom(Command command)
{
try
{
- return (FreedomCommand)(((PluginCommand)command).getExecutor());
+ if (command instanceof FCommand)
+ {
+ return ((FCommand) command).getExecutor();
+ }
}
catch (Exception ex)
{
+ FLog.severe(ex);
return null;
}
+
+ return null;
}
public static String getCommandPrefix()
@@ -119,7 +100,7 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
{
cmd.setUsage(this.usage);
}
- getCommandMap().register("totalfreedommod", cmd);
+ server.getCommandMap().register("totalfreedommod", cmd);
cmd.setExecutor(this);
}
@@ -246,6 +227,16 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
return player;
}
+ @Nullable
+ protected OfflinePlayer getOfflinePlayer(String name)
+ {
+ return Arrays.stream(Bukkit.getOfflinePlayers())
+ .filter(player -> player.getName() != null)
+ .filter(player -> player.getName().equalsIgnoreCase(name))
+ .findFirst()
+ .orElse(null);
+ }
+
protected Admin getAdmin(CommandSender sender)
{
return plugin.al.getAdmin(sender);
@@ -316,7 +307,7 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
return perms;
}
- private final class FCommand extends Command
+ public final class FCommand extends Command implements PluginIdentifiableCommand
{
private FreedomCommand cmd = null;
@@ -325,6 +316,11 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
super(command);
}
+ public final FreedomCommand getExecutor()
+ {
+ return cmd;
+ }
+
public void setExecutor(FreedomCommand cmd)
{
this.cmd = cmd;
@@ -427,5 +423,11 @@ public abstract class FreedomCommand implements CommandExecutor, TabCompleter
}
return new ArrayList<>();
}
+
+ @Override
+ public @NotNull Plugin getPlugin()
+ {
+ return plugin;
+ }
}
}
\ 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 4d336882..598c3d1f 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java
@@ -73,9 +73,10 @@ public enum ConfigEntry
SERVER_WHITELIST_MOTD(String.class, "server.motds.whitelist"),
SERVER_FULL_MOTD(String.class, "server.motds.full"),
//
- DISCORD_VERIFICATION(Boolean.class, "discord.verification"),
DISCORD_TOKEN(String.class, "discord.token"),
+ DISCORD_PREFIX(String.class, "discord.prefix"),
DISCORD_REPORT_CHANNEL_ID(String.class, "discord.report_channel_id"),
+ DISCORD_REPORT_ARCHIVE_CHANNEL_ID(String.class, "discord.report_archive_channel_id"),
DISCORD_CHAT_CHANNEL_ID(String.class, "discord.chat_channel_id"),
DISCORD_ADMINCHAT_CHANNEL_ID(String.class, "discord.adminchat_channel_id"),
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java
index 484d6016..77d1779c 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java
@@ -1,9 +1,6 @@
package me.totalfreedom.totalfreedommod.discord;
import com.google.common.base.Strings;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.ArrayList;
@@ -16,13 +13,15 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.security.auth.login.LoginException;
+
+import com.google.common.collect.ImmutableList;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommandManager;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FLog;
-import me.totalfreedom.totalfreedommod.util.FUtil;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
@@ -41,10 +40,14 @@ import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.ChunkingFilter;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.dv8tion.jda.internal.utils.concurrent.CountingThreadFactory;
-import org.apache.commons.codec.digest.DigestUtils;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
+import org.apache.commons.lang3.RandomStringUtils;
import org.bukkit.GameRule;
+import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -57,18 +60,14 @@ public class Discord extends FreedomService
{
public static HashMap LINK_CODES = new HashMap<>();
- public static HashMap VERIFICATION_CODES = new HashMap<>();
public static JDA bot = null;
+ public static DiscordCommandManager DISCORD_COMMAND_MANAGER;
public ScheduledThreadPoolExecutor RATELIMIT_EXECUTOR;
public List> sentMessages = new ArrayList<>();
public Boolean enabled = false;
+ private static final ImmutableList DISCORD_SUBDOMAINS = ImmutableList.of("discordapp.com", "discord.com", "discord.gg");
private final Pattern DISCORD_MENTION_PATTERN = Pattern.compile("(<@!?([0-9]{16,20})>)");
- public static String getMD5(String string)
- {
- return DigestUtils.md5Hex(string);
- }
-
public static String getCode(PlayerData playerData)
{
for (String code : LINK_CODES.keySet())
@@ -157,11 +156,8 @@ public class Discord extends FreedomService
public void startBot()
{
- boolean verificationEnabled = ConfigEntry.DISCORD_VERIFICATION.getBoolean();
- if (!verificationEnabled)
- {
- FLog.info("Discord Verification has been manually disabled.");
- }
+ DISCORD_COMMAND_MANAGER = new DiscordCommandManager();
+ DISCORD_COMMAND_MANAGER.init(this);
enabled = !Strings.isNullOrEmpty(ConfigEntry.DISCORD_TOKEN.getString());
if (!enabled)
@@ -185,6 +181,7 @@ public class Discord extends FreedomService
.addEventListeners(new PrivateMessageListener(),
new DiscordToMinecraftListener(),
new DiscordToAdminChatListener(),
+ new MessageReactionListener(),
new ListenerAdapter()
{
@Override
@@ -199,15 +196,15 @@ public class Discord extends FreedomService
.setMemberCachePolicy(MemberCachePolicy.ALL)
.enableIntents(GatewayIntent.GUILD_MEMBERS)
.build();
- FLog.info("Discord verification bot has successfully enabled!");
+ FLog.info("Discord integration has successfully enabled!");
}
catch (LoginException e)
{
- FLog.warning("An invalid token for the discord verification bot, the bot will not enable.");
+ FLog.warning("An invalid token for Discord integration was provided, the bot will not enable.");
}
catch (IllegalArgumentException e)
{
- FLog.warning("Discord verification bot failed to start.");
+ FLog.warning("Discord integration failed to start.");
}
catch (NoClassDefFoundError e)
{
@@ -232,7 +229,7 @@ public class Discord extends FreedomService
}
}
sentMessages.clear();
- messageChatChannel("**Message queue cleared**");
+ messageChatChannel("**Message queue cleared**", true);
}
public void sendPteroInfo(PlayerData playerData, String username, String password)
@@ -261,96 +258,9 @@ public class Discord extends FreedomService
return member.getUser();
}
- public boolean sendBackupCodes(PlayerData playerData)
- {
- List codes = generateBackupCodes();
- List encryptedCodes = generateEncryptedBackupCodes(codes);
- User user = getUser(playerData.getDiscordID());
- File file = generateBackupCodesFile(playerData.getName(), codes);
- if (file == null)
- {
- return false;
- }
- PrivateChannel privateChannel = user.openPrivateChannel().complete();
- privateChannel.sendMessage("Do not share these codes with anyone as they can be used to impose as you.").addFile(file).complete();
- playerData.setBackupCodes(encryptedCodes);
- plugin.pl.save(playerData);
- //noinspection ResultOfMethodCallIgnored
- file.delete();
- return true;
- }
-
- public List generateBackupCodes()
- {
- List codes = new ArrayList<>();
- for (int i = 0; i < 10; i++)
- {
- codes.add(FUtil.randomAlphanumericString(10));
- }
- return codes;
- }
-
public String generateCode(int size)
{
- StringBuilder code = new StringBuilder();
- SplittableRandom random = new SplittableRandom();
- for (int i = 0; i < size; i++)
- {
- code.append(random.nextInt(10));
- }
- return code.toString();
- }
-
- public List generateEncryptedBackupCodes(List codes)
- {
- List encryptedCodes = new ArrayList<>();
- for (String code : codes)
- {
- encryptedCodes.add(getMD5(code));
- }
- return encryptedCodes;
- }
-
- public File generateBackupCodesFile(String name, List codes)
- {
- StringBuilder text = new StringBuilder();
- text.append("Below are your backup codes for use on TotalFreedom in the event you lose access to your discord account.\n")
- .append("Simply pick a code, and run /verify on the server. Each code is one use, so be sure to cross it off once you use it.\n")
- .append("To generate new codes, simply run /generatebackupcodes\n\n");
-
- for (String code : codes)
- {
- text.append(code).append("\n");
- }
-
- String fileUrl = plugin.getDataFolder().getAbsolutePath() + "/TF-Backup-Codes-" + name + ".txt";
- try
- {
- FileWriter fileWriter = new FileWriter(fileUrl);
- fileWriter.write(text.toString());
- fileWriter.close();
- }
- catch (IOException e)
- {
- FLog.severe("Failed to generate backup codes file: " + e.toString());
- return null;
- }
- return new File(fileUrl);
- }
-
- public void addVerificationCode(String code, PlayerData playerData)
- {
- VERIFICATION_CODES.put(code, playerData);
- }
-
- public void removeVerificationCode(String code)
- {
- VERIFICATION_CODES.remove(code);
- }
-
- public HashMap getVerificationCodes()
- {
- return VERIFICATION_CODES;
+ return RandomStringUtils.randomNumeric(size);
}
@EventHandler(priority = EventPriority.MONITOR)
@@ -363,9 +273,11 @@ public class Discord extends FreedomService
return;
}
- if (event.getDeathMessage() != null)
+ Component deathMessage = event.deathMessage();
+
+ if (deathMessage != null)
{
- messageChatChannel("**" + event.getDeathMessage() + "**");
+ messageChatChannel("**" + PlainTextComponentSerializer.plainText().serialize(deathMessage) + "**", true);
}
}
@@ -380,7 +292,7 @@ public class Discord extends FreedomService
{
if (!plugin.al.isVanished(event.getPlayer().getName()))
{
- messageChatChannel("**" + event.getPlayer().getName() + " joined the server" + "**");
+ messageChatChannel("**" + event.getPlayer().getName() + " joined the server" + "**", true);
}
}
@@ -389,74 +301,77 @@ public class Discord extends FreedomService
{
if (!plugin.al.isVanished(event.getPlayer().getName()))
{
- messageChatChannel("**" + event.getPlayer().getName() + " left the server" + "**");
+ messageChatChannel("**" + event.getPlayer().getName() + " left the server" + "**", true);
}
}
+ public static String sanitizeChatMessage(String message)
+ {
+ String newMessage = message;
+
+ if (message.contains("@"))
+ {
+ // \u200B is Zero Width Space, invisible on Discord
+ newMessage = message.replaceAll("@", "@\u200B");
+ }
+
+ if (message.toLowerCase().contains("discord.gg")) // discord.gg/invite works as an invite
+ {
+ return "";
+ }
+
+ for (String subdomain : DISCORD_SUBDOMAINS)
+ {
+ if (message.toLowerCase().contains(subdomain + "/invite"))
+ {
+ return "";
+ }
+ }
+
+ if (message.contains("§"))
+ {
+ newMessage = message.replaceAll("§", "");
+ }
+
+ return deformat(newMessage);
+ }
+
public void messageChatChannel(String message)
+ {
+ messageChatChannel(message, false);
+ }
+
+ public void messageChatChannel(String message, boolean system)
{
String chat_channel_id = ConfigEntry.DISCORD_CHAT_CHANNEL_ID.getString();
- if (message.contains("@everyone") || message.contains("@here"))
- {
- message = StringUtils.remove(message, "@");
- }
- if (message.toLowerCase().contains("discord.gg"))
- {
- return;
- }
-
- if (message.contains("§"))
- {
- message = StringUtils.remove(message, "§");
- }
+ String sanitizedMessage = (system) ? message : sanitizeChatMessage(message);
-
- Matcher DISCORD_MENTION_MATCHER = DISCORD_MENTION_PATTERN.matcher(message);
-
- while (DISCORD_MENTION_MATCHER.find())
- {
- String mention = DISCORD_MENTION_MATCHER.group(1);
- message = message.replace(mention, mention.replace("@",""));
- }
+ if (sanitizedMessage.isBlank()) return;
if (enabled && !chat_channel_id.isEmpty())
{
- CompletableFuture sentMessage = Objects.requireNonNull(bot.getTextChannelById(chat_channel_id)).sendMessage(deformat(message)).submit(true);
+ CompletableFuture sentMessage = Objects.requireNonNull(bot.getTextChannelById(chat_channel_id)).sendMessage(sanitizedMessage).submit(true);
sentMessages.add(sentMessage);
}
}
public void messageAdminChatChannel(String message)
+ {
+ messageAdminChatChannel(message, false);
+ }
+
+ public void messageAdminChatChannel(String message, boolean system)
{
String chat_channel_id = ConfigEntry.DISCORD_ADMINCHAT_CHANNEL_ID.getString();
- if (message.contains("@everyone") || message.contains("@here"))
- {
- message = StringUtils.remove(message, "@");
- }
- if (message.toLowerCase().contains("discord.gg"))
- {
- return;
- }
-
- if (message.contains("§"))
- {
- message = StringUtils.remove(message, "§");
- }
+ String sanitizedMessage = sanitizeChatMessage(message);
-
- Matcher DISCORD_MENTION_MATCHER = DISCORD_MENTION_PATTERN.matcher(message);
-
- while (DISCORD_MENTION_MATCHER.find())
- {
- String mention = DISCORD_MENTION_MATCHER.group(1);
- message = message.replace(mention, mention.replace("@",""));
- }
+ if (sanitizedMessage.isBlank()) return;
if (enabled && !chat_channel_id.isEmpty())
{
- CompletableFuture sentMessage = Objects.requireNonNull(bot.getTextChannelById(chat_channel_id)).sendMessage(deformat(message)).submit(true);
+ CompletableFuture sentMessage = Objects.requireNonNull(bot.getTextChannelById(chat_channel_id)).sendMessage(sanitizedMessage).submit(true);
sentMessages.add(sentMessage);
}
}
@@ -464,7 +379,7 @@ public class Discord extends FreedomService
public String formatBotTag()
{
SelfUser user = bot.getSelfUser();
- return user.getName() + "#" + user.getDiscriminator();
+ return user.getAsTag();
}
@Override
@@ -472,18 +387,18 @@ public class Discord extends FreedomService
{
if (bot != null)
{
- messageChatChannel("**Server has stopped**");
+ messageChatChannel("**Server has stopped**", true);
}
- FLog.info("Discord verification bot has successfully shutdown.");
+ FLog.info("Discord integration has successfully shutdown.");
}
- public String deformat(String input)
+ public static String deformat(String input)
{
- return input.replace("_", "\\_");
+ return input.replaceAll("([_\\\\`*>|])", "\\\\$1");
}
- public boolean sendReport(Player reporter, Player reported, String reason)
+ public boolean shouldISendReport()
{
if (ConfigEntry.DISCORD_REPORT_CHANNEL_ID.getString().isEmpty())
{
@@ -498,6 +413,7 @@ public class Discord extends FreedomService
Guild server = bot.getGuildById(ConfigEntry.DISCORD_SERVER_ID.getString());
if (server == null)
+
{
FLog.severe("The Discord server ID specified is invalid, or the bot is not on the server.");
return false;
@@ -510,7 +426,57 @@ public class Discord extends FreedomService
return false;
}
- EmbedBuilder embedBuilder = new EmbedBuilder();
+ return true;
+ }
+
+ public boolean sendReportOffline(Player reporter, OfflinePlayer reported, String reason)
+ {
+ if (!shouldISendReport())
+ {
+ return false;
+ }
+
+ final Guild server = bot.getGuildById(ConfigEntry.DISCORD_SERVER_ID.getString());
+ final TextChannel channel = server.getTextChannelById(ConfigEntry.DISCORD_REPORT_CHANNEL_ID.getString());
+
+ final EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setTitle("Report for " + reported.getName() + " (offline)");
+ embedBuilder.setDescription(reason);
+ embedBuilder.setFooter("Reported by " + reporter.getName(), "https://minotar.net/helm/" + reporter.getName() + ".png");
+ embedBuilder.setTimestamp(Instant.from(ZonedDateTime.now()));
+ if (plugin.esb.isEnabled())
+ {
+ com.earth2me.essentials.User user = plugin.esb.getEssentialsUser(reported.getName());
+ String location = "World: " + Objects.requireNonNull(user.getLastLocation().getWorld()).getName() + ", X: " + user.getLastLocation().getBlockX() + ", Y: " + user.getLastLocation().getBlockY() + ", Z: " + user.getLastLocation().getBlockZ();
+ embedBuilder.addField("Location", location, true);
+ embedBuilder.addField("God Mode", WordUtils.capitalizeFully(String.valueOf(user.isGodModeEnabled())), true);
+ if (user.getNickname() != null)
+ {
+ embedBuilder.addField("Nickname", user.getNickname(), true);
+ }
+ }
+ MessageEmbed embed = embedBuilder.build();
+ Message message = channel.sendMessage(embed).complete();
+
+ if (!ConfigEntry.DISCORD_REPORT_ARCHIVE_CHANNEL_ID.getString().isEmpty())
+ {
+ message.addReaction("\uD83D\uDCCB").complete();
+ }
+
+ return true;
+ }
+
+ public boolean sendReport(Player reporter, Player reported, String reason)
+ {
+ if (!shouldISendReport())
+ {
+ return false;
+ }
+
+ final Guild server = bot.getGuildById(ConfigEntry.DISCORD_SERVER_ID.getString());
+ final TextChannel channel = server.getTextChannelById(ConfigEntry.DISCORD_REPORT_CHANNEL_ID.getString());
+
+ final EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("Report for " + reported.getName());
embedBuilder.setDescription(reason);
embedBuilder.setFooter("Reported by " + reporter.getName(), "https://minotar.net/helm/" + reporter.getName() + ".png");
@@ -518,14 +484,25 @@ public class Discord extends FreedomService
String location = "World: " + Objects.requireNonNull(reported.getLocation().getWorld()).getName() + ", X: " + reported.getLocation().getBlockX() + ", Y: " + reported.getLocation().getBlockY() + ", Z: " + reported.getLocation().getBlockZ();
embedBuilder.addField("Location", location, true);
embedBuilder.addField("Game Mode", WordUtils.capitalizeFully(reported.getGameMode().name()), true);
- com.earth2me.essentials.User user = plugin.esb.getEssentialsUser(reported.getName());
- embedBuilder.addField("God Mode", WordUtils.capitalizeFully(String.valueOf(user.isGodModeEnabled())), true);
- if (user.getNickname() != null)
+
+ if (plugin.esb.isEnabled())
{
- embedBuilder.addField("Nickname", user.getNickname(), true);
+ com.earth2me.essentials.User user = plugin.esb.getEssentialsUser(reported.getName());
+ embedBuilder.addField("God Mode", WordUtils.capitalizeFully(String.valueOf(user.isGodModeEnabled())), true);
+ if (user.getNickname() != null)
+ {
+ embedBuilder.addField("Nickname", user.getNickname(), true);
+ }
}
+
MessageEmbed embed = embedBuilder.build();
- channel.sendMessage(embed).complete();
+ Message message = channel.sendMessage(embed).complete();
+
+ if (!ConfigEntry.DISCORD_REPORT_ARCHIVE_CHANNEL_ID.getString().isEmpty())
+ {
+ message.addReaction("\uD83D\uDCCB").complete();
+ }
+
return true;
}
@@ -534,7 +511,7 @@ public class Discord extends FreedomService
{
public void start()
{
- messageChatChannel("**Server has started**");
+ messageChatChannel("**Server has started**", true);
}
}
}
\ No newline at end of file
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToMinecraftListener.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToMinecraftListener.java
index f4adf0d9..64c719bf 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToMinecraftListener.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToMinecraftListener.java
@@ -2,12 +2,12 @@ package me.totalfreedom.totalfreedommod.discord;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommandManager;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.rank.Title;
import me.totalfreedom.totalfreedommod.util.FLog;
-import net.dv8tion.jda.api.entities.Guild;
-import net.dv8tion.jda.api.entities.Member;
-import net.dv8tion.jda.api.entities.Message;
+import me.totalfreedom.totalfreedommod.util.FUtil;
+import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.md_5.bungee.api.chat.BaseComponent;
@@ -24,77 +24,108 @@ public class DiscordToMinecraftListener extends ListenerAdapter
{
public void onMessageReceived(MessageReceivedEvent event)
{
- String chat_channel_id = ConfigEntry.DISCORD_CHAT_CHANNEL_ID.getString();
- if (event.getMember() != null && !chat_channel_id.isEmpty() && event.getChannel().getId().equals(chat_channel_id))
+ final String chat_channel_id = ConfigEntry.DISCORD_CHAT_CHANNEL_ID.getString();
+ final MessageChannel genericChannel = event.getChannel();
+
+ if (event.getMember() == null)
{
- if (!event.getAuthor().getId().equals(Discord.bot.getSelfUser().getId()))
- {
- Member member = event.getMember();
- String tag = getDisplay(member);
- Message msg = event.getMessage();
+ return;
+ }
- ComponentBuilder emsg = new ComponentBuilder();
+ if (chat_channel_id.isEmpty())
+ {
+ return;
+ }
- // Prefix
- emsg.append(ChatColor.DARK_GRAY + "[");
- TextComponent inviteLink = new TextComponent("Discord");
- inviteLink.setColor(ChatColor.DARK_AQUA.asBungee());
- inviteLink.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
- new Text("Click here to get the invite link!")));
- inviteLink.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL,
- ConfigEntry.DISCORD_INVITE_LINK.getString()));
- emsg.append(inviteLink);
- emsg.append(ChatColor.DARK_GRAY + "] ", ComponentBuilder.FormatRetention.NONE);
+ if (event.getAuthor().getId().equals(Discord.bot.getSelfUser().getId()))
+ {
+ return;
+ }
- // Tag (if they have one)
- if (tag != null)
- {
- emsg.append(tag);
- }
+ if (!genericChannel.getId().equals(chat_channel_id))
+ {
+ return;
+ }
+ if (!(genericChannel instanceof TextChannel))
+ {
+ return;
+ }
+
+ final TextChannel textChannel = (TextChannel) genericChannel;
+
+ final Member member = event.getMember();
+ final String tag = getDisplay(member);
+ final Message msg = event.getMessage();
+ final String content = msg.getContentStripped();
+
+ if (content.startsWith(ConfigEntry.DISCORD_PREFIX.getString()))
+ {
+ Discord.DISCORD_COMMAND_MANAGER.parse(content, member, textChannel);
+ return;
+ }
+
+ ComponentBuilder emsg = new ComponentBuilder();
+
+ // Prefix
+ emsg.append(ChatColor.DARK_GRAY + "[");
+ TextComponent inviteLink = new TextComponent("Discord");
+ inviteLink.setColor(ChatColor.DARK_AQUA.asBungee());
+ inviteLink.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
+ new Text("Click here to get the invite link!")));
+ inviteLink.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL,
+ ConfigEntry.DISCORD_INVITE_LINK.getString()));
+ emsg.append(inviteLink);
+ emsg.append(ChatColor.DARK_GRAY + "] ", ComponentBuilder.FormatRetention.NONE);
+
+ // Tag (if they have one)
+ if (tag != null)
+ {
+ emsg.append(tag);
+ }
+
+ emsg.append(" ");
+
+ // User
+ TextComponent user = new TextComponent(FUtil.stripColors(member.getEffectiveName()));
+ user.setColor(ChatColor.RED.asBungee());
+ emsg.append(user);
+
+ // Message
+ emsg.append(ChatColor.DARK_GRAY + ": " + ChatColor.RESET
+ + FUtil.stripColors(msg.getContentDisplay()), ComponentBuilder.FormatRetention.NONE);
+
+ // Attachments
+ if (!msg.getAttachments().isEmpty())
+ {
+ if (!msg.getContentDisplay().isEmpty())
emsg.append(" ");
- // User
- TextComponent user = new TextComponent(ChatColor.stripColor(member.getEffectiveName()));
- user.setColor(ChatColor.RED.asBungee());
- emsg.append(user);
+ for (Message.Attachment attachment : msg.getAttachments())
+ {
+ TextComponent media = new TextComponent("[Media] ");
+ media.setColor(ChatColor.YELLOW.asBungee());
+ media.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, attachment.getUrl()));
+ media.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(attachment.getUrl())));
- // Message
- emsg.append(ChatColor.DARK_GRAY + ": " + ChatColor.RESET
- + ChatColor.stripColor(msg.getContentDisplay()), ComponentBuilder.FormatRetention.NONE);
-
- // Attachments
- if (!msg.getAttachments().isEmpty())
- {
- if (!msg.getContentDisplay().isEmpty())
- emsg.append(" ");
-
- for (Message.Attachment attachment : msg.getAttachments())
- {
- TextComponent media = new TextComponent("[Media] ");
- media.setColor(ChatColor.YELLOW.asBungee());
- media.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, attachment.getUrl()));
- media.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(attachment.getUrl())));
-
- emsg.append(media, ComponentBuilder.FormatRetention.NONE);
- }
- }
-
- BaseComponent[] components = emsg.create();
-
- for (Player player : Bukkit.getOnlinePlayers())
- {
- if (TotalFreedomMod.getPlugin().pl.getData(player).doesDisplayDiscord())
- {
- player.spigot().sendMessage(components);
- }
- }
-
- FLog.info(TextComponent.toLegacyText(components), true);
+ emsg.append(media, ComponentBuilder.FormatRetention.NONE);
}
}
+
+ BaseComponent[] components = emsg.create();
+
+ for (Player player : Bukkit.getOnlinePlayers())
+ {
+ if (TotalFreedomMod.getPlugin().pl.getData(player).doesDisplayDiscord())
+ {
+ player.sendMessage(components);
+ }
+ }
+
+ FLog.info(TextComponent.toLegacyText(components), true);
}
+
public String getDisplay(Member member)
{
Guild server = Discord.bot.getGuildById(ConfigEntry.DISCORD_SERVER_ID.getString());
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageReactionListener.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageReactionListener.java
new file mode 100644
index 00000000..738a2e5e
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/MessageReactionListener.java
@@ -0,0 +1,68 @@
+package me.totalfreedom.totalfreedommod.discord;
+
+import me.totalfreedom.totalfreedommod.config.ConfigEntry;
+import me.totalfreedom.totalfreedommod.util.FLog;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.Message;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+
+public class MessageReactionListener extends ListenerAdapter
+{
+ public void onMessageReactionAdd(MessageReactionAddEvent messageReactionAddEvent)
+ {
+ if (!messageReactionAddEvent.isFromGuild())
+ {
+ return;
+ }
+
+ if (messageReactionAddEvent.getMember() == null)
+ {
+ return;
+ }
+
+ if (messageReactionAddEvent.getMember().getUser().getId().equals(Discord.bot.getSelfUser().getId()))
+ {
+ return;
+ }
+
+ if (!messageReactionAddEvent.getChannel().getId().equals(ConfigEntry.DISCORD_REPORT_CHANNEL_ID.getString()))
+ {
+ return;
+ }
+
+ if (!messageReactionAddEvent.getReactionEmote().getEmoji().equals("\uD83D\uDCCB"))
+ {
+ return;
+ }
+
+ final TextChannel archiveChannel = Discord.bot.getTextChannelById(ConfigEntry.DISCORD_REPORT_ARCHIVE_CHANNEL_ID.getString());
+
+ if (archiveChannel == null)
+ {
+ FLog.warning("Report archive channel is defined in the config, yet doesn't actually exist!");
+ return;
+ }
+
+ final Message message = messageReactionAddEvent.retrieveMessage().complete();
+ final Member completer = messageReactionAddEvent.getMember();
+
+ if (!message.getAuthor().getId().equals(Discord.bot.getSelfUser().getId()))
+ {
+ return;
+ }
+
+ // We don't need other embeds... yet?
+ final MessageEmbed embed = message.getEmbeds().get(0);
+ final MessageBuilder archiveMessageBuilder = new MessageBuilder();
+ archiveMessageBuilder.setContent("Report completed by " + completer.getUser().getAsMention() + " (" + Discord.deformat(completer.getUser().getAsTag() + ")"));
+ archiveMessageBuilder.setEmbed(embed);
+ final Message archiveMessage = archiveMessageBuilder.build();
+
+ archiveChannel.sendMessage(archiveMessage).complete();
+ message.delete().complete();
+ }
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/PrivateMessageListener.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/PrivateMessageListener.java
index aee47a51..a9a2bde4 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/discord/PrivateMessageListener.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/PrivateMessageListener.java
@@ -22,9 +22,8 @@ public class PrivateMessageListener extends ListenerAdapter
PlayerData player = Discord.LINK_CODES.get(code);
name = player.getName();
player.setDiscordID(event.getMessage().getAuthor().getId());
- player.setVerification(true);
- Admin admin = TotalFreedomMod.getPlugin().al.getEntryByName(name);
+ Admin admin = TotalFreedomMod.getPlugin().al.getEntryByUuid(player.getUuid());
if (admin != null)
{
Discord.syncRoles(admin, player.getDiscordID());
@@ -37,8 +36,7 @@ public class PrivateMessageListener extends ListenerAdapter
{
return;
}
- event.getChannel().sendMessage("Link successful. Now this Discord account is linked with your Minecraft account **" + name + "**.\n"
- + "Now when you are an impostor on the server, you may use `/verify` to verify.").complete();
+ event.getChannel().sendMessage("Link successful. Now this Discord account is linked with your Minecraft account **" + name + "**.").complete();
}
}
}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommand.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommand.java
new file mode 100644
index 00000000..94c16ad4
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommand.java
@@ -0,0 +1,25 @@
+package me.totalfreedom.totalfreedommod.discord.command;
+
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.User;
+
+import java.util.List;
+
+public interface DiscordCommand
+{
+ String getCommandName();
+
+ String getDescription();
+
+ String getCategory();
+
+ List getAliases();
+
+ boolean isAdmin();
+
+ boolean canExecute(Member member);
+
+ MessageBuilder execute(Member member, List args);
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommandImpl.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommandImpl.java
new file mode 100644
index 00000000..8626be04
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommandImpl.java
@@ -0,0 +1,13 @@
+package me.totalfreedom.totalfreedommod.discord.command;
+
+import net.dv8tion.jda.api.entities.Member;
+
+public abstract class DiscordCommandImpl implements DiscordCommand
+{
+ @Override
+ public boolean canExecute(Member member)
+ {
+ //return !isAdmin() || member.getRoles().stream().filter((role -> role.getName().toLowerCase().contains("admin") && !role.getName().toLowerCase().contains("discord"))).toList().size() > 0;
+ return !isAdmin();
+ }
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommandManager.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommandManager.java
new file mode 100644
index 00000000..93f1c60b
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/command/DiscordCommandManager.java
@@ -0,0 +1,84 @@
+package me.totalfreedom.totalfreedommod.discord.command;
+
+import me.totalfreedom.totalfreedommod.config.ConfigEntry;
+import me.totalfreedom.totalfreedommod.discord.Discord;
+import me.totalfreedom.totalfreedommod.util.FLog;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.Message;
+import net.dv8tion.jda.api.entities.TextChannel;
+import org.reflections.Reflections;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+public class DiscordCommandManager
+{
+ public static final String PREFIX = ConfigEntry.DISCORD_PREFIX.getString();
+ private Discord discord;
+ public final List commands = new ArrayList<>();
+
+ public void init(Discord discord)
+ {
+ this.discord = discord;
+
+ final Reflections discordCommandsDir = new Reflections("me.totalfreedom.totalfreedommod.discord.commands");
+
+ final Set> commandClasses = discordCommandsDir.getSubTypesOf(DiscordCommand.class);
+
+ for (Class extends DiscordCommand> commandClass : commandClasses)
+ {
+ try
+ {
+ commands.add(commandClass.getDeclaredConstructor().newInstance());
+ }
+ catch (Exception e)
+ {
+ FLog.warning("Failed to load Discord command: " + commandClass.getName());
+ }
+ }
+
+ FLog.info("Loaded " + commands.size() + " Discord commands.");
+ }
+
+ public void parse(String content, Member member, TextChannel channel)
+ {
+ List args = new ArrayList<>(Arrays.asList(content.split(" ")));
+
+ final String alias = args.remove(0).split(PREFIX)[1]; // The joys of command parsing
+
+ for (DiscordCommand command : commands)
+ {
+ if (command.getCommandName().equalsIgnoreCase(alias) || command.getAliases().contains(alias.toLowerCase()))
+ {
+ if (command.canExecute(member))
+ {
+ final MessageBuilder messageBuilder = command.execute(member, args);
+ final Message message = messageBuilder.build();
+ final CompletableFuture futureMessage = channel.sendMessage(message).submit(true);
+
+ this.discord.sentMessages.add(futureMessage);
+ }
+ else
+ {
+ final MessageBuilder messageBuilder = new MessageBuilder();
+ final EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setTitle("Command error");
+ embedBuilder.setColor(Color.RED);
+ embedBuilder.setDescription("You don't have permission to execute this command.");
+ messageBuilder.setEmbed(embedBuilder.build());
+ final Message message = messageBuilder.build();
+
+ final CompletableFuture futureMessage = channel.sendMessage(message).submit(true);
+
+ this.discord.sentMessages.add(futureMessage);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/HelpCommand.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/HelpCommand.java
new file mode 100644
index 00000000..d9825083
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/HelpCommand.java
@@ -0,0 +1,86 @@
+package me.totalfreedom.totalfreedommod.discord.commands;
+
+import me.totalfreedom.totalfreedommod.discord.Discord;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommand;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommandImpl;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommandManager;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Member;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class HelpCommand extends DiscordCommandImpl
+{
+ @Override
+ public String getCommandName()
+ {
+ return "help";
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "Displays the help command";
+ }
+
+ @Override
+ public String getCategory()
+ {
+ return "Help";
+ }
+
+ @Override
+ public List getAliases()
+ {
+ return List.of("cmds", "commands", "elp");
+ }
+
+ @Override
+ public boolean isAdmin()
+ {
+ return false;
+ }
+
+ @Override
+ public MessageBuilder execute(Member member, List args)
+ {
+ final EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setColor(Color.GREEN);
+ embedBuilder.setTitle("Help Command");
+
+ final Map> commandCategories = new HashMap<>();
+
+ for (DiscordCommand command : Discord.DISCORD_COMMAND_MANAGER.commands)
+ {
+ if (!commandCategories.containsKey(command.getCategory()))
+ {
+ commandCategories.put(command.getCategory(), new ArrayList<>(List.of(command)));
+ }
+ else
+ {
+ commandCategories.get(command.getCategory()).add(command);
+ }
+ }
+
+ for (Map.Entry> entry : commandCategories.entrySet())
+ {
+ final String category = entry.getKey();
+ final List commands = entry.getValue();
+ final StringBuilder fieldValue = new StringBuilder();
+
+ for (DiscordCommand command : commands)
+ {
+ fieldValue.append("**").append(DiscordCommandManager.PREFIX).append(command.getCommandName()).append("** - ").append(command.getDescription()).append("\n");
+ }
+
+ embedBuilder.addField(category, fieldValue.toString().trim(), false);
+ }
+
+ return new MessageBuilder().setEmbed(embedBuilder.build());
+ }
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/ListCommand.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/ListCommand.java
new file mode 100644
index 00000000..d81d24ff
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/ListCommand.java
@@ -0,0 +1,106 @@
+package me.totalfreedom.totalfreedommod.discord.commands;
+
+import me.totalfreedom.totalfreedommod.TotalFreedomMod;
+import me.totalfreedom.totalfreedommod.admin.AdminList;
+import me.totalfreedom.totalfreedommod.config.ConfigEntry;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommand;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommandImpl;
+import me.totalfreedom.totalfreedommod.rank.Displayable;
+import me.totalfreedom.totalfreedommod.rank.RankManager;
+import me.totalfreedom.totalfreedommod.util.FUtil;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.User;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ListCommand extends DiscordCommandImpl
+{
+ private static final TotalFreedomMod PLUGIN = TotalFreedomMod.plugin();
+
+ @Override
+ public String getCommandName()
+ {
+ return "list";
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "Gives a list of online players.";
+ }
+
+ @Override
+ public String getCategory()
+ {
+ return "Server Commands";
+ }
+
+ @Override
+ public List getAliases()
+ {
+ return List.of("online", "who", "l", "lsit");
+ }
+
+ @Override
+ public boolean isAdmin()
+ {
+ return false;
+ }
+
+ @Override
+ public MessageBuilder execute(Member member, List args)
+ {
+ if (PLUGIN == null)
+ {
+ throw new IllegalStateException("TotalFreedomMod somehow null while executing a command!");
+ }
+
+ final AdminList adminList = PLUGIN.al;
+ final RankManager rankManager = PLUGIN.rm;
+
+ EmbedBuilder embedBuilder = new EmbedBuilder()
+ .setTitle("Player List - " + ConfigEntry.SERVER_NAME.getString())
+ .setDescription("There are " + FUtil.getFakePlayerCount() + " / " + Bukkit.getMaxPlayers() + " online players");
+
+ Map> displayables = new HashMap<>();
+
+ for (Player onlinePlayer : Bukkit.getOnlinePlayers())
+ {
+ if (adminList.isVanished(onlinePlayer.getName()))
+ {
+ continue;
+ }
+
+
+ Displayable displayable = rankManager.getDisplay(onlinePlayer);
+
+ if (displayables.containsKey(displayable))
+ {
+ displayables.get(displayable).add(onlinePlayer.getName());
+ }
+ else
+ {
+ displayables.put(displayable, new ArrayList<>(List.of(onlinePlayer.getName())));
+ }
+ }
+
+ for (Map.Entry> entry : displayables.entrySet())
+ {
+ final Displayable displayable = entry.getKey();
+ final List players = entry.getValue();
+
+ embedBuilder.addField(displayable.getPlural() + " (" + players.size() + ")",
+ String.join(", ", players), false);
+ }
+
+ return new MessageBuilder().setEmbed(embedBuilder.build());
+ }
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/TPSCommand.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/TPSCommand.java
new file mode 100644
index 00000000..0067af00
--- /dev/null
+++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/commands/TPSCommand.java
@@ -0,0 +1,60 @@
+package me.totalfreedom.totalfreedommod.discord.commands;
+
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommand;
+import me.totalfreedom.totalfreedommod.discord.command.DiscordCommandImpl;
+import me.totalfreedom.totalfreedommod.util.FUtil;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import org.bukkit.Bukkit;
+import org.bukkit.Server;
+
+import java.util.Collections;
+import java.util.List;
+
+public class TPSCommand extends DiscordCommandImpl
+{
+ @Override
+ public String getCommandName()
+ {
+ return "tps";
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "Lag information regarding the server.";
+ }
+
+ @Override
+ public String getCategory()
+ {
+ return "Server Commands";
+ }
+
+ @Override
+ public List getAliases()
+ {
+ return Collections.singletonList("lag");
+ }
+
+ @Override
+ public boolean isAdmin()
+ {
+ return false;
+ }
+
+ @Override
+ public MessageBuilder execute(Member member, List args)
+ {
+ final EmbedBuilder builder = new EmbedBuilder();
+ builder.setTitle("Server lag information");
+ builder.addField("TPS", String.valueOf(Math.round(FUtil.getMeanAverageDouble(Bukkit.getServer().getTPS()))), false);
+ builder.addField("Uptime", FUtil.getUptime(), false);
+ builder.addField("Maximum Memory", Math.ceil(FUtil.getMaxMem()) + " MB", false);
+ builder.addField("Allocated Memory", Math.ceil(FUtil.getTotalMem()) + " MB", false);
+ builder.addField("Free Memory", Math.ceil(FUtil.getFreeMem()) + " MB", false);
+
+ return new MessageBuilder().setEmbed(builder.build());
+ }
+}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/freeze/FreezeData.java b/src/main/java/me/totalfreedom/totalfreedommod/freeze/FreezeData.java
index bb03caaf..8a6dabc1 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/freeze/FreezeData.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/freeze/FreezeData.java
@@ -61,11 +61,8 @@ public class FreezeData
@Override
public void run()
{
- if (!Objects.requireNonNull(plugin()).al.isAdminImpostor(player) && Objects.requireNonNull(plugin()).pl.isPlayerImpostor(player))
- {
- FUtil.adminAction("TotalFreedom", "Unfreezing " + player.getName(), false);
- setFrozen(false);
- }
+ FUtil.adminAction("TotalFreedom", "Unfreezing " + player.getName(), false);
+ setFrozen(false);
}
}.runTaskLater(Objects.requireNonNull(plugin()), AUTO_PURGE_TICKS);
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java
index b682e8cc..a808ab53 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java
@@ -11,9 +11,15 @@ public class HTMLGenerationTools
return "" + escapeHtml4(data) + "
\r\n";
}
+ public static String heading(String data, String id, int level)
+ {
+ return "" + escapeHtml4(data)
+ + " \r\n";
+ }
+
public static String heading(String data, int level)
{
- return "" + escapeHtml4(data) + " \r\n";
+ return heading(data, null, level);
}
public static String list(Map map)
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java
index d19849be..dbaeddda 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java
@@ -1,52 +1,67 @@
package me.totalfreedom.totalfreedommod.httpd.module;
import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
-import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.command.FreedomCommand;
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD;
-import me.totalfreedom.totalfreedommod.rank.Displayable;
+import me.totalfreedom.totalfreedommod.rank.Rank;
import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.PluginIdentifiableCommand;
-import org.bukkit.command.SimpleCommandMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
import static me.totalfreedom.totalfreedommod.httpd.HTMLGenerationTools.heading;
import static me.totalfreedom.totalfreedommod.httpd.HTMLGenerationTools.paragraph;
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
public class Module_help extends HTTPDModule
{
-
public Module_help(NanoHTTPD.HTTPSession session)
{
super(session);
}
- private static String buildDescription(Command command)
+ private static String buildDescription(@NotNull Command command)
+ {
+ return buildDescription(command.getName(), command.getDescription(), command.getUsage(), StringUtils.join(command.getAliases(), ", "));
+ }
+
+ private static String buildDescription(@NotNull FreedomCommand command)
+ {
+ return buildDescription(command.getName(), command.getDescription(), command.getUsage(), command.getAliases());
+ }
+
+ private static String buildDescription(@NotNull String name, @Nullable String description, @NotNull String usage, @NotNull String aliases)
{
StringBuilder sb = new StringBuilder();
sb.append(
"{$CMD_NAME} - Usage: {$CMD_USAGE}"
- .replace("{$CMD_NAME}", escapeHtml4(command.getName().trim()))
- .replace("{$CMD_USAGE}", escapeHtml4(command.getUsage().trim())));
+ .replace("{$CMD_NAME}", escapeHtml4(name.trim()))
+ .replace("{$CMD_USAGE}", escapeHtml4(usage.trim())));
- if (!command.getAliases().isEmpty())
+ if (!aliases.isEmpty())
{
sb.append(
" - Aliases: {$CMD_ALIASES}"
- .replace("{$CMD_ALIASES}", escapeHtml4(StringUtils.join(command.getAliases(), ", "))));
+ .replace("{$CMD_ALIASES}", escapeHtml4(aliases.trim())));
}
- sb.append(
- "
{$CMD_DESC} \r\n"
- .replace("{$CMD_DESC}", escapeHtml4(command.getDescription().trim())));
+ if (description != null)
+ {
+ sb.append(
+ "
{$CMD_DESC}\r\n"
+ .replace("{$CMD_DESC}", escapeHtml4(description.trim())));
+ }
return sb.toString();
}
@@ -54,11 +69,7 @@ public class Module_help extends HTTPDModule
@Override
public String getBody()
{
- final CommandMap map = FreedomCommand.getCommandMap();
- if (!(map instanceof SimpleCommandMap))
- {
- return paragraph("Error loading commands.");
- }
+ final CommandMap map = Bukkit.getCommandMap();
final StringBuilder responseBody = new StringBuilder()
.append(heading("Command Help", 1))
@@ -66,7 +77,7 @@ public class Module_help extends HTTPDModule
"This page is an automatically generated listing of all plugin commands that are currently live on the server. "
+ "Please note that it does not include vanilla server commands."));
- final Collection knownCommands = ((SimpleCommandMap)map).getCommands();
+ final Collection knownCommands = map.getKnownCommands().values();
final Map> commandsByPlugin = new HashMap<>();
for (Command command : knownCommands)
@@ -79,34 +90,47 @@ public class Module_help extends HTTPDModule
List pluginCommands = commandsByPlugin.computeIfAbsent(pluginName, k -> Lists.newArrayList());
- pluginCommands.add(command);
+ if (!pluginCommands.contains(command))
+ {
+ pluginCommands.add(command);
+ }
}
+ final CommandComparator comparator = new CommandComparator();
+
+ // For every plugin...
for (Map.Entry> entry : commandsByPlugin.entrySet())
{
final String pluginName = entry.getKey();
final List commands = entry.getValue();
- commands.sort(new CommandComparator());
+ // Sort them alphabetically
+ commands.sort(comparator);
- responseBody.append(heading(pluginName, 2)).append("\r\n");
+ responseBody.append(heading(pluginName, pluginName, 2)).append("\r\n");
- Displayable lastTfmCommandLevel = null;
- for (Command command : commands)
+ if (!plugin.getName().equals(pluginName))
{
- if (!TotalFreedomMod.pluginName.equals(pluginName))
- {
- responseBody.append(buildDescription(command));
- continue;
- }
+ commands.forEach((command) -> responseBody.append(buildDescription(command)));
+ }
+ else
+ {
+ Map> freedomCommands = new HashMap<>();
- Displayable tfmCommandLevel = Objects.requireNonNull(FreedomCommand.getFrom(command)).getPerms().level();
- if (lastTfmCommandLevel == null || lastTfmCommandLevel != tfmCommandLevel)
- {
- responseBody.append("
\r\n").append(heading(tfmCommandLevel.getName(), 3)).append("\r\n");
- }
- lastTfmCommandLevel = tfmCommandLevel;
- responseBody.append(buildDescription(command));
+ // Filters out non-TFM commands
+ commands.stream().filter((cmd) -> cmd instanceof FreedomCommand.FCommand).forEach((tfmCmd) -> {
+ Rank rank = FreedomCommand.getFrom(tfmCmd).getLevel();
+ if (!freedomCommands.containsKey(rank))
+ freedomCommands.put(rank, new ArrayList<>());
+ freedomCommands.get(rank).add(FreedomCommand.getFrom(tfmCmd));
+ });
+
+ // Finally dumps them to HTML
+ Arrays.stream(Rank.values()).filter(freedomCommands::containsKey)
+ .sorted(comparator::compare).forEach((rank -> {
+ responseBody.append("
\r\n").append(heading(rank.getName(), 3)).append("\r\n");
+ freedomCommands.get(rank).stream().sorted(comparator::compare).forEach((command) -> responseBody.append(buildDescription(command)));
+ }));
}
responseBody.append("
\r\n");
@@ -118,7 +142,7 @@ public class Module_help extends HTTPDModule
@Override
public String getTitle()
{
- return "TotalFreedomMod :: Command Help";
+ return plugin.getName() + " :: Command Help";
}
@Override
@@ -129,23 +153,23 @@ public class Module_help extends HTTPDModule
public static class CommandComparator implements Comparator
{
-
@Override
public int compare(Command a, Command b)
{
- FreedomCommand ca = FreedomCommand.getFrom(a);
- FreedomCommand cb = FreedomCommand.getFrom(b);
+ return a.getName().compareTo(b.getName());
+ }
- if (ca == null
- || cb == null
- || ca.getPerms() == null
- || cb.getPerms() == null)
- {
- return a.getName().compareTo(b.getName());
- }
+ public int compare(FreedomCommand a, FreedomCommand b)
+ {
+ return a.getName().compareTo(b.getName());
+ }
- return ca.getPerms().level().getName().compareTo(cb.getPerms().level().getName());
+ public int compare(Rank a, Rank b)
+ {
+ Integer levelA = a.getLevel();
+ Integer levelB = b.getLevel();
+
+ return levelB.compareTo(levelA);
}
}
-
}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_list.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_list.java
index 33573926..fa2f5f6d 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_list.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_list.java
@@ -34,7 +34,6 @@ public class Module_list extends HTTPDModule
final JSONArray admins = new JSONArray();
final JSONArray masterbuilders = new JSONArray();
final JSONArray operators = new JSONArray();
- final JSONArray imposters = new JSONArray();
for (Player player : Bukkit.getOnlinePlayers())
{
@@ -43,11 +42,6 @@ public class Module_list extends HTTPDModule
continue;
}
- if (isImposter(player))
- {
- imposters.add(player.getName());
- }
-
if (plugin.pl.getData(player).isMasterBuilder())
{
masterbuilders.add(player.getName());
@@ -105,7 +99,6 @@ public class Module_list extends HTTPDModule
responseObject.put("admins", admins);
responseObject.put("master_builders", masterbuilders);
responseObject.put("operators", operators);
- responseObject.put("imposters", imposters);
responseObject.put("online", FUtil.getFakePlayerCount());
responseObject.put("max", server.getMaxPlayers());
@@ -141,11 +134,6 @@ public class Module_list extends HTTPDModule
}
}
- public boolean isImposter(Player player)
- {
- return plugin.al.isAdminImpostor(player) || plugin.pl.isPlayerImpostor(player);
- }
-
public boolean hasSpecialTitle(Player player)
{
return !FUtil.DEVELOPERS.contains(player.getUniqueId().toString()) && !ConfigEntry.SERVER_EXECUTIVES.getList().contains(player.getName()) && !ConfigEntry.SERVER_OWNERS.getList().contains(player.getName());
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_players.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_players.java
index 61f8b819..059b4009 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_players.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_players.java
@@ -37,7 +37,7 @@ public class Module_players extends HTTPDModule
if (!plugin.al.isVanished(player.getName()))
{
players.add(player.getName());
- if (plugin.al.isAdmin(player) && !plugin.al.isAdminImpostor(player))
+ if (plugin.al.isAdmin(player))
{
onlineadmins.add(player.getName());
}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/player/FPlayer.java b/src/main/java/me/totalfreedom/totalfreedommod/player/FPlayer.java
index 03e0c075..ced5a67a 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/player/FPlayer.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/player/FPlayer.java
@@ -16,6 +16,7 @@ import org.bukkit.scheduler.BukkitTask;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
public class FPlayer
{
@@ -26,7 +27,7 @@ public class FPlayer
private final TotalFreedomMod plugin;
private final String name;
-
+ private final UUID uuid;
private final String ip;
//
private final FreezeData freezeData = new FreezeData(this);
@@ -54,9 +55,6 @@ public class FPlayer
private String lastMessage = "";
private boolean inAdminchat = false;
private boolean allCommandsBlocked = false;
-
-
- private boolean superadminIdVerified = false;
private String lastCommand = "";
private boolean cmdspyEnabled = false;
private String tag = null;
@@ -73,12 +71,13 @@ public class FPlayer
public FPlayer(TotalFreedomMod plugin, Player player)
{
- this(plugin, player.getName(), FUtil.getIp(player));
+ this(plugin, player.getUniqueId(), player.getName(), FUtil.getIp(player));
}
- private FPlayer(TotalFreedomMod plugin, String name, String ip)
+ private FPlayer(TotalFreedomMod plugin, UUID uuid, String name, String ip)
{
this.plugin = plugin;
+ this.uuid = uuid;
this.name = name;
this.ip = ip;
}
@@ -97,14 +96,7 @@ public class FPlayer
if (player == null)
{
- for (Player onlinePlayer : Bukkit.getOnlinePlayers())
- {
- if (FUtil.getIp(onlinePlayer).equals(ip))
- {
- player = onlinePlayer;
- break;
- }
- }
+ player = Bukkit.getPlayer(uuid);
}
return player;
@@ -115,6 +107,14 @@ public class FPlayer
this.player = player;
}
+ // Ensure admins don't have admin functionality when removed (FS-222)
+ public void removeAdminFunctionality()
+ {
+ this.setCommandSpy(false);
+ this.setAdminChat(false);
+ this.setFuckoffRadius(0);
+ }
+
public boolean isOrbiting()
{
return isOrbiting;
@@ -648,16 +648,6 @@ public class FPlayer
this.allCommandsBlocked = allCommandsBlocked;
}
- public boolean isSuperadminIdVerified()
- {
- return superadminIdVerified;
- }
-
- public void setSuperadminIdVerified(boolean superadminIdVerified)
- {
- this.superadminIdVerified = superadminIdVerified;
- }
-
public boolean isCmdspyEnabled()
{
return cmdspyEnabled;
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java b/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java
index 942f9db4..680bc98d 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java
@@ -3,30 +3,25 @@ package me.totalfreedom.totalfreedommod.player;
import com.google.common.collect.Lists;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import me.totalfreedom.totalfreedommod.TotalFreedomMod;
+import java.util.*;
+
import me.totalfreedom.totalfreedommod.shop.ShopItem;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class PlayerData
{
+ private UUID uuid;
private final List ips = Lists.newArrayList();
private final List notes = Lists.newArrayList();
- private final List backupCodes = Lists.newArrayList();
- private String name;
private String tag = null;
private String discordID = null;
private Boolean masterBuilder = false;
- private Boolean verification = false;
-
private String rideMode = "ask";
@@ -48,17 +43,14 @@ public class PlayerData
{
try
{
- name = resultSet.getString("username");
+ uuid = UUID.fromString(resultSet.getString("uuid"));
ips.clear();
ips.addAll(FUtil.stringToList(resultSet.getString("ips")));
notes.clear();
notes.addAll(FUtil.stringToList(resultSet.getString("notes")));
tag = resultSet.getString("tag");
discordID = resultSet.getString("discord_id");
- backupCodes.clear();
- backupCodes.addAll(FUtil.stringToList(resultSet.getString("backup_codes")));
masterBuilder = resultSet.getBoolean("master_builder");
- verification = resultSet.getBoolean("verification");
rideMode = resultSet.getString("ride_mode");
coins = resultSet.getInt("coins");
items.clear();
@@ -72,40 +64,25 @@ public class PlayerData
{
FLog.severe("Failed to load player: " + e.getMessage());
}
-
- // Force verification for Master Builders
- if (masterBuilder && !verification)
- {
- verification = true;
- TotalFreedomMod.getPlugin().pl.save(this);
- }
- else if (!masterBuilder && discordID == null && verification)
- {
- this.verification = false;
- TotalFreedomMod.getPlugin().pl.save(this);
- }
}
public PlayerData(Player player)
{
- this.name = player.getName();
+ this.uuid = player.getUniqueId();
}
@Override
public String toString()
{
-
- return "Player: " + name + "\n" +
+ return "Player: " + getName() + "\n" +
"- IPs: " + StringUtils.join(ips, ", ") + "\n" +
"- Discord ID: " + discordID + "\n" +
"- Master Builder: " + masterBuilder + "\n" +
- "- Has Verification: " + verification + "\n" +
"- Coins: " + coins + "\n" +
"- Total Votes: " + totalVotes + "\n" +
"- Display Discord: " + displayDiscord + "\n" +
"- Tag: " + FUtil.colorize(tag) + ChatColor.GRAY + "\n" +
"- Ride Mode: " + rideMode + "\n" +
- "- Backup Codes: " + backupCodes.size() + "/10" + "\n" +
"- Login Message: " + loginMessage;
}
@@ -154,22 +131,6 @@ public class PlayerData
notes.clear();
}
- public List getBackupCodes()
- {
- return Collections.unmodifiableList(backupCodes);
- }
-
- public void setBackupCodes(List codes)
- {
- backupCodes.clear();
- backupCodes.addAll(codes);
- }
-
- public void removeBackupCode(String code)
- {
- backupCodes.remove(code);
- }
-
public void addNote(String note)
{
notes.add(note);
@@ -213,11 +174,6 @@ public class PlayerData
items.remove(item.getDataName());
}
- public boolean hasVerification()
- {
- return verification;
- }
-
public boolean isMasterBuilder()
{
return masterBuilder;
@@ -232,14 +188,12 @@ public class PlayerData
{
return new HashMap()
{{
- put("username", name);
+ put("uuid", uuid.toString());
put("ips", FUtil.listToString(ips));
put("notes", FUtil.listToString(notes));
put("tag", tag);
put("discord_id", discordID);
- put("backup_codes", FUtil.listToString(backupCodes));
put("master_builder", masterBuilder);
- put("verification", verification);
put("ride_mode", rideMode);
put("coins", coins);
put("items", FUtil.listToString(items));
@@ -255,14 +209,14 @@ public class PlayerData
return displayDiscord;
}
- public String getName()
+ public UUID getUuid()
{
- return name;
+ return uuid;
}
- public void setName(String name)
+ public String getName()
{
- this.name = name;
+ return Bukkit.getOfflinePlayer(uuid).getName();
}
public String getTag()
@@ -295,16 +249,6 @@ public class PlayerData
this.masterBuilder = masterBuilder;
}
- public Boolean getVerification()
- {
- return verification;
- }
-
- public void setVerification(Boolean verification)
- {
- this.verification = verification;
- }
-
public String getRideMode()
{
return rideMode;
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java b/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java
index 222e54d2..b04960c2 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java
@@ -3,11 +3,8 @@ package me.totalfreedom.totalfreedommod.player;
import com.google.common.collect.Maps;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
+
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
@@ -20,8 +17,8 @@ import org.bukkit.entity.Player;
public class PlayerList extends FreedomService
{
- public final Map playerMap = Maps.newHashMap(); // ip,dataMap
- public final Map dataMap = Maps.newHashMap(); // username, data
+ public final Map playerMap = Maps.newHashMap(); // uuid, dataMap
+ public final Map dataMap = Maps.newHashMap(); // uuid, data
@Override
public void onStart()
@@ -57,7 +54,7 @@ public class PlayerList extends FreedomService
while (resultSet.next())
{
PlayerData playerData = load(resultSet);
- dataMap.put(playerData.getName(), playerData);
+ dataMap.put(playerData.getUuid(), playerData);
}
}
catch (SQLException e)
@@ -103,28 +100,28 @@ public class PlayerList extends FreedomService
public boolean isTelnetMasterBuilder(PlayerData playerData)
{
- Admin admin = plugin.al.getEntryByName(playerData.getName());
+ Admin admin = plugin.al.getEntryByUuid(playerData.getUuid());
return admin != null && admin.getRank().isAtLeast(Rank.ADMIN) && playerData.isMasterBuilder();
}
// May not return null
public FPlayer getPlayer(Player player)
{
- FPlayer tPlayer = playerMap.get(FUtil.getIp(player));
+ FPlayer tPlayer = playerMap.get(player.getUniqueId());
if (tPlayer != null)
{
return tPlayer;
}
tPlayer = new FPlayer(plugin, player);
- playerMap.put(FUtil.getIp(player), tPlayer);
+ playerMap.put(player.getUniqueId(), tPlayer);
return tPlayer;
}
- public PlayerData loadByName(String name)
+ public PlayerData loadByUuid(UUID uuid)
{
- return load(plugin.sql.getPlayerByName(name));
+ return load(plugin.sql.getPlayerByUuid(uuid));
}
public PlayerData loadByIp(String ip)
@@ -141,43 +138,6 @@ public class PlayerList extends FreedomService
return new PlayerData(resultSet);
}
- public Boolean isPlayerImpostor(Player player)
- {
- PlayerData playerData = getData(player);
- return plugin.dc.enabled
- && !plugin.al.isAdmin(player)
- && (playerData.hasVerification())
- && !playerData.getIps().contains(FUtil.getIp(player));
- }
-
- public boolean IsImpostor(Player player)
- {
- return isPlayerImpostor(player) || plugin.al.isAdminImpostor(player);
- }
-
- public void verify(Player player, String backupCode)
- {
- PlayerData playerData = getData(player);
- if (backupCode != null)
- {
- playerData.removeBackupCode(backupCode);
- }
-
- playerData.addIp(FUtil.getIp(player));
- save(playerData);
-
- if (plugin.al.isAdminImpostor(player))
- {
- Admin admin = plugin.al.getEntryByName(player.getName());
- admin.setLastLogin(new Date());
- admin.addIp(FUtil.getIp(player));
- plugin.al.updateTables();
- plugin.al.save(admin);
- }
-
- plugin.rm.updateDisplay(player);
- }
-
public void syncIps(Admin admin)
{
PlayerData playerData = getData(admin.getName());
@@ -186,25 +146,11 @@ public class PlayerList extends FreedomService
plugin.pl.save(playerData);
}
- public void syncIps(PlayerData playerData)
- {
- Admin admin = plugin.al.getEntryByName(playerData.getName());
-
- if (admin != null && admin.isActive())
- {
- admin.clearIPs();
- admin.addIps(playerData.getIps());
- plugin.al.updateTables();
- plugin.al.save(admin);
- }
- }
-
-
public void save(PlayerData player)
{
try
{
- ResultSet currentSave = plugin.sql.getPlayerByName(player.getName());
+ ResultSet currentSave = plugin.sql.getPlayerByUuid(player.getUuid());
for (Map.Entry entry : player.toSQLStorable().entrySet())
{
Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue());
@@ -223,69 +169,56 @@ public class PlayerList extends FreedomService
public PlayerData getData(Player player)
{
// Check for existing data
- PlayerData playerData = dataMap.get(player.getName());
+ PlayerData playerData = dataMap.get(player.getUniqueId());
if (playerData != null)
{
return playerData;
}
// Load data
- playerData = loadByName(player.getName());
+ playerData = loadByUuid(player.getUniqueId());
+ // Oh you don't have any data? Well now you do
if (playerData == null)
{
- playerData = loadByIp(FUtil.getIp(player));
- if (playerData != null)
- {
- plugin.sql.updatePlayerName(playerData.getName(), player.getName());
- playerData.setName(player.getName());
- dataMap.put(player.getName(), playerData);
- return playerData;
- }
- }
- else
- {
- dataMap.put(player.getName(), playerData);
- return playerData;
+ FLog.info("Creating new player data entry for " + player.getName());
+
+ playerData = new PlayerData(player);
+ playerData.addIp(FUtil.getIp(player));
}
- // Create new data if nonexistent
- FLog.info("Creating new player verification entry for " + player.getName());
+ // Store it in memory.
+ dataMap.put(player.getUniqueId(), playerData);
- // Create new player
- playerData = new PlayerData(player);
- playerData.addIp(FUtil.getIp(player));
-
- // Store player
- dataMap.put(player.getName(), playerData);
-
- // Save player
+ // Send it to the SQL database.
plugin.sql.addPlayer(playerData);
- return playerData;
+ // Returns it
+ return playerData;
+ }
+
+ public PlayerData getData(UUID uuid)
+ {
+ PlayerData data = dataMap.get(uuid);
+
+ if (data == null)
+ {
+ data = loadByUuid(uuid);
+ }
+
+ return data;
}
public PlayerData getData(String username)
{
- // Check for existing data
- PlayerData playerData = dataMap.get(username);
- if (playerData != null)
+ OfflinePlayer player = server.getPlayer(username);
+
+ if (player == null)
{
- return playerData;
+ player = server.getOfflinePlayer(username);
}
- playerData = loadByName(username);
-
- if (playerData != null)
- {
- dataMap.put(username, playerData);
- }
- else
- {
- return null;
- }
-
- return playerData;
+ return getData(player.getUniqueId());
}
public PlayerData getDataByIp(String ip)
@@ -294,18 +227,18 @@ public class PlayerList extends FreedomService
if (player != null)
{
- dataMap.put(player.getName(), player);
+ dataMap.put(player.getUuid(), player);
}
return player;
}
- public Map getPlayerMap()
+ public Map getPlayerMap()
{
return playerMap;
}
- public Map getDataMap()
+ public Map getDataMap()
{
return dataMap;
}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/Displayable.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/Displayable.java
index 55cc2fc1..2b2f2e49 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/rank/Displayable.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/Displayable.java
@@ -13,6 +13,8 @@ public interface Displayable
String getAbbr();
+ String getPlural();
+
ChatColor getColor();
org.bukkit.ChatColor getTeamColor();
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/Rank.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/Rank.java
index b7ebb707..0c04dbbe 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/rank/Rank.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/Rank.java
@@ -4,20 +4,19 @@ import net.md_5.bungee.api.ChatColor;
public enum Rank implements Displayable
{
- IMPOSTOR("an", "Impostor", Type.PLAYER, "Imp", ChatColor.YELLOW, null, false, false),
- NON_OP("a", "Non-Op", Type.PLAYER, "", ChatColor.WHITE, null, false, false),
- OP("an", "Operator", Type.PLAYER, "OP", ChatColor.GREEN, null, false, false),
- ADMIN("an", "Admin", Type.ADMIN, "Admin", ChatColor.DARK_GREEN, org.bukkit.ChatColor.DARK_GREEN, true, true),
- SENIOR_ADMIN("a", "Senior Admin", Type.ADMIN, "SrA", ChatColor.GOLD, org.bukkit.ChatColor.GOLD, true, true),
- ADMIN_CONSOLE("the", "Console", Type.ADMIN_CONSOLE, "Console", ChatColor.DARK_PURPLE, null, false, false),
- SENIOR_CONSOLE("the", "Console", Type.ADMIN_CONSOLE, "Console", ChatColor.DARK_PURPLE, null, false, false);
+ NON_OP("a", "Non-Op", Type.PLAYER, "", "Non-Ops", ChatColor.WHITE, null, false, false),
+ OP("an", "Operator", Type.PLAYER, "OP", "Operators", ChatColor.GREEN, null, false, false),
+ ADMIN("an", "Admin", Type.ADMIN, "Admin", "Administrators", ChatColor.DARK_GREEN, org.bukkit.ChatColor.DARK_GREEN, true, true),
+ SENIOR_ADMIN("a", "Senior Admin", Type.ADMIN, "SrA", "Senior Administrators", ChatColor.GOLD, org.bukkit.ChatColor.GOLD, true, true),
+ ADMIN_CONSOLE("the", "Console", Type.ADMIN_CONSOLE, "Console", "Administrator Consoles", ChatColor.DARK_PURPLE, null, false, false),
+ SENIOR_CONSOLE("the", "Console", Type.ADMIN_CONSOLE, "Console", "Senior Consoles", ChatColor.DARK_PURPLE, null, false, false);
private final Type type;
private final String name;
private final String abbr;
-
+ private final String plural;
private final String article;
private final String tag;
@@ -32,11 +31,12 @@ public enum Rank implements Displayable
private final boolean hasDefaultLoginMessage;
- Rank(String article, String name, Type type, String abbr, ChatColor color, org.bukkit.ChatColor teamColor, Boolean hasTeam, Boolean hasDefaultLoginMessage)
+ Rank(String article, String name, Type type, String abbr, String plural, ChatColor color, org.bukkit.ChatColor teamColor, Boolean hasTeam, Boolean hasDefaultLoginMessage)
{
this.type = type;
this.name = name;
this.abbr = abbr;
+ this.plural = plural;
this.article = article;
this.tag = abbr.isEmpty() ? "" : "[" + abbr + "]";
this.coloredTag = abbr.isEmpty() ? "" : ChatColor.DARK_GRAY + "[" + color + abbr + ChatColor.DARK_GRAY + "]" + color;
@@ -89,6 +89,11 @@ public enum Rank implements Displayable
return abbr;
}
+ public String getPlural()
+ {
+ return plural;
+ }
+
public boolean isConsole()
{
return getType() == Type.ADMIN_CONSOLE;
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java
index d246b19f..e1d07e1e 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java
@@ -9,7 +9,6 @@ import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
-import org.bukkit.GameMode;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -39,12 +38,6 @@ public class RankManager extends FreedomService
final Player player = (Player)sender;
- // Display impostors
- if (plugin.al.isAdminImpostor(player))
- {
- return Rank.IMPOSTOR;
- }
-
// If the player's an owner, display that
if (ConfigEntry.SERVER_OWNERS.getList().contains(player.getName()))
{
@@ -67,11 +60,6 @@ public class RankManager extends FreedomService
return Title.ASSTEXEC;
}
- if (plugin.al.isVerifiedAdmin(player))
- {
- return Title.VERIFIED_ADMIN;
- }
-
// Master builders show up if they are not an admin
if (plugin.pl.getData(player).isMasterBuilder() && !plugin.al.isAdmin(player))
{
@@ -137,11 +125,6 @@ public class RankManager extends FreedomService
public Rank getRank(Player player)
{
- if (plugin.al.isAdminImpostor(player) || plugin.pl.isPlayerImpostor(player))
- {
- return Rank.IMPOSTOR;
- }
-
final Admin entry = plugin.al.getAdmin(player);
if (entry != null)
{
@@ -193,52 +176,20 @@ public class RankManager extends FreedomService
public void onPlayerJoin(PlayerJoinEvent event)
{
final Player player = event.getPlayer();
- final FPlayer fPlayer = plugin.pl.getPlayer(player);
PlayerData target = plugin.pl.getData(player);
- // Unban admins
boolean isAdmin = plugin.al.isAdmin(player);
+
+ // Updates last login time
if (isAdmin)
{
- // Verify strict IP match
- if (!plugin.al.isIdentityMatched(player))
- {
- FUtil.bcastMsg("Warning: " + player.getName() + " is an admin, but is using an account not registered to one of their ip-list.", ChatColor.RED);
- fPlayer.setSuperadminIdVerified(false);
- }
- else
- {
- fPlayer.setSuperadminIdVerified(true);
- plugin.al.updateLastLogin(player);
- }
- }
-
- if (plugin.al.isVerifiedAdmin(player))
+ plugin.al.updateLastLogin(player);
+ } else
{
- FUtil.bcastMsg("Warning: " + player.getName() + " is an admin, but does not have any admin permissions.", ChatColor.RED);
- }
+ // Ensure admins don't have admin functionality when removed (FS-222)
+ FPlayer freedomPlayer = plugin.pl.getPlayer(player);
- // Handle impostors
- boolean isImpostor = plugin.al.isAdminImpostor(player) || plugin.pl.isPlayerImpostor(player);
- if (isImpostor)
- {
- FUtil.bcastMsg(ChatColor.AQUA + player.getName() + " is " + Rank.IMPOSTOR.getColoredLoginMessage());
- if (plugin.al.isAdminImpostor(player))
- {
- FUtil.bcastMsg("Warning: " + player.getName() + " has been flagged as an admin impostor and has been frozen!", ChatColor.RED);
- }
- else if (plugin.pl.isPlayerImpostor(player))
- {
- FUtil.bcastMsg("Warning: " + player.getName() + " has been flagged as a player impostor and has been frozen!", ChatColor.RED);
- }
- String displayName = Rank.IMPOSTOR.getColor() + player.getName();
- player.setPlayerListName(StringUtils.substring(displayName, 0, 16));
- player.getInventory().clear();
- player.setOp(false);
- player.setGameMode(GameMode.SURVIVAL);
- plugin.pl.getPlayer(player).getFreezeData().setFrozen(true);
- player.sendMessage(ChatColor.RED + "You are marked as an impostor, please verify yourself!");
- return;
+ freedomPlayer.removeAdminFunctionality();
}
// Broadcast login message
@@ -253,12 +204,9 @@ public class RankManager extends FreedomService
// Set display
updateDisplay(player);
- if (!plugin.pl.isPlayerImpostor(player) && target.hasVerification())
+ if (target.getTag() != null)
{
- if (target.getTag() != null)
- {
- plugin.pl.getData(player).setTag(FUtil.colorize(target.getTag()));
- }
+ plugin.pl.getData(player).setTag(FUtil.colorize(target.getTag()));
}
}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java
index 93bd0339..8cdd0118 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java
@@ -5,12 +5,11 @@ import net.md_5.bungee.api.ChatColor;
public enum Title implements Displayable
{
- MASTER_BUILDER("a", "Master Builder", ChatColor.DARK_AQUA, org.bukkit.ChatColor.DARK_AQUA, "MB", true, true),
- VERIFIED_ADMIN("a", "Verified Admin", ChatColor.LIGHT_PURPLE, org.bukkit.ChatColor.LIGHT_PURPLE, "VA", false, true),
- EXECUTIVE("an", "Executive", ChatColor.RED, org.bukkit.ChatColor.RED, "Exec", true, true),
- ASSTEXEC("an", "Assistant Executive", ChatColor.RED, org.bukkit.ChatColor.RED, "Asst Exec", true, true),
- DEVELOPER("a", "Developer", ChatColor.DARK_PURPLE, org.bukkit.ChatColor.DARK_PURPLE, "Dev", true, true),
- OWNER("the", "Owner", ChatColor.DARK_RED, org.bukkit.ChatColor.DARK_RED, "Owner", true, true);
+ MASTER_BUILDER("a", "Master Builder", "Master Builders", ChatColor.DARK_AQUA, org.bukkit.ChatColor.DARK_AQUA, "MB", true, true),
+ EXECUTIVE("an", "Executive", "Executives", ChatColor.RED, org.bukkit.ChatColor.RED, "Exec", true, true),
+ ASSTEXEC("an", "Assistant Executive", "Assistant Executives", ChatColor.RED, org.bukkit.ChatColor.RED, "Asst Exec", true, true),
+ DEVELOPER("a", "Developer", "Developers", ChatColor.DARK_PURPLE, org.bukkit.ChatColor.DARK_PURPLE, "Dev", true, true),
+ OWNER("the", "Owner", "Owners", ChatColor.DARK_RED, org.bukkit.ChatColor.DARK_RED, "Owner", true, true);
private final String article;
@@ -18,6 +17,7 @@ public enum Title implements Displayable
private final String name;
private final String abbr;
+ private final String plural;
private final String tag;
@@ -30,10 +30,11 @@ public enum Title implements Displayable
private final boolean hasTeam;
private final boolean hasDefaultLoginMessage;
- Title(String article, String name, ChatColor color, org.bukkit.ChatColor teamColor, String tag, Boolean hasTeam, Boolean hasDefaultLoginMessage)
+ Title(String article, String name, String plural, ChatColor color, org.bukkit.ChatColor teamColor, String tag, Boolean hasTeam, Boolean hasDefaultLoginMessage)
{
this.article = article;
this.name = name;
+ this.plural = plural;
this.coloredTag = ChatColor.DARK_GRAY + "[" + color + tag + ChatColor.DARK_GRAY + "]" + color;
this.abbr = tag;
this.tag = "[" + tag + "]";
@@ -85,6 +86,12 @@ public enum Title implements Displayable
return abbr;
}
+ @Override
+ public String getPlural()
+ {
+ return plural;
+ }
+
@Override
public String getTag()
{
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java b/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java
index 09551e02..336c7934 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java
@@ -7,6 +7,8 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
+import java.util.UUID;
+
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.banning.Ban;
@@ -82,7 +84,7 @@ public class SQLite extends FreedomService
{
try
{
- connection.createStatement().execute("CREATE TABLE `admins` (`username` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `rank` VARCHAR NOT NULL, `active` BOOLEAN NOT NULL, `last_login` LONG NOT NULL, `command_spy` BOOLEAN NOT NULL, `potion_spy` BOOLEAN NOT NULL, `ac_format` VARCHAR, `ptero_id` VARCHAR);");
+ connection.createStatement().execute("CREATE TABLE `admins` (`uuid` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `rank` VARCHAR NOT NULL, `active` BOOLEAN NOT NULL, `last_login` LONG NOT NULL, `command_spy` BOOLEAN NOT NULL, `potion_spy` BOOLEAN NOT NULL, `ac_format` VARCHAR, `ptero_id` VARCHAR);");
}
catch (SQLException e)
{
@@ -93,7 +95,7 @@ public class SQLite extends FreedomService
{
try
{
- connection.createStatement().execute("CREATE TABLE `players` (`username` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `notes` VARCHAR, `tag` VARCHAR, `discord_id` VARCHAR, `backup_codes` VARCHAR, `master_builder` BOOLEAN NOT NULL,`verification` BOOLEAN NOT NULL, `ride_mode` VARCHAR NOT NULL, `coins` INT, `items` VARCHAR, `total_votes` INT NOT NULL, `display_discord` BOOLEAN NOT NULL, `login_message` VARCHAR, `inspect` BOOLEAN NOT NULL);");
+ connection.createStatement().execute("CREATE TABLE `players` (`uuid` VARCHAR NOT NULL, `ips` VARCHAR NOT NULL, `notes` VARCHAR, `tag` VARCHAR, `discord_id` VARCHAR, `master_builder` BOOLEAN NOT NULL, `ride_mode` VARCHAR NOT NULL, `coins` INT, `items` VARCHAR, `total_votes` INT NOT NULL, `display_discord` BOOLEAN NOT NULL, `login_message` VARCHAR, `inspect` BOOLEAN NOT NULL);");
}
catch (SQLException e)
{
@@ -133,8 +135,8 @@ public class SQLite extends FreedomService
{
try
{
- Object[] data = {key, admin.getName()};
- PreparedStatement statement = connection.prepareStatement(MessageFormat.format("UPDATE admins SET {0}=? WHERE username=''{1}''", data));
+ Object[] data = {key, admin.getUuid()};
+ PreparedStatement statement = connection.prepareStatement(MessageFormat.format("UPDATE admins SET {0}=? WHERE uuid=''{1}''", data));
statement = setUnknownType(statement, 1, value);
statement.executeUpdate();
@@ -150,8 +152,8 @@ public class SQLite extends FreedomService
{
try
{
- Object[] data = {key, player.getName()};
- PreparedStatement statement = connection.prepareStatement(MessageFormat.format("UPDATE players SET {0}=? WHERE username=''{1}''", data));
+ Object[] data = {key, player.getUuid()};
+ PreparedStatement statement = connection.prepareStatement(MessageFormat.format("UPDATE players SET {0}=? WHERE uuid=''{1}''", data));
statement = setUnknownType(statement, 1, value);
statement.executeUpdate();
@@ -162,36 +164,6 @@ public class SQLite extends FreedomService
}
}
- public void updateAdminName(String oldName, String newName)
- {
- try
- {
- PreparedStatement statement = connection.prepareStatement(MessageFormat.format("UPDATE admins SET username=? WHERE username=''{0}''", oldName));
- statement = setUnknownType(statement, 1, newName);
- statement.executeUpdate();
-
- }
- catch (SQLException e)
- {
- FLog.severe("Failed to update admin name: " + e.getMessage());
- }
- }
-
- public void updatePlayerName(String oldName, String newName)
- {
- try
- {
- PreparedStatement statement = connection.prepareStatement(MessageFormat.format("UPDATE players SET username=? WHERE username=''{0}''", oldName));
- statement = setUnknownType(statement, 1, newName);
- statement.executeUpdate();
-
- }
- catch (SQLException e)
- {
- FLog.severe("Failed to update player name: " + e.getMessage());
- }
- }
-
public PreparedStatement setUnknownType(PreparedStatement statement, int index, Object value) throws SQLException
{
if (value == null)
@@ -248,7 +220,7 @@ public class SQLite extends FreedomService
try
{
PreparedStatement statement = connection.prepareStatement("INSERT INTO admins VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
- statement.setString(1, admin.getName());
+ statement.setString(1, admin.getUuid().toString());
statement.setString(2, FUtil.listToString(admin.getIps()));
statement.setString(3, admin.getRank().toString());
statement.setBoolean(4, admin.isActive());
@@ -270,22 +242,20 @@ public class SQLite extends FreedomService
{
try
{
- PreparedStatement statement = connection.prepareStatement("INSERT INTO players VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
- statement.setString(1, player.getName());
+ PreparedStatement statement = connection.prepareStatement("INSERT INTO players VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+ statement.setString(1, player.getUuid().toString());
statement.setString(2, FUtil.listToString(player.getIps()));
statement.setString(3, FUtil.listToString(player.getNotes()));
statement.setString(4, player.getTag());
statement.setString(5, player.getDiscordID());
- statement.setString(6, FUtil.listToString(player.getBackupCodes()));
- statement.setBoolean(7, player.isMasterBuilder());
- statement.setBoolean(8, player.hasVerification());
- statement.setString(9, player.getRideMode());
- statement.setInt(10, player.getCoins());
- statement.setString(11, FUtil.listToString(player.getItems()));
- statement.setInt(12, player.getTotalVotes());
- statement.setBoolean(13, player.doesDisplayDiscord());
- statement.setString(14, player.getLoginMessage());
- statement.setBoolean(15, player.hasInspection());
+ statement.setBoolean(6, player.isMasterBuilder());
+ statement.setString(7, player.getRideMode());
+ statement.setInt(8, player.getCoins());
+ statement.setString(9, FUtil.listToString(player.getItems()));
+ statement.setInt(10, player.getTotalVotes());
+ statement.setBoolean(11, player.doesDisplayDiscord());
+ statement.setString(12, player.getLoginMessage());
+ statement.setBoolean(13, player.hasInspection());
statement.executeUpdate();
}
catch (SQLException e)
@@ -295,11 +265,11 @@ public class SQLite extends FreedomService
}
}
- public ResultSet getAdminByName(String name)
+ public ResultSet getAdminByUuid(UUID uuid)
{
try
{
- ResultSet resultSet = connection.createStatement().executeQuery(MessageFormat.format("SELECT * FROM admins WHERE username=''{0}''", name));
+ ResultSet resultSet = connection.createStatement().executeQuery(MessageFormat.format("SELECT * FROM admins WHERE uuid=''{0}''", uuid.toString()));
if (resultSet.next())
{
return resultSet;
@@ -314,11 +284,11 @@ public class SQLite extends FreedomService
return null;
}
- public ResultSet getPlayerByName(String name)
+ public ResultSet getPlayerByUuid(UUID uuid)
{
try
{
- ResultSet resultSet = connection.createStatement().executeQuery(MessageFormat.format("SELECT * FROM players WHERE username=''{0}''", name));
+ ResultSet resultSet = connection.createStatement().executeQuery(MessageFormat.format("SELECT * FROM players WHERE uuid=''{0}''", uuid.toString()));
if (resultSet.next())
{
return resultSet;
@@ -326,7 +296,7 @@ public class SQLite extends FreedomService
}
catch (SQLException e)
{
- FLog.severe("Failed to get player by name:");
+ FLog.severe("Failed to get player by UUID:");
FLog.severe(e);
}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/DepreciationAggregator.java b/src/main/java/me/totalfreedom/totalfreedommod/util/DepreciationAggregator.java
deleted file mode 100644
index fa87fc18..00000000
--- a/src/main/java/me/totalfreedom/totalfreedommod/util/DepreciationAggregator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package me.totalfreedom.totalfreedommod.util;
-
-import java.util.HashSet;
-import org.bukkit.Material;
-import org.bukkit.OfflinePlayer;
-import org.bukkit.Server;
-import org.bukkit.block.Block;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.LivingEntity;
-
-@SuppressWarnings("deprecation")
-public class DepreciationAggregator
-{
- public static Block getTargetBlock(LivingEntity entity, HashSet transparent, int maxDistance)
- {
- return entity.getTargetBlock(transparent, maxDistance);
- }
-
- public static OfflinePlayer getOfflinePlayer(Server server, String name)
- {
- return server.getOfflinePlayer(name);
- }
-
- public static String getName_EntityType(EntityType et)
- {
- return et.getName();
- }
-}
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java
index f6988aec..3fc1bb7a 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java
@@ -1,16 +1,12 @@
package me.totalfreedom.totalfreedommod.util;
+import com.earth2me.essentials.utils.DateUtil;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.Color;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.OfflinePlayer;
+import org.bukkit.*;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -19,10 +15,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
-import org.json.simple.JSONArray;
import java.io.*;
-import java.lang.reflect.Field;
+import java.lang.management.ManagementFactory;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
@@ -55,9 +50,32 @@ public class FUtil
"ba5aafba-9012-418f-9819-a7020d591068", // TFTWPhoenix
"d6dd9740-40db-45f5-ab16-4ee16a633009", // Abhi
"2e06e049-24c8-42e4-8bcf-d35372af31e6", // NotInSync
- "f97c0d7b-6413-4558-a409-88f09a8f9adb" // videogamesm12
+ "f97c0d7b-6413-4558-a409-88f09a8f9adb", // videogamesm12
+ "78408086-1991-4c33-a571-d8fa325465b2", // Telesphoreo
+ "f5cd54c4-3a24-4213-9a56-c06c49594dff", // Taahh
+ "a52f1f08-a398-400a-bca4-2b74b81feae6", // G6_
+ "ca83b658-c03b-4106-9edc-72f70a80656d" // ayunami2000
);
- public static final List DEVELOPER_NAMES = Arrays.asList("Madgeek1450", "Prozza", "WickedGamingUK", "Wild1145", "aggelosQQ", "scripthead", "CoolJWB", "elmon_", "speednt", "SupItsDillon", "Paldiu", "TFTWPhoenix", "abhithedev", "NotInSync", "videogamesm12");
+ public static final List DEVELOPER_NAMES = Arrays.asList(
+ "Madgeek1450",
+ "Prozza",
+ "WickedGamingUK",
+ "Wild1145",
+ "aggelosQQ",
+ "scripthead",
+ "Telesphoreo",
+ "CoolJWB",
+ "elmon_",
+ "speednt",
+ "SupItsDillon",
+ "Paldiu",
+ "TFTWPhoenix",
+ "abhithedev",
+ "NotInSync",
+ "videogamesm12",
+ "Taahh",
+ "G6_",
+ "ayunami2000");
public static final Map CHAT_COLOR_NAMES = new HashMap<>();
public static final List CHAT_COLOR_POOL = Arrays.asList(
ChatColor.DARK_RED,
@@ -225,33 +243,6 @@ public class FUtil
return names;
}
- @SuppressWarnings("unchecked")
- public static UUID nameToUUID(String name)
- {
- try
- {
- JSONArray json = new JSONArray();
- json.add(name);
- List headers = new ArrayList<>();
- headers.add("Accept:application/json");
- headers.add("Content-Type:application/json");
- Response response = sendRequest("https://api.mojang.com/profiles/minecraft", "POST", headers, json.toString());
- // Don't care how stupid this looks, couldn't find anything to parse a json string to something readable in java with something not horrendously huge, maybe im just retarded
- Pattern pattern = Pattern.compile("(?<=\"id\":\")[a-f0-9].{31}");
- Matcher matcher = pattern.matcher(response.getMessage());
- if (matcher.find())
- {
- String rawUUID = matcher.group(0).replaceFirst("([a-f0-9]{8})([a-f0-9]{4})([a-f0-9]{4})([a-f0-9]{4})([a-f0-9]+)", "$1-$2-$3-$4-$5");
- return UUID.fromString(rawUUID);
- }
- }
- catch (Exception e)
- {
- FLog.severe("Failed to convert name to UUID:\n" + e.toString());
- }
- return null;
- }
-
public static Response sendRequest(String endpoint, String method, List headers, String body) throws IOException
{
URL url = new URL(endpoint);
@@ -537,30 +528,6 @@ public class FUtil
return ip;
}
- //getField: Borrowed from WorldEdit
- @SuppressWarnings("unchecked")
- public static T getField(Object from, String name)
- {
- Class> checkClass = from.getClass();
- do
- {
- try
- {
- Field field = checkClass.getDeclaredField(name);
- field.setAccessible(true);
- return (T) field.get(from);
-
- }
- catch (NoSuchFieldException | IllegalAccessException ignored)
- {
- }
- }
- while (checkClass.getSuperclass() != Object.class
- && ((checkClass = checkClass.getSuperclass()) != null));
-
- return null;
- }
-
public static ChatColor randomChatColor()
{
return CHAT_COLOR_POOL.get(RANDOM.nextInt(CHAT_COLOR_POOL.size()));
@@ -601,6 +568,11 @@ public class FUtil
return string;
}
+ public static String stripColors(String string)
+ {
+ return string.replaceAll("§", "");
+ }
+
public static Date getUnixDate(long unix)
{
return new Date(unix);
@@ -846,6 +818,62 @@ public class FUtil
return getServer().getOnlinePlayers().size() - i;
}
+ public static double getMeanAverageDouble(double[] doubles)
+ {
+ double total = 0;
+
+ for (double aDouble : doubles)
+ {
+ total += aDouble;
+ }
+
+ return total / doubles.length;
+ }
+
+ public static int getMeanAverageInt(int[] ints)
+ {
+ int total = 0;
+
+ for (int anInt : ints)
+ {
+ total += anInt;
+ }
+
+ return total / ints.length;
+ }
+
+ public static long getMeanAverageLong(long[] longs)
+ {
+ long total = 0;
+
+ for (long aLong : longs)
+ {
+ total += aLong;
+ }
+
+ return total / longs.length;
+ }
+
+ public static String getUptime()
+ {
+ return DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime());
+ }
+
+ public static double getMaxMem()
+ {
+ return Runtime.getRuntime().maxMemory() / 1024f / 1024f;
+ }
+
+ public static double getTotalMem()
+ {
+ return Runtime.getRuntime().totalMemory() / 1024f / 1024f;
+ }
+
+ public static double getFreeMem()
+ {
+ return Runtime.getRuntime().freeMemory() / 1024f / 1024f;
+ }
+
public static class PaginationList extends ArrayList
{
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/Groups.java b/src/main/java/me/totalfreedom/totalfreedommod/util/Groups.java
index 0df27d99..5c1b7c9b 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/util/Groups.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/util/Groups.java
@@ -8,81 +8,11 @@ import org.bukkit.entity.EntityType;
public class Groups
{
- public static final List WOOL_COLORS = Arrays.asList(
- Material.WHITE_WOOL,
- Material.RED_WOOL,
- Material.ORANGE_WOOL,
- Material.YELLOW_WOOL,
- Material.GREEN_WOOL,
- Material.LIME_WOOL,
- Material.LIGHT_BLUE_WOOL,
- Material.CYAN_WOOL,
- Material.BLUE_WOOL,
- Material.PURPLE_WOOL,
- Material.MAGENTA_WOOL,
- Material.PINK_WOOL,
- Material.BROWN_WOOL,
- Material.GRAY_WOOL,
- Material.LIGHT_GRAY_WOOL,
- Material.BLACK_WOOL);
-
- public static final List SHULKER_BOXES = Arrays.asList(
- Material.SHULKER_BOX,
- Material.WHITE_SHULKER_BOX,
- Material.RED_SHULKER_BOX,
- Material.ORANGE_SHULKER_BOX,
- Material.YELLOW_SHULKER_BOX,
- Material.GREEN_SHULKER_BOX,
- Material.LIME_SHULKER_BOX,
- Material.LIGHT_BLUE_SHULKER_BOX,
- Material.CYAN_SHULKER_BOX,
- Material.BLUE_SHULKER_BOX,
- Material.PURPLE_SHULKER_BOX,
- Material.MAGENTA_SHULKER_BOX,
- Material.PINK_SHULKER_BOX,
- Material.BROWN_SHULKER_BOX,
- Material.GRAY_SHULKER_BOX,
- Material.LIGHT_GRAY_SHULKER_BOX,
- Material.BLACK_SHULKER_BOX);
-
+ public static final List WOOL_COLORS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_WOOL")).toList();
+ public static final List SHULKER_BOXES = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("SHULKER_BOX")).toList();
public static final List MOB_TYPES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).toList();
-
public static final List SPAWN_EGGS = Arrays.stream(Material.values()).filter((mat) -> mat.name().endsWith("_SPAWN_EGG")).toList();
-
- public static final List BANNERS = Arrays.asList(
- Material.BLACK_BANNER,
- Material.BLACK_WALL_BANNER,
- Material.BLUE_BANNER,
- Material.BLUE_WALL_BANNER,
- Material.BROWN_BANNER,
- Material.BROWN_WALL_BANNER,
- Material.CYAN_BANNER,
- Material.CYAN_WALL_BANNER,
- Material.GRAY_BANNER,
- Material.GRAY_WALL_BANNER,
- Material.GREEN_BANNER,
- Material.GREEN_WALL_BANNER,
- Material.LIGHT_BLUE_BANNER,
- Material.LIGHT_BLUE_WALL_BANNER,
- Material.LIGHT_GRAY_BANNER,
- Material.LIGHT_GRAY_WALL_BANNER,
- Material.LIME_BANNER,
- Material.LIME_WALL_BANNER,
- Material.MAGENTA_BANNER,
- Material.MAGENTA_WALL_BANNER,
- Material.ORANGE_BANNER,
- Material.ORANGE_WALL_BANNER,
- Material.PINK_BANNER,
- Material.PINK_WALL_BANNER,
- Material.PURPLE_BANNER,
- Material.PURPLE_WALL_BANNER,
- Material.RED_BANNER,
- Material.RED_WALL_BANNER,
- Material.WHITE_BANNER,
- Material.WHITE_WALL_BANNER,
- Material.YELLOW_BANNER,
- Material.YELLOW_WALL_BANNER);
-
+ public static final List BANNERS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_BANNER")).toList();
public static final List EXPLOSIVE_BED_BIOMES = Arrays.asList(
Biome.NETHER_WASTES,
Biome.CRIMSON_FOREST,
diff --git a/src/main/java/me/totalfreedom/totalfreedommod/world/WorldRestrictions.java b/src/main/java/me/totalfreedom/totalfreedommod/world/WorldRestrictions.java
index 4aef7377..3dc501b0 100644
--- a/src/main/java/me/totalfreedom/totalfreedommod/world/WorldRestrictions.java
+++ b/src/main/java/me/totalfreedom/totalfreedommod/world/WorldRestrictions.java
@@ -32,14 +32,6 @@ public class WorldRestrictions extends FreedomService
private final List BLOCKED_ESSENTIALS_COMMANDS = Arrays.asList(
"bigtree", "ebigtree", "largetree", "elargetree");
- private final Map, Object> flags = new HashMap, Object>()
- {{
- put(Flags.PLACE_VEHICLE, StateFlag.State.DENY);
- put(Flags.DESTROY_VEHICLE, StateFlag.State.DENY);
- put(Flags.ENTITY_ITEM_FRAME_DESTROY, StateFlag.State.DENY);
- put(Flags.ENTITY_PAINTING_DESTROY, StateFlag.State.DENY);
- }};
-
@Override
public void onStart()
{
@@ -155,20 +147,4 @@ public class WorldRestrictions extends FreedomService
}
}
}
-
- public void protectWorld(World world)
- {
- if (!plugin.wgb.isEnabled())
- {
- return;
- }
-
- RegionManager regionManager = plugin.wgb.getRegionManager(world);
-
- GlobalProtectedRegion region = new GlobalProtectedRegion("__global__");
-
- region.setFlags(flags);
-
- regionManager.addRegion(region);
- }
}
\ No newline at end of file
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 33b4b43e..d0f9ff4d 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -56,14 +56,16 @@ server:
# Discord
discord:
- # Do you want to enable the Discord verification system? (Disabled by default)
- verification: false
# If you do not have a token, make a bot account and get one at https://discordapp.com/developers/applications/me
token: ''
+ # The prefix for the integrated bot commands
+ prefix: 'tf!'
# The official discord server's ID for this server
server_id: ''
# Channel to send /report messages to
report_channel_id: ''
+ # Channel to send archived reports to
+ report_archive_channel_id: ''
# Channel for Discord to Minecraft and vice-versa
chat_channel_id: ''
# Channel for Discord to AdminChat and vice-versa