diff --git a/.github/workflows/codacy-analysis.yml b/.github/workflows/codacy-analysis.yml index e5aa4641..f39f89ba 100644 --- a/.github/workflows/codacy-analysis.yml +++ b/.github/workflows/codacy-analysis.yml @@ -21,11 +21,11 @@ jobs: steps: # Checkout the repository to the GitHub Actions runner - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis - name: Run Codacy Analysis CLI - uses: codacy/codacy-analysis-cli-action@4.0.0 + uses: codacy/codacy-analysis-cli-action@v4.1.0 with: # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository # You can also omit the token and run the tools that support default configurations @@ -41,6 +41,6 @@ jobs: # Upload the SARIF file generated in the previous step - name: Upload SARIF results file - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 with: sarif_file: results.sarif diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index eaf30927..972ab7f7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,10 +35,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Java JDK - uses: actions/setup-java@v2.3.0 + uses: actions/setup-java@v3.3.0 with: # The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x). Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28 java-version: 17 @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -57,7 +57,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -71,4 +71,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml index 33365e0b..93fed296 100644 --- a/.github/workflows/downstream.yml +++ b/.github/workflows/downstream.yml @@ -26,7 +26,7 @@ jobs: # Step 2: run this sync action - specify the upstream repo, upstream branch to sync with, and target sync branch - name: Pull (Fast-Forward) upstream changes id: sync - uses: aormsby/Fork-Sync-With-Upstream-action@v2.1 + uses: aormsby/Fork-Sync-With-Upstream-action@v3.3 with: upstream_repository: AtlasMediaGroup/TotalFreedomMod upstream_branch: main diff --git a/.github/workflows/java17-maven.yml b/.github/workflows/java17-maven.yml index 43d090ab..6f55c804 100644 --- a/.github/workflows/java17-maven.yml +++ b/.github/workflows/java17-maven.yml @@ -9,11 +9,11 @@ jobs: steps: # Checkout the code - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 # Java 16 Builds - name: Set up JDK 17 - uses: actions/setup-java@v2.3.0 + uses: actions/setup-java@v3.3.0 with: java-version: 17 distribution: 'adopt' diff --git a/README.md b/README.md index 5f31795f..ec933dff 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TotalFreedomMod [![Maven-Build](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/maven.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/maven.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/29c0f964da304666bd654bc7b1d556db)](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade) [![CodeQL](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml) +# TotalFreedomMod [![Maven-Build](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/29c0f964da304666bd654bc7b1d556db)](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade) [![CodeQL](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml) TotalFreedomMod is a CraftBukkit server plugin designed primarily to support the [Official TotalFreedom Minecraft Server](https://totalfreedom.me/). However, you are more than welcome to adapt the source for your own server. diff --git a/pom.xml b/pom.xml index 58c6cee0..a6d8a95e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ me.totalfreedom TotalFreedomMod - 2022.02 + 2022.06 jar @@ -50,11 +50,6 @@ https://repo.codemc.org/repository/maven-public/ - - nms-repo - https://repo.codemc.org/repository/nms/ - - spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots/ @@ -125,23 +120,16 @@ compile - - commons-codec - commons-codec - 1.15 - compile - - org.bstats bstats-bukkit - 2.2.1 + 3.0.0 compile - org.spigotmc - spigot + io.papermc.paper + paper-api 1.17.1-R0.1-SNAPSHOT provided @@ -163,35 +151,35 @@ com.sk89q.worldedit worldedit-bukkit - 7.2.8 + 7.2.10 provided net.dv8tion JDA - 4.2.1_255 + 4.4.0_352 provided net.coreprotect coreprotect - 20.4 + 21.2 provided com.sk89q.worldguard worldguard-bukkit - 7.0.6 + 7.0.7 provided io.papermc paperlib - 1.0.6 + 1.0.7 compile @@ -205,21 +193,21 @@ net.essentialsx EssentialsX - 2.19.0 + 2.19.4 provided org.reflections reflections - 0.9.12 + 0.10.2 compile org.javassist javassist - 3.28.0-GA + 3.29.0-GA compile @@ -233,7 +221,7 @@ org.jetbrains annotations - 22.0.0 + 23.0.0 compile @@ -247,14 +235,14 @@ org.junit.jupiter junit-jupiter - 5.8.0 + 5.8.2 compile org.eclipse.sisu org.eclipse.sisu.inject - 0.3.4 + 0.3.5 @@ -279,7 +267,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 TotalFreedomMod.jar 17 @@ -333,7 +321,7 @@ org.apache.maven.plugins maven-antrun-plugin - 3.0.0 + 3.1.0 default-cli @@ -363,7 +351,7 @@ org.codehaus.mojo properties-maven-plugin - 1.0.0 + 1.1.0 initialize @@ -383,7 +371,7 @@ org.codehaus.mojo buildnumber-maven-plugin - 1.4 + 3.0.0 generate-resources @@ -432,7 +420,6 @@ commons-io:commons-io org.apache.commons:commons-lang3 - commons-codec:commons-codec org.reflections:reflections org.javassist:javassist io.papermc:paperlib diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java b/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java index eebefc44..2156af99 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java @@ -175,15 +175,15 @@ public class ChatManager extends FreedomService }); } - public void reportAction(Player reporter, Player reported, String report) + public void reportAction(Player reporter, String reportedName, String report) { for (Player player : server.getOnlinePlayers()) { if (plugin.al.isAdmin(player)) { - playerMsg(player, ChatColor.RED + "[REPORTS] " + ChatColor.GOLD + reporter.getName() + " has reported " + reported.getName() + " for " + report); + playerMsg(player, ChatColor.RED + "[REPORTS] " + ChatColor.GOLD + reporter.getName() + " has reported " + reportedName + " for " + report); } } - FLog.info("[REPORTS] " + reporter.getName() + " has reported " + reported.getName() + " for " + report); + FLog.info("[REPORTS] " + reporter.getName() + " has reported " + reportedName + " for " + report); } } \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java b/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java index 64700e61..f413a39c 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java @@ -3,7 +3,10 @@ package me.totalfreedom.totalfreedommod; import io.papermc.lib.PaperLib; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.regex.Pattern; + +import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.PlayerData; @@ -58,13 +61,13 @@ public class LoginProcess extends FreedomService @EventHandler(priority = EventPriority.NORMAL) public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event) { - final String ip = event.getAddress().getHostAddress().trim(); - final boolean isAdmin = plugin.al.getEntryByIp(ip) != null; + final Admin entry = plugin.al.getEntryByUuid(event.getUniqueId()); + final boolean isAdmin = entry != null && entry.isActive(); // Check if the player is already online for (Player onlinePlayer : server.getOnlinePlayers()) { - if (!onlinePlayer.getName().equalsIgnoreCase(event.getName())) + if (!onlinePlayer.getUniqueId().equals(event.getUniqueId())) { continue; } @@ -86,7 +89,7 @@ public class LoginProcess extends FreedomService { final Player player = event.getPlayer(); final String username = player.getName(); - final String ip = event.getAddress().getHostAddress().trim(); + final UUID uuid = player.getUniqueId(); // Check username length if (username.length() < MIN_USERNAME_LENGTH || username.length() > MAX_USERNAME_LENGTH) @@ -120,7 +123,8 @@ public class LoginProcess extends FreedomService } // Validation below this point - if (plugin.al.getEntryByIp(ip) != null) // Check if player is admin + final Admin entry = plugin.al.getEntryByUuid(uuid); + if (entry != null && entry.isActive()) // Check if player is admin { // Force-allow log in event.allow(); @@ -175,12 +179,9 @@ public class LoginProcess extends FreedomService } // Whitelist - if (plugin.si.isWhitelisted()) + if (server.hasWhitelist() && !player.isWhitelisted()) { - if (!plugin.si.getWhitelisted().contains(username.toLowerCase())) - { - event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server."); - } + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server."); } } @@ -221,7 +222,7 @@ public class LoginProcess extends FreedomService return; } - if (!playerData.hasVerification() && !playerData.getIps().contains(FUtil.getIp(player))) + if (!playerData.getIps().contains(FUtil.getIp(player))) { playerData.addIp(FUtil.getIp(player)); plugin.pl.save(playerData); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Pterodactyl.java b/src/main/java/me/totalfreedom/totalfreedommod/Pterodactyl.java index 12c0cefd..75b2e548 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/Pterodactyl.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/Pterodactyl.java @@ -3,7 +3,7 @@ package me.totalfreedom.totalfreedommod; import java.io.IOException; import java.util.Arrays; import java.util.List; -import joptsimple.internal.Strings; +import com.google.common.base.Strings; import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.rank.Rank; diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java deleted file mode 100644 index 3821a949..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java +++ /dev/null @@ -1,78 +0,0 @@ -package me.totalfreedom.totalfreedommod; - -import java.util.Arrays; -import java.util.List; -import me.totalfreedom.totalfreedommod.util.FLog; -import me.totalfreedom.totalfreedommod.util.FUtil; -import net.minecraft.server.level.EntityPlayer; -import net.minecraft.server.MinecraftServer; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.CraftServer; - -public class ServerInterface extends FreedomService -{ - public static final String COMPILE_NMS_VERSION = "v1_17_R1"; - - public static void warnVersion() - { - final String nms = FUtil.getNMSVersion(); - - if (!COMPILE_NMS_VERSION.equals(nms)) - { - FLog.warning(TotalFreedomMod.pluginName + " is compiled for " + COMPILE_NMS_VERSION + " but the server is running version " + nms + "!"); - FLog.warning("This might result in unexpected behaviour!"); - } - } - - @Override - public void onStart() - { - } - - @Override - public void onStop() - { - } - - public int purgeWhitelist() - { - String[] whitelisted = getServer().getPlayerList().getWhitelisted(); - int size = whitelisted.length; - for (EntityPlayer player : getServer().getPlayerList().getPlayers()) - { - getServer().getPlayerList().getWhitelist().remove(player.getProfile()); - } - - try - { - getServer().getPlayerList().getWhitelist().save(); - } - catch (Exception ex) - { - FLog.warning("Could not purge the whitelist!"); - FLog.warning(ex); - } - return size; - } - - public boolean isWhitelisted() - { - return getServer().getPlayerList().getHasWhitelist(); - } - - public List getWhitelisted() - { - return Arrays.asList(getServer().getPlayerList().getWhitelisted()); - } - - public String getVersion() - { - return getServer().getVersion(); - } - - private MinecraftServer getServer() - { - return ((CraftServer)Bukkit.getServer()).getServer(); - } - -} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ServerPing.java b/src/main/java/me/totalfreedom/totalfreedommod/ServerPing.java index 57148a53..42eaf643 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/ServerPing.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/ServerPing.java @@ -1,5 +1,6 @@ package me.totalfreedom.totalfreedommod; +import com.google.gson.Gson; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.util.FUtil; import org.bukkit.Bukkit; @@ -7,8 +8,13 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.server.ServerListPingEvent; +import java.io.InputStreamReader; + public class ServerPing extends FreedomService { + private final Gson gson = new Gson(); + private final VersionMeta meta = gson.fromJson(new InputStreamReader(Bukkit.class.getClassLoader().getResourceAsStream("version.json")),VersionMeta.class); + @Override public void onStart() { @@ -54,7 +60,7 @@ public class ServerPing extends FreedomService return; } - String baseMotd = ConfigEntry.SERVER_MOTD.getString().replace("%mcversion%", plugin.si.getVersion()); + String baseMotd = ConfigEntry.SERVER_MOTD.getString().replace("%mcversion%", meta.id); baseMotd = baseMotd.replace("\\n", "\n"); baseMotd = FUtil.colorize(baseMotd); @@ -73,4 +79,9 @@ public class ServerPing extends FreedomService event.setMotd(motd.toString().trim()); } + + private static class VersionMeta + { + private String id; + } } \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java index e5593b91..31dff85b 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java @@ -14,7 +14,6 @@ import me.totalfreedom.totalfreedommod.blocking.InteractBlocker; import me.totalfreedom.totalfreedommod.blocking.MobBlocker; import me.totalfreedom.totalfreedommod.blocking.PVPBlocker; import me.totalfreedom.totalfreedommod.blocking.PotionBlocker; -import me.totalfreedom.totalfreedommod.blocking.SignBlocker; import me.totalfreedom.totalfreedommod.blocking.command.CommandBlocker; import me.totalfreedom.totalfreedommod.bridge.BukkitTelnetBridge; import me.totalfreedom.totalfreedommod.bridge.CoreProtectBridge; @@ -54,7 +53,6 @@ import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import org.spigotmc.SpigotConfig; public class TotalFreedomMod extends JavaPlugin { @@ -74,7 +72,6 @@ public class TotalFreedomMod extends JavaPlugin // Command Loader public CommandLoader cl; // Services - public ServerInterface si; public WorldManager wm; public LogViewer lv; public AdminList al; @@ -121,7 +118,6 @@ public class TotalFreedomMod extends JavaPlugin public Trailer tr; public HTTPDaemon hd; public WorldRestrictions wr; - public SignBlocker snp; public EntityWiper ew; public Sitter st; public VanishHandler vh; @@ -176,9 +172,6 @@ public class TotalFreedomMod extends JavaPlugin final MethodTimer timer = new MethodTimer(); timer.start(); - // Warn if we're running on a wrong version - ServerInterface.warnVersion(); - // Delete unused files FUtil.deleteCoreDumps(); FUtil.deleteFolder(new File("./_deleteme")); @@ -211,13 +204,10 @@ public class TotalFreedomMod extends JavaPlugin FLog.info("Started " + fsh.getServiceAmount() + " services."); timer.update(); - FLog.info("Version " + pluginVersion + " for " + ServerInterface.COMPILE_NMS_VERSION + " enabled in " + timer.getTotal() + "ms"); + FLog.info("Version " + pluginVersion + " enabled in " + timer.getTotal() + "ms"); // Metrics @ https://bstats.org/plugin/bukkit/TotalFreedomMod/2966 new Metrics(this, 2966); - - // little workaround to stop spigot from autorestarting - causing AMP to detach from process. - SpigotConfig.config.set("settings.restart-on-crash", false); } @Override @@ -296,7 +286,6 @@ public class TotalFreedomMod extends JavaPlugin private void initServices() { // Start services - si = new ServerInterface(); wm = new WorldManager(); lv = new LogViewer(); sql = new SQLite(); @@ -324,7 +313,6 @@ public class TotalFreedomMod extends JavaPlugin im = new IndefiniteBanList(); pem = new PermissionManager(); gr = new GameRuleHandler(); - snp = new SignBlocker(); ew = new EntityWiper(); st = new Sitter(); vh = new VanishHandler(); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java index 17920853..535b5cd3 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java @@ -2,26 +2,23 @@ package me.totalfreedom.totalfreedommod.admin; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; + import me.totalfreedom.totalfreedommod.LogViewer.LogsRegistrationMode; import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.player.FPlayer; 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.Server; import org.bukkit.entity.Player; public class Admin { - - private final List ips = new ArrayList<>(); - private String name; + private UUID uuid; private boolean active = true; private Rank rank = Rank.ADMIN; private Date lastLogin = new Date(); @@ -32,7 +29,7 @@ public class Admin public Admin(Player player) { - this.name = player.getName(); + uuid = player.getUniqueId(); this.ips.add(FUtil.getIp(player)); } @@ -40,7 +37,7 @@ public class Admin { try { - this.name = resultSet.getString("username"); + this.uuid = UUID.fromString(resultSet.getString("uuid")); this.active = resultSet.getBoolean("active"); this.rank = Rank.findRank(resultSet.getString("rank")); this.ips.clear(); @@ -62,7 +59,7 @@ public class Admin { final StringBuilder output = new StringBuilder(); - output.append("Admin: ").append(name).append("\n") + output.append("Admin: ").append(getName() != null ? getName() : getUuid().toString()).append("\n") .append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n") .append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n") .append("- Rank: ").append(rank.getName()).append("\n") @@ -78,7 +75,7 @@ public class Admin { Map map = new HashMap() {{ - put("username", name); + put("uuid", uuid.toString()); put("active", active); put("rank", rank.toString()); put("ips", FUtil.listToString(ips)); @@ -120,20 +117,20 @@ public class Admin public boolean isValid() { - return name != null + return uuid != null && rank != null && !ips.isEmpty() && lastLogin != null; } - 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 boolean isActive() @@ -162,6 +159,34 @@ public class Admin { plugin.btb.killTelnetSessions(getName()); } + + // Ensure admins don't have admin functionality when removed (FS-222) + AdminList.vanished.remove(getName()); + + if (plugin.esb != null) + { + plugin.esb.setVanished(getName(), false); + } + + setCommandSpy(false); + setPotionSpy(false); + + Server server = Bukkit.getServer(); + Player player = server.getPlayer(getUuid()); + + if (player != null) + { + // Update chats + FPlayer freedomPlayer = plugin.pl.getPlayer(player); + freedomPlayer.removeAdminFunctionality(); + + // Disable vanish + for (Player player1 : server.getOnlinePlayers()) + { + player1.showPlayer(plugin, player); + } + } + } plugin.lv.updateLogsRegistration(null, getName(), LogsRegistrationMode.DELETE); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java index 8cbb49b8..8073713c 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java @@ -4,11 +4,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; 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.Set; +import java.util.*; import java.util.concurrent.TimeUnit; import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.config.ConfigEntry; @@ -22,10 +18,10 @@ import org.bukkit.entity.Player; public class AdminList extends FreedomService { public static final List vanished = new ArrayList<>(); - public final Map> verifiedNoAdmin = Maps.newHashMap(); private final Set allAdmins = Sets.newHashSet(); // Includes disabled admins // Only active admins below private final Set activeAdmins = Sets.newHashSet(); + private final Map uuidTable = Maps.newHashMap(); private final Map nameTable = Maps.newHashMap(); private final Map ipTable = Maps.newHashMap(); @@ -52,12 +48,18 @@ public class AdminList extends FreedomService try { ResultSet adminSet = plugin.sql.getAdminList(); + while (adminSet.next()) { - while (adminSet.next()) + try { Admin admin = new Admin(adminSet); allAdmins.add(admin); } + catch (Throwable ex) + { + FLog.warning("An error occurred whilst reading the admin entry at row #" + adminSet.getRow()); + FLog.warning(ex); + } } } catch (SQLException e) @@ -66,7 +68,7 @@ public class AdminList extends FreedomService } updateTables(); - FLog.info("Loaded " + allAdmins.size() + " admins (" + nameTable.size() + " active, " + ipTable.size() + " IPs)"); + FLog.info("Loaded " + allAdmins.size() + " admins (" + uuidTable.size() + " active, " + ipTable.size() + " IPs)"); } public void messageAllAdmins(String message) @@ -154,40 +156,20 @@ public class AdminList extends FreedomService public Admin getAdmin(Player player) { - // Find admin - String ip = FUtil.getIp(player); - Admin admin = getEntryByName(player.getName()); + final String ip = FUtil.getIp(player); + final Admin entry = getEntryByUuid(player.getUniqueId()); - // Admin by name - if (admin != null) + if (entry != null && !entry.getIps().contains(ip)) { - // Check if we're in online mode, - // Or the players IP is in the admin entry - if (Bukkit.getOnlineMode() || admin.getIps().contains(ip)) - { - if (!admin.getIps().contains(ip)) - { - // Add the new IP if we have to - admin.addIp(ip); - save(admin); - updateTables(); - } - return admin; - } + entry.addIp(ip); } - // Admin by ip - admin = getEntryByIp(ip); - if (admin != null) - { - // Set the new username - String oldName = admin.getName(); - admin.setName(player.getName()); - plugin.sql.updateAdminName(oldName, admin.getName()); - updateTables(); - } + return entry; + } - return null; + public Admin getEntryByUuid(UUID uuid) + { + return uuidTable.get(uuid); } public Admin getEntryByName(String name) @@ -200,25 +182,6 @@ public class AdminList extends FreedomService return ipTable.get(ip); } - public Admin getEntryByIpFuzzy(String needleIp) - { - final Admin directAdmin = getEntryByIp(needleIp); - if (directAdmin != null) - { - return directAdmin; - } - - for (String ip : ipTable.keySet()) - { - if (FUtil.fuzzyIpMatch(needleIp, ip, 3)) - { - return ipTable.get(ip); - } - } - - return null; - } - public void updateLastLogin(Player player) { final Admin admin = getAdmin(player); @@ -228,31 +191,9 @@ public class AdminList extends FreedomService } admin.setLastLogin(new Date()); - admin.setName(player.getName()); save(admin); } - public boolean isAdminImpostor(Player player) - { - return getEntryByName(player.getName()) != null && !isAdmin(player) && !isVerifiedAdmin(player); - } - - public boolean isVerifiedAdmin(Player player) - { - return verifiedNoAdmin.containsKey(player.getName()) && verifiedNoAdmin.get(player.getName()).contains(FUtil.getIp(player)); - } - - public boolean isIdentityMatched(Player player) - { - if (Bukkit.getOnlineMode()) - { - return true; - } - - Admin admin = getAdmin(player); - return admin != null && admin.getName().equalsIgnoreCase(player.getName()); - } - public boolean addAdmin(Admin admin) { if (!admin.isValid()) @@ -297,6 +238,7 @@ public class AdminList extends FreedomService public void updateTables() { activeAdmins.clear(); + uuidTable.clear(); nameTable.clear(); ipTable.clear(); @@ -308,13 +250,16 @@ public class AdminList extends FreedomService } activeAdmins.add(admin); - nameTable.put(admin.getName().toLowerCase(), admin); + uuidTable.put(admin.getUuid(), admin); + if (admin.getName() != null) + { + nameTable.put(admin.getName().toLowerCase(), admin); + } for (String ip : admin.getIps()) { ipTable.put(ip, admin); } - } } @@ -332,11 +277,10 @@ public class AdminList extends FreedomService { try { - ResultSet currentSave = plugin.sql.getAdminByName(admin.getName()); + ResultSet currentSave = plugin.sql.getAdminByUuid(admin.getUuid()); for (Map.Entry entry : admin.toSQLStorable().entrySet()) { - Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); - if (storedValue != null && !storedValue.equals(entry.getValue()) || storedValue == null && entry.getValue() != null || entry.getValue() == null) + Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); if (storedValue != null && !storedValue.equals(entry.getValue()) || storedValue == null && entry.getValue() != null || entry.getValue() == null) { plugin.sql.setAdminValue(admin, entry.getKey(), entry.getValue()); } @@ -401,9 +345,4 @@ public class AdminList extends FreedomService { return ipTable; } - - public Map> getVerifiedNoAdmin() - { - return verifiedNoAdmin; - } } \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java index 70ed87f3..fb3713cd 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; + +import io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent; import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.util.FUtil; @@ -265,4 +267,10 @@ public class EventBlocker extends FreedomService FUtil.fixCommandVoid(event.getEntity()); event.setDeathMessage(event.getDeathMessage()); } + + @EventHandler + public void onSignInteract(PlayerSignCommandPreprocessEvent event) + { + event.setCancelled(true); + } } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java index 2e53f9de..17f6c5fe 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java @@ -5,6 +5,8 @@ import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.util.Groups; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -79,9 +81,33 @@ public class InteractBlocker extends FreedomService if (Groups.SPAWN_EGGS.contains(event.getMaterial())) { - player.getInventory().clear(player.getInventory().getHeldItemSlot()); - player.sendMessage(ChatColor.GRAY + "Spawn eggs are currently disabled."); event.setCancelled(true); + Block clickedBlock = event.getClickedBlock(); + if (clickedBlock == null) + { + return; + } + EntityType eggType = null; + try + { + Material mat = event.getMaterial(); + if (mat == Material.MOOSHROOM_SPAWN_EGG) + { + eggType = EntityType.MUSHROOM_COW; + } + else + { + eggType = EntityType.valueOf(mat.name().substring(0, mat.name().length() - 10)); + } + } + catch (IllegalArgumentException ignored) + { + // + } + if (eggType != null) + { + clickedBlock.getWorld().spawnEntity(clickedBlock.getLocation().add(event.getBlockFace().getDirection()).add(0.5, 0.5, 0.5), eggType); + } return; } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/SignBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/SignBlocker.java deleted file mode 100644 index 3fabc837..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/blocking/SignBlocker.java +++ /dev/null @@ -1,67 +0,0 @@ -package me.totalfreedom.totalfreedommod.blocking; - -import me.totalfreedom.totalfreedommod.FreedomService; -import net.minecraft.nbt.NBTTagCompound; -import org.bukkit.ChatColor; -import org.bukkit.Tag; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; - -//codebeat:disable[LOC,ABC] - -public class SignBlocker extends FreedomService -{ - @Override - public void onStart() - { - } - - @Override - public void onStop() - { - } - - @EventHandler(priority = EventPriority.NORMAL) - public void onPlayerPlaceBlock(BlockPlaceEvent event) - { - - final Player player = event.getPlayer(); - if (Tag.SIGNS.getValues().contains(event.getBlock().getType())) - { - ItemStack sign = event.getItemInHand(); - net.minecraft.world.item.ItemStack nmsSign = CraftItemStack.asNMSCopy(sign); - NBTTagCompound compound = (nmsSign.hasTag()) ? nmsSign.getTag() : new NBTTagCompound(); - assert compound != null; - NBTTagCompound bet = compound.getCompound("BlockEntityTag"); - String line1 = bet.getString("Text1"); - String line2 = bet.getString("Text2"); - String line3 = bet.getString("Text3"); - String line4 = bet.getString("Text4"); - if (line1.contains("run_command") || line2.contains("run_command") || line3.contains("run_command") || line4.contains("run_command")) - { - player.sendMessage(ChatColor.GRAY + "You are not allowed to place command signs."); - event.setCancelled(true); - } - } - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerInteractSign(PlayerInteractEvent event) - { - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) - { - return; - } - - if (event.getClickedBlock() != null && Tag.SIGNS.getValues().contains(event.getClickedBlock().getType())) - { - event.setCancelled(true); - } - } -} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java index 8ccde03e..9325f8cb 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java @@ -2,10 +2,10 @@ package me.totalfreedom.totalfreedommod.blocking.command; import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.spigotmc.SpigotConfig; public class CommandBlockerEntry { @@ -45,7 +45,7 @@ public class CommandBlockerEntry } if (action == CommandBlockerAction.BLOCK_UNKNOWN) { - sender.sendMessage(SpigotConfig.unknownCommandMessage); + sender.sendMessage(Bukkit.spigot().getSpigotConfig().getString("messages.unknown-command")); return; } FUtil.playerMsg(sender, FUtil.colorize(message)); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java index 479a30e1..d9e75846 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java @@ -42,7 +42,7 @@ public class BukkitTelnetBridge extends FreedomService return; } - final Admin admin = plugin.al.getEntryByIpFuzzy(ip); + final Admin admin = plugin.al.getEntryByIp(ip); if (admin == null || !admin.isActive() || !admin.getRank().hasConsoleVariant()) { diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java index d58f8761..56e2937d 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java @@ -114,8 +114,7 @@ public class EssentialsBridge extends FreedomService User user = getEssentialsUser(username); if (user != null) { - Long l = FUtil.getField(user, "lastActivity"); - return (l != null) ? l : 0L; + return user.getLastOnlineActivity(); } } catch (Exception ex) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java index 79ccaa6f..bb75d14a 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java @@ -48,52 +48,6 @@ public class WorldEditBridge extends FreedomService return worldeditPlugin; } - public void undo(Player player, int count) - { - try - { - LocalSession session = getPlayerSession(player); - if (session != null) - { - final BukkitPlayer bukkitPlayer = getBukkitPlayer(player); - if (bukkitPlayer != null) - { - for (int i = 0; i < count; i++) - { - session.undo(session.getBlockBag(bukkitPlayer), bukkitPlayer); - } - } - } - } - catch (Exception ex) - { - FLog.severe(ex); - } - } - - public void redo(Player player, int count) - { - try - { - LocalSession session = getPlayerSession(player); - if (session != null) - { - final BukkitPlayer bukkitPlayer = getBukkitPlayer(player); - if (bukkitPlayer != null) - { - for (int i = 0; i < count; i++) - { - session.redo(session.getBlockBag(bukkitPlayer), bukkitPlayer); - } - } - } - } - catch (Exception ex) - { - FLog.severe(ex); - } - } - public void setLimit(Player player, int limit) { try @@ -153,23 +107,4 @@ public class WorldEditBridge extends FreedomService return null; } } - - private BukkitPlayer getBukkitPlayer(Player player) - { - final WorldEditPlugin wep = getWorldEditPlugin(); - if (wep == null) - { - return null; - } - - try - { - return wep.wrapPlayer(player); - } - catch (Exception ex) - { - FLog.severe(ex); - return null; - } - } } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldGuardBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldGuardBridge.java index ea03b670..e7632719 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldGuardBridge.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldGuardBridge.java @@ -1,19 +1,12 @@ package me.totalfreedom.totalfreedommod.bridge; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.util.Location; import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; -import com.sk89q.worldguard.protection.flags.Flags; -import com.sk89q.worldguard.protection.managers.RegionManager; -import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.RegionContainer; -import java.util.Map; import com.sk89q.worldguard.protection.regions.RegionQuery; import me.totalfreedom.totalfreedommod.FreedomService; -import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -22,7 +15,6 @@ public class WorldGuardBridge extends FreedomService @Override public void onStart() { - plugin.wr.protectWorld(plugin.wm.masterBuilderWorld.getWorld()); } @Override @@ -32,34 +24,19 @@ public class WorldGuardBridge extends FreedomService public boolean canEditCurrentWorld(Player player) { - LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); - - RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); - RegionQuery query = container.createQuery(); - - return query.testBuild(localPlayer.getLocation(), localPlayer); - } - - public RegionManager getRegionManager(World world) - { - RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); - return container.get(BukkitAdapter.adapt(world)); - } - - public int wipeRegions(World world) - { - int count = 0; - RegionManager regionManager = getRegionManager(world); - if (regionManager != null) + // If WorldGuard integration is enabled, do a check with it. + if (isEnabled()) { - Map regions = regionManager.getRegions(); - for (ProtectedRegion region : regions.values()) - { - regionManager.removeRegion(region.getId()); - count++; - } + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + + return query.testBuild(localPlayer.getLocation(), localPlayer); } - return count; + + // If the plugin isn't present, return true. + return true; } public boolean isEnabled() diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java index 3d0a812d..f1ffc80b 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java @@ -112,6 +112,9 @@ public class Command_coins extends FreedomCommand + ChatColor.GOLD + coinsToTransfer + ChatColor.GREEN + " coin" + (coinsToTransfer > 1 ? "s" : "") + " to " + ChatColor.GOLD + target.getName() + ChatColor.GREEN + ".", ChatColor.GREEN); + + plugin.pl.save(playerData); + plugin.pl.save(senderData); } return true; diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java index 40df6d93..56d5315e 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_linkdiscord.java @@ -18,7 +18,7 @@ public class Command_linkdiscord extends FreedomCommand { if (!plugin.dc.enabled) { - msg("The Discord verification system is currently disabled.", ChatColor.RED); + msg("The Discord integration system is currently disabled.", ChatColor.RED); return true; } @@ -32,7 +32,7 @@ public class Command_linkdiscord extends FreedomCommand } playerData.setDiscordID(args[1]); - msg("Linked " + args[0] + "'s discord account.", ChatColor.GREEN); + msg("Linked " + args[0] + "'s Discord account.", ChatColor.GREEN); return true; } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_list.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_list.java index 996ac302..fc592793 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_list.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_list.java @@ -15,8 +15,8 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; -@CommandPermissions(level = Rank.IMPOSTOR, source = SourceType.BOTH) -@CommandParameters(description = "Lists the real names of all online players.", usage = "/ [-s | -i | -f | -v]", aliases = "who,lsit") +@CommandPermissions(level = Rank.NON_OP, source = SourceType.BOTH) +@CommandParameters(description = "Lists the real names of all online players.", usage = "/ [-s | -f | -v]", aliases = "who,lsit") public class Command_list extends FreedomCommand { @@ -63,11 +63,6 @@ public class Command_list extends FreedomCommand listFilter = ListFilter.TELNET_SESSIONS; break; } - case "-i": - { - listFilter = ListFilter.IMPOSTORS; - break; - } case "-f": { listFilter = ListFilter.FAMOUS_PLAYERS; @@ -122,10 +117,6 @@ public class Command_list extends FreedomCommand { continue; } - if (listFilter == ListFilter.IMPOSTORS && !plugin.al.isAdminImpostor(p)) - { - continue; - } if (listFilter == ListFilter.FAMOUS_PLAYERS && !ConfigEntry.FAMOUS_PLAYERS.getList().contains(p.getName().toLowerCase())) { continue; @@ -164,7 +155,6 @@ public class Command_list extends FreedomCommand ADMINS, VANISHED_ADMINS, TELNET_SESSIONS, - FAMOUS_PLAYERS, - IMPOSTORS + FAMOUS_PLAYERS } } \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_manuallyverify.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_manuallyverify.java deleted file mode 100644 index 1776538f..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_manuallyverify.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.totalfreedom.totalfreedommod.command; - -import me.totalfreedom.totalfreedommod.config.ConfigEntry; -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 = "Manually verify someone", usage = "/ ", aliases = "mv") -public class Command_manuallyverify 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 (args.length == 0) - { - return false; - } - - final Player player = getPlayer(args[0]); - if (player == null) - { - msg(FreedomCommand.PLAYER_NOT_FOUND); - return true; - } - - if (!plugin.pl.IsImpostor(player)) - { - msg("That player is not an impostor."); - return true; - } - - FUtil.adminAction(sender.getName(), "Manually verifying player " + player.getName(), false); - player.setOp(true); - msg(player, YOU_ARE_OP); - - if (plugin.pl.getPlayer(player).getFreezeData().isFrozen()) - { - plugin.pl.getPlayer(player).getFreezeData().setFrozen(false); - msg(player, "You have been unfrozen."); - } - - plugin.pl.verify(player, null); - plugin.rm.updateDisplay(player); - return true; - } -} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java index 23320e41..0bd5cc40 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mbconfig.java @@ -116,39 +116,21 @@ public class Command_mbconfig extends FreedomCommand return true; } - if (data.isMasterBuilder() && plugin.pl.isPlayerImpostor(player)) - { - FUtil.adminAction(sender.getName(), "Re-adding " + data.getName() + " to the Master Builder list", true); - - if (plugin.pl.getPlayer(player).getFreezeData().isFrozen()) - { - plugin.pl.getPlayer(player).getFreezeData().setFrozen(false); - } - if (player != null) - { - plugin.pl.verify(player, null); - plugin.rm.updateDisplay(player); - player.setOp(true); - msg(player, YOU_ARE_OP); - } - } - else if (!data.isMasterBuilder()) + if (!data.isMasterBuilder()) { FUtil.adminAction(sender.getName(), "Adding " + data.getName() + " to the Master Builder list", true); data.setMasterBuilder(true); - data.setVerification(true); plugin.pl.save(data); if (player != null) { plugin.rm.updateDisplay(player); } - return true; } else { msg("That player is already on the Master Builder list."); - return true; } + return true; } case "remove": { @@ -173,10 +155,6 @@ public class Command_mbconfig extends FreedomCommand FUtil.adminAction(sender.getName(), "Removing " + data.getName() + " from the Master Builder list", true); data.setMasterBuilder(false); - if (data.getDiscordID() == null) - { - data.setVerification(false); - } plugin.pl.save(data); if (player != null) { diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_modifyitem.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_modifyitem.java deleted file mode 100644 index 4ba7ab88..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_modifyitem.java +++ /dev/null @@ -1,266 +0,0 @@ -package me.totalfreedom.totalfreedommod.command; - -import java.util.ArrayList; -import java.util.List; -import java.util.SplittableRandom; -import me.totalfreedom.totalfreedommod.rank.Rank; -import me.totalfreedom.totalfreedommod.util.FUtil; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Material; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.potion.PotionEffectType; - -@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) -@CommandParameters(description = "Modify the current item you are holding.", usage = "/ | lore | enchant | potion | attribute | clear>", aliases = "mi") -public class Command_modifyitem extends FreedomCommand -{ - - @SuppressWarnings("deprecation") - @Override - public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) - { - if (args.length < 1) - { - return false; - } - - ItemStack item = playerSender.getInventory().getItemInMainHand(); - if (item.getType().equals(Material.AIR)) - { - msg("You must have an item in your hand!"); - return true; - } - - if (args[0].equalsIgnoreCase("clear")) - { - item.setItemMeta(null); - playerSender.getInventory().setItemInMainHand(item); - return true; - } - - if (args.length < 2) - { - return false; - } - - ItemMeta meta = item.getItemMeta(); - assert meta != null; - switch (args[0]) - { - case "name": - String name = FUtil.colorize(StringUtils.join(args, " ", 1, args.length)); - meta.setDisplayName(name); - item.setItemMeta(meta); - break; - - case "lore": - List lore = new ArrayList<>(); - for (String line : StringUtils.join(args, " ", 1, args.length).split("\\\\n")) - { - lore.add(FUtil.colorize(line)); - } - meta.setLore(lore); - item.setItemMeta(meta); - break; - - case "enchant": - if (args.length < 3) - { - return false; - } - - Enchantment enchantment = Enchantment.getByName(args[1].toUpperCase()); - if (enchantment == null) - { - msg("Invalid enchantment. Please run /enchant list for a list of valid enchantments."); - return true; - } - - int level; - try - { - level = Integer.parseInt(args[2]); - } - catch (NumberFormatException ex) - { - msg("The level specified is not a valid integer."); - return true; - } - meta.addEnchant(enchantment, level, true); - item.setItemMeta(meta); - break; - - case "potion": - { - if (!item.getType().equals(Material.POTION) & !item.getType().equals(Material.SPLASH_POTION) & !item.getType().equals(Material.LINGERING_POTION) & !item.getType().equals(Material.TIPPED_ARROW)) - { - msg("This item can not have potion effects added to it."); - return true; - } - - if (args.length < 4) - { - return false; - } - - PotionEffectType type = PotionEffectType.getByName(args[1]); - if (type == null) - { - msg("Invalid potion effect. Please run /potion list for a list of valid potion effects."); - return true; - } - - int duration; - try - { - duration = Math.max(1, Math.min(1000000, Integer.parseInt(args[2]))); - } - catch (NumberFormatException ex) - { - msg("The duration specified is not a valid integer."); - return true; - } - - int amplifier; - try - { - amplifier = Math.max(1, Math.min(256, Integer.parseInt(args[2]))); - } - catch (NumberFormatException ex) - { - msg("The amplifier specified is not a valid integer."); - return true; - } - PotionMeta potionMeta = (PotionMeta)meta; - potionMeta.addCustomEffect(type.createEffect(duration, amplifier), true); - item.setItemMeta(potionMeta); - break; - } - - case "attribute": - if (args.length < 3) - { - return false; - } - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(item); - NBTTagCompound compound = (nmsStack.hasTag()) ? nmsStack.getTag() : new NBTTagCompound(); - NBTTagList modifiers = getAttributeList(nmsStack); - NBTTagCompound cmpnd = new NBTTagCompound(); - Attribute attribute = Attribute.getByName(args[1].toUpperCase()); - if (attribute == null) - { - msg("Invalid attribute. Please run /attributelist for a list of valid attributes."); - return true; - } - cmpnd.setString("AttributeName", attribute.getAttribute()); - cmpnd.setString("Name", attribute.getAttribute()); - double amount; - try - { - amount = Double.parseDouble(args[2]); - } - catch (NumberFormatException ex) - { - msg("The amount specified is not a valid integer."); - return true; - } - if (Double.isNaN(amount)) - { - msg("The amount specified is illegal."); - return true; - } - cmpnd.setDouble("Amount", amount); - cmpnd.setInt("Operation", 0); - SplittableRandom random = new SplittableRandom(); - cmpnd.setIntArray("UUID", new int[] - { - random.nextInt(), - random.nextInt(), - random.nextInt(), - random.nextInt() - }); - cmpnd.setString("Slot", "mainhand"); - modifiers.add(cmpnd); - assert compound != null; - compound.set("AttributeModifiers", modifiers); - nmsStack.setTag(compound); - item = CraftItemStack.asBukkitCopy(nmsStack); - break; - default: - return false; - } - playerSender.getInventory().setItemInMainHand(item); - return true; - } - - private NBTTagList getAttributeList(net.minecraft.world.item.ItemStack stack) - { - if (stack.getTag() == null) - { - stack.setTag(new NBTTagCompound()); - } - NBTTagList attr = stack.getTag().getList("AttributeModifiers", 10); - if (attr == null) - { - stack.getTag().set("AttributeModifiers", new NBTTagList()); - } - return stack.getTag().getList("AttributeModifiers", 10); - } - - private enum Attribute - { - GENERIC_MAX_HEALTH("GENERIC_MAX_HEALTH", "generic.max_health"), - GENERIC_FOLLOW_RANGE("GENERIC_FOLLOW_RANGE", "generic.follow_range"), - GENERIC_KNOCKBACK_RESISTANCE("GENERIC_KNOCKBACK_RESISTANCE", "generic.knockback_resistance"), - GENERIC_MOVEMENT_SPEED("GENERIC_MOVEMENT_SPEED", "generic.movement_speed"), - GENERIC_FLYING_SPEED("GENERIC_FLYING_SPEED", "generic.flying_speed"), - GENERIC_ATTACK_DAMAGE("GENERIC_ATTACK_DAMAGE", "generic.attack_damage"), - GENERIC_ATTACK_SPEED("GENERIC_ATTACK_SPEED", "generic.attack_speed"), - GENERIC_ARMOR("GENERIC_ARMOR", "generic.armor"), - GENERIC_ARMOR_TOUGHNESS("GENERIC_ARMOR_TOUGHNESS", "generic.armor_toughmess"), - GENERIC_LUCK("GENERIC_LUCK", "generic.luck"), - HORSE_JUMP_STRENGTH("GENERIC_MAX_HEALTH", "horse.jump_strength"), - ZOMBIE_SPAWN_REINFORCEMENTS("ZOMBIE_SPAWN_REINFORCEMENTS", "zombie.spawn_reinforcements"); - - private final String name; - private final String attribute; - - Attribute(String name, String attribute) - { - this.name = name; - this.attribute = attribute; - } - - public static Attribute getByName(String name) - { - for (Attribute attr : Attribute.values()) - { - if (attr.toString().toUpperCase().equals(name)) - { - return attr; - } - } - return null; - } - - public String getAttribute() - { - return attribute; - } - - @Override - public String toString() - { - return name; - } - } -} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_playerverification.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_playerverification.java deleted file mode 100644 index 0bfe476a..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_playerverification.java +++ /dev/null @@ -1,158 +0,0 @@ -package me.totalfreedom.totalfreedommod.command; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import me.totalfreedom.totalfreedommod.config.ConfigEntry; -import me.totalfreedom.totalfreedommod.player.PlayerData; -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.OP, source = SourceType.ONLY_IN_GAME) -@CommandParameters(description = "Manage your verification", usage = "/ | status | genbackupcodes>", aliases = "playerverify,pv") -public class Command_playerverification extends FreedomCommand -{ - @Override - public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) - { - PlayerData target = plugin.pl.getData(playerSender); - boolean verificationEnabled = ConfigEntry.DISCORD_VERIFICATION.getBoolean(); - List ips = new ArrayList<>(target.getIps()); - - if (verificationEnabled) - { - if (args.length == 1) - { - if (args[0].equalsIgnoreCase("clearips")) - { - int cleared = 0; - for (String ip : ips) - { - if (!ip.equals(FUtil.getIp(playerSender))) - { - target.removeIp(ip); - cleared++; - } - } - - msg("Cleared all IP's except your current IP \"" + FUtil.getIp(playerSender) + "\""); - msg("Cleared " + cleared + " IP's."); - plugin.pl.save(target); - plugin.pl.syncIps(target); - return true; - } - else if (args[0].equalsIgnoreCase("clearip")) - { - return false; - } - } - - if (args.length < 1) - { - return false; - } - - PlayerData data = plugin.pl.getData(playerSender); - - switch (args[0].toLowerCase()) - { - case "enable": - { - if (!plugin.dc.enabled) - { - msg("The Discord verification system is currently disabled.", ChatColor.RED); - return true; - } - else if (data.hasVerification()) - { - msg("Discord verification is already enabled for you.", ChatColor.RED); - return true; - } - else if (data.getDiscordID() == null) - { - msg("Please link a discord account with /linkdiscord.", ChatColor.RED); - return true; - } - - data.setVerification(true); - plugin.pl.save(data); - msg("Re-enabled Discord verification.", ChatColor.GREEN); - return true; - } - - case "disable": - { - if (!data.hasVerification()) - { - msg("Discord verification is already disabled for you.", ChatColor.RED); - return true; - } - - data.setVerification(false); - plugin.pl.save(data); - msg("Disabled Discord verification.", ChatColor.GREEN); - return true; - } - - case "status": - { - boolean enabled = target.hasVerification(); - boolean specified = target.getDiscordID() != null; - msg(ChatColor.GRAY + "Discord Verification Enabled: " + (enabled ? ChatColor.GREEN + "true" : ChatColor.RED + "false")); - msg(ChatColor.GRAY + "Discord ID: " + (specified ? ChatColor.GREEN + target.getDiscordID() : ChatColor.RED + "not set")); - msg(ChatColor.GRAY + "Backup Codes: " + data.getBackupCodes().size() + "/" + "10"); - return true; - } - - case "genbackupcodes": - { - if (!plugin.dc.enabled) - { - msg("The Discord verification system is currently disabled.", ChatColor.RED); - return true; - } - else if (!data.hasVerification()) - { - msg("Discord verification is not enabled for you.", ChatColor.RED); - return true; - } - - boolean generated = plugin.dc.sendBackupCodes(data); - - if (generated) - { - msg("Your backup codes have been sent to your discord account. They can be re-generated at anytime.", ChatColor.GREEN); - } - else - { - msg("Failed to generate backup codes, please contact a developer.", ChatColor.RED); - } - return true; - } - default: - return false; - } - } - else - { - msg("The Discord verification system is currently disabled.", ChatColor.RED); - } - return true; - } - - @Override - public List getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args) - { - if (args.length == 1) - { - return Arrays.asList("enable", "disable", "status", "clearips", "genbackupcodes"); - } - - return Collections.emptyList(); - } -} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_report.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_report.java index 086bac6c..554c1f6d 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_report.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_report.java @@ -4,6 +4,7 @@ import me.totalfreedom.totalfreedommod.rank.Rank; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -22,36 +23,40 @@ public class Command_report extends FreedomCommand } Player player = getPlayer(args[0], true); + OfflinePlayer offlinePlayer = getOfflinePlayer(args[0]); - if (player == null) + if (player == null && offlinePlayer == null) { msg(PLAYER_NOT_FOUND); return true; } - - if (sender instanceof Player) + else if (player != null) { - if (player.equals(playerSender)) + if (sender instanceof Player) { - msg(ChatColor.RED + "Please, don't try to report yourself."); + if (player.equals(playerSender)) + { + msg(ChatColor.RED + "Please, don't try to report yourself."); + return true; + } + } + + if (plugin.al.isAdmin(player)) + { + msg(ChatColor.RED + "You can not report admins."); return true; } - } - if (plugin.al.isAdmin(player)) - { - msg(ChatColor.RED + "You can not report admins."); - return true; } String report = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " "); - plugin.cm.reportAction(playerSender, player, report); + plugin.cm.reportAction(playerSender, (player == null) ? offlinePlayer.getName() : player.getName(), report); boolean logged = false; if (plugin.dc.enabled) { - logged = plugin.dc.sendReport(playerSender, player, report); + logged = (player == null) ? plugin.dc.sendReportOffline(playerSender, offlinePlayer, report) : plugin.dc.sendReport(playerSender, player, report); } msg(ChatColor.GREEN + "Thank you, your report has been successfully logged." diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java index 0a1c06dc..ee5c63b5 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java @@ -176,26 +176,18 @@ public class Command_saconfig extends FreedomCommand } // Find the old admin entry - String name = player.getName(); Admin admin = null; for (Admin loopAdmin : plugin.al.getAllAdmins()) { - if (loopAdmin.getName().equalsIgnoreCase(name) || loopAdmin.getIps().contains(FUtil.getIp(player))) + if (loopAdmin.getUuid().equals(player.getUniqueId())) { admin = loopAdmin; break; } } - if (plugin.pl.isPlayerImpostor(player)) - { - msg("This player was labeled as a Player impostor and is not an admin, therefore they cannot be added to the admin list.", ChatColor.RED); - return true; - } - if (admin == null) // New admin { - FUtil.adminAction(sender.getName(), "Adding " + player.getName() + " to the admin list", true); admin = new Admin(player); @@ -205,23 +197,10 @@ public class Command_saconfig extends FreedomCommand else // Existing admin { FUtil.adminAction(sender.getName(), "Re-adding " + player.getName() + " to the admin list", true); - - String oldName = admin.getName(); - if (!oldName.equals(player.getName())) - { - admin.setName(player.getName()); - plugin.sql.updateAdminName(oldName, admin.getName()); - } admin.addIp(FUtil.getIp(player)); - admin.setActive(true); admin.setLastLogin(new Date()); - if (plugin.al.isVerifiedAdmin(player)) - { - plugin.al.verifiedNoAdmin.remove(player.getName()); - } - plugin.al.save(admin); plugin.al.updateTables(); plugin.rm.updateDisplay(player); @@ -259,6 +238,7 @@ public class Command_saconfig extends FreedomCommand checkRank(Rank.ADMIN); Player player = getPlayer(args[1]); + Admin admin = player != null ? plugin.al.getAdmin(player) : plugin.al.getEntryByName(args[1]); if (admin == null) @@ -267,20 +247,22 @@ public class Command_saconfig extends FreedomCommand return true; } + String adminName = admin.getName(); + FUtil.adminAction(sender.getName(), "Removing " + admin.getName() + " from the admin list", true); admin.setActive(false); plugin.al.save(admin); plugin.al.updateTables(); + if (player != null) { plugin.rm.updateDisplay(player); - plugin.pl.getPlayer(player).setAdminChat(false); } if (plugin.dc.enabled && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean()) { - Discord.syncRoles(admin, plugin.pl.getData(admin.getName()).getDiscordID()); + Discord.syncRoles(admin, plugin.pl.getData(adminName).getDiscordID()); } plugin.ptero.updateAccountStatus(admin); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java index 922db3a4..e34df0c9 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unlinkdiscord.java @@ -17,7 +17,7 @@ public class Command_unlinkdiscord extends FreedomCommand { if (!plugin.dc.enabled) { - msg("The Discord verification system is currently disabled.", ChatColor.RED); + msg("The Discord integration system is currently disabled.", ChatColor.RED); return true; } @@ -31,7 +31,7 @@ public class Command_unlinkdiscord extends FreedomCommand } playerData.setDiscordID(null); - msg("Unlinked " + args[0] + "'s discord account.", ChatColor.GREEN); + msg("Unlinked " + args[0] + "'s Discord account.", ChatColor.GREEN); return true; } @@ -42,7 +42,6 @@ public class Command_unlinkdiscord extends FreedomCommand return true; } data.setDiscordID(null); - data.setVerification(false); plugin.pl.save(data); msg("Your Minecraft account has been successfully unlinked from the Discord account.", ChatColor.GREEN); return true; diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_vanish.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_vanish.java index 68ce1b41..9511b28d 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_vanish.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_vanish.java @@ -45,7 +45,7 @@ public class Command_vanish extends FreedomCommand msg("You have unvanished.", ChatColor.GOLD); FUtil.bcastMsg(plugin.rm.craftLoginMessage(playerSender, null)); FUtil.bcastMsg(playerSender.getName() + " joined the game.", ChatColor.YELLOW); - plugin.dc.messageChatChannel("**" + playerSender.getName() + " joined the server" + "**"); + plugin.dc.messageChatChannel("**" + playerSender.getName() + " joined the server" + "**", true); } PlayerData playerData = plugin.pl.getData(playerSender); @@ -91,7 +91,7 @@ public class Command_vanish extends FreedomCommand { msg("You have vanished.", ChatColor.GOLD); FUtil.bcastMsg(playerSender.getName() + " left the game.", ChatColor.YELLOW); - plugin.dc.messageChatChannel("**" + playerSender.getName() + " left the server" + "**"); + plugin.dc.messageChatChannel("**" + playerSender.getName() + " left the server" + "**", true); } FLog.info(playerSender.getName() + " is now vanished."); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java deleted file mode 100644 index fb33dca6..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_verify.java +++ /dev/null @@ -1,101 +0,0 @@ -package me.totalfreedom.totalfreedommod.command; - -import me.totalfreedom.totalfreedommod.config.ConfigEntry; -import me.totalfreedom.totalfreedommod.discord.Discord; -import me.totalfreedom.totalfreedommod.player.FPlayer; -import me.totalfreedom.totalfreedommod.player.PlayerData; -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.IMPOSTOR, source = SourceType.BOTH) -@CommandParameters(description = "Sends a verification code to the player, or the player can input the sent code. Admins can manually verify a player impostor.", usage = "/ >") -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 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