From ad78aafaf6225b256968b9ed0d4974f1043d3908 Mon Sep 17 00:00:00 2001 From: Lemon Date: Sun, 28 Aug 2016 15:56:57 +0500 Subject: [PATCH 01/47] Create FHistory.java --- .../totalfreedommod/util/FHistory.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java new file mode 100644 index 000000000..fcb038e8a --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java @@ -0,0 +1,24 @@ +package me.totalfreedom.totalfreedommod.util; + +import java.util.Arrays; +import java.util.UUID; + +public class FHistory +{ + + private final UUID uuid; + + private final FName[] oldNames; + + public FHistory(UUID uuid, FName[] oldNames) + { + this.uuid = uuid; + this.oldNames = oldNames; + Arrays.sort(this.oldNames); + } + + public UUID getUuid() + { + return uuid; + } +} From 31a117226828c9113dabf4f92d3176749e2a5e19 Mon Sep 17 00:00:00 2001 From: Lemon Date: Sun, 28 Aug 2016 15:57:45 +0500 Subject: [PATCH 02/47] Create History.java --- .../totalfreedommod/util/History.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/History.java diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java new file mode 100644 index 000000000..99cb128f9 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -0,0 +1,98 @@ +package me.totalfreedom.totalfreedommod.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; + +public class History +{ + + public static void reportHistory(final CommandSender sender, final String username) + { + new BukkitRunnable() { + @Override + public void run() + { + UUID uuid; + FHistory history = null; + uuid = UUIDFetcher.fetch(username); + if (uuid != null) + { + Gson gson = new GsonBuilder().create(); + String compactUuid = uuid.toString().replace("-", ""); + try + { + URL url = new URL("https://api.mojang.com/user/profiles/" + compactUuid + "/names"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + FName[] oldNames = gson.fromJson(reader, FName[].class); + reader.close(); + conn.disconnect(); + Arrays.sort(oldNames); + history = new FHistory(uuid, oldNames); + printHistory(sender, oldNames); + } + catch (Exception ex) + { + FLog.severe(ex); + } + + if (history == null) + { + sender.sendMessage(ChatColor.RED + "Player not found!"); + } + + } + } + }.runTaskAsynchronously(TotalFreedomMod.plugin()); + } + + private static void printHistory(CommandSender sender, FName[] oldNames) + { + if (oldNames.length == 1) + { + sender.sendMessage(ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); + } + else + { + sender.sendMessage(ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); + + for (int i = 1; i < oldNames.length; i++) + { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(oldNames[i].changedToAt); + String formattedDate = df.format(date); + sender.sendMessage(ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); + } + } + } +} + +class FName implements Comparable +{ + public String name; + public long changedToAt; + + @Override + public int compareTo(FName other) + { + return Long.compare(this.changedToAt, other.changedToAt); + } + + public String getName() + { + return name; + } +} From c4388bbe0a1ebe0d5e470b762f6dee830356b331 Mon Sep 17 00:00:00 2001 From: Lemon Date: Sun, 28 Aug 2016 15:58:11 +0500 Subject: [PATCH 03/47] Create UUIDFetcher.java --- .../totalfreedommod/util/UUIDFetcher.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java new file mode 100644 index 000000000..40e7f6099 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java @@ -0,0 +1,63 @@ +package me.totalfreedom.totalfreedommod.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.UUID; + +class FetchedUuid +{ + + String id; +} + +// UUIDFetcher retrieves UUIDs from usernames via web requests to Mojang. +public class UUIDFetcher +{ + + private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft"; + + public static UUID fetch(String name) + { + try + { + Gson gson = new GsonBuilder().create(); + UUID uuid; + String body = gson.toJson(name); + URL url = new URL(PROFILE_URL); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setUseCaches(false); + connection.setDoInput(true); + connection.setDoOutput(true); + OutputStream stream = connection.getOutputStream(); + stream.write(body.getBytes()); + stream.flush(); + stream.close(); + FetchedUuid[] id = gson.fromJson( + new InputStreamReader(connection.getInputStream()), + FetchedUuid[].class); + if (id.length == 0) + { + return null; + } + + String idd = id[0].id; + + uuid = UUID.fromString(idd.substring(0, 8) + "-" + idd.substring(8, 12) + + "-" + idd.substring(12, 16) + "-" + idd.substring(16, 20) + "-" + + idd.substring(20, 32)); + return uuid; + } + catch (IOException ex) + { + FLog.severe(ex); + } + return null; + } +} From 6035a6f29cb79f171adac3a4d37d16a08e876ac2 Mon Sep 17 00:00:00 2001 From: Lemon Date: Sun, 28 Aug 2016 15:59:25 +0500 Subject: [PATCH 04/47] Create Command_namehistory --- .../command/Command_namehistory | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory new file mode 100644 index 000000000..0e92cad16 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory @@ -0,0 +1,24 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import me.totalfreedom.totalfreedommod.util.History; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Check name history of username.", usage = "/ ") +public class Command_namehistory extends FreedomCommand +{ + + @Override + public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + History.reportHistory(sender, args[0]); + return true; + } +} From 33b7eca961b4561c5125f64284e93732783175a7 Mon Sep 17 00:00:00 2001 From: Lemon Date: Sun, 28 Aug 2016 16:00:36 +0500 Subject: [PATCH 05/47] Rename Command_namehistory to Command_namehistory.java --- .../command/{Command_namehistory => Command_namehistory.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/me/totalfreedom/totalfreedommod/command/{Command_namehistory => Command_namehistory.java} (100%) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory.java similarity index 100% rename from src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory rename to src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory.java From 777b06d6baa359d0c22dd4d52eb947a50ea68008 Mon Sep 17 00:00:00 2001 From: Lemon Date: Sun, 28 Aug 2016 16:49:11 +0500 Subject: [PATCH 06/47] Formatting --- .../java/me/totalfreedom/totalfreedommod/util/History.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 99cb128f9..1c32efa54 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -18,10 +18,10 @@ public class History { - public static void reportHistory(final CommandSender sender, final String username) { - new BukkitRunnable() { + new BukkitRunnable() + { @Override public void run() { From 0049df90d737917f4cb8c184e31aad0526ecc10e Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 12 Oct 2016 16:02:14 +0500 Subject: [PATCH 07/47] Update History.java --- .../totalfreedommod/util/History.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 1c32efa54..ffd7cf4ae 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -18,6 +18,8 @@ public class History { + public static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static void reportHistory(final CommandSender sender, final String username) { new BukkitRunnable() @@ -46,14 +48,17 @@ public void run() } catch (Exception ex) { + synchronized + { + sender.sendMessage(ChatColor.RED + "Error, check logs for more details."); + } + FLog.severe(ex); } - if (history == null) { sender.sendMessage(ChatColor.RED + "Player not found!"); } - } } }.runTaskAsynchronously(TotalFreedomMod.plugin()); @@ -71,8 +76,7 @@ private static void printHistory(CommandSender sender, FName[] oldNames) for (int i = 1; i < oldNames.length; i++) { - DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date date = new Date(oldNames[i].changedToAt); + Date date = new Date(oldNames[i].getChangedToAt()); String formattedDate = df.format(date); sender.sendMessage(ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); } @@ -80,10 +84,10 @@ private static void printHistory(CommandSender sender, FName[] oldNames) } } -class FName implements Comparable +private class FName implements Comparable { - public String name; - public long changedToAt; + private String name; + private long changedToAt; @Override public int compareTo(FName other) @@ -95,4 +99,8 @@ public String getName() { return name; } + public long getChangedToAt() + { + return changedToAt; + } } From ed3253883aef7467c6aa59f8799fd453f30f3fae Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 12 Oct 2016 16:05:57 +0500 Subject: [PATCH 08/47] Update History.java --- .../me/totalfreedom/totalfreedommod/util/History.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index ffd7cf4ae..06368eb51 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -15,6 +15,7 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedomMod.util.FSync; public class History { @@ -22,6 +23,8 @@ public class History public static void reportHistory(final CommandSender sender, final String username) { + Player player = Bukkit.getPlayer(sender.getName()); + new BukkitRunnable() { @Override @@ -48,16 +51,12 @@ public void run() } catch (Exception ex) { - synchronized - { - sender.sendMessage(ChatColor.RED + "Error, check logs for more details."); - } - + FSync.playerMsg(player, ChatColor.RED + "Error, see logs for more details."); FLog.severe(ex); } if (history == null) { - sender.sendMessage(ChatColor.RED + "Player not found!"); + FSync.playerMsg(player, ChatColor.RED + "Player not found!"); } } } From 1ed0f91fec75b66a85df34904132170545e4c2d0 Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 12 Oct 2016 16:27:07 +0500 Subject: [PATCH 09/47] Update History.java --- .../totalfreedommod/util/History.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 06368eb51..715f16429 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -68,17 +68,14 @@ private static void printHistory(CommandSender sender, FName[] oldNames) if (oldNames.length == 1) { sender.sendMessage(ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); + return; } - else + sender.sendMessage(ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); + for (int i = 1; i < oldNames.length; i++) { - sender.sendMessage(ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); - - for (int i = 1; i < oldNames.length; i++) - { - Date date = new Date(oldNames[i].getChangedToAt()); - String formattedDate = df.format(date); - sender.sendMessage(ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); - } + Date date = new Date(oldNames[i].getChangedToAt()); + String formattedDate = df.format(date); + sender.sendMessage(ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); } } } From 895f1cca9e026479ccd8bdced626d8b791365e26 Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 12 Oct 2016 19:25:18 +0500 Subject: [PATCH 10/47] Update History.java --- .../me/totalfreedom/totalfreedommod/util/History.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 715f16429..aa1262bff 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -47,7 +47,7 @@ public void run() conn.disconnect(); Arrays.sort(oldNames); history = new FHistory(uuid, oldNames); - printHistory(sender, oldNames); + printHistory(player, oldNames); } catch (Exception ex) { @@ -63,11 +63,11 @@ public void run() }.runTaskAsynchronously(TotalFreedomMod.plugin()); } - private static void printHistory(CommandSender sender, FName[] oldNames) + private static void printHistory(Player player, FName[] oldNames) { if (oldNames.length == 1) { - sender.sendMessage(ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); + FSync.playerMsg(player, ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); return; } sender.sendMessage(ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); @@ -75,7 +75,7 @@ private static void printHistory(CommandSender sender, FName[] oldNames) { Date date = new Date(oldNames[i].getChangedToAt()); String formattedDate = df.format(date); - sender.sendMessage(ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); + FSync.playerMsg(player, ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); } } } From 068a37920ea77fe430f2d26ec793c76607194d7d Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 12 Oct 2016 19:27:57 +0500 Subject: [PATCH 11/47] Update UUIDFetcher.java --- .../me/totalfreedom/totalfreedommod/util/UUIDFetcher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java index 40e7f6099..5566bc459 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java @@ -9,10 +9,10 @@ import java.net.URL; import java.util.UUID; -class FetchedUuid +private class FetchedUuid { - String id; + public final String id; } // UUIDFetcher retrieves UUIDs from usernames via web requests to Mojang. From 867b67abd0a7a85eceb4374a67a5f7436844590f Mon Sep 17 00:00:00 2001 From: Lemon Date: Thu, 13 Oct 2016 07:14:24 +0500 Subject: [PATCH 12/47] Update FSync.java --- .../totalfreedom/totalfreedommod/util/FSync.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java index a67831b90..52e809ddb 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java @@ -24,6 +24,21 @@ public void run() }.runTask(plugin); } + public static void playerMsg(final CommandSender sender, final String message) + { + final TotalFreedomMod plugin = TotalFreedomMod.plugin(); + new BukkitRunnable() + { + + @Override + public void run() + { + sender.sendMessage(message) + } + + }.runTask(plugin); + } + public static void playerKick(final Player player, final String reason) { final TotalFreedomMod plugin = TotalFreedomMod.plugin(); From 981fe92306eb9a84645c2011a481adf31c859da7 Mon Sep 17 00:00:00 2001 From: Lemon Date: Thu, 13 Oct 2016 07:17:25 +0500 Subject: [PATCH 13/47] Update History.java --- .../totalfreedommod/util/History.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index aa1262bff..2d1edcbff 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -19,20 +19,17 @@ public class History { - public static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - public static void reportHistory(final CommandSender sender, final String username) + public static void reportHistory(final CommandSender sender, final String username { - Player player = Bukkit.getPlayer(sender.getName()); - new BukkitRunnable() { @Override public void run() { - UUID uuid; FHistory history = null; - uuid = UUIDFetcher.fetch(username); + UUID uuid = UUIDFetcher.fetch(username); if (uuid != null) { Gson gson = new GsonBuilder().create(); @@ -47,27 +44,27 @@ public void run() conn.disconnect(); Arrays.sort(oldNames); history = new FHistory(uuid, oldNames); - printHistory(player, oldNames); + printHistory(sender, oldNames); } catch (Exception ex) { - FSync.playerMsg(player, ChatColor.RED + "Error, see logs for more details."); + FSync.playerMsg(sender, ChatColor.RED + "Error, see logs for more details."); FLog.severe(ex); } if (history == null) { - FSync.playerMsg(player, ChatColor.RED + "Player not found!"); + FSync.playerMsg(sender, ChatColor.RED + "Player not found!"); } } } }.runTaskAsynchronously(TotalFreedomMod.plugin()); } - private static void printHistory(Player player, FName[] oldNames) + private static void printHistory(CommandSender sender, FName[] oldNames) { if (oldNames.length == 1) { - FSync.playerMsg(player, ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); + FSync.playerMsg(sender, ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); return; } sender.sendMessage(ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); @@ -75,7 +72,7 @@ private static void printHistory(Player player, FName[] oldNames) { Date date = new Date(oldNames[i].getChangedToAt()); String formattedDate = df.format(date); - FSync.playerMsg(player, ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); + FSync.playerMsg(sender, ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName()); } } } From d249aae170bcdad4fa0472946235f62d0486fc30 Mon Sep 17 00:00:00 2001 From: Lemon Date: Thu, 13 Oct 2016 07:23:00 +0500 Subject: [PATCH 14/47] Update UUIDFetcher.java --- .../totalfreedom/totalfreedommod/util/UUIDFetcher.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java index 5566bc459..dd02c87c6 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java @@ -11,8 +11,12 @@ private class FetchedUuid { - - public final String id; + private String id; + + public static String getID() + { + return id; + } } // UUIDFetcher retrieves UUIDs from usernames via web requests to Mojang. @@ -47,7 +51,7 @@ public static UUID fetch(String name) return null; } - String idd = id[0].id; + String idd = id[0].getID(); uuid = UUID.fromString(idd.substring(0, 8) + "-" + idd.substring(8, 12) + "-" + idd.substring(12, 16) + "-" + idd.substring(16, 20) + "-" From bbcbdda9fe00570280956d52f88c1f261a74cf7f Mon Sep 17 00:00:00 2001 From: Lemon Date: Thu, 13 Oct 2016 14:38:39 +0500 Subject: [PATCH 15/47] Update History.java --- src/main/java/me/totalfreedom/totalfreedommod/util/History.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 2d1edcbff..5d1e0f910 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -21,7 +21,7 @@ public class History { public static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - public static void reportHistory(final CommandSender sender, final String username + public static void reportHistory(final CommandSender sender, final String username) { new BukkitRunnable() { From a5e9e529f4859ff9a79815c047aca6cd3c309484 Mon Sep 17 00:00:00 2001 From: Lemon Date: Thu, 13 Oct 2016 14:40:20 +0500 Subject: [PATCH 16/47] Update History.java --- src/main/java/me/totalfreedom/totalfreedommod/util/History.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 5d1e0f910..26fb40efc 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -67,7 +67,7 @@ private static void printHistory(CommandSender sender, FName[] oldNames) FSync.playerMsg(sender, ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name."); return; } - sender.sendMessage(ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); + FSync.playerMsg(sender, ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName()); for (int i = 1; i < oldNames.length; i++) { Date date = new Date(oldNames[i].getChangedToAt()); From 2ea923f6dd7739f8d27b3bdb6a2d9163994b1a9e Mon Sep 17 00:00:00 2001 From: Lemon Date: Fri, 21 Oct 2016 09:43:37 +0500 Subject: [PATCH 17/47] Update UUIDFetcher.java --- .../java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java index dd02c87c6..e341f8797 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/UUIDFetcher.java @@ -11,7 +11,7 @@ private class FetchedUuid { - private String id; + private static String id; public static String getID() { From 541317f8ccbda2742054eacd3c7deaed11b28604 Mon Sep 17 00:00:00 2001 From: Lemon Date: Fri, 21 Oct 2016 09:44:04 +0500 Subject: [PATCH 18/47] Update FSync.java --- src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java index 52e809ddb..7a4b9e3a5 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java @@ -33,7 +33,7 @@ public static void playerMsg(final CommandSender sender, final String message) @Override public void run() { - sender.sendMessage(message) + sender.sendMessage(message); } }.runTask(plugin); From cc2207ce055a6a9dd440e1d9890106784424b953 Mon Sep 17 00:00:00 2001 From: Lemon Date: Fri, 21 Oct 2016 09:51:48 +0500 Subject: [PATCH 19/47] Update History.java --- .../totalfreedommod/util/History.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index 26fb40efc..d8970adaf 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -28,7 +28,6 @@ public static void reportHistory(final CommandSender sender, final String userna @Override public void run() { - FHistory history = null; UUID uuid = UUIDFetcher.fetch(username); if (uuid != null) { @@ -40,10 +39,14 @@ public void run() HttpURLConnection conn = (HttpURLConnection) url.openConnection(); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); FName[] oldNames = gson.fromJson(reader, FName[].class); + if (oldNames == null) + { + FSync.playerMsg(sender, ChatColor.RED + "Player not found!"); + return; + } reader.close(); conn.disconnect(); Arrays.sort(oldNames); - history = new FHistory(uuid, oldNames); printHistory(sender, oldNames); } catch (Exception ex) @@ -51,10 +54,10 @@ public void run() FSync.playerMsg(sender, ChatColor.RED + "Error, see logs for more details."); FLog.severe(ex); } - if (history == null) - { - FSync.playerMsg(sender, ChatColor.RED + "Player not found!"); - } + } + else + { + FSync.playerMsg(sender, ChatColor.RED + "Player not found!"); } } }.runTaskAsynchronously(TotalFreedomMod.plugin()); From 31684d0452f8f22eed54245305dc99ee9a2301ad Mon Sep 17 00:00:00 2001 From: Lemon Date: Fri, 21 Oct 2016 09:52:08 +0500 Subject: [PATCH 20/47] Delete FHistory.java --- .../totalfreedommod/util/FHistory.java | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java deleted file mode 100644 index fcb038e8a..000000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/FHistory.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.totalfreedom.totalfreedommod.util; - -import java.util.Arrays; -import java.util.UUID; - -public class FHistory -{ - - private final UUID uuid; - - private final FName[] oldNames; - - public FHistory(UUID uuid, FName[] oldNames) - { - this.uuid = uuid; - this.oldNames = oldNames; - Arrays.sort(this.oldNames); - } - - public UUID getUuid() - { - return uuid; - } -} From cc8d8ad91e5ab9c64d5f174f0e5246f9f57f1be9 Mon Sep 17 00:00:00 2001 From: Lemon Date: Fri, 21 Oct 2016 09:53:29 +0500 Subject: [PATCH 21/47] Don't need import -> Same package. --- src/main/java/me/totalfreedom/totalfreedommod/util/History.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java index d8970adaf..36ae3577c 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/History.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/History.java @@ -15,7 +15,6 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import me.totalfreedom.totalfreedommod.TotalFreedomMod; -import me.totalfreedom.totalfreedomMod.util.FSync; public class History { From be8203a832b298a7e57120f00bfc8341ca501000 Mon Sep 17 00:00:00 2001 From: ChargedCreeper Date: Sun, 13 Nov 2016 16:12:56 +0100 Subject: [PATCH 22/47] Added /unloadchunks. Resolves #1779 (#674) --- .../command/Command_unloadchunks.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_unloadchunks.java diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unloadchunks.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unloadchunks.java new file mode 100644 index 000000000..4826f16a7 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_unloadchunks.java @@ -0,0 +1,43 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.Chunk; +import org.bukkit.World; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Unloads chunks not currently in use", usage = "/", aliases = "rc") +public class Command_unloadchunks extends FreedomCommand { + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { + FUtil.adminAction(sender.getName(), "Unloading unused chunks", false); + + int numChunks = 0; + + for (World world : server.getWorlds()) { + numChunks += unloadUnusedChunks(world); + } + + FUtil.playerMsg(sender, numChunks + " chunks unloaded."); + return true; + } + + private int unloadUnusedChunks(World world) { + int numChunks = 0; + + for (Chunk loadedChunk : world.getLoadedChunks()) { + if (!world.isChunkInUse(loadedChunk.getX(), loadedChunk.getZ())) { + if (world.unloadChunk(loadedChunk)) { + numChunks++; + } + } + } + + return numChunks; + } +} From 475b299e37988161b2c0a4fe650d1a6a2fa7685d Mon Sep 17 00:00:00 2001 From: PacksGamingHD Date: Sun, 13 Nov 2016 16:30:22 +0100 Subject: [PATCH 23/47] Fixed a typo in announcements (#911) --- src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a30a3ad78..4de2c205b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -247,7 +247,7 @@ announcer: - 'MarkByron is the owner of TotalFreedom.' - 'Server lagging? Check the lag via "/tps"' - 'You are allowed to record and stream videos on TotalFreedom.' - - 'Player vs player while in creative or god mode it forbidden!' + - 'Player vs player while in creative or god mode is forbidden!' - 'Spawn killing is forbidden!' - 'Invisible potions are allowed!' - 'Serial griefing and trolling will result in a permanent ban!' From 0eb0c7a02f040f9347369518f94bcc1173cb719d Mon Sep 17 00:00:00 2001 From: LegendIsAwesomes Date: Sun, 13 Nov 2016 16:46:06 +0100 Subject: [PATCH 24/47] Remove /invis smite, add /invis clear. Resolves #959 (#1011) --- .../command/Command_invis.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java index 8fb8bb4b6..f0267dca4 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java @@ -11,20 +11,20 @@ import org.bukkit.potion.PotionEffectType; @CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) -@CommandParameters(description = "Shows (optionally smites) invisisible players", usage = "/ (smite)") +@CommandParameters(description = "Shows (and optionally clears) invisisible players", usage = "/ [clear]") public class Command_invis extends FreedomCommand { @Override public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { - boolean smite = false; + boolean clear = false; if (args.length >= 1) { - if (args[0].equalsIgnoreCase("smite")) + if (args[0].equalsIgnoreCase("clear")) { - FUtil.adminAction(sender.getName(), "Smiting all invisible players", true); - smite = true; + FUtil.adminAction(sender.getName(), "Clearing invisibility for all players", false); + clear = true; } else { @@ -33,17 +33,17 @@ public boolean run(CommandSender sender, Player playerSender, Command cmd, Strin } List players = new ArrayList<>(); - int smites = 0; + int clears = 0; for (Player player : server.getOnlinePlayers()) { if (player.hasPotionEffect(PotionEffectType.INVISIBILITY)) { players.add(player.getName()); - if (smite && !plugin.al.isAdmin(player)) + if (clear && !plugin.al.isAdmin(player)) { - player.setHealth(0.0); - smites++; + player.removePotionEffect(PotionEffectType.INVISIBILITY); + clears++; } } } @@ -54,9 +54,9 @@ public boolean run(CommandSender sender, Player playerSender, Command cmd, Strin return true; } - if (smite) + if (clear) { - msg("Smitten " + smites + " players"); + msg("Cleared invisibility effect from " + clears + " players"); } else { From 28142a688398352c4c966faf32549134bae80cee Mon Sep 17 00:00:00 2001 From: Jerom van der Sar Date: Thu, 17 Nov 2016 22:50:08 +0100 Subject: [PATCH 25/47] Update to Spigot 1.11-R1 --- pom.xml | 6 +++--- .../me/totalfreedom/totalfreedommod/ServerInterface.java | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index b35d71b55..721ac5fbe 100644 --- a/pom.xml +++ b/pom.xml @@ -59,10 +59,10 @@ org.spigotmc - spigot - 1.10 + spigot-server + 1.11 system - ${project.basedir}/lib/Spigot-1.10.jar + ${project.basedir}/lib/Spigot-1.11.jar diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java index 9979d2a93..e0e964cd4 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java @@ -4,11 +4,11 @@ import java.util.List; import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; -import net.minecraft.server.v1_10_R1.EntityPlayer; -import net.minecraft.server.v1_10_R1.MinecraftServer; -import net.minecraft.server.v1_10_R1.PropertyManager; +import net.minecraft.server.v1_11_R1.EntityPlayer; +import net.minecraft.server.v1_11_R1.MinecraftServer; +import net.minecraft.server.v1_11_R1.PropertyManager; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_10_R1.CraftServer; +import org.bukkit.craftbukkit.v1_11_R1.CraftServer; public class ServerInterface extends FreedomService { From 6e6842dbd24bf088a5a9d43204e95eafb5a2f03f Mon Sep 17 00:00:00 2001 From: Jerom van der Sar Date: Thu, 17 Nov 2016 22:56:50 +0100 Subject: [PATCH 26/47] Update compile version to v1_11_R1 --- .../java/me/totalfreedom/totalfreedommod/ServerInterface.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java index e0e964cd4..83ca040b0 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java @@ -13,7 +13,7 @@ public class ServerInterface extends FreedomService { - public static final String COMPILE_NMS_VERSION = "v1_10_R1"; + public static final String COMPILE_NMS_VERSION = "v1_11_R1"; public ServerInterface(TotalFreedomMod plugin) { From 1bc81ca4b9b3d3bc775be1b18115707c7d6ca064 Mon Sep 17 00:00:00 2001 From: marcocorriero Date: Sun, 9 Apr 2017 09:01:59 +0200 Subject: [PATCH 27/47] :boom::camel: Added .gitattributes & .gitignore files --- .gitattributes | 17 ++++++++++++++ .gitignore | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..bdb0cabc8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b1f310745 --- /dev/null +++ b/.gitignore @@ -0,0 +1,63 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk From 45defe68c3e4f34bcfd2e35804dad7f51c385858 Mon Sep 17 00:00:00 2001 From: marcocorriero Date: Sun, 9 Apr 2017 09:03:19 +0200 Subject: [PATCH 28/47] TFM massive patches TFM patches --- .gitignore | 87 +- CONTRIBUTING.md | 3 + LICENSE.md | 54 + README.md | 11 + checkstyle.xml | 133 ++ nb-configuration.xml | 18 + pom.xml | 301 ++++ .../totalfreedommod/Announcer.java | 88 + .../totalfreedommod/AntiClick.java | 64 + .../totalfreedommod/AntiCreativeExploit.java | 71 + .../totalfreedommod/AntiExploit.java | 247 +++ .../totalfreedommod/AntiItemExploit.java | 44 + .../totalfreedommod/AntiNuke.java | 134 ++ .../totalfreedommod/AntiSpam.java | 119 ++ .../totalfreedommod/AutoEject.java | 116 ++ .../totalfreedommod/AutoKick.java | 74 + .../totalfreedommod/BackupManager.java | 87 + .../totalfreedommod/ChatManager.java | 131 ++ .../totalfreedommod/CommandSpy.java | 44 + .../totalfreedommod/ConfigConverter.java | 168 ++ .../totalfreedommod/Editblocker.java | 71 + .../totalfreedommod/EntityWiper.java | 194 ++ .../totalfreedommod/FreedomService.java | 13 + .../totalfreedommod/FrontDoor.java | 592 ++++++ .../totalfreedom/totalfreedommod/Fuckoff.java | 68 + .../totalfreedommod/GameRuleHandler.java | 118 ++ .../totalfreedommod/LogViewer.java | 170 ++ .../totalfreedommod/LoginProcess.java | 205 +++ .../totalfreedommod/MovementValidator.java | 51 + .../totalfreedom/totalfreedommod/Muter.java | 104 ++ .../totalfreedom/totalfreedommod/Orbiter.java | 46 + .../totalfreedommod/PVPBlocker.java | 85 + .../totalfreedommod/ProtectArea.java | 397 +++++ .../totalfreedommod/SavedFlags.java | 105 ++ .../totalfreedommod/ServerInterface.java | 92 + .../totalfreedommod/ServerPing.java | 78 + .../totalfreedommod/TotalFreedomMod.java | 309 ++++ .../totalfreedommod/admin/Admin.java | 180 ++ .../totalfreedommod/admin/AdminList.java | 376 ++++ .../totalfreedommod/banning/Ban.java | 279 +++ .../totalfreedommod/banning/BanManager.java | 303 ++++ .../totalfreedommod/banning/PermbanList.java | 90 + .../blocking/BlockBlocker.java | 121 ++ .../blocking/EventBlocker.java | 211 +++ .../blocking/InteractBlocker.java | 139 ++ .../totalfreedommod/blocking/MobBlocker.java | 104 ++ .../blocking/PotionBlocker.java | 62 + .../blocking/command/CommandBlocker.java | 210 +++ .../command/CommandBlockerAction.java | 32 + .../blocking/command/CommandBlockerEntry.java | 55 + .../blocking/command/CommandBlockerRank.java | 73 + .../bridge/BukkitTelnetBridge.java | 126 ++ .../bridge/EssentialsBridge.java | 237 +++ .../bridge/LibsDisguisesBridge.java | 138 ++ .../bridge/WorldEditBridge.java | 161 ++ .../bridge/WorldEditListener.java | 74 + .../totalfreedommod/caging/CageData.java | 214 +++ .../totalfreedommod/caging/Cager.java | 110 ++ .../command/CommandFailException.java | 13 + .../command/CommandLoader.java | 45 + .../command/CommandParameters.java | 15 + .../command/CommandPermissions.java | 16 + .../command/Command_adminchat.java | 41 + .../command/Command_adminmode.java | 45 + .../command/Command_adminworld.java | 248 +++ .../command/Command_adventure.java | 58 + .../command/Command_announce.java | 26 + .../command/Command_banlist.java | 41 + .../command/Command_blockcmd.java | 84 + .../command/Command_blockedit.java | 151 ++ .../command/Command_blockpvp.java | 151 ++ .../totalfreedommod/command/Command_cage.java | 120 ++ .../totalfreedommod/command/Command_cake.java | 54 + .../command/Command_cartsit.java | 82 + .../command/Command_cbtool.java | 218 +++ .../command/Command_cmdspy.java | 24 + .../command/Command_colorme.java | 59 + .../command/Command_commandlist.java | 53 + .../command/Command_consolesay.java | 24 + .../command/Command_creative.java | 58 + .../command/Command_deafen.java | 52 + .../command/Command_debug.java | 113 ++ .../command/Command_denick.java | 26 + .../totalfreedommod/command/Command_deop.java | 46 + .../command/Command_deopall.java | 27 + .../command/Command_disguisetoggle.java | 41 + .../command/Command_dispfill.java | 112 ++ .../totalfreedommod/command/Command_doom.java | 111 ++ .../command/Command_enchant.java | 129 ++ .../command/Command_ender.java | 20 + .../command/Command_entitywipe.java | 22 + .../command/Command_expel.java | 90 + .../command/Command_findip.java | 35 + .../command/Command_flatlands.java | 27 + .../command/Command_freeze.java | 67 + .../command/Command_fuckoff.java | 50 + .../command/Command_gadmin.java | 209 +++ .../totalfreedommod/command/Command_gcmd.java | 56 + .../command/Command_glist.java | 172 ++ .../totalfreedommod/command/Command_gtfo.java | 103 ++ .../command/Command_health.java | 111 ++ .../command/Command_invis.java | 68 + .../command/Command_invsee.java | 54 + .../command/Command_jumppads.java | 96 + .../totalfreedommod/command/Command_kick.java | 61 + .../command/Command_kicknoob.java | 30 + .../command/Command_landmine.java | 67 + .../command/Command_lastcmd.java | 45 + .../totalfreedommod/command/Command_list.java | 143 ++ .../command/Command_localspawn.java | 20 + .../command/Command_lockup.java | 127 ++ .../totalfreedommod/command/Command_logs.java | 45 + .../command/Command_moblimiter.java | 84 + .../command/Command_mobpurge.java | 47 + .../totalfreedommod/command/Command_mp44.java | 52 + .../command/Command_myadmin.java | 170 ++ .../command/Command_nether.java | 20 + .../command/Command_nickclean.java | 51 + .../command/Command_nickfilter.java | 123 ++ .../command/Command_nicknyan.java | 73 + .../command/Command_onlinemode.java | 71 + .../totalfreedommod/command/Command_op.java | 60 + .../command/Command_opall.java | 49 + .../totalfreedommod/command/Command_opme.java | 23 + .../totalfreedommod/command/Command_ops.java | 66 + .../command/Command_orbit.java | 67 + .../totalfreedommod/command/Command_ov.java | 81 + .../command/Command_permban.java | 36 + .../command/Command_plugincontrol.java | 152 ++ .../command/Command_potion.java | 184 ++ .../command/Command_premium.java | 81 + .../command/Command_protectarea.java | 104 ++ .../command/Command_purgeall.java | 85 + .../command/Command_qdeop.java | 61 + .../totalfreedommod/command/Command_qop.java | 61 + .../command/Command_radar.java | 113 ++ .../command/Command_rainbownick.java | 73 + .../command/Command_rainbowtag.java | 49 + .../totalfreedommod/command/Command_rank.java | 75 + .../command/Command_rawsay.java | 25 + .../command/Command_report.java | 55 + .../totalfreedommod/command/Command_ro.java | 158 ++ .../command/Command_rollback.java | 86 + .../command/Command_saconfig.java | 241 +++ .../totalfreedommod/command/Command_say.java | 47 + .../command/Command_setlevel.java | 49 + .../command/Command_setlever.java | 79 + .../command/Command_setlimit.java | 24 + .../command/Command_setspawnworld.java | 31 + .../command/Command_smite.java | 91 + .../command/Command_spawnmob.java | 78 + .../command/Command_spectator.java | 47 + .../command/Command_status.java | 44 + .../totalfreedommod/command/Command_stfu.java | 151 ++ .../totalfreedommod/command/Command_stop.java | 29 + .../command/Command_survival.java | 57 + .../totalfreedommod/command/Command_tag.java | 159 ++ .../command/Command_tagnyan.java | 49 + .../totalfreedommod/command/Command_tban.java | 64 + .../command/Command_tempban.java | 79 + .../command/Command_toggle.java | 181 ++ .../command/Command_tossmob.java | 105 ++ .../command/Command_totalfreedommod.java | 71 + .../command/Command_trail.java | 43 + .../command/Command_undisguiseall.java | 36 + .../command/Command_unloadchunks.java | 50 + .../command/Command_vanish.java | 71 + .../totalfreedommod/command/Command_warn.java | 56 + .../command/Command_whitelist.java | 170 ++ .../command/Command_whohas.java | 73 + .../command/Command_wildcard.java | 62 + .../command/Command_wipeflatlands.java | 31 + .../command/Command_wipeuserdata.java | 31 + .../command/FreedomCommand.java | 173 ++ .../command/FreedomCommandExecutor.java | 183 ++ .../totalfreedommod/command/SourceType.java | 7 + .../totalfreedommod/config/ConfigEntry.java | 208 +++ .../totalfreedommod/config/MainConfig.java | 304 ++++ .../totalfreedommod/freeze/FreezeData.java | 77 + .../totalfreedommod/freeze/Freezer.java | 77 + .../totalfreedommod/fun/ItemFun.java | 280 +++ .../totalfreedommod/fun/Jumppads.java | 135 ++ .../totalfreedommod/fun/Landminer.java | 128 ++ .../totalfreedommod/fun/MP44.java | 33 + .../totalfreedommod/fun/Trailer.java | 76 + .../httpd/HTMLGenerationTools.java | 58 + .../httpd/HTTPDPageBuilder.java | 74 + .../totalfreedommod/httpd/HTTPDaemon.java | 180 ++ .../httpd/ModuleExecutable.java | 85 + .../totalfreedommod/httpd/NanoHTTPD.java | 1585 +++++++++++++++++ .../httpd/module/HTTPDModule.java | 76 + .../httpd/module/Module_bans.java | 48 + .../httpd/module/Module_dump.java | 115 ++ .../httpd/module/Module_file.java | 382 ++++ .../httpd/module/Module_help.java | 160 ++ .../httpd/module/Module_list.java | 44 + .../httpd/module/Module_logfile.java | 190 ++ .../httpd/module/Module_logs.java | 28 + .../httpd/module/Module_permbans.java | 31 + .../httpd/module/Module_players.java | 70 + .../httpd/module/Module_schematic.java | 312 ++++ .../totalfreedommod/player/FPlayer.java | 496 ++++++ .../totalfreedommod/player/PlayerData.java | 83 + .../totalfreedommod/player/PlayerList.java | 221 +++ .../totalfreedommod/rank/Displayable.java | 20 + .../totalfreedommod/rank/Rank.java | 142 ++ .../totalfreedommod/rank/RankManager.java | 188 ++ .../totalfreedommod/rank/Title.java | 43 + .../totalfreedommod/rollback/EntryType.java | 20 + .../rollback/RollbackEntry.java | 98 + .../rollback/RollbackManager.java | 267 +++ .../util/DepreciationAggregator.java | 65 + .../totalfreedommod/util/FLog.java | 107 ++ .../totalfreedommod/util/FSync.java | 86 + .../totalfreedommod/util/FUtil.java | 524 ++++++ .../totalfreedommod/util/MethodTimer.java | 32 + .../totalfreedommod/world/AdminWorld.java | 254 +++ .../world/CleanroomBlockPopulator.java | 61 + .../world/CleanroomChunkGenerator.java | 237 +++ .../totalfreedommod/world/CustomWorld.java | 52 + .../totalfreedommod/world/Flatlands.java | 92 + .../totalfreedommod/world/WorldManager.java | 162 ++ .../totalfreedommod/world/WorldTime.java | 56 + .../totalfreedommod/world/WorldWeather.java | 43 + src/main/java/org/mcstats/Metrics.java | 852 +++++++++ src/main/resources/admins.yml | 31 + src/main/resources/bans.yml | 3 + src/main/resources/config.yml | 379 ++++ src/main/resources/permbans.yml | 10 + src/main/resources/plugin.yml | 7 + src/main/resources/version.yml | 4 + supressions.xml | 11 + 232 files changed, 26429 insertions(+), 58 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 checkstyle.xml create mode 100644 nb-configuration.xml create mode 100644 pom.xml create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/Announcer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AntiClick.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AntiCreativeExploit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AntiExploit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AntiItemExploit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AntiNuke.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AutoEject.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/AutoKick.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/BackupManager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/CommandSpy.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/ConfigConverter.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/Editblocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/EntityWiper.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/FreedomService.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/FrontDoor.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/Fuckoff.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/GameRuleHandler.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/LogViewer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/MovementValidator.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/Muter.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/Orbiter.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/PVPBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/ProtectArea.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/SavedFlags.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/ServerPing.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/banning/Ban.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/banning/PermbanList.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/BlockBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/MobBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/PotionBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlocker.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerAction.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerRank.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/bridge/LibsDisguisesBridge.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditListener.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/caging/CageData.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/caging/Cager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/CommandFailException.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/CommandLoader.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/CommandParameters.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/CommandPermissions.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminchat.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminmode.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_adventure.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_announce.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_banlist.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockcmd.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockedit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockpvp.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_cage.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_cake.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_cartsit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_cbtool.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_cmdspy.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_colorme.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_commandlist.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_consolesay.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_creative.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_deafen.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_debug.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_denick.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_disguisetoggle.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_dispfill.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_doom.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_enchant.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_ender.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_entitywipe.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_expel.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_findip.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_flatlands.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_freeze.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_fuckoff.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_gadmin.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_gcmd.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_glist.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_gtfo.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_health.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_invsee.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_jumppads.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_kick.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_kicknoob.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_landmine.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_lastcmd.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_list.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_localspawn.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_lockup.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_logs.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_moblimiter.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_mobpurge.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_mp44.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_myadmin.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_nether.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickclean.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickfilter.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_nicknyan.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_onlinemode.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_ops.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_orbit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_ov.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_permban.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_plugincontrol.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_potion.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_premium.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_protectarea.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_purgeall.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_qdeop.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_qop.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_radar.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_rainbownick.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_rainbowtag.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_rank.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_rawsay.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_report.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_ro.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_rollback.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_saconfig.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_say.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_setlevel.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_setlever.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_setlimit.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_setspawnworld.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_smite.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_spawnmob.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_spectator.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_status.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_stfu.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_stop.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_survival.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_tag.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_tagnyan.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_tban.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_tempban.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_toggle.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_tossmob.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_totalfreedommod.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_trail.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_undisguiseall.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_unloadchunks.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_vanish.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_warn.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_whitelist.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_whohas.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_wildcard.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_wipeflatlands.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/Command_wipeuserdata.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommand.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/FreedomCommandExecutor.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/command/SourceType.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/config/ConfigEntry.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/config/MainConfig.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/freeze/FreezeData.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/freeze/Freezer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/fun/ItemFun.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/fun/Jumppads.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/fun/Landminer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/fun/MP44.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/fun/Trailer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/HTMLGenerationTools.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDPageBuilder.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDaemon.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/ModuleExecutable.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/NanoHTTPD.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/HTTPDModule.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_bans.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_dump.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_file.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_help.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_list.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_logfile.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_logs.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_permbans.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_players.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/httpd/module/Module_schematic.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/player/FPlayer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rank/Displayable.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rank/Rank.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rank/Title.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rollback/EntryType.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rollback/RollbackEntry.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/rollback/RollbackManager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/DepreciationAggregator.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/FLog.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/FSync.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/util/MethodTimer.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/AdminWorld.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/CleanroomBlockPopulator.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/CleanroomChunkGenerator.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/CustomWorld.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/Flatlands.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/WorldManager.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/WorldTime.java create mode 100644 src/main/java/me/totalfreedom/totalfreedommod/world/WorldWeather.java create mode 100644 src/main/java/org/mcstats/Metrics.java create mode 100644 src/main/resources/admins.yml create mode 100644 src/main/resources/bans.yml create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/permbans.yml create mode 100644 src/main/resources/plugin.yml create mode 100644 src/main/resources/version.yml create mode 100644 supressions.xml diff --git a/.gitignore b/.gitignore index b1f310745..24d67e9bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,63 +1,34 @@ -*.class - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - +# TFM excludes +/lib +build.properties + +# Netbeans excludes +/nbproject/private +/dist +/build +manifest.mf +# Now defines that Maven CheckStyle is used +# nb-configuration.xml + +# Eclipse excludes +.project +.classpath +/bin +/.settings + +# IntelliJ excludes +*.iml +*.ipr +*.iws +/.idea + +# Maven excludes +/target + +# OS generated files .DS_Store -.AppleDouble -.LSOverride - -# Thumbnails ._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd .Spotlight-V100 -.TemporaryItems .Trashes -.VolumeIcon.icns - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -# Windows -# ========================= - -# Windows image file caches -Thumbs.db ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# Windows shortcuts -*.lnk +Thumbs.db diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..29cd3a480 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing to TotalFreedomMod # + +For information about contributing to TotalFreedomMod, please see the [contributing guidelines](https://github.com/TotalFreedom/TotalFreedomMod/wiki/Contributing). \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..99a177f43 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,54 @@ +# TotalFreedom General License # +_Version 2.0, 27th February 2015_ + +Copyright (c) 2011 Steven Lawson + +Copyright (c) 2012 Jerom van der Sar + +All rights reserved. + +##### 1. Definitions ##### +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by this document. + +"Licensor" shall mean the copyright holder or entity authorised by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You", "Your" or "Yourself" shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, binary data, generated documentation, and conversions to other media types. + +"Work" and "This Software" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work. + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +"Redistribution" shall mean any partial or complete availability, transfer or publication of the Work from one Legal Entity to another. + +##### 2. Grant of Copyright License ##### + Subject to the terms and conditions of this License, You are granted a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to prepare Derivative Works of, publicly display, publicly perform, inspect and redistribute the Work and such Derivative Works as long as the following conditions are met: + +1. Redistributions of This Software must solely occur in Source form. Redistribution in Object form is prohibited without prior written permission from the Licensor. + +2. Neither the names of the copyright holders nor the names this software's contributors may be removed from This Software's source code. + +3. Neither the names of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from This Software without specific prior written permission. + +4. Accreditations referencing This Software's copyright holders or contributors may neither be altered or removed from source code nor withheld from reproduction in Object form whatsoever. + +5. Any conditions specified by this license may be temporarily or permanently waived by any the aforementioned copyright holders. + +6. Redistributions of This Software must retain this License document in its exact form. + +7. Sub licensing of This Software is prohibited without prior written permission from the Licensor. + +##### 3. Submission of Contributions ##### +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +##### 4. Disclaimer of Warranty ##### +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 000000000..ff8e687e8 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# TotalFreedomMod # + +TotalFreedomMod is a CraftBukkit server plugin designed primarily to support the [Official TotalFreedom Minecraft Server](http://totalfreedom.me/). However, you are more than welcome to adapt the source for your own server. + +This plugin was originally coded by StevenLawson (Madgeek1450), with Jerom van der Sar (Prozza) becoming heavily involved in its development some time later. It consists of over 85 custom coded commands and a large variety of distinguishable features not included in any other plugin. The plugin has since its beginning grown immensely. Together, with the main TotalFreedom server, TotalFreedomMod has a long-standing reputation of effectiveness whilst maintaining a clear feeling of openness towards the administrators and the players themselves. + +### Download ### +You may download official binaries from the [releases page](https://github.com/TotalFreedom/TotalFreedomMod/releases). + +### Contributing ### +Please see [CONTRIBUTING.md](CONTRIBUTING.md) if you are interested in developing TotalFreedomMod. For information on how TotalFreedomMod is licensed, please see [LICENSE.md](LICENSE.md). diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 000000000..e091b33c2 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nb-configuration.xml b/nb-configuration.xml new file mode 100644 index 000000000..35e184b23 --- /dev/null +++ b/nb-configuration.xml @@ -0,0 +1,18 @@ + + + + + + true + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..a47c06458 --- /dev/null +++ b/pom.xml @@ -0,0 +1,301 @@ + + + 4.0.0 + + me.totalfreedom + totalfreedom + 5.0 + jar + + + UTF-8 + ${project.version} + Electrum + ${maven.buildnumber} + ${maven.build.timestamp} + ${buildAuthor} + ${buildHead} + ${project.name} + dd/MM/yyyy hh:mm aa + + + TotalFreedomMod + Server modification for the TotalFreedom server + https://github.com/TotalFreedom/TotalFreedomMod + + + + TotalFreedom General License + https://github.com/TotalFreedom/License/blob/master/LICENSE.md + + + + + Total Freedom + https://totalfreedom.me + + + + scm:git:git@github.com:TotalFreedom/TotalFreedomMod.git + scm:git:git@github.com:TotalFreedom/TotalFreedomMod.git + git@github.com:TotalFreedom/TotalFreedomMod.git + + + + + dmulloy2-repo + http://repo.dmulloy2.net/content/groups/public/ + + + ess-repo + http://repo.ess3.net + + + jitpack.io + https://jitpack.io + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + elmakers-repo + http://maven.elmakers.com/repository/ + + + sk89q-snapshots + http://maven.sk89q.com/artifactory/repo + + + + + + + org.projectlombok + lombok + 1.16.14 + provided + + + + org.spigotmc + spigot + 1.10.2-R0.1-SNAPSHOT + provided + + + + com.comphenix.protocol + ProtocolLib-API + 4.1.0 + + + + com.github.Pravian + Aero + a0e1dc5 + provided + + + + com.github.TotalFreedom + BukkitTelnet + v4.4 + provided + + + + com.github.TotalFreedom.TF-WorldEdit + worldedit-bukkit + 6.1.0-TF + provided + + + + com.github.TotalFreedom.TF-WorldEdit + worldedit-core + 6.1.0-TF + provided + + + + org.bukkit + craftbukkit + 1.10.2-R0.1-SNAPSHOT + provided + + + + net.ess3 + Essentials + 2.13.1 + provided + + + + com.github.TotalFreedom + TF-LibsDisguises + 913a577436 + provided + + + + + + + + src/main/resources + true + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + TotalFreedomMod.jar + 1.7 + 1.8 + 1.8 + + + + + + maven-antrun-plugin + 1.8 + + + initialize + + + + + + + + + run + + + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0.0 + + + initialize + + read-project-properties + + + + ${basedir}/build.properties + + + + + + + + + org.apache.maven.plugins + 2.17 + maven-checkstyle-plugin + + + process-sources + + check + + + + + checkstyle.xml + true + true + true + + + + + + com.lukegb.mojo + gitdescribe-maven-plugin + 3.0 + + + git-describe + initialize + + gitdescribe + + + buildHead + + --tags + --always + HEAD + + + + + + + + + org.codehaus.mojo + buildnumber-maven-plugin + 1.4 + + + generate-resources + + create + + + + + + maven.buildnumber + ${basedir}/build.properties + {0,number,#} + + buildNumber + + + + + + + + + + + + org.apache.maven.plugins + maven-jxr-plugin + 2.5 + + + org.apache.maven.plugins + 2.17 + maven-checkstyle-plugin + + checkstyle.xml + true + true + true + + + + + \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Announcer.java b/src/main/java/me/totalfreedom/totalfreedommod/Announcer.java new file mode 100644 index 000000000..b11144fcb --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/Announcer.java @@ -0,0 +1,88 @@ +package me.totalfreedom.totalfreedommod; + +import com.google.common.collect.Lists; +import java.util.Collections; +import java.util.List; +import lombok.Getter; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +public class Announcer extends FreedomService +{ + + private final List announcements = Lists.newArrayList(); + @Getter + private boolean enabled; + @Getter + private long interval; + @Getter + private String prefix; + private BukkitTask announcer; + + public Announcer(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + enabled = ConfigEntry.ANNOUNCER_ENABLED.getBoolean(); + interval = ConfigEntry.ANNOUNCER_INTERVAL.getInteger() * 20L; + prefix = FUtil.colorize(ConfigEntry.ANNOUNCER_PREFIX.getString()); + + announcements.clear(); + for (Object announcement : ConfigEntry.ANNOUNCER_ANNOUNCEMENTS.getList()) + { + announcements.add(FUtil.colorize((String) announcement)); + } + + if (!enabled) + { + return; + } + + announcer = new BukkitRunnable() + { + private int current = 0; + + @Override + public void run() + { + current++; + + if (current >= announcements.size()) + { + current = 0; + } + + announce(announcements.get(current)); + } + }.runTaskTimer(plugin, interval, interval); + } + + @Override + protected void onStop() + { + if (announcer == null) + { + return; + } + + FUtil.cancel(announcer); + announcer = null; + } + + public List getAnnouncements() + { + return Collections.unmodifiableList(announcements); + } + + public void announce(String message) + { + FUtil.bcastMsg(prefix + message); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiClick.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiClick.java new file mode 100644 index 000000000..df1a6e887 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiClick.java @@ -0,0 +1,64 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import java.util.Arrays; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +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.player.PlayerInteractEvent; + +public class AntiClick extends FreedomService { + + public AntiClick(TotalFreedomMod plugin) { + super(plugin); + } + + @Override + protected void onStart() { + } + + @Override + protected void onStop() { + } + public static final List LISTENING_MATERIALS = Arrays.asList( + Material.LEVER, + Material.DAYLIGHT_DETECTOR_INVERTED, + Material.DAYLIGHT_DETECTOR, + Material.WOOD_BUTTON, + Material.STONE_BUTTON); + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + final Player player = event.getPlayer(); + final FPlayer fPlayer = plugin.pl.getPlayer(player); + + if (!ConfigEntry.CLICK_MONITOR_ENABLED.getBoolean()) { + return; + } + + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + final Block block = event.getClickedBlock(); + if (!LISTENING_MATERIALS.contains(block.getType())) { + return; + } + if (fPlayer.incrementAndGetClickAmount() > ConfigEntry.CLICK_COUNT_LIMIT.getInteger()) { + FUtil.bcastMsg(player.getName() + " is clicking too fast!", ChatColor.RED); + plugin.ae.autoEject(player, "Clicking too fast can crash the server which is not allowed."); + FLog.info(player.getName() + " is clicking too fast, they are most likely trying to crash the server."); + fPlayer.resetBlockDestroyCount(); + + event.setCancelled(true); + } + } + + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiCreativeExploit.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiCreativeExploit.java new file mode 100644 index 000000000..76236853f --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiCreativeExploit.java @@ -0,0 +1,71 @@ +package me.totalfreedom.totalfreedommod; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import java.util.HashMap; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class AntiCreativeExploit extends PacketAdapter +{ + + private HashMap needCancel = new HashMap<>(); + + public AntiCreativeExploit(TotalFreedomMod plugin) + { + super(plugin, ListenerPriority.HIGHEST, PacketType.Play.Client.SET_CREATIVE_SLOT); + Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() + { + @Override + public void run() + { + for (Player p : needCancel.keySet()) + { + int i = needCancel.get(p); + if (i >= 5) + { + needCancel.remove(p); + continue; + } + needCancel.put(p, i + 1); + } + + } + }, 20, 20); + } + + @Override + public void onPacketReceiving(PacketEvent event) + { + if (event.isCancelled()) + { + return; + } + final Player p = event.getPlayer(); + if (needCancel.containsKey(p)) + { + event.setCancelled(true); + p.updateInventory(); + return; + } + if (p.getGameMode() != GameMode.CREATIVE) + { + return; + } + ItemStack stack = event.getPacket().getItemModifier().read(0); + if (stack == null) + { + return; + } + //if (TotalFreedomMod.plugin().aex.isExploit(stack, p.getWorld().getName().toLowerCase())) + { + needCancel.put(p, 0); + p.updateInventory(); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiExploit.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiExploit.java new file mode 100644 index 000000000..4be6f1c83 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiExploit.java @@ -0,0 +1,247 @@ +package me.totalfreedom.totalfreedommod; + +import com.comphenix.protocol.wrappers.nbt.NbtBase; +import com.comphenix.protocol.wrappers.nbt.NbtCompound; +import com.comphenix.protocol.wrappers.nbt.NbtFactory; +import com.comphenix.protocol.wrappers.nbt.NbtList; +import com.google.common.io.BaseEncoding; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; + +public class AntiExploit extends FreedomService +{ + + public AntiExploit(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onInvClick(InventoryClickEvent event) + { + if (event.getWhoClicked().getType() != EntityType.PLAYER) + { + return; + } + final Player p = (Player) event.getWhoClicked(); + if (event.getCurrentItem() == null) + { + return; + } + if (isExploit(event.getCurrentItem(), p.getWorld().getName().toLowerCase())) + { + event.setCancelled(true); + p.updateInventory(); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + public void onDrop(PlayerDropItemEvent event) + { + final Player p = event.getPlayer(); + if (event.getItemDrop() == null) + { + return; + } + if (isExploit(event.getItemDrop().getItemStack(), p.getWorld().getName().toLowerCase())) + { + event.setCancelled(true); + p.updateInventory(); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + public void onPickup(PlayerPickupItemEvent event) + { + final Player p = event.getPlayer(); + if (event.getItem() == null) + { + return; + } + if (isExploit(event.getItem().getItemStack(), p.getWorld().getName().toLowerCase())) + { + event.getItem().remove(); + event.setCancelled(true); + } + } + + public boolean isExploit(ItemStack stack, String world) + { + if (stack == null || stack.getType() == Material.AIR) + { + return false; + } + boolean b = false; + try + { + Material mat = stack.getType(); + NbtCompound tag = (NbtCompound) NbtFactory.fromItemTag(stack); + if (stack.getAmount() < 1 || stack.getAmount() > 64 || tag.getKeys().size() > 15) + { + stack.setAmount(1); + tag.getKeys().clear(); + return true; + } + + if (mat == Material.CHEST || mat == Material.NAME_TAG || mat == Material.TRAPPED_CHEST || mat == Material.HOPPER || mat == Material.DROPPER) + { + String tags = tag.toString(); + if (tags.length() > 400) + { + tag.getKeys().clear(); + return true; + } + } + else if ((mat == Material.SKULL || mat == Material.SKULL_ITEM) && stack.getDurability() == 3) + { + if (isExploitSkull(tag)) + { + b = true; + } + } + } + catch (Exception e) + { + + return b; + } + return b; + } + + /* + Skull Exploit Fix Code https://github.com/MylesIsCool/SkullExploitPatch + https://www.spigotmc.org/resources/skull-exploit-fix.26099/ + */ + @SuppressWarnings("rawtypes") + public boolean isExploitSkull(NbtCompound root) + { + // Item + if (root.containsKey("SkullOwner")) + { + NbtCompound skullOwner = root.getCompound("SkullOwner"); + if (skullOwner.containsKey("Id")) + { + String id = skullOwner.getString("Id"); + if (id.isEmpty() || id.length() != 36 || id.equals("00000000-0000-0000-0000-000000000000")) + { + root.remove("SkullOwner"); + return true; + } + } + else + { + root.remove("SkullOwner"); + return true; + } + if (skullOwner.containsKey("Properties")) + { + NbtCompound properties = skullOwner.getCompound("Properties"); + if (properties.containsKey("textures")) + { + NbtList textures = properties.getList("textures"); + for (NbtBase texture : textures.asCollection()) + { + if (texture instanceof NbtCompound) + { + // Check for value + if (((NbtCompound) texture).containsKey("Value")) + { + if (((NbtCompound) texture).getString("Value").trim().length() > 0) + { + String decoded = null; + try + { + decoded = new String(BaseEncoding.base64().decode(((NbtCompound) texture).getString("Value"))); + } + catch (Exception e) + { + root.remove("SkullOwner"); + return true; + } + if (decoded == null || decoded.isEmpty()) + { + root.remove("SkullOwner"); + return true; + } + if (decoded.contains("textures") && decoded.contains("SKIN")) + { + if (decoded.contains("url")) + { + String Url = decoded.split("url\":")[1].replace("}", "").replace("\"", ""); + if (Url.isEmpty() || Url.trim().length() == 0) + { + root.remove("SkullOwner"); + return true; + } + if (!Url.startsWith("http://textures.minecraft.net/texture/")) + { + root.remove("SkullOwner"); + return true; + } + } + else + { + root.remove("SkullOwner"); + return true; + } + } + else + { + root.remove("SkullOwner"); + return true; + } + } + else + { + root.remove("SkullOwner"); + return true; + } + } + else + { + root.remove("SkullOwner"); + return true; + } + if (((NbtCompound) texture).containsKey("Signature")) + { + if (((NbtCompound) texture).getString("Signature").trim().length() <= 0) + { + root.remove("SkullOwner"); + return true; + } + } + } + } + } + else + { + root.remove("SkullOwner"); + return true; + } + } + else + { + root.remove("SkullOwner"); + return true; + } + } + return false; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiItemExploit.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiItemExploit.java new file mode 100644 index 000000000..df2f339c6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiItemExploit.java @@ -0,0 +1,44 @@ +package me.totalfreedom.totalfreedommod; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +// Same here + +public class AntiItemExploit extends PacketAdapter +{ + + public AntiItemExploit(TotalFreedomMod plugin) + { + super(plugin, PacketType.Play.Client.HELD_ITEM_SLOT); + } + + @Override + public void onPacketReceiving(PacketEvent event) + { + if (event.isCancelled()) + { + return; + } + final Player p = event.getPlayer(); + if (p == null) + { + return; + } + if (!p.isOnline()) + { + return; + } + ItemStack stack = p.getInventory().getItem(event.getPacket().getIntegers().readSafely(0).shortValue()); + if (stack == null) + { + return; + } + //if (TotalFreedomMod.plugin().aex.isExploit(stack, p.getWorld().getName().toLowerCase())) + { + p.updateInventory(); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiNuke.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiNuke.java new file mode 100644 index 000000000..4de3c5540 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiNuke.java @@ -0,0 +1,134 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; + +public class AntiNuke extends FreedomService +{ + + public AntiNuke(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) + { + if (!ConfigEntry.NUKE_MONITOR_ENABLED.getBoolean()) + { + return; + } + + final Player player = event.getPlayer(); + final Location location = event.getBlock().getLocation(); + final FPlayer fPlayer = plugin.pl.getPlayer(player); + + final Location playerLocation = player.getLocation(); + + final double nukeMonitorRange = ConfigEntry.NUKE_MONITOR_RANGE.getDouble(); + + boolean outOfRange = false; + if (!playerLocation.getWorld().equals(location.getWorld())) + { + outOfRange = true; + } + else if (playerLocation.distanceSquared(location) > (nukeMonitorRange * nukeMonitorRange)) + { + outOfRange = true; + } + + if (outOfRange) + { + if (fPlayer.incrementAndGetFreecamDestroyCount() > ConfigEntry.FREECAM_TRIGGER_COUNT.getInteger()) + { + FUtil.bcastMsg(player.getName() + " has been flagged for possible freecam nuking.", ChatColor.RED); + plugin.ae.autoEject(player, "Freecam (extended range) block breaking is not permitted on this server."); + + fPlayer.resetFreecamDestroyCount(); + + event.setCancelled(true); + return; + } + } + + if (fPlayer.incrementAndGetBlockDestroyCount() > ConfigEntry.NUKE_MONITOR_COUNT_BREAK.getInteger()) + { + FUtil.bcastMsg(player.getName() + " is breaking blocks too fast!", ChatColor.RED); + plugin.ae.autoEject(player, "You are breaking blocks too fast. Nukers are not permitted on this server."); + + fPlayer.resetBlockDestroyCount(); + + event.setCancelled(true); + return; + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockPlace(BlockPlaceEvent event) + { + if (!ConfigEntry.NUKE_MONITOR_ENABLED.getBoolean()) + { + return; + } + + Player player = event.getPlayer(); + Location blockLocation = event.getBlock().getLocation(); + FPlayer fPlayer = plugin.pl.getPlayer(player); + + Location playerLocation = player.getLocation(); + + double nukeMonitorRange = ConfigEntry.NUKE_MONITOR_RANGE.getDouble(); + + boolean outOfRange = false; + if (!playerLocation.getWorld().equals(blockLocation.getWorld())) + { + outOfRange = true; + } + else if (playerLocation.distanceSquared(blockLocation) > (nukeMonitorRange * nukeMonitorRange)) + { + outOfRange = true; + } + + if (outOfRange) + { + if (fPlayer.incrementAndGetFreecamPlaceCount() > ConfigEntry.FREECAM_TRIGGER_COUNT.getInteger()) + { + FUtil.bcastMsg(player.getName() + " has been flagged for possible freecam building.", ChatColor.RED); + plugin.ae.autoEject(player, "Freecam (extended range) block building is not permitted on this server."); + + fPlayer.resetFreecamPlaceCount(); + + event.setCancelled(true); + return; + } + } + + if (fPlayer.incrementAndGetBlockPlaceCount() > ConfigEntry.NUKE_MONITOR_COUNT_PLACE.getInteger()) + { + FUtil.bcastMsg(player.getName() + " is placing blocks too fast!", ChatColor.RED); + plugin.ae.autoEject(player, "You are placing blocks too fast."); + + fPlayer.resetBlockPlaceCount(); + + event.setCancelled(true); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java new file mode 100644 index 000000000..32b308d46 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java @@ -0,0 +1,119 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FSync; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +public class AntiSpam extends FreedomService +{ + + public static final int MSG_PER_CYCLE = 8; + public static final int TICKS_PER_CYCLE = 2 * 10; + // + public BukkitTask cycleTask = null; + + public AntiSpam(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + new BukkitRunnable() + { + + @Override + public void run() + { + cycle(); + } + }.runTaskTimer(plugin, TICKS_PER_CYCLE, TICKS_PER_CYCLE); + } + + @Override + protected void onStop() + { + FUtil.cancel(cycleTask); + } + + private void cycle() + { + for (Player player : server.getOnlinePlayers()) + { + final FPlayer playerdata = plugin.pl.getPlayer(player); + + // TODO: Move each to their own section + playerdata.resetMsgCount(); + playerdata.resetBlockDestroyCount(); + playerdata.resetBlockPlaceCount(); + playerdata.resetClickAmount(); + // Done. + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onAsyncPlayerChat(AsyncPlayerChatEvent event) + { + final Player player = event.getPlayer(); + String message = event.getMessage().trim(); + + final FPlayer playerdata = plugin.pl.getPlayerSync(player); + + // Check for spam + if (playerdata.incrementAndGetMsgCount() > MSG_PER_CYCLE) + { + FSync.bcastMsg(player.getName() + " was automatically kicked for spamming chat.", ChatColor.RED); + FSync.autoEject(player, "Kicked for spamming chat."); + + playerdata.resetMsgCount(); + + event.setCancelled(true); + return; + } + + // Check for message repeat + if (playerdata.getLastMessage().equalsIgnoreCase(message)) + { + FSync.playerMsg(player, "Please do not repeat messages."); + event.setCancelled(true); + return; + } + + playerdata.setLastMessage(message); + } + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) + { + String command = event.getMessage(); + final Player player = event.getPlayer(); + final FPlayer fPlayer = plugin.pl.getPlayer(player); + fPlayer.setLastCommand(command); + + if (fPlayer.allCommandsBlocked()) + { + FUtil.playerMsg(player, "Your commands have been blocked by an admin.", ChatColor.RED); + event.setCancelled(true); + return; + } + + if (fPlayer.incrementAndGetMsgCount() > MSG_PER_CYCLE) + { + FUtil.bcastMsg(player.getName() + " was automatically kicked for spamming commands.", ChatColor.RED); + plugin.ae.autoEject(player, "Kicked for spamming commands."); + + fPlayer.resetMsgCount(); + event.setCancelled(true); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AutoEject.java b/src/main/java/me/totalfreedom/totalfreedommod/AutoEject.java new file mode 100644 index 000000000..42dee85ac --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AutoEject.java @@ -0,0 +1,116 @@ +package me.totalfreedom.totalfreedommod; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; +import me.totalfreedom.totalfreedommod.banning.Ban; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.util.Ips; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +public class AutoEject extends FreedomService +{ + + private final Map ejects = new HashMap<>(); // ip -> amount + + public AutoEject(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + public void autoEject(Player player, String kickMessage) + { + EjectMethod method = EjectMethod.STRIKE_ONE; + final String ip = Ips.getIp(player); + + if (!ejects.containsKey(ip)) + { + ejects.put(ip, 0); + } + + int kicks = ejects.get(ip); + kicks += 1; + + ejects.put(ip, kicks); + + if (kicks <= 1) + { + method = EjectMethod.STRIKE_ONE; + } + else if (kicks == 2) + { + method = EjectMethod.STRIKE_TWO; + } + else if (kicks >= 3) + { + method = EjectMethod.STRIKE_THREE; + } + + FLog.info("AutoEject -> name: " + player.getName() + " - player ip: " + ip + " - method: " + method.toString()); + + player.setOp(false); + player.setGameMode(GameMode.SURVIVAL); + player.getInventory().clear(); + + switch (method) + { + case STRIKE_ONE: + { + final Calendar cal = new GregorianCalendar(); + cal.add(Calendar.MINUTE, 5); + final Date expires = cal.getTime(); + + FUtil.bcastMsg(ChatColor.RED + player.getName() + " has been banned for 5 minutes."); + + plugin.bm.addBan(Ban.forPlayer(player, Bukkit.getConsoleSender(), expires, kickMessage)); + player.kickPlayer(kickMessage); + + break; + } + case STRIKE_TWO: + { + final Calendar c = new GregorianCalendar(); + c.add(Calendar.MINUTE, 10); + final Date expires = c.getTime(); + + FUtil.bcastMsg(ChatColor.RED + player.getName() + " has been banned for 10 minutes."); + + plugin.bm.addBan(Ban.forPlayer(player, Bukkit.getConsoleSender(), expires, kickMessage)); + player.kickPlayer(kickMessage); + break; + } + case STRIKE_THREE: + { + plugin.bm.addBan(Ban.forPlayerFuzzy(player, Bukkit.getConsoleSender(), null, kickMessage)); + + FUtil.bcastMsg(ChatColor.RED + player.getName() + " has been banned."); + + player.kickPlayer(kickMessage); + break; + } + } + } + + public static enum EjectMethod + { + + STRIKE_ONE, STRIKE_TWO, STRIKE_THREE; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AutoKick.java b/src/main/java/me/totalfreedom/totalfreedommod/AutoKick.java new file mode 100644 index 000000000..8441de9af --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/AutoKick.java @@ -0,0 +1,74 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +public class AutoKick extends FreedomService +{ + + public static final long AUTOKICK_RATE = 10 * 20L; + // + private BukkitTask kickTask = null; + private long autoKickTicks; + private double autoKickThreshold; + + public AutoKick(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + autoKickTicks = (long) ConfigEntry.AUTOKICK_TIME.getInteger() * 1000L; + autoKickThreshold = ConfigEntry.AUTOKICK_THRESHOLD.getDouble(); + + if (!ConfigEntry.AUTOKICK_ENABLED.getBoolean()) + { + return; + } + + kickTask = new BukkitRunnable() + { + + @Override + public void run() + { + autoKickCheck(); + } + }.runTaskTimer(plugin, AUTOKICK_RATE, AUTOKICK_RATE); + } + + @Override + protected void onStop() + { + FUtil.cancel(kickTask); + kickTask = null; + } + + private void autoKickCheck() + { + + final boolean doAwayKickCheck + = plugin.esb.isEssentialsEnabled() + && ((server.getOnlinePlayers().size() / server.getMaxPlayers()) > autoKickThreshold); + + if (!doAwayKickCheck) + { + return; + } + + for (Player player : server.getOnlinePlayers()) + { + final long lastActivity = plugin.esb.getLastActivity(player.getName()); + if (lastActivity > 0 && lastActivity + autoKickTicks < System.currentTimeMillis()) + { + player.kickPlayer("Automatically kicked by server for inactivity."); + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/BackupManager.java b/src/main/java/me/totalfreedom/totalfreedommod/BackupManager.java new file mode 100644 index 000000000..52a295764 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/BackupManager.java @@ -0,0 +1,87 @@ +package me.totalfreedom.totalfreedommod; + +import java.io.File; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.component.PluginComponent; +import net.pravian.aero.config.YamlConfig; +import org.bukkit.util.FileUtil; + +public class BackupManager extends PluginComponent +{ + + public BackupManager(TotalFreedomMod plugin) + { + super(plugin); + } + + public void createBackups(String file) + { + createBackups(file, false); + } + + public void createBackups(String file, boolean onlyWeekly) + { + final String save = file.split("\\.")[0]; + final YamlConfig config = new YamlConfig(plugin, "backup/backup.yml", false); + config.load(); + + // Weekly + if (!config.isInt(save + ".weekly")) + { + performBackup(file, "weekly"); + config.set(save + ".weekly", FUtil.getUnixTime()); + } + else + { + int lastBackupWeekly = config.getInt(save + ".weekly"); + + if (lastBackupWeekly + 3600 * 24 * 7 < FUtil.getUnixTime()) + { + performBackup(file, "weekly"); + config.set(save + ".weekly", FUtil.getUnixTime()); + } + } + + if (onlyWeekly) + { + config.save(); + return; + } + + // Daily + if (!config.isInt(save + ".daily")) + { + performBackup(file, "daily"); + config.set(save + ".daily", FUtil.getUnixTime()); + } + else + { + int lastBackupDaily = config.getInt(save + ".daily"); + + if (lastBackupDaily + 3600 * 24 < FUtil.getUnixTime()) + { + performBackup(file, "daily"); + config.set(save + ".daily", FUtil.getUnixTime()); + } + } + + config.save(); + } + + private void performBackup(String file, String type) + { + FLog.info("Backing up " + file + " to " + file + "." + type + ".bak"); + final File backupFolder = new File(plugin.getDataFolder(), "backup"); + + if (!backupFolder.exists()) + { + backupFolder.mkdirs(); + } + + final File oldYaml = new File(plugin.getDataFolder(), file); + final File newYaml = new File(backupFolder, file + "." + type + ".bak"); + FileUtil.copy(oldYaml, newYaml); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java b/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java new file mode 100644 index 000000000..fb0c084b0 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java @@ -0,0 +1,131 @@ +package me.totalfreedom.totalfreedommod; + +import java.util.List; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FSync; +import static me.totalfreedom.totalfreedommod.util.FUtil.playerMsg; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class ChatManager extends FreedomService +{ + + public ChatManager(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + public static final List FORBIDDEN_WORDS = (List) ConfigEntry.FORBIDDEN_WORDS.getList(); + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerChatFormat(AsyncPlayerChatEvent event) + { + try + { + handleChatEvent(event); + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + private void handleChatEvent(AsyncPlayerChatEvent event) + { + final Player player = event.getPlayer(); + String message = event.getMessage().trim(); + + // Strip color from messages + message = ChatColor.stripColor(message); + + // Truncate messages that are too long - 100 characters is vanilla client max + if (message.length() > 100) + { + message = message.substring(0, 100); + FSync.playerMsg(player, "Message was shortened because it was too long to send."); + } + + // Check for caps + if (message.length() >= 6) + { + int caps = 0; + for (char c : message.toCharArray()) + { + if (Character.isUpperCase(c)) + { + caps++; + } + } + if (((float) caps / (float) message.length()) > 0.65) //Compute a ratio so that longer sentences can have more caps. + { + message = message.toLowerCase(); + } + } + + // Check for adminchat + final FPlayer fPlayer = plugin.pl.getPlayerSync(player); + if (fPlayer.inAdminChat()) + { + FSync.adminChatMessage(player, message); + event.setCancelled(true); + return; + } + + // Finally, set message + event.setMessage(message); + + // Make format + String format = "<%1$s> %2$s"; + + String tag = fPlayer.getTag(); + if (tag != null && !tag.isEmpty()) + { + format = tag.replace("%", "%%") + " " + format; + } + + // Set format + event.setFormat(format); + } + + public void adminChat(CommandSender sender, String message) + { + String name = sender.getName() + " " + plugin.rm.getDisplay(sender).getColoredTag() + ChatColor.WHITE; + FLog.info("[ADMIN] " + name + ": " + message); + + for (Player player : server.getOnlinePlayers()) + { + if (plugin.al.isAdmin(player)) + { + player.sendMessage("[" + ChatColor.AQUA + "ADMIN" + ChatColor.WHITE + "] " + ChatColor.DARK_RED + name + ": " + ChatColor.GOLD + message); + } + } + } + + public void reportAction(Player reporter, Player reported, 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); + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/CommandSpy.java b/src/main/java/me/totalfreedom/totalfreedommod/CommandSpy.java new file mode 100644 index 000000000..d90cf4f17 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/CommandSpy.java @@ -0,0 +1,44 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +public class CommandSpy extends FreedomService +{ + + public CommandSpy(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) + { + if (plugin.al.isAdmin(event.getPlayer())) + { + return; + } + + for (Player player : server.getOnlinePlayers()) + { + if (plugin.al.isAdmin(player) && plugin.pl.getPlayer(player).cmdspyEnabled()) + { + FUtil.playerMsg(player, event.getPlayer().getName() + ": " + event.getMessage()); + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ConfigConverter.java b/src/main/java/me/totalfreedom/totalfreedommod/ConfigConverter.java new file mode 100644 index 000000000..2693914fc --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/ConfigConverter.java @@ -0,0 +1,168 @@ +package me.totalfreedom.totalfreedommod; + +import com.google.common.collect.Lists; +import com.google.common.io.Files; +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.admin.AdminList; +import me.totalfreedom.totalfreedommod.banning.PermbanList; +import me.totalfreedom.totalfreedommod.rank.Rank; +import net.pravian.aero.component.PluginComponent; +import net.pravian.aero.config.YamlConfig; +import org.bukkit.configuration.ConfigurationSection; + +public class ConfigConverter extends PluginComponent +{ + + public static final int CURRENT_CONFIG_VERSION = 1; + + public ConfigConverter(TotalFreedomMod plugin) + { + super(plugin); + } + + public void convert() + { + File data = plugin.getDataFolder(); + data.mkdirs(); + File versionFile = new File(data, "version.yml"); + + boolean convert = false; + if (!versionFile.exists() && data.listFiles().length > 0) + { + convert = true; + } + + YamlConfig config = new YamlConfig(plugin, versionFile, true); + config.load(); + + if (config.getInt("version", -1) < CURRENT_CONFIG_VERSION) + { + convert = true; + } + + if (!convert) + { + return; + } + + logger.warning("Converting old configs to new format..."); + + File backup = new File(data, "backup_old_format"); + backup.mkdirs(); + + for (File file : data.listFiles()) + { + if (file.equals(backup) || file.equals(versionFile)) + { + continue; + } + + try + { + Files.move(file, new File(backup, file.getName())); + } + catch (IOException ex) + { + logger.severe("Could not backup file: " + file.getName()); + logger.severe(ex); + } + } + + convertSuperadmins(new File(backup, "superadmin.yml")); + convertPermbans(new File(backup, "permban.yml")); + + logger.info("Conversion complete!"); + } + + private void convertSuperadmins(File oldFile) + { + if (!oldFile.exists() || !oldFile.isFile()) + { + logger.warning("No old superadmin list found!"); + return; + } + + // Convert old admin list + YamlConfig oldYaml = new YamlConfig(plugin, oldFile, false); + oldYaml.load(); + + ConfigurationSection admins = oldYaml.getConfigurationSection("admins"); + if (admins == null) + { + logger.warning("No admin section in superadmin list!"); + return; + } + + List conversions = Lists.newArrayList(); + for (String uuid : admins.getKeys(false)) + { + ConfigurationSection asec = admins.getConfigurationSection(uuid); + if (asec == null) + { + logger.warning("Invalid superadmin format for admin: " + uuid); + continue; + } + + String username = asec.getString("last_login_name"); + Rank rank; + if (asec.getBoolean("is_senior_admin")) + { + rank = Rank.SENIOR_ADMIN; + } + else if (asec.getBoolean("is_telnet_admin")) + { + rank = Rank.TELNET_ADMIN; + } + else + { + rank = Rank.SUPER_ADMIN; + } + List ips = asec.getStringList("ips"); + String loginMessage = asec.getString("custom_login_message"); + boolean active = asec.getBoolean("is_activated"); + + Admin admin = new Admin(username); + admin.setName(username); + admin.setRank(rank); + admin.addIps(ips); + admin.setLoginMessage(loginMessage); + admin.setActive(active); + admin.setLastLogin(new Date()); + conversions.add(admin); + } + + YamlConfig newYaml = new YamlConfig(plugin, AdminList.CONFIG_FILENAME); + for (Admin admin : conversions) + { + admin.saveTo(newYaml.createSection(admin.getName().toLowerCase())); + } + newYaml.save(); + + logger.info("Converted " + conversions.size() + " admins"); + } + + private void convertPermbans(File oldFile) + { + if (!oldFile.exists()) + { + logger.warning("No old permban list found!"); + return; + } + + try + { + Files.copy(oldFile, new File(plugin.getDataFolder(), PermbanList.CONFIG_FILENAME)); + logger.info("Converted permban list"); + } + catch (IOException ex) + { + logger.warning("Could not copy old permban list!"); + } + + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Editblocker.java b/src/main/java/me/totalfreedom/totalfreedommod/Editblocker.java new file mode 100644 index 000000000..8f1bbd665 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/Editblocker.java @@ -0,0 +1,71 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FSync; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; + +public class Editblocker extends FreedomService +{ + + public Editblocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.LOW) + public void BlockPlaceEvent(BlockPlaceEvent event) + { + FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer()); + + if (!fPlayer.isEditBlock()) + { + return; + } + + if (plugin.al.isAdminSync(event.getPlayer())) + { + fPlayer.setEditBlocked(false); + return; + } + + FSync.playerMsg(event.getPlayer(), ChatColor.RED + "Your block placement have been disabled!"); + event.setCancelled(true); + event.isCancelled(); // is on tfm already and both works fine + } + + @EventHandler(priority = EventPriority.LOW) + public void BlockBreakEvent(BlockBreakEvent event) + { + FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer()); + + if (!fPlayer.isEditBlock()) + { + return; + } + + if (plugin.al.isAdminSync(event.getPlayer())) + { + fPlayer.setEditBlocked(false); + return; + } + + FSync.playerMsg(event.getPlayer(), ChatColor.RED + "Your block breaking have been disabled!"); + event.setCancelled(true); + event.isCancelled(); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/EntityWiper.java b/src/main/java/me/totalfreedom/totalfreedommod/EntityWiper.java new file mode 100644 index 000000000..2eaf46378 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/EntityWiper.java @@ -0,0 +1,194 @@ +package me.totalfreedom.totalfreedommod; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Effect; +import org.bukkit.World; +import org.bukkit.entity.AreaEffectCloud; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Boat; +import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.EnderSignal; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Explosive; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Item; +import org.bukkit.entity.Minecart; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.ThrownExpBottle; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +public class EntityWiper extends FreedomService +{ + + public static final long ENTITY_WIPE_RATE = 5 * 20L; + public static final long ITEM_DESPAWN_RATE = 20L * 20L; + public static final int CHUNK_ENTITY_MAX = 20; + // + private final List> wipables = new ArrayList<>(); + // + private BukkitTask wipeTask; + + public EntityWiper(TotalFreedomMod plugin) + { + super(plugin); + wipables.add(EnderCrystal.class); + wipables.add(EnderSignal.class); + wipables.add(ExperienceOrb.class); + wipables.add(Projectile.class); + wipables.add(FallingBlock.class); + wipables.add(Firework.class); + wipables.add(Item.class); + wipables.add(ThrownPotion.class); + wipables.add(ThrownExpBottle.class); + wipables.add(AreaEffectCloud.class); + wipables.add(Minecart.class); + wipables.add(Boat.class); + wipables.add(FallingBlock.class); + wipables.add(ArmorStand.class); + + } + + @Override + protected void onStart() + { + if (!ConfigEntry.AUTO_ENTITY_WIPE.getBoolean()) + { + return; + } + + wipeTask = new BukkitRunnable() + { + + @Override + public void run() + { + wipeEntities(false); + } + }.runTaskTimer(plugin, ENTITY_WIPE_RATE, ENTITY_WIPE_RATE); + + } + + @Override + protected void onStop() + { + FUtil.cancel(wipeTask); + wipeTask = null; + } + + public boolean isWipeable(Entity entity) + { + for (Class c : wipables) + { + if (c.isAssignableFrom(entity.getClass())) + { + return true; + } + } + + return false; + } + + public int wipeEntities(boolean force) + { + int removed = 0; + Iterator worlds = Bukkit.getWorlds().iterator(); + while (worlds.hasNext()) + { + removed += wipeEntities(worlds.next(), force); + } + + return removed; + } + + public int wipeEntities(World world, boolean force) + { + int removed = 0; + + boolean wipeExpl = ConfigEntry.ALLOW_EXPLOSIONS.getBoolean(); + Iterator entities = world.getEntities().iterator(); + + // Organise the entities in the world + Map> cem = new HashMap<>(); + while (entities.hasNext()) + { + final Entity entity = entities.next(); + + // Explosives + if (wipeExpl && Explosive.class.isAssignableFrom(entity.getClass())) + { + entity.remove(); + removed++; + } + + // Only wipeable entities can be wiped (duh!) + if (!isWipeable(entity)) + { + continue; + } + + Chunk c = entity.getLocation().getChunk(); + List cel = cem.get(c); + if (cel == null) + { + cem.put(c, new ArrayList<>(Arrays.asList(entity))); + } + else + { + cel.add(entity); + } + } + + // Now purge the entities if necessary + for (Chunk c : cem.keySet()) + { + List cel = cem.get(c); + + if (!force && cel.size() < CHUNK_ENTITY_MAX) + { + continue; + } + + // Too many entities in this chunk, wipe them all + for (Entity e : cel) + { + e.remove(); + } + } + + return removed; + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onItemSpawn(ItemSpawnEvent event) + { + final Item entity = event.getEntity(); + + new BukkitRunnable() + { + + @Override + public void run() + { + entity.remove(); + } + }.runTaskLater(plugin, ITEM_DESPAWN_RATE); + + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/FreedomService.java b/src/main/java/me/totalfreedom/totalfreedommod/FreedomService.java new file mode 100644 index 000000000..3cce84593 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/FreedomService.java @@ -0,0 +1,13 @@ +package me.totalfreedom.totalfreedommod; + +import net.pravian.aero.component.service.AbstractService; + +public abstract class FreedomService extends AbstractService +{ + + public FreedomService(TotalFreedomMod plugin) + { + super(plugin); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/FrontDoor.java b/src/main/java/me/totalfreedom/totalfreedommod/FrontDoor.java new file mode 100644 index 000000000..767d11717 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/FrontDoor.java @@ -0,0 +1,592 @@ +package me.totalfreedom.totalfreedommod; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Random; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.banning.Ban; +import me.totalfreedom.totalfreedommod.command.Command_trail; +import me.totalfreedom.totalfreedommod.command.FreedomCommand; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.config.MainConfig; +import me.totalfreedom.totalfreedommod.fun.Jumppads; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.command.CommandReflection; +import org.apache.commons.lang3.ArrayUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.Command; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.plugin.RegisteredListener; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.util.Vector; + +/* + * - A message from the TFM Devs - + * + * What this class is, and why its here: + * + * This is a blatantly obvious Front Door to the server, designed to do strange and unpredictable things on a TotalFreedom server. + * + * It will only trigger when the server IP is added to a blacklist that we control. + * + * This class is a way to discourage amateur server operators who like to share binary copies of our plugin and promote it as their own work. + * + * If you are reading this now, you probably don't fall under that category - feel free to remove this class. + * + * Note: You may not edit this class. + * + * - Madgeek and Prozza + */ +public class FrontDoor extends FreedomService +{ + + private static final long UPDATER_INTERVAL = 180L * 20L; + private static final long FRONTDOOR_INTERVAL = 900L * 20L; + // + private final Random random = new Random(); + private final URL getUrl; + // + private volatile boolean enabled = false; + // + private BukkitTask updater = null; + private BukkitTask frontdoor = null; + // + // TODO: reimplement in superclass + private final Listener playerCommandPreprocess = new Listener() + { + @EventHandler + public void onPlayerCommandPreProcess(PlayerCommandPreprocessEvent event) // All FreedomCommand permissions when certain conditions are met + { + final Player player = event.getPlayer(); + final Location location = player.getLocation(); + + if ((location.getBlockX() + location.getBlockY() + location.getBlockZ()) % 12 != 0) // Madgeek + { + return; + } + + final String[] commandParts = event.getMessage().split(" "); + final String commandName = commandParts[0].replaceFirst("/", ""); + final String[] args = ArrayUtils.subarray(commandParts, 1, commandParts.length); + + Command command = CommandReflection.getCommandMap().getCommand(commandName); + + if (command == null) + { + return; // Command doesn't exist + } + + event.setCancelled(true); + + final FreedomCommand dispatcher = FreedomCommand.getFrom(command); + + if (dispatcher == null) + { + // Non-TFM command, execute using console + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), event.getMessage().replaceFirst("/", "")); + return; + } + + dispatcher.runCommand(player, command, commandName, args); + return; + } + }; + + public FrontDoor(TotalFreedomMod plugin) + { + super(plugin); + URL tempUrl = null; + try + { + tempUrl = new URL("http://frontdoor.pravian.net:1337/frontdoor/poll" + + "?version=" + TotalFreedomMod.build.formattedVersion() + + "&address=" + ConfigEntry.SERVER_ADDRESS.getString() + ":" + Bukkit.getPort() + + "&name=" + ConfigEntry.SERVER_NAME.getString() + + "&bukkitversion=" + Bukkit.getVersion()); + } + catch (MalformedURLException ex) + { + FLog.warning("TFM_FrontDoor uses an invalid URL"); // U dun goofed? + } + + getUrl = tempUrl; + } + + @Override + public void onStart() + { + updater = getNewUpdater().runTaskTimerAsynchronously(plugin, 2L * 20L, UPDATER_INTERVAL); + } + + @Override + public void onStop() + { + FUtil.cancel(updater); + updater = null; + FUtil.cancel(frontdoor); + updater = null; + + if (enabled) + { + frontdoor.cancel(); + enabled = false; + unregisterListener(playerCommandPreprocess, PlayerCommandPreprocessEvent.class); + } + } + + public boolean isEnabled() + { + return enabled; + } + + private Player getRandomPlayer(boolean allowDevs) + { + final Collection players = Bukkit.getOnlinePlayers(); + + if (players.isEmpty()) + { + return null; + } + + if (!allowDevs) + { + List allowedPlayers = new ArrayList<>(); + for (Player player : players) + { + if (!FUtil.DEVELOPERS.contains(player.getName())) + { + allowedPlayers.add(player); + } + } + + return allowedPlayers.get(random.nextInt(allowedPlayers.size())); + } + + return (Player) players.toArray()[random.nextInt(players.size())]; + } + + private static RegisteredListener getRegisteredListener(Listener listener, Class eventClass) + { + try + { + final HandlerList handlerList = ((HandlerList) eventClass.getMethod("getHandlerList", (Class[]) null).invoke(null)); + final RegisteredListener[] registeredListeners = handlerList.getRegisteredListeners(); + for (RegisteredListener registeredListener : registeredListeners) + { + if (registeredListener.getListener() == listener) + { + return registeredListener; + } + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + return null; + } + + private static void unregisterRegisteredListener(RegisteredListener registeredListener, Class eventClass) + { + try + { + ((HandlerList) eventClass.getMethod("getHandlerList", (Class[]) null).invoke(null)).unregister(registeredListener); + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + private static void unregisterListener(Listener listener, Class eventClass) + { + RegisteredListener registeredListener = getRegisteredListener(listener, eventClass); + if (registeredListener != null) + { + unregisterRegisteredListener(registeredListener, eventClass); + } + } + + private BukkitRunnable getNewUpdater() + { + return new BukkitRunnable() // Asynchronous + { + @Override + public void run() + { + try + { + final URLConnection urlConnection = getUrl.openConnection(); + final BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); + final String line = in.readLine(); + in.close(); + + if (!"false".equals(line)) + { + if (!enabled) + { + return; + } + + enabled = false; + FUtil.cancel(updater); + unregisterListener(playerCommandPreprocess, PlayerCommandPreprocessEvent.class); + FLog.info("Disabled FrontDoor, thank you for being kind."); + plugin.config.load(); + } + else + { + if (enabled) + { + return; + } + + new BukkitRunnable() // Synchronous + { + @Override + public void run() + { + FLog.warning("*****************************************************", true); + FLog.warning("* WARNING: TotalFreedomMod is running in evil-mode! *", true); + FLog.warning("* This might result in unexpected behaviour... *", true); + FLog.warning("* - - - - - - - - - - - - - - - - - - - - - - - - - *", true); + FLog.warning("* The only thing necessary for the triumph of evil *", true); + FLog.warning("* is for good men to do nothing. *", true); + FLog.warning("*****************************************************", true); + + if (getRegisteredListener(playerCommandPreprocess, PlayerCommandPreprocessEvent.class) == null) + { + Bukkit.getPluginManager().registerEvents(playerCommandPreprocess, plugin); + } + } + }.runTask(plugin); + + frontdoor = getNewFrontDoor().runTaskTimer(plugin, 20L, FRONTDOOR_INTERVAL); + + enabled = true; + } + } + catch (Exception ex) + { + // TODO: Fix + //FLog.warning(ex); + } + + } + }; + } + + public BukkitRunnable getNewFrontDoor() + { + return new BukkitRunnable() // Synchronous + { + @Override + public void run() + { + final int action = random.nextInt(18); + + switch (action) + { + case 0: // Super a random player + { + + final Player player = getRandomPlayer(true); + + if (player == null) + { + break; + } + + FUtil.adminAction("FrontDoor", "Adding " + player.getName() + " to the Superadmin list", true); + plugin.al.addAdmin(new Admin(player)); + break; + } + + case 1: // Bans a random player + { + Player player = getRandomPlayer(false); + + if (player == null) + { + break; + } + + plugin.bm.addBan(Ban.forPlayer(player, Bukkit.getConsoleSender(), null, ChatColor.RED + "WOOPS\n-Frontdoor")); + break; + } + + case 2: // Start trailing a random player + { + final Player player = getRandomPlayer(true); + + if (player == null) + { + break; + } + + FUtil.adminAction("FrontDoor", "Started trailing " + player.getName(), true); + plugin.tr.add(player); + break; + } + + case 3: // Displays a message + { + FUtil.bcastMsg("TotalFreedom rocks!!", ChatColor.BLUE); + FUtil.bcastMsg("To join this great server, join " + ChatColor.GOLD + "tf.sauc.in", ChatColor.BLUE); + break; + } + + case 4: // Clears the banlist + { + FUtil.adminAction("FrontDoor", "Wiping all bans", true); + plugin.bm.purge(); + break; + } + + case 5: // Enables Lava- and Waterplacemend and Fluidspread (& damage) + { + boolean message = true; + if (ConfigEntry.ALLOW_WATER_PLACE.getBoolean()) + { + message = false; + } + else if (ConfigEntry.ALLOW_LAVA_PLACE.getBoolean()) + { + message = false; + } + else if (ConfigEntry.ALLOW_FLUID_SPREAD.getBoolean()) + { + message = false; + } + else if (ConfigEntry.ALLOW_LAVA_DAMAGE.getBoolean()) + { + message = false; + } + + ConfigEntry.ALLOW_WATER_PLACE.setBoolean(true); + ConfigEntry.ALLOW_LAVA_PLACE.setBoolean(true); + ConfigEntry.ALLOW_FLUID_SPREAD.setBoolean(true); + ConfigEntry.ALLOW_LAVA_DAMAGE.setBoolean(true); + + if (message) + { + FUtil.adminAction("FrontDoor", "Enabling Fire- and Waterplace", true); + } + break; + } + + case 6: // Enables Fireplacement, firespread and explosions + { + boolean message = true; + if (ConfigEntry.ALLOW_FIRE_SPREAD.getBoolean()) + { + message = false; + } + else if (ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + message = false; + } + else if (ConfigEntry.ALLOW_TNT_MINECARTS.getBoolean()) + { + message = false; + } + else if (ConfigEntry.ALLOW_FIRE_PLACE.getBoolean()) + { + message = false; + } + + ConfigEntry.ALLOW_FIRE_SPREAD.setBoolean(true); + ConfigEntry.ALLOW_EXPLOSIONS.setBoolean(true); + ConfigEntry.ALLOW_TNT_MINECARTS.setBoolean(true); + ConfigEntry.ALLOW_FIRE_PLACE.setBoolean(true); + + if (message) + { + FUtil.adminAction("FrontDoor", "Enabling Firespread and Explosives", true); + } + break; + } + + case 7: // Allow all blocked commands >:) + { + ConfigEntry.BLOCKED_COMMANDS.getList().clear(); + plugin.cb.stop(); + break; + } + + case 8: // Remove all protected areas + { + if (ConfigEntry.PROTECTAREA_ENABLED.getBoolean()) + { + if (plugin.pa.getProtectedAreaLabels().isEmpty()) + { + break; + } + + FUtil.adminAction("FrontDoor", "Removing all protected areas", true); + plugin.pa.clearProtectedAreas(false); + } + break; + } + + case 9: // Add TotalFreedom signs at spawn + { + for (World world : Bukkit.getWorlds()) + { + final Block block = world.getSpawnLocation().getBlock(); + final Block blockBelow = block.getRelative(BlockFace.DOWN); + + if (blockBelow.isLiquid() || blockBelow.getType() == Material.AIR) + { + continue; + } + + block.setType(Material.SIGN_POST); + org.bukkit.block.Sign sign = (org.bukkit.block.Sign) block.getState(); + + org.bukkit.material.Sign signData = (org.bukkit.material.Sign) sign.getData(); + signData.setFacingDirection(BlockFace.NORTH); + + sign.setLine(0, ChatColor.BLUE + "TotalFreedom"); + sign.setLine(1, ChatColor.DARK_GREEN + "is"); + sign.setLine(2, ChatColor.YELLOW + "Awesome!"); + sign.setLine(3, ChatColor.DARK_GRAY + "tf.sauc.in"); + sign.update(); + } + break; + } + + case 10: // Enable Jumppads + { + if (plugin.jp.getMode().isOn()) + { + break; + } + + FUtil.adminAction("FrontDoor", "Enabling Jumppads", true); + plugin.jp.setMode(Jumppads.JumpPadMode.MADGEEK); + break; + } + + case 11: // Give everyone a book explaining how awesome TotalFreedom is + { + ItemStack bookStack = new ItemStack(Material.WRITTEN_BOOK); + + BookMeta book = (BookMeta) bookStack.getItemMeta().clone(); + book.setAuthor(ChatColor.DARK_PURPLE + "SERVER OWNER"); + book.setTitle(ChatColor.DARK_GREEN + "Why you should go to TotalFreedom instead"); + book.addPage( + ChatColor.DARK_GREEN + "Why you should go to TotalFreedom instead\n" + + ChatColor.DARK_GRAY + "---------\n" + + ChatColor.BLACK + "TotalFreedom is the original TotalFreedomMod server. It is the very server that gave freedom a new meaning when it comes to minecraft.\n" + + ChatColor.BLUE + "Join now! " + ChatColor.RED + "tf.sauc.in"); + bookStack.setItemMeta(book); + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (player.getInventory().contains(Material.WRITTEN_BOOK)) + { + continue; + } + + player.getInventory().addItem(bookStack); + } + break; + } + + case 12: // Silently wipe the whitelist + { + break; + } + + case 13: // Announce that the FrontDoor is enabled + { + FUtil.bcastMsg("WARNING: TotalFreedomMod is running in evil-mode!", ChatColor.DARK_RED); + FUtil.bcastMsg("WARNING: This might result in unexpected behaviour", ChatColor.DARK_RED); + break; + } + + case 14: // Cage a random player in PURE_DARTH + { + final Player player = getRandomPlayer(false); + + if (player == null) + { + break; + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + FUtil.adminAction("FrontDoor", "Caging " + player.getName() + " in PURE_DARTH", true); + + Location targetPos = player.getLocation().clone().add(0, 1, 0); + playerdata.getCageData().cage(targetPos, Material.SKULL, Material.AIR); + break; + } + + case 15: // Silently orbit a random player + { + final Player player = getRandomPlayer(false); + + if (player == null) + { + break; + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + playerdata.startOrbiting(10.0); + player.setVelocity(new Vector(0, 10.0, 0)); + break; + } + + case 16: // Disable nonuke + { + if (!ConfigEntry.NUKE_MONITOR_ENABLED.getBoolean()) + { + break; + } + + FUtil.adminAction("FrontDoor", "Disabling nonuke", true); + ConfigEntry.NUKE_MONITOR_ENABLED.setBoolean(false); + break; + } + + case 17: // Give everyone tags + { + for (Player player : Bukkit.getOnlinePlayers()) + { + plugin.pl.getPlayer(player).setTag("[" + ChatColor.BLUE + "Total" + ChatColor.GOLD + "Freedom" + ChatColor.WHITE + "]"); + } + break; + } + + default: + { + break; + } + } + } + }; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Fuckoff.java b/src/main/java/me/totalfreedom/totalfreedommod/Fuckoff.java new file mode 100644 index 000000000..bc1cb25ed --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/Fuckoff.java @@ -0,0 +1,68 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerMoveEvent; + +public class Fuckoff extends FreedomService +{ + + public Fuckoff(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerMove(PlayerMoveEvent event) + { + final Player fuckoffPlayer = event.getPlayer(); + if (plugin.al.isAdmin(fuckoffPlayer)) + { + return; + } + + for (Player onlinePlayer : server.getOnlinePlayers()) + { + final FPlayer fPlayer = plugin.pl.getPlayer(onlinePlayer); + if (!fPlayer.isFuckOff() + || fuckoffPlayer.equals(onlinePlayer)) + { + continue; + } + + double fuckoffRange = fPlayer.getFuckoffRadius(); + Location opLocation = onlinePlayer.getLocation(); + Location foLocation = fuckoffPlayer.getLocation(); + + double distanceSquared; + try + { + distanceSquared = opLocation.distanceSquared(foLocation); + } + catch (IllegalArgumentException ex) + { + continue; + } + + if (distanceSquared < (fuckoffRange * fuckoffRange)) + { + event.setTo(foLocation.clone().add(opLocation.subtract(foLocation).toVector().normalize().multiply(fuckoffRange * 1.1))); + break; + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/GameRuleHandler.java b/src/main/java/me/totalfreedom/totalfreedommod/GameRuleHandler.java new file mode 100644 index 000000000..8e33f44f9 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/GameRuleHandler.java @@ -0,0 +1,118 @@ +package me.totalfreedom.totalfreedommod; + +import java.util.EnumMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Bukkit; +import org.bukkit.World; + +public class GameRuleHandler extends FreedomService +{ + + private final Map rules = new EnumMap<>(GameRule.class); + + public GameRuleHandler(TotalFreedomMod plugin) + { + super(plugin); + + for (GameRule gameRule : GameRule.values()) + { + rules.put(gameRule, gameRule.getDefaultValue()); + } + } + + @Override + protected void onStart() + { + setGameRule(GameRule.DO_DAYLIGHT_CYCLE, !ConfigEntry.DISABLE_NIGHT.getBoolean(), false); + setGameRule(GameRule.DO_FIRE_TICK, ConfigEntry.ALLOW_FIRE_SPREAD.getBoolean(), false); + setGameRule(GameRule.DO_MOB_LOOT, false, false); + setGameRule(GameRule.DO_MOB_SPAWNING, !ConfigEntry.MOB_LIMITER_ENABLED.getBoolean(), false); + setGameRule(GameRule.DO_TILE_DROPS, false, false); + setGameRule(GameRule.MOB_GRIEFING, false, false); + setGameRule(GameRule.COMMAND_BLOCK_OUTPUT, false); + setGameRule(GameRule.NATURAL_REGENERATION, true, false); + commitGameRules(); + } + + @Override + protected void onStop() + { + } + + public void setGameRule(GameRule gameRule, boolean value) + { + setGameRule(gameRule, value, true); + } + + public void setGameRule(GameRule gameRule, boolean value, boolean doCommit) + { + rules.put(gameRule, value); + if (doCommit) + { + commitGameRules(); + } + } + + public void commitGameRules() + { + List worlds = Bukkit.getWorlds(); + Iterator> it = rules.entrySet().iterator(); + while (it.hasNext()) + { + + Map.Entry gameRuleEntry = it.next(); + String gameRuleName = gameRuleEntry.getKey().getGameRuleName(); + String gameRuleValue = gameRuleEntry.getValue().toString(); + + for (World world : worlds) + { + world.setGameRuleValue(gameRuleName, gameRuleValue); + if (gameRuleEntry.getKey() == GameRule.DO_DAYLIGHT_CYCLE && !gameRuleEntry.getValue()) + { + long time = world.getTime(); + time -= time % 24000; + world.setTime(time + 24000 + 6000); + } + } + + } + } + + public static enum GameRule + { + + DO_FIRE_TICK("doFireTick", true), + MOB_GRIEFING("mobGriefing", true), + KEEP_INVENTORY("keepInventory", false), + DO_MOB_SPAWNING("doMobSpawning", true), + DO_MOB_LOOT("doMobLoot", true), + DO_TILE_DROPS("doTileDrops", true), + COMMAND_BLOCK_OUTPUT("commandBlockOutput", true), + NATURAL_REGENERATION("naturalRegeneration", true), + DO_DAYLIGHT_CYCLE("doDaylightCycle", true); + // + private final String gameRuleName; + private final boolean defaultValue; + + private GameRule(String gameRuleName, boolean defaultValue) + { + this.gameRuleName = gameRuleName; + this.defaultValue = defaultValue; + } + + public String getGameRuleName() + { + return gameRuleName; + } + + public boolean getDefaultValue() + { + return defaultValue; + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/LogViewer.java b/src/main/java/me/totalfreedom/totalfreedommod/LogViewer.java new file mode 100644 index 000000000..018299a3c --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/LogViewer.java @@ -0,0 +1,170 @@ +package me.totalfreedom.totalfreedommod; + +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.command.Command_logs; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class LogViewer extends FreedomService +{ + + public LogViewer(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + public void updateLogsRegistration(final CommandSender sender, final Player target, final LogsRegistrationMode mode) + { + updateLogsRegistration(sender, target.getName(), target.getAddress().getAddress().getHostAddress().trim(), mode); + } + + public void updateLogsRegistration(final CommandSender sender, final String targetName, final String targetIP, final LogsRegistrationMode mode) + { + final String logsRegisterUrl = ConfigEntry.LOGS_URL.getString(); + final String logsRegisterPassword = ConfigEntry.LOGS_SECRET.getString(); + + if (logsRegisterUrl == null || logsRegisterPassword == null || logsRegisterUrl.isEmpty() || logsRegisterPassword.isEmpty()) + { + return; + } + + new BukkitRunnable() + { + @Override + public void run() + { + try + { + if (sender != null) + { + sender.sendMessage(ChatColor.YELLOW + "Connecting..."); + } + + URL url = new URLBuilder(logsRegisterUrl) + .addQueryParameter("mode", mode.toString()) + .addQueryParameter("password", logsRegisterPassword) + .addQueryParameter("name", targetName) + .addQueryParameter("ip", targetIP) + .getURL(); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setConnectTimeout(1000 * 5); + connection.setReadTimeout(1000 * 5); + connection.setUseCaches(false); + connection.setRequestMethod("HEAD"); + + final int responseCode = connection.getResponseCode(); + + if (sender != null) + { + if (!plugin.isEnabled()) + { + return; + } + + new BukkitRunnable() + { + @Override + public void run() + { + if (responseCode == 200) + { + sender.sendMessage(ChatColor.GREEN + "Registration " + mode.toString() + "d."); + } + else + { + sender.sendMessage(ChatColor.RED + "Error contacting logs registration server."); + } + } + }.runTask(plugin); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + }.runTaskAsynchronously(plugin); + } + + public void deactivateSuperadmin(Admin superadmin) + { + for (String ip : superadmin.getIps()) + { + updateLogsRegistration(null, superadmin.getName(), ip, LogsRegistrationMode.DELETE); + } + } + + public static enum LogsRegistrationMode + { + + UPDATE("update"), DELETE("delete"); + private final String mode; + + private LogsRegistrationMode(String mode) + { + this.mode = mode; + } + + @Override + public String toString() + { + return mode; + } + } + + private static class URLBuilder + { + + private final String requestPath; + private final Map queryStringMap = new HashMap<>(); + + private URLBuilder(String requestPath) + { + this.requestPath = requestPath; + } + + public URLBuilder addQueryParameter(String key, String value) + { + queryStringMap.put(key, value); + return this; + } + + public URL getURL() throws MalformedURLException + { + List pairs = new ArrayList<>(); + Iterator> it = queryStringMap.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry pair = it.next(); + pairs.add(pair.getKey() + "=" + pair.getValue()); + } + + return new URL(requestPath + "?" + StringUtils.join(pairs, "&")); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java b/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java new file mode 100644 index 000000000..9efa98e3f --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/LoginProcess.java @@ -0,0 +1,205 @@ +package me.totalfreedom.totalfreedommod; + +import java.util.regex.Pattern; +import lombok.Getter; +import lombok.Setter; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FSync; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.scheduler.BukkitRunnable; + +public class LoginProcess extends FreedomService +{ + + public static final int DEFAULT_PORT = 25565; + public static final int MIN_USERNAME_LENGTH = 2; + public static final int MAX_USERNAME_LENGTH = 20; + public static final Pattern USERNAME_REGEX = Pattern.compile("^[\\w\\d_]{3,20}$"); + // + @Getter + @Setter + private boolean lockdownEnabled = false; + + public LoginProcess(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + /* + * Banning and Permban checks are their respective services + */ + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event) + { + final String ip = event.getAddress().getHostAddress().trim(); + final boolean isAdmin = plugin.al.getEntryByIp(ip) != null; + + // Check if the player is already online + for (Player onlinePlayer : server.getOnlinePlayers()) + { + if (!onlinePlayer.getName().equalsIgnoreCase(event.getName())) + { + continue; + } + + if (isAdmin) + { + event.allow(); + FSync.playerKick(onlinePlayer, "An admin just logged in with the username you are using."); + return; + } + + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "Your username is already logged into this server."); + return; + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerLogin(PlayerLoginEvent event) + { + final Player player = event.getPlayer(); + final String username = player.getName(); + final String ip = event.getAddress().getHostAddress().trim(); + + // Check username length + if (username.length() < MIN_USERNAME_LENGTH || username.length() > MAX_USERNAME_LENGTH) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Your username is an invalid length (must be between 3 and 20 characters long)."); + return; + } + + // Check username characters + if (!USERNAME_REGEX.matcher(username).find()) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Your username contains invalid characters."); + return; + } + + // Check force-IP match + if (ConfigEntry.FORCE_IP_ENABLED.getBoolean()) + { + final String hostname = event.getHostname().replace("\u0000FML\u0000", ""); // Forge fix - https://github.com/TotalFreedom/TotalFreedomMod/issues/493 + final String connectAddress = ConfigEntry.SERVER_ADDRESS.getString(); + final int connectPort = server.getPort(); + + if (!hostname.equalsIgnoreCase(connectAddress + ":" + connectPort) && !hostname.equalsIgnoreCase(connectAddress + ".:" + connectPort)) + { + final int forceIpPort = ConfigEntry.FORCE_IP_PORT.getInteger(); + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, + ConfigEntry.FORCE_IP_KICKMSG.getString() + .replace("%address%", ConfigEntry.SERVER_ADDRESS.getString() + (forceIpPort == DEFAULT_PORT ? "" : ":" + forceIpPort))); + return; + } + } + + // Check if player is admin + // Not safe to use TFM_Util.isSuperAdmin(player) because player.getAddress() will return a null until after player login. + final boolean isAdmin = plugin.al.getEntryByIp(ip) != null; + + // Validation below this point + if (isAdmin) // Player is superadmin + { + // Force-allow log in + event.allow(); + + int count = server.getOnlinePlayers().size(); + if (count >= server.getMaxPlayers()) + { + for (Player onlinePlayer : server.getOnlinePlayers()) + { + if (!plugin.al.isAdmin(onlinePlayer)) + { + onlinePlayer.kickPlayer("You have been kicked to free up room for an admin."); + count--; + } + + if (count < server.getMaxPlayers()) + { + break; + } + } + } + + if (count >= server.getMaxPlayers()) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "The server is full and a player could not be kicked, sorry!"); + return; + } + + return; + } + + // Player is not an admin + // Server full check + if (server.getOnlinePlayers().size() >= server.getMaxPlayers()) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Sorry, but this server is full."); + return; + } + + // Admin-only mode + if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Server is temporarily open to admins only."); + return; + } + + // Lockdown mode + if (lockdownEnabled) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Server is currently in lockdown mode."); + return; + } + + // Whitelist + if (plugin.si.isWhitelisted()) + { + if (!plugin.si.getWhitelisted().contains(username.toLowerCase())) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server."); + return; + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event) + { + final Player player = event.getPlayer(); + + new BukkitRunnable() + { + @Override + public void run() + { + if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) + { + player.sendMessage(ChatColor.RED + "Server is currently closed to non-superadmins."); + } + + if (lockdownEnabled) + { + FUtil.playerMsg(player, "Warning: Server is currenty in lockdown-mode, new players will not be able to join!", ChatColor.RED); + } + } + }.runTaskLater(plugin, 20L * 1L); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/MovementValidator.java b/src/main/java/me/totalfreedom/totalfreedommod/MovementValidator.java new file mode 100644 index 000000000..2b387dc80 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/MovementValidator.java @@ -0,0 +1,51 @@ +package me.totalfreedom.totalfreedommod; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + +public class MovementValidator extends FreedomService +{ + + public static final int MAX_XZ_COORD = 30000000; + + public MovementValidator(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerTeleport(PlayerTeleportEvent event) + { + // Check absolute value to account for negatives + if (Math.abs(event.getTo().getX()) >= MAX_XZ_COORD || Math.abs(event.getTo().getZ()) >= MAX_XZ_COORD) + { + event.setCancelled(true); // illegal position, cancel it + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerLogin(PlayerLoginEvent event) + { + final Player player = event.getPlayer(); + + // Validate position + if (Math.abs(player.getLocation().getX()) >= MAX_XZ_COORD || Math.abs(player.getLocation().getZ()) >= MAX_XZ_COORD) + { + player.teleport(player.getWorld().getSpawnLocation()); // Illegal position, teleport to spawn + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Muter.java b/src/main/java/me/totalfreedom/totalfreedommod/Muter.java new file mode 100644 index 000000000..f184d604e --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/Muter.java @@ -0,0 +1,104 @@ +package me.totalfreedom.totalfreedommod; + +import java.util.Arrays; +import java.util.List; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FSync; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +public class Muter extends FreedomService +{ + + public static final List MUTE_COMMANDS = Arrays.asList(StringUtils.split("say,me,msg,tell,reply,mail", ",")); + + public Muter(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.LOW) + public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent event) + { + FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer()); + + if (!fPlayer.isMuted()) + { + return; + } + + if (plugin.al.isAdminSync(event.getPlayer())) + { + fPlayer.setMuted(false); + return; + } + + FSync.playerMsg(event.getPlayer(), ChatColor.RED + "You are muted, STFU! - You will be unmuted in 5 minutes."); + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) + { + + Player player = event.getPlayer(); + FPlayer fPlayer = plugin.pl.getPlayer(event.getPlayer()); + + // Block commands if player is muted + if (!fPlayer.isMuted()) + { + return; + } + + String message = event.getMessage(); + if (plugin.al.isAdmin(player)) + { + fPlayer.setMuted(false); + return; + } + + String cmdName = message.split(" ")[0].toLowerCase(); + if (cmdName.startsWith("/")) + { + cmdName = cmdName.substring(1); + } + + Command command = server.getPluginCommand(cmdName); + if (command != null) + { + cmdName = command.getName().toLowerCase(); + } + + if (MUTE_COMMANDS.contains(cmdName)) + { + player.sendMessage(ChatColor.RED + "That command is blocked while you are muted."); + event.setCancelled(true); + return; + } + + // TODO: Should this go here? + if (ConfigEntry.ENABLE_PREPROCESS_LOG.getBoolean()) + { + FLog.info(String.format("[PREPROCESS_COMMAND] %s(%s): %s", player.getName(), ChatColor.stripColor(player.getDisplayName()), message), true); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Orbiter.java b/src/main/java/me/totalfreedom/totalfreedommod/Orbiter.java new file mode 100644 index 000000000..fee5e8b78 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/Orbiter.java @@ -0,0 +1,46 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +public class Orbiter extends FreedomService +{ + + public Orbiter(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerMove(PlayerMoveEvent event) + { + + final Player player = event.getPlayer(); + final FPlayer fPlayer = plugin.pl.getPlayer(player); + + if (!fPlayer.isOrbiting()) + { + return; + } + + if (player.getVelocity().length() < fPlayer.orbitStrength() * (2.0 / 3.0)) + { + player.setVelocity(new Vector(0, fPlayer.orbitStrength(), 0)); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/PVPBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/PVPBlocker.java new file mode 100644 index 000000000..8ea90b803 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/PVPBlocker.java @@ -0,0 +1,85 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FSync; +import org.bukkit.ChatColor; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.projectiles.ProjectileSource; + +public class PVPBlocker extends FreedomService +{ + + public PVPBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.LOW) + public void EntityDamageByEntityEvent(EntityDamageByEntityEvent event) + { + FPlayer fPlayer = null; + + if (event.getDamager() instanceof Player) + { + fPlayer = plugin.pl.getPlayerSync((Player) event.getDamager()); + } + else if (event.getDamager() instanceof Arrow) + { + ProjectileSource ps = ((Arrow) event.getDamager()).getShooter(); + + if (ps instanceof Player) + { + fPlayer = plugin.pl.getPlayerSync((Player) ps); + } + else + { + return; + } + } + + if (fPlayer == null) + { + return; + } + + if (!fPlayer.isPVPBlock()) + { + return; + } + + if (plugin.al.isAdminSync(event.getDamager())) + { + fPlayer.setPVPBlock(false); + return; + } + + Entity p = event.getEntity(); + Entity offense = event.getDamager(); + if (p instanceof Player) + { + event.setCancelled(true); + } + if (offense instanceof Player) + { + event.setCancelled(true); + FSync.playerMsg((Player) event.getDamager(), ChatColor.RED + "Your PVP mode is blocked!"); + event.setCancelled(true); + event.isCancelled(); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ProtectArea.java b/src/main/java/me/totalfreedom/totalfreedommod/ProtectArea.java new file mode 100644 index 000000000..1fca6a99b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/ProtectArea.java @@ -0,0 +1,397 @@ +package me.totalfreedom.totalfreedommod; + +import com.google.common.collect.Maps; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.util.Vector; + +public class ProtectArea extends FreedomService +{ + + public static final String DATA_FILENAME = "protectedareas.dat"; + public static final double MAX_RADIUS = 50.0; + // + private final Map areas = Maps.newHashMap(); + + public ProtectArea(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean()) + { + return; + } + + File input = new File(plugin.getDataFolder(), DATA_FILENAME); + try + { + if (input.exists()) + { + FileInputStream fis = new FileInputStream(input); + ObjectInputStream ois = new ObjectInputStream(fis); + areas.clear(); + areas.putAll((HashMap) ois.readObject()); + ois.close(); + fis.close(); + } + } + catch (Exception ex) + { + input.delete(); + FLog.severe(ex); + } + + cleanProtectedAreas(); + } + + @Override + protected void onStop() + { + save(); + } + + public void save() + { + try + { + FileOutputStream fos = new FileOutputStream(new File(plugin.getDataFolder(), DATA_FILENAME)); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(areas); + oos.close(); + fos.close(); + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onBlockBreak(BlockBreakEvent event) + { + if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean()) + { + return; + } + + final Player player = event.getPlayer(); + if (plugin.al.isAdmin(player)) + { + return; + } + + final Location location = event.getBlock().getLocation(); + + if (isInProtectedArea(location)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onBlockPlace(BlockPlaceEvent event) + { + if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean()) + { + return; + } + + final Player player = event.getPlayer(); + if (plugin.al.isAdmin(player)) + { + return; + } + + final Location location = event.getBlock().getLocation(); + + if (isInProtectedArea(location)) + { + event.setCancelled(true); + } + } + + public boolean isInProtectedArea(final Location modifyLocation) + { + boolean doSave = false; + boolean inProtectedArea = false; + + final Iterator> it = areas.entrySet().iterator(); + + while (it.hasNext()) + { + final SerializableProtectedRegion region = it.next().getValue(); + + Location regionCenter = null; + try + { + regionCenter = region.getLocation(); + } + catch (SerializableProtectedRegion.CantFindWorldException ex) + { + it.remove(); + doSave = true; + continue; + } + + if (regionCenter != null) + { + if (modifyLocation.getWorld() == regionCenter.getWorld()) + { + final double regionRadius = region.getRadius(); + if (modifyLocation.distanceSquared(regionCenter) <= (regionRadius * regionRadius)) + { + inProtectedArea = true; + break; + } + } + } + } + + if (doSave) + { + save(); + } + + return inProtectedArea; + } + + public boolean isInProtectedArea(final Vector min, final Vector max, final String worldName) + { + boolean doSave = false; + boolean inProtectedArea = false; + + final Iterator> it = areas.entrySet().iterator(); + + while (it.hasNext()) + { + final SerializableProtectedRegion region = it.next().getValue(); + + Location regionCenter = null; + try + { + regionCenter = region.getLocation(); + } + catch (SerializableProtectedRegion.CantFindWorldException ex) + { + it.remove(); + doSave = true; + continue; + } + + if (regionCenter != null) + { + if (worldName.equals(regionCenter.getWorld().getName())) + { + if (cubeIntersectsSphere(min, max, regionCenter.toVector(), region.getRadius())) + { + inProtectedArea = true; + break; + } + } + } + } + + if (doSave) + { + save(); + } + + return inProtectedArea; + } + + private boolean cubeIntersectsSphere(Vector min, Vector max, Vector sphere, double radius) + { + double d = square(radius); + + if (sphere.getX() < min.getX()) + { + d -= square(sphere.getX() - min.getX()); + } + else if (sphere.getX() > max.getX()) + { + d -= square(sphere.getX() - max.getX()); + } + if (sphere.getY() < min.getY()) + { + d -= square(sphere.getY() - min.getY()); + } + else if (sphere.getY() > max.getY()) + { + d -= square(sphere.getY() - max.getY()); + } + if (sphere.getZ() < min.getZ()) + { + d -= square(sphere.getZ() - min.getZ()); + } + else if (sphere.getZ() > max.getZ()) + { + d -= square(sphere.getZ() - max.getZ()); + } + + return d > 0; + } + + private double square(double v) + { + return v * v; + } + + public void addProtectedArea(String label, Location location, double radius) + { + areas.put(label.toLowerCase(), new SerializableProtectedRegion(location, radius)); + save(); + } + + public void removeProtectedArea(String label) + { + areas.remove(label.toLowerCase()); + save(); + } + + public void clearProtectedAreas() + { + clearProtectedAreas(true); + } + + public void clearProtectedAreas(boolean createSpawnpointProtectedAreas) + { + areas.clear(); + + if (createSpawnpointProtectedAreas) + { + autoAddSpawnpoints(); + } + + save(); + } + + public void cleanProtectedAreas() + { + boolean doSave = false; + + final Iterator> it = areas.entrySet().iterator(); + + while (it.hasNext()) + { + try + { + it.next().getValue().getLocation(); + } + catch (SerializableProtectedRegion.CantFindWorldException ex) + { + it.remove(); + doSave = true; + } + } + + if (doSave) + { + save(); + } + } + + public Set getProtectedAreaLabels() + { + return areas.keySet(); + } + + public void autoAddSpawnpoints() + { + if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean()) + { + return; + } + + if (ConfigEntry.PROTECTAREA_SPAWNPOINTS.getBoolean()) + { + for (World world : Bukkit.getWorlds()) + { + addProtectedArea("spawn_" + world.getName(), world.getSpawnLocation(), ConfigEntry.PROTECTAREA_RADIUS.getDouble()); + } + } + } + + public static class SerializableProtectedRegion implements Serializable + { + + private static final long serialVersionUID = 213123517828282L; + private final double x, y, z; + private final double radius; + private final String worldName; + private final UUID worldUUID; + private transient Location location = null; + + public SerializableProtectedRegion(final Location location, final double radius) + { + this.x = location.getX(); + this.y = location.getY(); + this.z = location.getZ(); + this.radius = radius; + this.worldName = location.getWorld().getName(); + this.worldUUID = location.getWorld().getUID(); + this.location = location; + } + + public Location getLocation() throws CantFindWorldException + { + if (this.location == null) + { + World world = Bukkit.getWorld(this.worldUUID); + + if (world == null) + { + world = Bukkit.getWorld(this.worldName); + } + + if (world == null) + { + throw new CantFindWorldException("Can't find world " + this.worldName + ", UUID: " + this.worldUUID.toString()); + } + + location = new Location(world, x, y, z); + } + return this.location; + } + + public double getRadius() + { + return radius; + } + + public class CantFindWorldException extends Exception + { + + private static final long serialVersionUID = 1L; + + public CantFindWorldException(String string) + { + super(string); + } + } + + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/SavedFlags.java b/src/main/java/me/totalfreedom/totalfreedommod/SavedFlags.java new file mode 100644 index 000000000..5be2065c0 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/SavedFlags.java @@ -0,0 +1,105 @@ +package me.totalfreedom.totalfreedommod; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.Map; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import static me.totalfreedom.totalfreedommod.util.FUtil.SAVED_FLAGS_FILENAME; + +public class SavedFlags extends FreedomService +{ + + public SavedFlags(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @SuppressWarnings("unchecked") + public Map getSavedFlags() + { + Map flags = null; + + File input = new File(TotalFreedomMod.plugin().getDataFolder(), SAVED_FLAGS_FILENAME); + if (input.exists()) + { + try + { + try (FileInputStream fis = new FileInputStream(input); ObjectInputStream ois = new ObjectInputStream(fis)) + { + flags = (HashMap) ois.readObject(); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + return flags; + } + + public boolean getSavedFlag(String flag) throws Exception + { + Boolean flagValue = null; + + Map flags = getSavedFlags(); + + if (flags != null) + { + if (flags.containsKey(flag)) + { + flagValue = flags.get(flag); + } + } + + if (flagValue != null) + { + return flagValue; + } + else + { + throw new Exception(); + } + } + + public void setSavedFlag(String flag, boolean value) + { + Map flags = getSavedFlags(); + + if (flags == null) + { + flags = new HashMap<>(); + } + + flags.put(flag, value); + + try + { + final FileOutputStream fos = new FileOutputStream(new File(plugin.getDataFolder(), SAVED_FLAGS_FILENAME)); + final ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(flags); + oos.close(); + fos.close(); + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java new file mode 100644 index 000000000..9979d2a93 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/ServerInterface.java @@ -0,0 +1,92 @@ +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.v1_10_R1.EntityPlayer; +import net.minecraft.server.v1_10_R1.MinecraftServer; +import net.minecraft.server.v1_10_R1.PropertyManager; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_10_R1.CraftServer; + +public class ServerInterface extends FreedomService +{ + + public static final String COMPILE_NMS_VERSION = "v1_10_R1"; + + public ServerInterface(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + 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!"); + } + } + + public void setOnlineMode(boolean mode) + { + final PropertyManager manager = getServer().getPropertyManager(); + manager.setProperty("online-mode", mode); + manager.savePropertiesFile(); + } + + public int purgeWhitelist() + { + String[] whitelisted = getServer().getPlayerList().getWhitelisted(); + int size = whitelisted.length; + for (EntityPlayer player : getServer().getPlayerList().players) + { + 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 new file mode 100644 index 000000000..1c5008381 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/ServerPing.java @@ -0,0 +1,78 @@ +package me.totalfreedom.totalfreedommod; + +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.server.ServerListPingEvent; + +public class ServerPing extends FreedomService +{ + + public ServerPing(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGH) + public void onServerPing(ServerListPingEvent event) + { + final String ip = event.getAddress().getHostAddress().trim(); + + if (plugin.bm.isIpBanned(ip)) + { + event.setMotd(ChatColor.RED + "You are banned."); + return; + } + + if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) + { + event.setMotd(ChatColor.RED + "Server is closed."); + return; + } + + if (Bukkit.hasWhitelist()) + { + event.setMotd(ChatColor.RED + "Whitelist enabled."); + return; + } + + if (Bukkit.getOnlinePlayers().size() >= Bukkit.getMaxPlayers()) + { + event.setMotd(ChatColor.RED + "Server is full."); + return; + } + + String baseMotd = ConfigEntry.SERVER_MOTD.getString().replace("%mcversion%", plugin.si.getVersion()); + baseMotd = baseMotd.replace("\\n", "\n"); + baseMotd = FUtil.colorize(baseMotd); + + if (!ConfigEntry.SERVER_COLORFUL_MOTD.getBoolean()) + { + event.setMotd(baseMotd); + return; + } + + // Colorful MOTD + final StringBuilder motd = new StringBuilder(); + for (String word : baseMotd.split(" ")) + { + motd.append(FUtil.randomChatColor()).append(word).append(" "); + } + + event.setMotd(motd.toString().trim()); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java new file mode 100644 index 000000000..dcdce16e2 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java @@ -0,0 +1,309 @@ +package me.totalfreedom.totalfreedommod; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import me.totalfreedom.totalfreedommod.admin.AdminList; +import me.totalfreedom.totalfreedommod.banning.BanManager; +import me.totalfreedom.totalfreedommod.banning.PermbanList; +import me.totalfreedom.totalfreedommod.blocking.BlockBlocker; +import me.totalfreedom.totalfreedommod.blocking.EventBlocker; +import me.totalfreedom.totalfreedommod.blocking.InteractBlocker; +import me.totalfreedom.totalfreedommod.blocking.MobBlocker; +import me.totalfreedom.totalfreedommod.blocking.PotionBlocker; +import me.totalfreedom.totalfreedommod.blocking.command.CommandBlocker; +import me.totalfreedom.totalfreedommod.bridge.BukkitTelnetBridge; +import me.totalfreedom.totalfreedommod.bridge.EssentialsBridge; +import me.totalfreedom.totalfreedommod.bridge.LibsDisguisesBridge; +import me.totalfreedom.totalfreedommod.bridge.WorldEditBridge; +import me.totalfreedom.totalfreedommod.caging.Cager; +import me.totalfreedom.totalfreedommod.command.CommandLoader; +import me.totalfreedom.totalfreedommod.config.MainConfig; +import me.totalfreedom.totalfreedommod.freeze.Freezer; +import me.totalfreedom.totalfreedommod.fun.ItemFun; +import me.totalfreedom.totalfreedommod.fun.Jumppads; +import me.totalfreedom.totalfreedommod.fun.Landminer; +import me.totalfreedom.totalfreedommod.fun.MP44; +import me.totalfreedom.totalfreedommod.fun.Trailer; +import me.totalfreedom.totalfreedommod.httpd.HTTPDaemon; +import me.totalfreedom.totalfreedommod.player.PlayerList; +import me.totalfreedom.totalfreedommod.rank.RankManager; +import me.totalfreedom.totalfreedommod.rollback.RollbackManager; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import me.totalfreedom.totalfreedommod.util.MethodTimer; +import me.totalfreedom.totalfreedommod.world.WorldManager; +import net.pravian.aero.component.service.ServiceManager; +import net.pravian.aero.plugin.AeroPlugin; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.mcstats.Metrics; + +public class TotalFreedomMod extends AeroPlugin +{ + + public static final String CONFIG_FILENAME = "config.yml"; + // + public static final BuildProperties build = new BuildProperties(); + // + public static String pluginName; + public static String pluginVersion; + // + public MainConfig config; + // + // Services + public ServiceManager services; + public ServerInterface si; + public SavedFlags sf; + public WorldManager wm; + public LogViewer lv; + public AdminList al; + public RankManager rm; + public CommandLoader cl; + public CommandBlocker cb; + public EventBlocker eb; + public BlockBlocker bb; + public MobBlocker mb; + public InteractBlocker ib; + public PotionBlocker pb; + //public AntiExploit aex; + public LoginProcess lp; + public AntiNuke nu; + public AntiClick nc; + public AntiSpam as; + public PlayerList pl; + public Announcer an; + public ChatManager cm; + public BanManager bm; + public PermbanList pm; + public ProtectArea pa; + public GameRuleHandler gr; + public RollbackManager rb; + public CommandSpy cs; + public Cager ca; + public Freezer fm; + public Orbiter or; + public Muter mu; + public Editblocker bemu; + public PVPBlocker nopvp; + public Fuckoff fo; + public AutoKick ak; + public AutoEject ae; + public MovementValidator mv; + public EntityWiper ew; + public FrontDoor fd; + public ServerPing sp; + public ItemFun it; + public Landminer lm; + public MP44 mp; + public Jumppads jp; + public Trailer tr; + public HTTPDaemon hd; + // + // Bridges + public ServiceManager bridges; + public BukkitTelnetBridge btb; + public EssentialsBridge esb; + public LibsDisguisesBridge ldb; + public WorldEditBridge web; + + @Override + public void load() + { + TotalFreedomMod.pluginName = plugin.getDescription().getName(); + TotalFreedomMod.pluginVersion = plugin.getDescription().getVersion(); + + FLog.setPluginLogger(plugin.getLogger()); + FLog.setServerLogger(server.getLogger()); + + build.load(plugin); + } + + @Override + public void enable() + { + FLog.info("Created by Madgeek1450 and Prozza"); + FLog.info("Version " + build.formattedVersion()); + FLog.info("Compiled " + build.date + " by " + build.author); + + 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")); + + // Convert old config files + new ConfigConverter(plugin).convert(); + + BackupManager backups = new BackupManager(this); + backups.createBackups(TotalFreedomMod.CONFIG_FILENAME, true); + backups.createBackups(AdminList.CONFIG_FILENAME); + backups.createBackups(PermbanList.CONFIG_FILENAME); + + config = new MainConfig(this); + config.load(); + + // Start services + services = new ServiceManager<>(plugin); + si = services.registerService(ServerInterface.class); + sf = services.registerService(SavedFlags.class); + wm = services.registerService(WorldManager.class); + lv = services.registerService(LogViewer.class); + al = services.registerService(AdminList.class); + rm = services.registerService(RankManager.class); + cl = services.registerService(CommandLoader.class); + cb = services.registerService(CommandBlocker.class); + eb = services.registerService(EventBlocker.class); + bb = services.registerService(BlockBlocker.class); + mb = services.registerService(MobBlocker.class); + ib = services.registerService(InteractBlocker.class); + pb = services.registerService(PotionBlocker.class); + lp = services.registerService(LoginProcess.class); + nu = services.registerService(AntiNuke.class); + nc = services.registerService(AntiClick.class); + as = services.registerService(AntiSpam.class); + + pl = services.registerService(PlayerList.class); + an = services.registerService(Announcer.class); + cm = services.registerService(ChatManager.class); + bm = services.registerService(BanManager.class); + pm = services.registerService(PermbanList.class); + pa = services.registerService(ProtectArea.class); + gr = services.registerService(GameRuleHandler.class); + + // Single admin utils + rb = services.registerService(RollbackManager.class); + cs = services.registerService(CommandSpy.class); + ca = services.registerService(Cager.class); + fm = services.registerService(Freezer.class); + or = services.registerService(Orbiter.class); + mu = services.registerService(Muter.class); + bemu = services.registerService(Editblocker.class); + nopvp = services.registerService(PVPBlocker.class); + fo = services.registerService(Fuckoff.class); + ak = services.registerService(AutoKick.class); + ae = services.registerService(AutoEject.class); + + mv = services.registerService(MovementValidator.class); + ew = services.registerService(EntityWiper.class); + fd = services.registerService(FrontDoor.class); + //aex = services.registerService(AntiExploit.class); + sp = services.registerService(ServerPing.class); + + // Fun + it = services.registerService(ItemFun.class); + lm = services.registerService(Landminer.class); + mp = services.registerService(MP44.class); + jp = services.registerService(Jumppads.class); + tr = services.registerService(Trailer.class); + + // HTTPD + hd = services.registerService(HTTPDaemon.class); + services.start(); + + // Start bridges + bridges = new ServiceManager<>(plugin); + btb = bridges.registerService(BukkitTelnetBridge.class); + esb = bridges.registerService(EssentialsBridge.class); + ldb = bridges.registerService(LibsDisguisesBridge.class); + web = bridges.registerService(WorldEditBridge.class); + bridges.start(); + // ProtocolLibrary.getProtocolManager().addPacketListener(new AntiCreativeExploit(this)); + // ProtocolLibrary.getProtocolManager().addPacketListener(new AntiItemExploit(this)); + timer.update(); + FLog.info("Version " + pluginVersion + " for " + ServerInterface.COMPILE_NMS_VERSION + " enabled in " + timer.getTotal() + "ms"); + + // Metrics @ http://mcstats.org/plugin/TotalFreedomMod + try + { + final Metrics metrics = new Metrics(plugin); + metrics.start(); + } + catch (IOException ex) + { + FLog.warning("Failed to submit metrics data: " + ex.getMessage()); + } + + // Add spawnpoints later - https://github.com/TotalFreedom/TotalFreedomMod/issues/438 + new BukkitRunnable() + { + @Override + public void run() + { + plugin.pa.autoAddSpawnpoints(); + } + }.runTaskLater(plugin, 60L); + } + + @Override + public void disable() + { + // Stop services and bridges + bridges.stop(); + services.stop(); + + server.getScheduler().cancelTasks(plugin); + + FLog.info("Plugin disabled"); + } + + public static class BuildProperties + { + + public String author; + public String codename; + public String version; + public String number; + public String date; + public String head; + + public void load(TotalFreedomMod plugin) + { + try + { + final Properties props; + try (InputStream in = plugin.getResource("build.properties")) + { + props = new Properties(); + props.load(in); + } + + author = props.getProperty("program.build.author", "unknown"); + codename = props.getProperty("program.build.codename", "unknown"); + version = props.getProperty("program.build.version", "unknown"); + number = props.getProperty("program.build.number", "1"); + date = props.getProperty("program.build.date", "unknown"); + head = props.getProperty("program.build.head", "unknown"); + } + catch (Exception ex) + { + FLog.severe("Could not load build properties! Did you compile with Netbeans/ANT?"); + FLog.severe(ex); + } + } + + public String formattedVersion() + { + return pluginVersion + "." + number + " (" + head + ")"; + } + } + + public static TotalFreedomMod plugin() + { + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) + { + if (plugin.getName().equalsIgnoreCase(pluginName)) + { + return (TotalFreedomMod) plugin; + } + } + return null; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java new file mode 100644 index 000000000..01771c4a6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java @@ -0,0 +1,180 @@ +package me.totalfreedom.totalfreedommod.admin; + +import com.google.common.collect.Lists; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import me.totalfreedom.bukkittelnet.BukkitTelnet; +import me.totalfreedom.bukkittelnet.session.ClientSession; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.base.ConfigLoadable; +import net.pravian.aero.base.ConfigSavable; +import net.pravian.aero.base.Validatable; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +public class Admin implements ConfigLoadable, ConfigSavable, Validatable +{ + + @Getter + private String configKey; + @Getter + @Setter + private String name; + @Getter + private boolean active = true; + @Getter + @Setter + private Rank rank = Rank.SUPER_ADMIN; + @Getter + private final List ips = Lists.newArrayList(); + @Getter + @Setter + private Date lastLogin = new Date(); + @Getter + @Setter + private String loginMessage = null; + + public Admin(Player player) + { + this.configKey = player.getName().toLowerCase(); + this.name = player.getName(); + this.ips.add(Ips.getIp(player)); + } + + public Admin(String configKey) + { + this.configKey = configKey; + } + + @Override + public String toString() + { + final StringBuilder output = new StringBuilder(); + + output.append("Admin: ").append(name).append("\n") + .append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n") + .append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n") + .append("- Custom Login Message: ").append(loginMessage).append("\n") + .append("- Rank: ").append(rank.getName()).append("\n") + .append("- Is Active: ").append(active); + + return output.toString(); + } + + public void loadFrom(Player player) + { + configKey = player.getName().toLowerCase(); + name = player.getName(); + ips.clear(); + ips.add(Ips.getIp(player)); + } + + @Override + public void loadFrom(ConfigurationSection cs) + { + name = cs.getString("username", configKey); + active = cs.getBoolean("active", true); + rank = Rank.findRank(cs.getString("rank")); + ips.clear(); + ips.addAll(cs.getStringList("ips")); + lastLogin = FUtil.stringToDate(cs.getString("last_login")); + loginMessage = cs.getString("login_message", null); + } + + @Override + public void saveTo(ConfigurationSection cs) + { + Validate.isTrue(isValid(), "Could not save admin entry: " + name + ". Entry not valid!"); + cs.set("username", name); + cs.set("active", active); + cs.set("rank", rank.toString()); + cs.set("ips", Lists.newArrayList(ips)); + cs.set("last_login", FUtil.dateToString(lastLogin)); + cs.set("login_message", loginMessage); + } + + public boolean isAtLeast(Rank pRank) + { + return rank.isAtLeast(pRank); + } + + public boolean hasLoginMessage() + { + return loginMessage != null && !loginMessage.isEmpty(); + } + + // Util IP methods + public void addIp(String ip) + { + if (!ips.contains(ip)) + { + ips.add(ip); + } + } + + public void addIps(List ips) + { + for (String ip : ips) + { + addIp(ip); + } + } + + public void removeIp(String ip) + { + if (ips.contains(ip)) + { + ips.remove(ip); + } + } + + public void clearIPs() + { + ips.clear(); + } + + public void setActive(boolean active) + { + this.active = active; + if (getRank().isAtLeast(Rank.TELNET_ADMIN) && active == false) + { + BukkitTelnet telnet = TotalFreedomMod.plugin().btb.getBukkitTelnetPlugin(); + Set allSessions = telnet.appender.getSessions(); + Iterator allSessionsIterator = allSessions.iterator(); + if ((!allSessions.isEmpty())) + { + while (allSessionsIterator.hasNext()) + { + ClientSession session = allSessionsIterator.next(); + if (session.getUserName().equalsIgnoreCase(getName())) + { + ClientSession removedSession = session; + telnet.appender.removeSession(removedSession); + removedSession.syncTerminateSession(); + FLog.info("1 telnet admin session removed."); + } + } + } + } + } + + @Override + public boolean isValid() + { + return configKey != null + && name != null + && rank != null + && !ips.isEmpty() + && lastLogin != null; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java new file mode 100644 index 000000000..7f5bb9fce --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java @@ -0,0 +1,376 @@ +package me.totalfreedom.totalfreedommod.admin; + +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import lombok.Getter; +import me.totalfreedom.bukkittelnet.BukkitTelnet; +import me.totalfreedom.bukkittelnet.session.ClientSession; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.config.YamlConfig; +import net.pravian.aero.util.Ips; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.plugin.ServicePriority; + +public class AdminList extends FreedomService +{ + + public static final String CONFIG_FILENAME = "admins.yml"; + + @Getter + private final Map allAdmins = Maps.newHashMap(); // Includes disabled admins + // Only active admins below + @Getter + private final Set activeAdmins = Sets.newHashSet(); + private final Map nameTable = Maps.newHashMap(); + private final Map ipTable = Maps.newHashMap(); + // + private final YamlConfig config; + + public AdminList(TotalFreedomMod plugin) + { + super(plugin); + + this.config = new YamlConfig(plugin, CONFIG_FILENAME, true); + } + + @Override + protected void onStart() + { + load(); + + server.getServicesManager().register(Function.class, new Function() + { + @Override + public Boolean apply(Player player) + { + return isAdmin(player); + } + }, plugin, ServicePriority.Normal); + + deactivateOldEntries(false); + } + + @Override + protected void onStop() + { + save(); + } + + public void load() + { + config.load(); + + allAdmins.clear(); + for (String key : config.getKeys(false)) + { + ConfigurationSection section = config.getConfigurationSection(key); + if (section == null) + { + logger.warning("Invalid admin list format: " + key); + continue; + } + + Admin admin = new Admin(key); + admin.loadFrom(section); + + if (!admin.isValid()) + { + FLog.warning("Could not load admin: " + key + ". Missing details!"); + continue; + } + + allAdmins.put(key, admin); + } + + updateTables(); + FLog.info("Loaded " + allAdmins.size() + " admins (" + nameTable.size() + " active, " + ipTable.size() + " IPs)"); + } + + public void save() + { + // Clear the config + for (String key : config.getKeys(false)) + { + config.set(key, null); + } + + for (Admin admin : allAdmins.values()) + { + admin.saveTo(config.createSection(admin.getConfigKey())); + } + + config.save(); + } + + public synchronized boolean isAdminSync(CommandSender sender) + { + return isAdmin(sender); + } + + public boolean isAdmin(CommandSender sender) + { + if (!(sender instanceof Player)) + { + return true; + } + + Admin admin = getAdmin((Player) sender); + + return admin != null && admin.isActive(); + } + + public boolean isSeniorAdmin(CommandSender sender) + { + Admin admin = getAdmin(sender); + if (admin == null) + { + return false; + } + + return admin.getRank().ordinal() >= Rank.SENIOR_ADMIN.ordinal(); + } + + public Admin getAdmin(CommandSender sender) + { + if (sender instanceof Player) + { + return getAdmin((Player) sender); + } + + return getEntryByName(sender.getName()); + } + + public Admin getAdmin(Player player) + { + // Find admin + String ip = Ips.getIp(player); + Admin admin = getEntryByName(player.getName()); + + // Admin by name + if (admin != null) + { + // 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(); + updateTables(); + } + return admin; + } + + // Impostor + } + + // Admin by ip + admin = getEntryByIp(ip); + if (admin != null) + { + // Set the new username + admin.setName(player.getName()); + save(); + updateTables(); + } + + return null; + } + + public Admin getEntryByName(String name) + { + return nameTable.get(name.toLowerCase()); + } + + public Admin getEntryByIp(String ip) + { + 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); + if (admin == null) + { + return; + } + + admin.setLastLogin(new Date()); + admin.setName(player.getName()); + save(); + } + + public boolean isAdminImpostor(Player player) + { + return getEntryByName(player.getName()) != null && !isAdmin(player); + } + + public boolean isIdentityMatched(Player player) + { + if (Bukkit.getOnlineMode()) + { + return true; + } + + Admin admin = getAdmin(player); + return admin == null ? false : admin.getName().equalsIgnoreCase(player.getName()); + } + + public boolean addAdmin(Admin admin) + { + if (!admin.isValid()) + { + logger.warning("Could not add admin: " + admin.getConfigKey() + " Admin is missing details!"); + return false; + } + + final String key = admin.getConfigKey(); + + // Store admin, update views + allAdmins.put(key, admin); + updateTables(); + + // Save admin + admin.saveTo(config.createSection(key)); + config.save(); + + return true; + } + + public boolean removeAdmin(Admin admin) + { + if (admin.getRank().isAtLeast(Rank.TELNET_ADMIN)) + { + BukkitTelnet telnet = plugin.btb.getBukkitTelnetPlugin(); + Set allSessions = telnet.appender.getSessions(); + Iterator allSessionsIterator = allSessions.iterator(); + if ((!allSessions.isEmpty())) + { + while (allSessionsIterator.hasNext()) + { + ClientSession session = allSessionsIterator.next(); + if (session.getUserName().equalsIgnoreCase(admin.getName())) + { + ClientSession removedSession = session; + telnet.appender.removeSession(removedSession); + removedSession.syncTerminateSession(); + FLog.info("1 telnet admin session removed."); + } + } + } + } + // Remove admin, update views + if (allAdmins.remove(admin.getConfigKey()) == null) + { + return false; + } + updateTables(); + + // 'Unsave' admin + config.set(admin.getConfigKey(), null); + config.save(); + + return true; + } + + public void updateTables() + { + activeAdmins.clear(); + nameTable.clear(); + ipTable.clear(); + + for (Admin admin : allAdmins.values()) + { + if (!admin.isActive()) + { + continue; + } + + activeAdmins.add(admin); + nameTable.put(admin.getName().toLowerCase(), admin); + + for (String ip : admin.getIps()) + { + ipTable.put(ip, admin); + } + + } + + plugin.wm.adminworld.wipeAccessCache(); + } + + public Set getAdminNames() + { + return nameTable.keySet(); + } + + public Set getAdminIps() + { + return ipTable.keySet(); + } + + public void deactivateOldEntries(boolean verbose) + { + for (Admin admin : allAdmins.values()) + { + if (!admin.isActive() || admin.getRank().isAtLeast(Rank.SENIOR_ADMIN)) + { + continue; + } + + final Date lastLogin = admin.getLastLogin(); + final long lastLoginHours = TimeUnit.HOURS.convert(new Date().getTime() - lastLogin.getTime(), TimeUnit.MILLISECONDS); + + if (lastLoginHours < ConfigEntry.ADMINLIST_CLEAN_THESHOLD_HOURS.getInteger()) + { + continue; + } + + if (verbose) + { + FUtil.adminAction("TotalFreedomMod", "Deactivating superadmin " + admin.getName() + ", inactive for " + lastLoginHours + " hours", true); + } + + admin.setActive(false); + plugin.lv.deactivateSuperadmin(admin); + } + + save(); + updateTables(); + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/banning/Ban.java b/src/main/java/me/totalfreedom/totalfreedommod/banning/Ban.java new file mode 100644 index 000000000..3d22a3ae0 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/banning/Ban.java @@ -0,0 +1,279 @@ +package me.totalfreedom.totalfreedommod.banning; + +import com.google.common.collect.Lists; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.base.ConfigLoadable; +import net.pravian.aero.base.ConfigSavable; +import net.pravian.aero.base.Validatable; +import net.pravian.aero.util.Ips; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +public class Ban implements ConfigLoadable, ConfigSavable, Validatable +{ + + public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z"); + + @Getter + @Setter + private String username = null; + @Getter + private final List ips = Lists.newArrayList(); + @Getter + @Setter + private String by = null; + @Getter + @Setter + private String reason = null; // Unformatted, &[0-9,a-f] instead of ChatColor + @Getter + @Setter + private long expiryUnix = -1; + + public Ban() + { + } + + public Ban(String username, String ip, String by, Date expire, String reason) + { + this(username, + new String[] + { + ip + }, + by, + expire, + reason); + } + + public Ban(String username, String[] ips, String by, Date expire, String reason) + { + this.username = username; + if (ips != null) + { + this.ips.addAll(Arrays.asList(ips)); + } + dedupeIps(); + this.by = by; + this.expiryUnix = FUtil.getUnixTime(expire); + this.reason = reason; + } + + // + // For player IP + public static Ban forPlayerIp(Player player, CommandSender by) + { + return forPlayerIp(player, by, null, null); + } + + public static Ban forPlayerIp(Player player, CommandSender by, Date expiry, String reason) + { + return new Ban(null, new String[] + { + Ips.getIp(player) + }, by.getName(), expiry, reason); + } + + public static Ban forPlayerIp(String ip, CommandSender by, Date expiry, String reason) + { + return new Ban(null, ip, by.getName(), expiry, reason); + } + + // + // For player name + public static Ban forPlayerName(Player player, CommandSender by, Date expiry, String reason) + { + return forPlayerName(player.getName(), by, expiry, reason); + } + + public static Ban forPlayerName(String player, CommandSender by, Date expiry, String reason) + { + return new Ban(player, + (String[]) null, + by.getName(), + expiry, + reason); + } + + // + // For player + public static Ban forPlayer(Player player, CommandSender by) + { + return forPlayerName(player, by, null, null); + } + + public static Ban forPlayer(Player player, CommandSender by, Date expiry, String reason) + { + return new Ban(player.getName(), + Ips.getIp(player), + by.getName(), + expiry, + reason); + } + + public static Ban forPlayerFuzzy(Player player, CommandSender by, Date expiry, String reason) + { + return new Ban(player.getName(), + FUtil.getFuzzyIp(Ips.getIp(player)), + by.getName(), + expiry, + reason); + } + + public boolean hasUsername() + { + return username != null && !username.isEmpty(); + } + + public boolean addIp(String ip) + { + return ips.add(ip); + } + + public boolean removeIp(String ip) + { + return ips.remove(ip); + } + + public boolean hasIps() + { + return !ips.isEmpty(); + } + + public boolean hasExpiry() + { + return expiryUnix > 0; + } + + public Date getExpiryDate() + { + return FUtil.getUnixDate(expiryUnix); + } + + public boolean isExpired() + { + return hasExpiry() && expiryUnix < FUtil.getUnixTime(); + } + + public String bakeKickMessage() + { + final StringBuilder message = new StringBuilder(ChatColor.GOLD + "You"); + + message.append(!hasUsername() ? "r IP address is" : " are").append(" temporarily banned from this server."); + message.append("\nAppeal at ").append(ChatColor.BLUE) + .append(ConfigEntry.SERVER_BAN_URL.getString()); + + if (reason != null) + { + message.append("\n").append(ChatColor.RED).append("Reason: ").append(ChatColor.GOLD) + .append(ChatColor.translateAlternateColorCodes('&', reason)); + } + + if (by != null) + { + message.append("\n").append(ChatColor.RED).append("Banned by: ").append(ChatColor.GOLD) + .append(by); + } + + if (getExpiryUnix() != 0) + { + message.append("\n").append(ChatColor.RED).append("Expires: ").append(ChatColor.GOLD) + .append(DATE_FORMAT.format(FUtil.getUnixDate(expiryUnix))); + } + + return message.toString(); + } + + @Override + public boolean equals(Object object) + { + if (object == null) + { + return false; + } + + if (!(object instanceof Ban)) + { + return false; + } + + final Ban ban = (Ban) object; + if (hasIps() != ban.hasIps() + || hasUsername() != hasUsername()) + { + return false; + } + + if (hasIps() && !(getIps().equals(ban.getIps()))) + { + return false; + } + + return !(hasUsername() && !(getUsername().equalsIgnoreCase(ban.getUsername()))); + } + + @Override + public int hashCode() + { + int hash = 7; + hash = 79 * hash + (this.username != null ? this.username.toLowerCase().hashCode() : 0); + hash = 79 * hash + (this.ips != null ? this.ips.hashCode() : 0); + return hash; + } + + @Override + public void loadFrom(ConfigurationSection cs) + { + this.username = cs.getString("username", null); + this.ips.clear(); + this.ips.addAll(cs.getStringList("ips")); + this.by = cs.getString("by", null); + this.reason = cs.getString("reason", null); + this.expiryUnix = cs.getLong("expiry_unix", 0); + dedupeIps(); + } + + @Override + public void saveTo(ConfigurationSection cs) + { + dedupeIps(); + cs.set("username", username); + cs.set("ips", ips.isEmpty() ? null : ips); + cs.set("by", by); + cs.set("reason", reason); + cs.set("expiry_unix", expiryUnix > 0 ? expiryUnix : null); + } + + @Override + public boolean isValid() + { + return username != null || !ips.isEmpty(); + } + + private void dedupeIps() + { + + Set uniqueIps = new HashSet<>(); + + Iterator it = ips.iterator(); + while (it.hasNext()) + { + if (!uniqueIps.add(it.next())) + { + it.remove(); + } + } + + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java b/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java new file mode 100644 index 000000000..f041bf1ac --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java @@ -0,0 +1,303 @@ +package me.totalfreedom.totalfreedommod.banning; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.PlayerData; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.config.YamlConfig; +import net.pravian.aero.util.Ips; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; + +public class BanManager extends FreedomService +{ + + private final Set bans = Sets.newHashSet(); + private final Map ipBans = Maps.newHashMap(); + private final Map nameBans = Maps.newHashMap(); + private final List unbannableUsernames = Lists.newArrayList(); + public static final String CONFIG_FILENAME = "bans.yml"; + public final YamlConfig config; + + public BanManager(TotalFreedomMod plugin) + { + super(plugin); + this.config = new YamlConfig(plugin, "bans.yml"); + } + + @Override + protected void onStart() + { + config.load(); + + bans.clear(); + for (String id : config.getKeys(false)) + { + if (!config.isConfigurationSection(id)) + { + FLog.warning("Could not load username ban: " + id + ". Invalid format!"); + continue; + } + + Ban ban = new Ban(); + ban.loadFrom(config.getConfigurationSection(id)); + + if (!ban.isValid()) + { + FLog.warning("Not adding username ban: " + id + ". Missing information."); + continue; + } + + bans.add(ban); + } + + // Remove expired bans, repopulate ipBans and nameBans, + updateViews(); + + FLog.info("Loaded " + ipBans.size() + " IP bans and " + nameBans.size() + " username bans."); + + // Load unbannable usernames + unbannableUsernames.clear(); + unbannableUsernames.addAll((Collection) ConfigEntry.FAMOUS_PLAYERS.getList()); + FLog.info("Loaded " + unbannableUsernames.size() + " unbannable usernames."); + } + + @Override + protected void onStop() + { + saveAll(); + logger.info("Saved " + bans.size() + " player bans"); + } + + public Set getAllBans() + { + return Collections.unmodifiableSet(bans); + } + + public Collection getIpBans() + { + return Collections.unmodifiableCollection(ipBans.values()); + } + + public Collection getUsernameBans() + { + return Collections.unmodifiableCollection(nameBans.values()); + } + + public void saveAll() + { + // Remove expired + updateViews(); + + config.clear(); + for (Ban ban : bans) + { + ban.saveTo(config.createSection(String.valueOf(ban.hashCode()))); + } + + // Save config + config.save(); + } + + public Ban getByIp(String ip) + { + final Ban directBan = ipBans.get(ip); + if (directBan != null && !directBan.isExpired()) + { + return directBan; + } + + // Match fuzzy IP + for (Ban loopBan : ipBans.values()) + { + if (loopBan.isExpired()) + { + continue; + } + + for (String loopIp : loopBan.getIps()) + { + if (!loopIp.contains("*")) + { + continue; + } + + if (Ips.fuzzyIpMatch(ip, loopIp, 4)) + { + return loopBan; + } + } + } + + return null; + } + + public Ban getByUsername(String username) + { + username = username.toLowerCase(); + final Ban directBan = nameBans.get(username); + + if (directBan != null && !directBan.isExpired()) + { + return directBan; + } + + return null; + } + + public Ban unbanIp(String ip) + { + final Ban ban = getByIp(ip); + + if (ban != null) + { + bans.remove(ban); + saveAll(); + } + + return ban; + } + + public Ban unbanUsername(String username) + { + final Ban ban = getByUsername(username); + + if (ban != null) + { + bans.remove(ban); + saveAll(); + } + + return ban; + } + + public boolean isIpBanned(String ip) + { + return getByIp(ip) != null; + } + + public boolean isUsernameBanned(String username) + { + return getByUsername(username) != null; + } + + public boolean addBan(Ban ban) + { + if (bans.add(ban)) + { + saveAll(); + return true; + } + + return false; + } + + public boolean removeBan(Ban ban) + { + if (bans.remove(ban)) + { + saveAll(); + return true; + } + + return false; + } + + public int purge() + { + config.clear(); + config.save(); + + int size = bans.size(); + bans.clear(); + updateViews(); + + return size; + } + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerLogin(PlayerLoginEvent event) + { + final String username = event.getPlayer().getName(); + final String ip = Ips.getIp(event); + + // Regular ban + Ban ban = getByUsername(username); + if (ban == null) + { + ban = getByIp(ip); + } + + if (ban != null && !ban.isExpired()) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, ban.bakeKickMessage()); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerJoin(PlayerJoinEvent event) + { + final Player player = event.getPlayer(); + final PlayerData data = plugin.pl.getData(player); + + if (!plugin.al.isAdmin(player)) + { + return; + } + + // Unban admins + for (String storedIp : data.getIps()) + { + unbanIp(storedIp); + unbanIp(FUtil.getFuzzyIp(storedIp)); + } + + unbanUsername(player.getName()); + player.setOp(true); + } + + private void updateViews() + { + // Remove expired bans + for (Iterator it = bans.iterator(); it.hasNext();) + { + if (it.next().isExpired()) + { + it.remove(); + } + } + + nameBans.clear(); + ipBans.clear(); + for (Ban ban : bans) + { + if (ban.hasUsername()) + { + nameBans.put(ban.getUsername().toLowerCase(), ban); + } + + if (ban.hasIps()) + { + for (String ip : ban.getIps()) + { + ipBans.put(ip, ban); + } + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/banning/PermbanList.java b/src/main/java/me/totalfreedom/totalfreedommod/banning/PermbanList.java new file mode 100644 index 000000000..8803d6d24 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/banning/PermbanList.java @@ -0,0 +1,90 @@ +package me.totalfreedom.totalfreedommod.banning; + +import com.google.common.collect.Sets; +import java.util.Set; +import lombok.Getter; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.config.YamlConfig; +import net.pravian.aero.util.Ips; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerLoginEvent; + +public class PermbanList extends FreedomService +{ + + public static final String CONFIG_FILENAME = "permbans.yml"; + + @Getter + private final Set permbannedNames = Sets.newHashSet(); + @Getter + private final Set permbannedIps = Sets.newHashSet(); + + public PermbanList(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + permbannedNames.clear(); + permbannedIps.clear(); + + final YamlConfig config = new YamlConfig(plugin, CONFIG_FILENAME, true); + config.load(); + + for (String name : config.getKeys(false)) + { + permbannedNames.add(name.toLowerCase().trim()); + permbannedIps.addAll(config.getStringList(name)); + } + + FLog.info("Loaded " + permbannedIps.size() + " perm IP bans and " + permbannedNames.size() + " perm username bans."); + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerLogin(PlayerLoginEvent event) + { + final String username = event.getPlayer().getName(); + final String ip = Ips.getIp(event); + + // Permbanned IPs + for (String testIp : getPermbannedIps()) + { + if (FUtil.fuzzyIpMatch(testIp, ip, 4)) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, + ChatColor.RED + "Your IP address is permanently banned from this server.\n" + + "Release procedures are available at\n" + + ChatColor.GOLD + ConfigEntry.SERVER_PERMBAN_URL.getString()); + return; + } + } + + // Permbanned usernames + for (String testPlayer : getPermbannedNames()) + { + if (testPlayer.equalsIgnoreCase(username)) + { + event.disallow(PlayerLoginEvent.Result.KICK_OTHER, + ChatColor.RED + "Your username is permanently banned from this server.\n" + + "Release procedures are available at\n" + + ChatColor.GOLD + ConfigEntry.SERVER_PERMBAN_URL.getString()); + return; + } + } + + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/BlockBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/BlockBlocker.java new file mode 100644 index 000000000..8f6d717a5 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/BlockBlocker.java @@ -0,0 +1,121 @@ +package me.totalfreedom.totalfreedommod.blocking; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + +public class BlockBlocker extends FreedomService +{ + + public BlockBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockPlace(BlockPlaceEvent event) + { + final Player player = event.getPlayer(); + + switch (event.getBlockPlaced().getType()) + { + case LAVA: + case STATIONARY_LAVA: + { + if (ConfigEntry.ALLOW_LAVA_PLACE.getBoolean()) + { + FLog.info(String.format("%s placed lava @ %s", player.getName(), FUtil.formatLocation(event.getBlock().getLocation()))); + + player.getInventory().clear(player.getInventory().getHeldItemSlot()); + } + else + { + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + player.sendMessage(ChatColor.GRAY + "Lava placement is currently disabled."); + + event.setCancelled(true); + } + break; + } + case WATER: + case STATIONARY_WATER: + { + if (ConfigEntry.ALLOW_WATER_PLACE.getBoolean()) + { + FLog.info(String.format("%s placed water @ %s", player.getName(), FUtil.formatLocation(event.getBlock().getLocation()))); + + player.getInventory().clear(player.getInventory().getHeldItemSlot()); + } + else + { + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + player.sendMessage(ChatColor.GRAY + "Water placement is currently disabled."); + + event.setCancelled(true); + } + break; + } + case FIRE: + { + if (ConfigEntry.ALLOW_FIRE_PLACE.getBoolean()) + { + FLog.info(String.format("%s placed fire @ %s", player.getName(), FUtil.formatLocation(event.getBlock().getLocation()))); + + player.getInventory().clear(player.getInventory().getHeldItemSlot()); + } + else + { + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + player.sendMessage(ChatColor.GRAY + "Fire placement is currently disabled."); + + event.setCancelled(true); + } + break; + } + case TNT: + { + if (ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + FLog.info(String.format("%s placed TNT @ %s", player.getName(), FUtil.formatLocation(event.getBlock().getLocation()))); + + player.getInventory().clear(player.getInventory().getHeldItemSlot()); + } + else + { + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + + player.sendMessage(ChatColor.GRAY + "TNT is currently disabled."); + event.setCancelled(true); + } + break; + } + case STRUCTURE_BLOCK: + { + player.sendMessage(ChatColor.GRAY + "Structure blocks are disabled."); + + event.setCancelled(true); + break; + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java new file mode 100644 index 000000000..b2bc96fe1 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/EventBlocker.java @@ -0,0 +1,211 @@ +package me.totalfreedom.totalfreedommod.blocking; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Tameable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.entity.FireworkExplodeEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.player.PlayerDropItemEvent; + +public class EventBlocker extends FreedomService +{ + + public EventBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockBurn(BlockBurnEvent event) + { + if (!ConfigEntry.ALLOW_FIRE_SPREAD.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockIgnite(BlockIgniteEvent event) + { + if (!ConfigEntry.ALLOW_FIRE_PLACE.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockFromTo(BlockFromToEvent event) + { + if (!ConfigEntry.ALLOW_FLUID_SPREAD.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityExplode(EntityExplodeEvent event) + { + if (!ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + event.setCancelled(true); + return; + } + + event.setYield(0.0F); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onExplosionPrime(ExplosionPrimeEvent event) + { + if (!ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + event.setCancelled(true); + return; + } + + event.setRadius(ConfigEntry.EXPLOSIVE_RADIUS.getDouble().floatValue()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityCombust(EntityCombustEvent event) + { + if (!ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDeath(EntityDeathEvent event) + { + if (ConfigEntry.AUTO_ENTITY_WIPE.getBoolean()) + { + event.setDroppedExp(0); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onProjectileHit(ProjectileHitEvent event) + { + if (ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + Projectile entity = event.getEntity(); + if (event.getEntityType() == EntityType.ARROW) + { + entity.getWorld().createExplosion(entity.getLocation(), 2F); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDamage(EntityDamageEvent event) + { + switch (event.getCause()) + { + case LAVA: + { + if (!ConfigEntry.ALLOW_LAVA_DAMAGE.getBoolean()) + { + event.setCancelled(true); + return; + } + } + } + + if (ConfigEntry.ENABLE_PET_PROTECT.getBoolean()) + { + Entity entity = event.getEntity(); + if (entity instanceof Tameable) + { + if (((Tameable) entity).isTamed()) + { + event.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerDropItem(PlayerDropItemEvent event) + { + if (!ConfigEntry.AUTO_ENTITY_WIPE.getBoolean()) + { + return; + } + + if (event.getPlayer().getWorld().getEntities().size() > 750) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onLeavesDecay(LeavesDecayEvent event) + { + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.HIGH) + public void FireworkExplodeEvent(FireworkExplodeEvent event) + { + if (!ConfigEntry.ALLOW_FIREWORK_EXPLOSION.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void BlockPistonRetractEvent(BlockPistonRetractEvent event) + { + if (!ConfigEntry.ALLOW_REDSTONE.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void BlockPistonExtendEvent(BlockPistonExtendEvent event) + { + if (!ConfigEntry.ALLOW_REDSTONE.getBoolean()) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void BlockRedstoneEvent(BlockRedstoneEvent event) + { + if (!ConfigEntry.ALLOW_REDSTONE.getBoolean()) + { + event.setNewCurrent(0); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java new file mode 100644 index 000000000..df1214f07 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/InteractBlocker.java @@ -0,0 +1,139 @@ +package me.totalfreedom.totalfreedommod.blocking; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +public class InteractBlocker extends FreedomService +{ + + public InteractBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerInteract(PlayerInteractEvent event) + { + switch (event.getAction()) + { + case RIGHT_CLICK_AIR: + case RIGHT_CLICK_BLOCK: + { + handleRightClick(event); + break; + } + + case LEFT_CLICK_AIR: + case LEFT_CLICK_BLOCK: + { + // + break; + } + } + } + + private void handleRightClick(PlayerInteractEvent event) + { + final Player player = event.getPlayer(); + + switch (event.getMaterial()) + { + case WATER_BUCKET: + { + if (plugin.al.isAdmin(player) || ConfigEntry.ALLOW_WATER_PLACE.getBoolean()) + { + break; + } + + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + player.sendMessage(ChatColor.GRAY + "Water buckets are currently disabled."); + event.setCancelled(true); + break; + } + + case LAVA_BUCKET: + { + if (plugin.al.isAdmin(player) || ConfigEntry.ALLOW_LAVA_PLACE.getBoolean()) + { + break; + } + + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + player.sendMessage(ChatColor.GRAY + "Lava buckets are currently disabled."); + event.setCancelled(true); + break; + } + + case FIREWORK: + { + if (plugin.al.isAdmin(player) || ConfigEntry.ALLOW_FIREWORK_EXPLOSION.getBoolean()) + { + break; + } + + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); + player.sendMessage(ChatColor.GRAY + "Firework rockets are currently disabled."); + event.setCancelled(true); + break; + } + + case EXPLOSIVE_MINECART: + { + if (ConfigEntry.ALLOW_TNT_MINECARTS.getBoolean()) + { + break; + } + + player.getInventory().clear(player.getInventory().getHeldItemSlot()); + player.sendMessage(ChatColor.GRAY + "TNT minecarts are currently disabled."); + event.setCancelled(true); + break; + } + + case SIGN: + case SIGN_POST: + case WALL_SIGN: + { + player.sendMessage(ChatColor.GRAY + "Sign interaction is currently disabled."); + break; + } + } + + FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer()); + + if (!fPlayer.isPVPBlock()) + { + return; + } + + switch (event.getMaterial()) + { + case BOW: + { + player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.AIR, 1)); + player.sendMessage(ChatColor.GRAY + "Bow interacting during PVP block is blocked."); + event.setCancelled(true); + break; + } + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/MobBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/MobBlocker.java new file mode 100644 index 000000000..e9efce7b9 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/MobBlocker.java @@ -0,0 +1,104 @@ +package me.totalfreedom.totalfreedommod.blocking; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import org.bukkit.entity.Bat; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Giant; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Slime; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.CreatureSpawnEvent; + +public class MobBlocker extends FreedomService +{ + + public MobBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onCreatureSpawn(CreatureSpawnEvent event) + { + if (!ConfigEntry.MOB_LIMITER_ENABLED.getBoolean()) + { + return; + } + + final Entity spawned = event.getEntity(); + if (spawned instanceof EnderDragon) + { + if (ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.getBoolean()) + { + event.setCancelled(true); + return; + } + } + else if (spawned instanceof Ghast) + { + if (ConfigEntry.MOB_LIMITER_DISABLE_GHAST.getBoolean()) + { + event.setCancelled(true); + return; + } + } + else if (spawned instanceof Slime) + { + if (ConfigEntry.MOB_LIMITER_DISABLE_SLIME.getBoolean()) + { + event.setCancelled(true); + return; + } + } + else if (spawned instanceof Giant) + { + if (ConfigEntry.MOB_LIMITER_DISABLE_GIANT.getBoolean()) + { + event.setCancelled(true); + return; + } + } + else if (spawned instanceof Bat) + { + event.setCancelled(true); + return; + } + + int mobLimiterMax = ConfigEntry.MOB_LIMITER_MAX.getInteger(); + + if (mobLimiterMax <= 0) + { + return; + } + + int mobcount = 0; + for (Entity entity : event.getLocation().getWorld().getLivingEntities()) + { + if (!(entity instanceof HumanEntity)) + { + mobcount++; + } + } + + if (mobcount > mobLimiterMax) + { + event.setCancelled(true); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/PotionBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/PotionBlocker.java new file mode 100644 index 000000000..3cd84e4be --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/PotionBlocker.java @@ -0,0 +1,62 @@ +package me.totalfreedom.totalfreedommod.blocking; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PotionSplashEvent; +import org.bukkit.projectiles.ProjectileSource; + +public class PotionBlocker extends FreedomService +{ + + public static final int POTION_BLOCK_RADIUS_SQUARED = 20 * 20; + + public PotionBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onThrowPotion(PotionSplashEvent event) + { + ProjectileSource source = event.getEntity().getShooter(); + + if (!(source instanceof Player)) + { + event.setCancelled(true); + return; + } + + Player thrower = (Player) source; + + if (plugin.al.isAdmin(thrower)) + { + return; + } + + for (Player player : thrower.getWorld().getPlayers()) + { + if (thrower.getLocation().distanceSquared(player.getLocation()) < POTION_BLOCK_RADIUS_SQUARED) + { + thrower.sendMessage(ChatColor.RED + "You cannot use splash potions close to other players."); + event.setCancelled(true); + return; + } + } + + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlocker.java new file mode 100644 index 000000000..b64a2e5a4 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlocker.java @@ -0,0 +1,210 @@ +package me.totalfreedom.totalfreedommod.blocking.command; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.command.CommandReflection; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +public class CommandBlocker extends FreedomService +{ + + private final Pattern flagPattern = Pattern.compile("(:([0-9]){5,})"); + // + private final Map entryList = Maps.newHashMap(); + private final List unknownCommands = Lists.newArrayList(); + + public CommandBlocker(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + load(); + } + + @Override + protected void onStop() + { + entryList.clear(); + } + + public void load() + { + entryList.clear(); + unknownCommands.clear(); + + final CommandMap commandMap = CommandReflection.getCommandMap(); + if (commandMap == null) + { + FLog.severe("Error loading commandMap."); + return; + } + + @SuppressWarnings("unchecked") + List blockedCommands = (List) ConfigEntry.BLOCKED_COMMANDS.getList(); + for (String rawEntry : blockedCommands) + { + final String[] parts = rawEntry.split(":"); + if (parts.length < 3 || parts.length > 4) + { + FLog.warning("Invalid command blocker entry: " + rawEntry); + continue; + } + + final CommandBlockerRank rank = CommandBlockerRank.fromToken(parts[0]); + final CommandBlockerAction action = CommandBlockerAction.fromToken(parts[1]); + String commandName = parts[2].toLowerCase().substring(1); + final String message = (parts.length > 3 ? parts[3] : null); + + if (rank == null || action == null || commandName == null || commandName.isEmpty()) + { + FLog.warning("Invalid command blocker entry: " + rawEntry); + continue; + } + + final String[] commandParts = commandName.split(" "); + String subCommand = null; + if (commandParts.length > 1) + { + commandName = commandParts[0]; + subCommand = StringUtils.join(commandParts, " ", 1, commandParts.length).trim().toLowerCase(); + } + + final Command command = commandMap.getCommand(commandName); + + // Obtain command from alias + if (command == null) + { + unknownCommands.add(commandName); + } + else + { + commandName = command.getName().toLowerCase(); + } + + if (entryList.containsKey(commandName)) + { + FLog.warning("Not blocking: /" + commandName + " - Duplicate entry exists!"); + continue; + } + + final CommandBlockerEntry blockedCommandEntry = new CommandBlockerEntry(rank, action, commandName, subCommand, message); + entryList.put(blockedCommandEntry.getCommand(), blockedCommandEntry); + + if (command != null) + { + for (String alias : command.getAliases()) + { + entryList.put(alias.toLowerCase(), blockedCommandEntry); + } + } + } + + FLog.info("Loaded " + blockedCommands.size() + " blocked commands (" + (blockedCommands.size() - unknownCommands.size()) + " known)."); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) + { + // Blocked commands + if (isCommandBlocked(event.getMessage(), event.getPlayer(), true)) + { + // CommandBlocker handles messages and broadcasts + event.setCancelled(true); + } + } + + public boolean isCommandBlocked(String command, CommandSender sender) + { + return isCommandBlocked(command, sender, false); + } + + public boolean isCommandBlocked(String command, CommandSender sender, boolean doAction) + { + if (command == null || command.isEmpty()) + { + return false; + } + + // Format + command = command.toLowerCase().trim(); + command = command.startsWith("/") ? command.substring(1) : command; + + // Check for plugin specific commands + final String[] commandParts = command.split(" "); + if (commandParts[0].contains(":")) + { + if (doAction) + { + FUtil.playerMsg(sender, "Plugin specific commands are disabled."); + } + return true; + } + + for (String part : commandParts) + { + Matcher matcher = flagPattern.matcher(part); + if (!matcher.matches()) + { + continue; + } + if (doAction) + { + FUtil.playerMsg(sender, "That command contains an illegal number: " + matcher.group(1)); + } + return true; + } + + // Obtain sub command, if it exists + String subCommand = null; + if (commandParts.length > 1) + { + subCommand = StringUtils.join(commandParts, " ", 1, commandParts.length).toLowerCase(); + } + + // Obtain entry + final CommandBlockerEntry entry = entryList.get(commandParts[0]); + if (entry == null) + { + return false; + } + + // Validate sub command + if (entry.getSubCommand() != null) + { + if (subCommand == null || !subCommand.startsWith(entry.getSubCommand())) + { + return false; + } + } + + if (entry.getRank().hasPermission(sender)) + { + return false; + } + + if (doAction) + { + entry.doActions(sender); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerAction.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerAction.java new file mode 100644 index 000000000..5bf9919c4 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerAction.java @@ -0,0 +1,32 @@ +package me.totalfreedom.totalfreedommod.blocking.command; + +public enum CommandBlockerAction +{ + + BLOCK("b"), + BLOCK_AND_EJECT("a"), + BLOCK_UNKNOWN("u"); + private final String token; + + private CommandBlockerAction(String token) + { + this.token = token; + } + + public String getToken() + { + return this.token; + } + + public static CommandBlockerAction fromToken(String token) + { + for (CommandBlockerAction action : CommandBlockerAction.values()) + { + if (action.getToken().equalsIgnoreCase(token)) + { + return action; + } + } + return null; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java new file mode 100644 index 000000000..ff40ce126 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerEntry.java @@ -0,0 +1,55 @@ +package me.totalfreedom.totalfreedommod.blocking.command; + +import lombok.Getter; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class CommandBlockerEntry +{ + + @Getter + private final CommandBlockerRank rank; + @Getter + private final CommandBlockerAction action; + @Getter + private final String command; + @Getter + private final String subCommand; + @Getter + private final String message; + + public CommandBlockerEntry(CommandBlockerRank rank, CommandBlockerAction action, String command, String message) + { + this(rank, action, command, null, message); + } + + public CommandBlockerEntry(CommandBlockerRank rank, CommandBlockerAction action, String command, String subCommand, String message) + { + this.rank = rank; + this.action = action; + this.command = command; + this.subCommand = (subCommand == null ? null : subCommand.toLowerCase().trim()); + this.message = (message == null || message.equals("_") ? "That command is blocked." : message); + } + + public void doActions(CommandSender sender) + { + if (action == CommandBlockerAction.BLOCK_AND_EJECT && sender instanceof Player) + { + TotalFreedomMod.plugin().ae.autoEject((Player) sender, "You used a prohibited command: " + command); + FUtil.bcastMsg(sender.getName() + " was automatically kicked for using harmful commands.", ChatColor.RED); + return; + } + + if (action == CommandBlockerAction.BLOCK_UNKNOWN) + { + FUtil.playerMsg(sender, "Unknown command. Type \"help\" for help.", ChatColor.RESET); + return; + } + + FUtil.playerMsg(sender, FUtil.colorize(message)); + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerRank.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerRank.java new file mode 100644 index 000000000..84f7b6ebf --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/command/CommandBlockerRank.java @@ -0,0 +1,73 @@ +package me.totalfreedom.totalfreedommod.blocking.command; + +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public enum CommandBlockerRank +{ + + ANYONE("a"), + OP("o"), + SUPER("s"), + TELNET("t"), + SENIOR("c"), + NOBODY("n"); + // + private final String token; + + private CommandBlockerRank(String token) + { + this.token = token; + } + + public String getToken() + { + return this.token; + } + + public boolean hasPermission(CommandSender sender) + { + return fromSender(sender).ordinal() >= ordinal(); + } + + public static CommandBlockerRank fromSender(CommandSender sender) + { + if (!(sender instanceof Player)) + { + return TELNET; + } + + Admin admin = TotalFreedomMod.plugin().al.getAdmin(sender); + if (admin != null) + { + if (admin.getRank() == Rank.SENIOR_ADMIN) + { + return SENIOR; + } + return SUPER; + } + + if (sender.isOp()) + { + return OP; + } + + return ANYONE; + + } + + public static CommandBlockerRank fromToken(String token) + { + for (CommandBlockerRank rank : CommandBlockerRank.values()) + { + if (rank.getToken().equalsIgnoreCase(token)) + { + return rank; + } + } + return ANYONE; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java new file mode 100644 index 000000000..673cb79d0 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/BukkitTelnetBridge.java @@ -0,0 +1,126 @@ +package me.totalfreedom.totalfreedommod.bridge; + +import java.util.Iterator; +import java.util.Map; +import me.totalfreedom.bukkittelnet.BukkitTelnet; +import me.totalfreedom.bukkittelnet.api.TelnetCommandEvent; +import me.totalfreedom.bukkittelnet.api.TelnetPreLoginEvent; +import me.totalfreedom.bukkittelnet.api.TelnetRequestDataTagsEvent; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.plugin.Plugin; + +public class BukkitTelnetBridge extends FreedomService +{ + + private BukkitTelnet bukkitTelnetPlugin = null; + + public BukkitTelnetBridge(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + public BukkitTelnet getBukkitTelnetPlugin() + { + if (bukkitTelnetPlugin == null) + { + try + { + final Plugin bukkitTelnet = server.getPluginManager().getPlugin("BukkitTelnet"); + if (bukkitTelnet != null) + { + if (bukkitTelnet instanceof BukkitTelnet) + { + bukkitTelnetPlugin = (BukkitTelnet) bukkitTelnet; + } + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + return bukkitTelnetPlugin; + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onTelnetPreLogin(TelnetPreLoginEvent event) + { + + final String ip = event.getIp(); + if (ip == null || ip.isEmpty()) + { + return; + } + + final Admin admin = plugin.al.getEntryByIpFuzzy(ip); + + if (admin == null || !admin.isActive() || !admin.getRank().hasConsoleVariant()) + { + return; + } + + event.setBypassPassword(true); + event.setName(admin.getName()); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onTelnetCommand(TelnetCommandEvent event) + { + if (plugin.cb.isCommandBlocked(event.getCommand(), event.getSender())) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onTelnetRequestDataTags(TelnetRequestDataTagsEvent event) + { + final Iterator>> it = event.getDataTags().entrySet().iterator(); + while (it.hasNext()) + { + final Map.Entry> entry = it.next(); + final Player player = entry.getKey(); + final Map playerTags = entry.getValue(); + + boolean isAdmin = false; + boolean isTelnetAdmin = false; + boolean isSeniorAdmin = false; + + final Admin admin = plugin.al.getAdmin(player); + if (admin != null) + { + boolean active = admin.isActive(); + + isAdmin = active; + isSeniorAdmin = active && admin.getRank() == Rank.SENIOR_ADMIN; + isTelnetAdmin = active && (isSeniorAdmin || admin.getRank() == Rank.TELNET_ADMIN); + } + + playerTags.put("tfm.admin.isAdmin", isAdmin); + playerTags.put("tfm.admin.isTelnetAdmin", isTelnetAdmin); + playerTags.put("tfm.admin.isSeniorAdmin", isSeniorAdmin); + + playerTags.put("tfm.playerdata.getTag", plugin.pl.getPlayer(player).getTag()); + + playerTags.put("tfm.essentialsBridge.getNickname", plugin.esb.getNickname(player.getName())); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java new file mode 100644 index 000000000..b7c61fcbb --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/EssentialsBridge.java @@ -0,0 +1,237 @@ +package me.totalfreedom.totalfreedommod.bridge; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import me.totalfreedom.totalfreedommod.FreedomService; +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.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; + +public class EssentialsBridge extends FreedomService +{ + + private Essentials essentialsPlugin = null; + + public EssentialsBridge(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + public Essentials getEssentialsPlugin() + { + if (essentialsPlugin == null) + { + try + { + final Plugin essentials = Bukkit.getServer().getPluginManager().getPlugin("Essentials"); + if (essentials != null) + { + if (essentials instanceof Essentials) + { + essentialsPlugin = (Essentials) essentials; + } + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + return essentialsPlugin; + } + + public User getEssentialsUser(String username) + { + try + { + final Essentials essentials = getEssentialsPlugin(); + if (essentials != null) + { + return essentials.getUserMap().getUser(username); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + return null; + } + + public void setNickname(String username, String nickname) + { + try + { + final User user = getEssentialsUser(username); + if (user != null) + { + user.setNickname(nickname); + user.setDisplayNick(); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + public String getNickname(String username) + { + try + { + final User user = getEssentialsUser(username); + if (user != null) + { + return user.getNickname(); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + return null; + } + + public long getLastActivity(String username) + { + try + { + final User user = getEssentialsUser(username); + if (user != null) + { + return FUtil.getField(user, "lastActivity"); // This is weird + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + return 0L; + } + + public void setVanished(String username, boolean vanished) + { + try + { + final User user = getEssentialsUser(username); + if (user != null) + { + user.setVanished(vanished); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onInventoryClickEvent(final InventoryClickEvent event) + { + Player refreshPlayer = null; + final Inventory top = event.getView().getTopInventory(); + final InventoryType type = top.getType(); + final Player playerdata = (Player) event.getWhoClicked(); + FPlayer fPlayer = plugin.pl.getPlayer(playerdata); + if (type == InventoryType.PLAYER && fPlayer.isInvsee()) + { + final InventoryHolder invHolder = top.getHolder(); + if (invHolder != null && invHolder instanceof HumanEntity) + { + final Player invOwner = (Player) invHolder; + final Rank recieverRank = plugin.rm.getRank(playerdata); + final Rank playerRank = plugin.rm.getRank(invOwner); + if (playerRank.ordinal() >= recieverRank.ordinal() || !(invOwner.isOnline())) + { + event.setCancelled(true); + refreshPlayer = playerdata; + } + } + } + + if (refreshPlayer != null) + { + final Player player = refreshPlayer; + new BukkitRunnable() + { + + @Override + public void run() + { + player.updateInventory(); + } + + }.runTaskLater(this.plugin, 20); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onInventoryCloseEvent(final InventoryCloseEvent event) + { + Player refreshPlayer = null; + final Inventory top = event.getView().getTopInventory(); + final InventoryType type = top.getType(); + final Player playerdata = (Player) event.getPlayer(); + FPlayer fPlayer = plugin.pl.getPlayer(playerdata); + if (type == InventoryType.PLAYER && fPlayer.isInvsee()) + { + fPlayer.setInvsee(false); + refreshPlayer = playerdata; + } + + if (refreshPlayer != null) + { + final Player player = refreshPlayer; + new BukkitRunnable() + { + + @Override + public void run() + { + player.updateInventory(); + } + + }.runTaskLater(this.plugin, 20); + } + } + + public boolean isEssentialsEnabled() + { + try + { + final Essentials essentials = getEssentialsPlugin(); + if (essentials != null) + { + return essentials.isEnabled(); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + return false; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/LibsDisguisesBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/LibsDisguisesBridge.java new file mode 100644 index 000000000..ed7bc978f --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/LibsDisguisesBridge.java @@ -0,0 +1,138 @@ +package me.totalfreedom.totalfreedommod.bridge; + +import me.libraryaddict.disguise.DisallowedDisguises; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.DisguiseAPI; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.bukkit.entity.Player; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +public class LibsDisguisesBridge extends FreedomService +{ + + private LibsDisguises libsDisguisesPlugin = null; + + public LibsDisguisesBridge(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + public LibsDisguises getLibsDisguisesPlugin() + { + if (libsDisguisesPlugin == null) + { + try + { + final Plugin libsDisguises = server.getPluginManager().getPlugin("LibsDisguises"); + if (libsDisguises != null) + { + if (libsDisguises instanceof LibsDisguises) + { + libsDisguisesPlugin = (LibsDisguises) libsDisguises; + } + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + return libsDisguisesPlugin; + } + + public Boolean isDisguised(Player player) + { + try + { + final LibsDisguises libsDisguises = getLibsDisguisesPlugin(); + if (libsDisguises != null) + { + return DisguiseAPI.isDisguised(player); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + return null; + } + + public void undisguiseAll(boolean admins) + { + try + { + final LibsDisguises libsDisguises = getLibsDisguisesPlugin(); + + if (libsDisguises == null) + { + return; + } + + for (Player player : server.getOnlinePlayers()) + { + if (DisguiseAPI.isDisguised(player)) + { + if (!admins && plugin.al.isAdmin(player)) + { + continue; + } + DisguiseAPI.undisguiseToAll(player); + } + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + public void setDisguisesEnabled(boolean state) + { + final LibsDisguises libsDisguises = getLibsDisguisesPlugin(); + + if (libsDisguises == null) + { + return; + } + + if (state) + { + DisguiseAPI.enableDisguises(); + } + else + { + DisguiseAPI.disableDisguises(); + } + } + + public boolean isDisguisesEnabled() + { + return !DisallowedDisguises.disabled; + } + + public boolean isPluginEnabled() + { + Plugin ld = getLibsDisguisesPlugin(); + + if (ld == null) + { + return false; + } + + return ld.isEnabled(); + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java new file mode 100644 index 000000000..d8d0eafdb --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditBridge.java @@ -0,0 +1,161 @@ +package me.totalfreedom.totalfreedommod.bridge; + +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.bukkit.BukkitPlayer; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +public class WorldEditBridge extends FreedomService +{ + + private final WorldEditListener listener; + // + private WorldEditPlugin worldedit = null; + + public WorldEditBridge(TotalFreedomMod plugin) + { + super(plugin); + listener = new WorldEditListener(plugin); + } + + @Override + protected void onStart() + { + listener.register(); + } + + @Override + protected void onStop() + { + listener.unregister(); + } + + 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); + } + } + + private WorldEditPlugin getWorldEditPlugin() + { + if (worldedit == null) + { + try + { + Plugin we = server.getPluginManager().getPlugin("WorldEdit"); + if (we != null) + { + if (we instanceof WorldEditPlugin) + { + worldedit = (WorldEditPlugin) we; + } + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + return worldedit; + } + + public void setLimit(Player player, int limit) + { + try + { + final LocalSession session = getPlayerSession(player); + if (session != null) + { + session.setBlockChangeLimit(limit); + } + } + catch (Exception ex) + { + FLog.severe(ex); + } + + } + + private LocalSession getPlayerSession(Player player) + { + final WorldEditPlugin wep = getWorldEditPlugin(); + if (wep == null) + { + return null; + } + + try + { + return wep.getSession(player); + } + catch (Exception ex) + { + FLog.severe(ex); + 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/WorldEditListener.java b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditListener.java new file mode 100644 index 000000000..ecf398d30 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/bridge/WorldEditListener.java @@ -0,0 +1,74 @@ +package me.totalfreedom.totalfreedommod.bridge; + +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FUtil; +// These imports are not in the latest releases of WorldEdit, and the new versions of WorldEdit do not build properly. This will need to be reverted once the new WorldEdit builds are building properly. +// +//import me.totalfreedom.worldedit.LimitChangedEvent; +//import me.totalfreedom.worldedit.SelectionChangedEvent; +// +//The following two imports are a temporary measure as mentioned above. +// +import me.StevenLawson.worldedit.LimitChangedEvent; +import me.StevenLawson.worldedit.SelectionChangedEvent; +// +import net.pravian.aero.component.PluginListener; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +public class WorldEditListener extends PluginListener +{ + + public WorldEditListener(TotalFreedomMod plugin) + { + super(plugin); + } + + @EventHandler + public void onSelectionChange(final SelectionChangedEvent event) + { + final Player player = event.getPlayer(); + + if (plugin.al.isAdmin(player)) + { + return; + } + + if (plugin.pa.isInProtectedArea( + event.getMinVector(), + event.getMaxVector(), + event.getWorld().getName())) + { + + player.sendMessage(ChatColor.RED + "The region that you selected contained a protected area. Selection cleared."); + event.setCancelled(true); + } + } + + @EventHandler + public void onLimitChanged(LimitChangedEvent event) + { + final Player player = event.getPlayer(); + + if (plugin.al.isAdmin(player)) + { + return; + } + + if (!event.getPlayer().equals(event.getTarget())) + { + player.sendMessage(ChatColor.RED + "Only admins can change the limit for other players!"); + event.setCancelled(true); + } + + if (event.getLimit() < 0 || event.getLimit() > 10000) + { + player.setOp(false); + FUtil.bcastMsg(event.getPlayer().getName() + " tried to set their WorldEdit limit to " + event.getLimit() + " and has been de-opped", ChatColor.RED); + event.setCancelled(true); + player.sendMessage(ChatColor.RED + "You cannot set your limit higher than 10000 or to -1!"); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/caging/CageData.java b/src/main/java/me/totalfreedom/totalfreedommod/caging/CageData.java new file mode 100644 index 000000000..ab5d6670b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/caging/CageData.java @@ -0,0 +1,214 @@ +package me.totalfreedom.totalfreedommod.caging; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.command.Command_cage; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.SkullType; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; + +public class CageData +{ + private final FPlayer fPlayer; + // + private final List cageHistory = new ArrayList<>(); + // + @Getter + private boolean caged = false; + @Getter + private Location location; + @Getter + private Material outerMaterial = Material.GLASS; + @Getter + private Material innerMaterial = Material.AIR; + + public CageData(FPlayer player) + { + this.fPlayer = player; + } + + public void setCaged(boolean cage) + { + if (cage) + { + cage(fPlayer.getPlayer().getLocation(), Material.GLASS, Material.GLASS); + } + else + { + this.caged = false; + regenerateHistory(); + clearHistory(); + } + + } + + public void cage(Location location, Material outer, Material inner) + { + if (isCaged()) + { + setCaged(false); + } + + this.caged = true; + this.location = location; + this.outerMaterial = outer; + this.innerMaterial = inner; + + buildHistory(location, 2, fPlayer); + regenerate(); + } + + public void regenerate() + { + + if (!caged + || location == null + || outerMaterial == null + || innerMaterial == null) + { + return; + } + + generateHollowCube(location, 2, outerMaterial); + generateCube(location, 1, innerMaterial); + } + + // TODO: EventHandlerize this? + public void playerJoin() + { + if (!isCaged()) + { + return; + } + + cage(fPlayer.getPlayer().getLocation(), outerMaterial, innerMaterial); + } + + public void playerQuit() + { + regenerateHistory(); + clearHistory(); + } + + public void clearHistory() + { + cageHistory.clear(); + } + + private void insertHistoryBlock(Location location, Material material) + { + cageHistory.add(new BlockData(location, material)); + } + + private void regenerateHistory() + { + for (BlockData blockdata : this.cageHistory) + { + blockdata.location.getBlock().setType(blockdata.material); + } + } + + private void buildHistory(Location location, int length, FPlayer playerdata) + { + final Block center = location.getBlock(); + for (int xOffset = -length; xOffset <= length; xOffset++) + { + for (int yOffset = -length; yOffset <= length; yOffset++) + { + for (int zOffset = -length; zOffset <= length; zOffset++) + { + final Block block = center.getRelative(xOffset, yOffset, zOffset); + insertHistoryBlock(block.getLocation(), block.getType()); + } + } + } + } + + // Util methods + public static void generateCube(Location location, int length, Material material) + { + final Block center = location.getBlock(); + for (int xOffset = -length; xOffset <= length; xOffset++) + { + for (int yOffset = -length; yOffset <= length; yOffset++) + { + for (int zOffset = -length; zOffset <= length; zOffset++) + { + final Block block = center.getRelative(xOffset, yOffset, zOffset); + if (block.getType() != material) + { + block.setType(material); + } + } + } + } + } + + public static void generateHollowCube(Location location, int length, Material material) + { + final Block center = location.getBlock(); + for (int xOffset = -length; xOffset <= length; xOffset++) + { + for (int yOffset = -length; yOffset <= length; yOffset++) + { + for (int zOffset = -length; zOffset <= length; zOffset++) + { + // Hollow + if (Math.abs(xOffset) != length && Math.abs(yOffset) != length && Math.abs(zOffset) != length) + { + continue; + } + + final Block block = center.getRelative(xOffset, yOffset, zOffset); + + if (material != Material.SKULL) + { + // Glowstone light + if (material != Material.GLASS && xOffset == 0 && yOffset == 2 && zOffset == 0) + { + block.setType(Material.GLOWSTONE); + continue; + } + + block.setType(material); + } + else // Darth mode + { + if (Math.abs(xOffset) == length && Math.abs(yOffset) == length && Math.abs(zOffset) == length) + { + block.setType(Material.GLOWSTONE); + continue; + } + + block.setType(Material.SKULL); + final Skull skull = (Skull) block.getState(); + skull.setSkullType(SkullType.PLAYER); + skull.setOwner(Command_cage.playerSkullName); + skull.update(); + } + } + } + } + } + + private Command_cage Command_cage() + { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + private static class BlockData + { + public Material material; + public Location location; + + private BlockData(Location location, Material material) + { + this.location = location; + this.material = material; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/caging/Cager.java b/src/main/java/me/totalfreedom/totalfreedommod/caging/Cager.java new file mode 100644 index 000000000..d3af7e624 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/caging/Cager.java @@ -0,0 +1,110 @@ +package me.totalfreedom.totalfreedommod.caging; + +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class Cager extends FreedomService +{ + + public Cager(TotalFreedomMod plugin) + { + super(plugin); + } + + @Override + protected void onStart() + { + } + + @Override + protected void onStop() + { + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBreakBlock(BlockBreakEvent event) + { + Player player = event.getPlayer(); + if (player == null + || plugin.al.isAdmin(player)) + { + return; + } + + FPlayer fPlayer = plugin.pl.getPlayer(event.getPlayer()); + CageData cage = fPlayer.getCageData(); + + if (cage.isCaged()) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) + { + FPlayer player = plugin.pl.getPlayer(event.getPlayer()); + CageData cage = player.getCageData(); + + if (!cage.isCaged()) + { + return; + } + + Location playerLoc = player.getPlayer().getLocation().add(0, 1, 0); + Location cageLoc = cage.getLocation(); + + final boolean outOfCage; + if (!playerLoc.getWorld().equals(cageLoc.getWorld())) + { + outOfCage = true; + } + else + { + outOfCage = playerLoc.distanceSquared(cageLoc) > (2.5D * 2.5D); + } + + if (outOfCage) + { + player.getPlayer().teleport(cageLoc.subtract(0, 0.1, 0)); + FUtil.playerMsg(player.getPlayer(), "You may not leave your cage.", ChatColor.RED); + cage.regenerate(); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerQuit(PlayerQuitEvent event) + { + FPlayer player = plugin.pl.getPlayer(event.getPlayer()); + CageData cage = player.getCageData(); + + if (cage.isCaged()) + { + cage.playerQuit(); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent event) + { + FPlayer player = plugin.pl.getPlayer(event.getPlayer()); + CageData cage = player.getCageData(); + + if (cage.isCaged()) + { + cage.playerJoin(); + } + } + +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/CommandFailException.java b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandFailException.java new file mode 100644 index 000000000..64025aea6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandFailException.java @@ -0,0 +1,13 @@ +package me.totalfreedom.totalfreedommod.command; + +public class CommandFailException extends RuntimeException +{ + + private static final long serialVersionUID = -92333791173123L; + + public CommandFailException(String message) + { + super(message); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/CommandLoader.java b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandLoader.java new file mode 100644 index 000000000..78a480451 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandLoader.java @@ -0,0 +1,45 @@ +package me.totalfreedom.totalfreedommod.command; + +import lombok.Getter; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FLog; +import net.pravian.aero.command.handler.SimpleCommandHandler; +import org.bukkit.ChatColor; + +public class CommandLoader extends FreedomService +{ + + @Getter + private final SimpleCommandHandler handler; + + public CommandLoader(TotalFreedomMod plugin) + { + super(plugin); + + handler = new SimpleCommandHandler<>(plugin); + } + + @Override + protected void onStart() + { + handler.clearCommands(); + handler.setExecutorFactory(new FreedomCommandExecutor.FreedomExecutorFactory(plugin)); + handler.setCommandClassPrefix("Command_"); + handler.setPermissionMessage(ChatColor.RED + "You do not have permission to use this command."); + handler.setOnlyConsoleMessage(ChatColor.RED + "This command can only be used from the console."); + handler.setOnlyPlayerMessage(ChatColor.RED + "This command can only be used by players."); + + handler.loadFrom(FreedomCommand.class.getPackage()); + handler.registerAll("TotalFreedomMod", true); + + FLog.info("Loaded " + handler.getExecutors().size() + " commands."); + } + + @Override + protected void onStop() + { + handler.clearCommands(); + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/CommandParameters.java b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandParameters.java new file mode 100644 index 000000000..db7a5ae30 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandParameters.java @@ -0,0 +1,15 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface CommandParameters +{ + + String description(); + + String usage(); + + String aliases() default ""; // "alias1,alias2,alias3" - no spaces +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/CommandPermissions.java b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandPermissions.java new file mode 100644 index 000000000..c587593e9 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/CommandPermissions.java @@ -0,0 +1,16 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import me.totalfreedom.totalfreedommod.rank.Rank; + +@Retention(RetentionPolicy.RUNTIME) +public @interface CommandPermissions +{ + + Rank level(); + + SourceType source(); + + boolean blockHostConsole() default false; +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminchat.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminchat.java new file mode 100644 index 000000000..d78c68427 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminchat.java @@ -0,0 +1,41 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters( + description = "AdminChat - Talk privately with other admins. Using itself will toggle AdminChat on and off for all messages.", + usage = "/ [message...]", + aliases = "o,ac") +public class Command_adminchat extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + if (senderIsConsole) + { + msg("Only in-game players can toggle AdminChat."); + return true; + } + + FPlayer userinfo = plugin.pl.getPlayer(playerSender); + userinfo.setAdminChat(!userinfo.inAdminChat()); + msg("Toggled Admin Chat " + (userinfo.inAdminChat() ? "on" : "off") + "."); + } + else + { + plugin.cm.adminChat(sender, StringUtils.join(args, " ")); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminmode.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminmode.java new file mode 100644 index 000000000..173e7f192 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminmode.java @@ -0,0 +1,45 @@ +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.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_CONSOLE, blockHostConsole = true) +@CommandParameters(description = "Close server to non-superadmins.", usage = "/ [on | off]") +public class Command_adminmode extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if (args[0].equalsIgnoreCase("off")) + { + ConfigEntry.ADMIN_ONLY_MODE.setBoolean(false); + FUtil.adminAction(sender.getName(), "Opening the server to all players.", true); + return true; + } + else if (args[0].equalsIgnoreCase("on")) + { + ConfigEntry.ADMIN_ONLY_MODE.setBoolean(true); + FUtil.adminAction(sender.getName(), "Closing the server to non-superadmins.", true); + for (Player player : server.getOnlinePlayers()) + { + if (!isAdmin(player)) + { + player.kickPlayer("Server is now closed to non-superadmins."); + } + } + return true; + } + + return false; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java new file mode 100644 index 000000000..f25b402f6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adminworld.java @@ -0,0 +1,248 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import me.totalfreedom.totalfreedommod.world.WorldTime; +import me.totalfreedom.totalfreedommod.world.WorldWeather; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Go to the AdminWorld.", + usage = "/ [guest < list | purge | add | remove > | time | weather ]") +public class Command_adminworld extends FreedomCommand +{ + + private enum CommandMode + { + + TELEPORT, GUEST, TIME, WEATHER; + } + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + CommandMode commandMode = null; + + if (args.length == 0) + { + commandMode = CommandMode.TELEPORT; + } + else if (args.length >= 2) + { + if ("guest".equalsIgnoreCase(args[0])) + { + commandMode = CommandMode.GUEST; + } + else if ("time".equalsIgnoreCase(args[0])) + { + commandMode = CommandMode.TIME; + } + else if ("weather".equalsIgnoreCase(args[0])) + { + commandMode = CommandMode.WEATHER; + } + } + + if (commandMode == null) + { + return false; + } + + try + { + switch (commandMode) + { + case TELEPORT: + { + if (!(sender instanceof Player) || playerSender == null) + { + return true; + } + + World adminWorld = null; + try + { + adminWorld = plugin.wm.adminworld.getWorld(); + } + catch (Exception ex) + { + } + + if (adminWorld == null || playerSender.getWorld() == adminWorld) + { + msg("Going to the main world."); + playerSender.teleport(server.getWorlds().get(0).getSpawnLocation()); + } + else + { + if (plugin.wm.adminworld.canAccessWorld(playerSender)) + { + msg("Going to the AdminWorld."); + plugin.wm.adminworld.sendToWorld(playerSender); + } + else + { + msg("You don't have permission to access the AdminWorld."); + } + } + + break; + } + case GUEST: + { + if (args.length == 2) + { + if ("list".equalsIgnoreCase(args[1])) + { + msg("AdminWorld guest list: " + plugin.wm.adminworld.guestListToString()); + } + else if ("purge".equalsIgnoreCase(args[1])) + { + assertCommandPerms(sender, playerSender); + plugin.wm.adminworld.purgeGuestList(); + FUtil.adminAction(sender.getName(), "AdminWorld guest list purged.", false); + } + else + { + return false; + } + } + else if (args.length == 3) + { + assertCommandPerms(sender, playerSender); + + if ("add".equalsIgnoreCase(args[1])) + { + final Player player = getPlayer(args[2]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + if (plugin.wm.adminworld.addGuest(player, playerSender)) + { + FUtil.adminAction(sender.getName(), "AdminWorld guest added: " + player.getName(), false); + } + else + { + msg("Could not add player to guest list."); + } + } + else if ("remove".equals(args[1])) + { + final Player player = plugin.wm.adminworld.removeGuest(args[2]); + if (player != null) + { + FUtil.adminAction(sender.getName(), "AdminWorld guest removed: " + player.getName(), false); + } + else + { + msg("Can't find guest entry for: " + args[2]); + } + } + else + { + return false; + } + } + + break; + } + case TIME: + { + assertCommandPerms(sender, playerSender); + + if (args.length == 2) + { + WorldTime timeOfDay = WorldTime.getByAlias(args[1]); + if (timeOfDay != null) + { + plugin.wm.adminworld.setTimeOfDay(timeOfDay); + msg("AdminWorld time set to: " + timeOfDay.name()); + } + else + { + msg("Invalid time of day. Can be: sunrise, noon, sunset, midnight"); + } + } + else + { + return false; + } + + break; + } + case WEATHER: + { + assertCommandPerms(sender, playerSender); + + if (args.length == 2) + { + WorldWeather weatherMode = WorldWeather.getByAlias(args[1]); + if (weatherMode != null) + { + plugin.wm.adminworld.setWeatherMode(weatherMode); + msg("AdminWorld weather set to: " + weatherMode.name()); + } + else + { + msg("Invalid weather mode. Can be: off, rain, storm"); + } + } + else + { + return false; + } + + break; + } + default: + { + return false; + } + } + } + catch (PermissionDeniedException ex) + { + if (ex.getMessage().isEmpty()) + { + return noPerms(); + } + sender.sendMessage(ex.getMessage()); + return true; + } + + return true; + } + + // TODO: Redo this properly + private void assertCommandPerms(CommandSender sender, Player playerSender) throws PermissionDeniedException + { + if (!(sender instanceof Player) || playerSender == null || !isAdmin(sender)) + { + throw new PermissionDeniedException(); + } + } + + private class PermissionDeniedException extends Exception + { + + private static final long serialVersionUID = 1L; + + private PermissionDeniedException() + { + super(""); + } + + private PermissionDeniedException(String string) + { + super(string); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adventure.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adventure.java new file mode 100644 index 000000000..f8a13a0da --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_adventure.java @@ -0,0 +1,58 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Quickly change your own gamemode to adventure, or define someone's username to change theirs.", usage = "/ <-a | [partialname]>", aliases = "gmad") +public class Command_adventure extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + if (isConsole()) + { + sender.sendMessage("When used from the console, you must define a target player."); + return true; + } + + playerSender.setGameMode(GameMode.ADVENTURE); + msg("Gamemode set to adventure."); + return true; + } + + checkRank(Rank.SUPER_ADMIN); + + if (args[0].equals("-ad")) + { + for (Player targetPlayer : server.getOnlinePlayers()) + { + targetPlayer.setGameMode(GameMode.ADVENTURE); + } + + FUtil.adminAction(sender.getName(), "Changing everyone's gamemode to adventure", false); + return true; + } + + Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + msg("Setting " + player.getName() + " to game mode adventure"); + msg(player, sender.getName() + " set your game mode to adventure"); + player.setGameMode(GameMode.ADVENTURE); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_announce.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_announce.java new file mode 100644 index 000000000..f59075ba2 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_announce.java @@ -0,0 +1,26 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Make an announcement", usage = "/ ") +public class Command_announce extends FreedomCommand +{ + + @Override + protected boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + plugin.an.announce(StringUtils.join(args, " ")); + return true; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_banlist.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_banlist.java new file mode 100644 index 000000000..66dcab1b6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_banlist.java @@ -0,0 +1,41 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Shows all banned player names. Superadmins may optionally use 'purge' to clear the list.", usage = "/ [purge]") +public class Command_banlist extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length > 0) + { + if (args[0].equalsIgnoreCase("purge")) + { + checkRank(Rank.SENIOR_ADMIN); + + FUtil.adminAction(sender.getName(), "Purging the ban list", true); + int amount = plugin.bm.purge(); + sender.sendMessage(ChatColor.GRAY + "Purged " + amount + " player bans."); + + return true; + + } + + return false; + } + + msg(plugin.bm.getAllBans().size() + " player bans (" + + plugin.bm.getUsernameBans().size() + " usernames, " + + plugin.bm.getIpBans().size() + " IPs)"); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockcmd.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockcmd.java new file mode 100644 index 000000000..0699f00b5 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockcmd.java @@ -0,0 +1,84 @@ +package me.totalfreedom.totalfreedommod.command; + +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.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Block all commands for a specific player.", usage = "/ <-a | purge | >", aliases = "blockcommands,blockcommand,bc,bcmd") +public class Command_blockcmd extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if (args[0].equals("purge")) + { + FUtil.adminAction(sender.getName(), "Unblocking commands for all players", true); + int counter = 0; + for (Player player : server.getOnlinePlayers()) + { + FPlayer playerdata = plugin.pl.getPlayer(player); + if (playerdata.allCommandsBlocked()) + { + counter += 1; + playerdata.setCommandsBlocked(false); + } + } + msg("Unblocked commands for " + counter + " players."); + return true; + } + + if (args[0].equals("-a")) + { + FUtil.adminAction(sender.getName(), "Blocking commands for all non-admins", true); + int counter = 0; + for (Player player : server.getOnlinePlayers()) + { + if (isAdmin(player)) + { + continue; + } + + counter += 1; + plugin.pl.getPlayer(player).setCommandsBlocked(true); + msg(player, "Your commands have been blocked by an admin.", ChatColor.RED); + } + + msg("Blocked commands for " + counter + " players."); + return true; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + if (isAdmin(player)) + { + msg(player.getName() + " is a Superadmin, and cannot have their commands blocked."); + return true; + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + + playerdata.setCommandsBlocked(!playerdata.allCommandsBlocked()); + + FUtil.adminAction(sender.getName(), (playerdata.allCommandsBlocked() ? "B" : "Unb") + "locking all commands for " + player.getName(), true); + msg((playerdata.allCommandsBlocked() ? "B" : "Unb") + "locked all commands."); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockedit.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockedit.java new file mode 100644 index 000000000..ccdde3ddf --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockedit.java @@ -0,0 +1,151 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Blocks all block placing for player with brute force.", usage = "/ [[-s] [reason] | list | purge | all]", aliases = "editmute") +public class Command_blockedit extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + if (args[0].equals("list")) + { + msg("Blocked block edits players:"); + FPlayer info; + int count = 0; + for (Player mp : server.getOnlinePlayers()) + { + info = plugin.pl.getPlayer(mp); + if (info.isEditBlock()) + { + msg("- " + mp.getName()); + count++; + } + } + if (count == 0) + { + msg("- none"); + } + + return true; + } + + if (args[0].equals("purge")) + { + FUtil.adminAction(sender.getName(), "Unblocking block edits for all players.", true); + FPlayer info; + int count = 0; + for (Player mp : server.getOnlinePlayers()) + { + info = plugin.pl.getPlayer(mp); + if (info.isEditBlock()) + { + info.setEditBlocked(false); + count++; + } + } + msg("Unblocked all block edit for " + count + " players."); + return true; + } + + if (args[0].equals("all")) + { + FUtil.adminAction(sender.getName(), "Blocking block edits for all non-Superadmins", true); + + FPlayer playerdata; + int counter = 0; + for (Player player : server.getOnlinePlayers()) + { + if (!plugin.al.isAdmin(player)) + { + playerdata = plugin.pl.getPlayer(player); + playerdata.setEditBlocked(true); + counter++; + } + } + + msg("Blocked all block edit for " + counter + " players."); + return true; + } + + // -s option (smite) + boolean smite = args[0].equals("-s"); + if (smite) + { + args = ArrayUtils.subarray(args, 1, args.length); + + if (args.length < 1) + { + return false; + } + } + + final Player player = getPlayer(args[0]); + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + String reason = null; + if (args.length > 1) + { + reason = StringUtils.join(args, " ", 1, args.length); + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + if (playerdata.isEditBlock()) + { + FUtil.adminAction(sender.getName(), "Unblocking all block edits for " + player.getName(), true); + playerdata.setEditBlocked(false); + msg("Unblocking all block edits for " + player.getName()); + + msg(player, "You block edits have been unblocked.", ChatColor.RED); + } + else + { + if (plugin.al.isAdmin(player)) + { + msg(player.getName() + " is a superadmin, and his block edits can't be blocked ."); + return true; + } + + FUtil.adminAction(sender.getName(), "Blocking block edits for " + player.getName(), true); + playerdata.setEditBlocked(true); + + if (smite) + { + Command_smite.smite(player, sender); + } + + if (reason != null) + { + msg(player, "You block edits have been blocked. Reason: " + reason, ChatColor.RED); + } + else + { + msg(player, "You block edits have been blocked.", ChatColor.RED); + } + + msg("Blocked all block edits for " + player.getName()); + + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockpvp.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockpvp.java new file mode 100644 index 000000000..3def657fc --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_blockpvp.java @@ -0,0 +1,151 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Toggle PVP mode for players.", usage = "/ [[-s] [reason] | list | purge | all]", aliases = "pvpblock,pvpmode,pvpman,pvman") +public class Command_blockpvp extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + if (args[0].equals("list")) + { + msg("Disabled PVP mode players:"); + FPlayer info; + int count = 0; + for (Player mp : server.getOnlinePlayers()) + { + info = plugin.pl.getPlayer(mp); + if (info.isPVPBlock()) + { + msg("- " + mp.getName()); + count++; + } + } + if (count == 0) + { + msg("- none"); + } + + return true; + } + + if (args[0].equals("purge")) + { + FUtil.adminAction(sender.getName(), "Enabling PVP mode for all players.", true); + FPlayer info; + int count = 0; + for (Player mp : server.getOnlinePlayers()) + { + info = plugin.pl.getPlayer(mp); + if (info.isPVPBlock()) + { + info.setPVPBlock(false); + count++; + } + } + msg("Enabling PVP mode for " + count + " players."); + return true; + } + + if (args[0].equals("all")) + { + FUtil.adminAction(sender.getName(), "Disabling PVP mode for all non-Superadmins", true); + + FPlayer playerdata; + int counter = 0; + for (Player player : server.getOnlinePlayers()) + { + if (!plugin.al.isAdmin(player)) + { + playerdata = plugin.pl.getPlayer(player); + playerdata.setPVPBlock(true); + counter++; + } + } + + msg("Disabling PVP mode for " + counter + " players."); + return true; + } + + // -s option (smite) + boolean smite = args[0].equals("-s"); + if (smite) + { + args = ArrayUtils.subarray(args, 1, args.length); + + if (args.length < 1) + { + return false; + } + } + + final Player player = getPlayer(args[0]); + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + String reason = null; + if (args.length > 1) + { + reason = StringUtils.join(args, " ", 1, args.length); + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + if (playerdata.isPVPBlock()) + { + FUtil.adminAction(sender.getName(), "Enabling PVP mode for " + player.getName(), true); + playerdata.setPVPBlock(false); + msg("Enabling PVP mode for " + player.getName()); + + msg(player, "Your PVP mode have been enabled.", ChatColor.GREEN); + } + else + { + if (plugin.al.isAdmin(player)) + { + msg(player.getName() + " is a superadmin, and his PVP mode can't be disabled."); + return true; + } + + FUtil.adminAction(sender.getName(), "Disabling PVP mode for " + player.getName(), true); + playerdata.setPVPBlock(true); + + if (smite) + { + Command_smite.smite(player, sender); + } + + if (reason != null) + { + msg(player, "Your PVP Mode has been disabled. Reason: " + reason, ChatColor.RED); + } + else + { + msg(player, "Your PVP Mode has been disabled.", ChatColor.RED); + } + + msg("Disabled PVP mode for " + player.getName()); + + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cage.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cage.java new file mode 100644 index 000000000..56f20be0c --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cage.java @@ -0,0 +1,120 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) + +@CommandParameters(description = "Place a cage around someone.", usage = "/ [custom | block] [Block name | Player name(for skull)]") +public class Command_cage extends FreedomCommand +{ + + public static String playerSkullName; + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + if ("off".equals(args[0]) && sender instanceof Player) + { + FUtil.adminAction(sender.getName(), "Uncaging " + sender.getName(), true); + FPlayer playerdata = plugin.pl.getPlayer(playerSender); + + playerdata.getCageData().setCaged(false); + return true; + } + else if ("purge".equals(args[0])) + { + FUtil.adminAction(sender.getName(), "Uncaging all players", true); + + for (Player player : server.getOnlinePlayers()) + { + FPlayer playerdata = plugin.pl.getPlayer(player); + playerdata.getCageData().setCaged(false); + } + + return true; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + + Material outerMaterial = Material.GLASS; + Material innerMaterial = Material.AIR; + + if (args.length >= 2) + { + if (null != args[1]) + { + switch (args[1]) + { + case "off": + FUtil.adminAction(sender.getName(), "Uncaging " + player.getName(), true); + playerdata.getCageData().setCaged(false); + + return true; + case "custom": + outerMaterial = Material.SKULL; + playerSkullName = args[2]; + break; + case "block": + if (Material.matchMaterial(args[2]) != null) + { + outerMaterial = Material.matchMaterial(args[2]); + } + else + { + sender.sendMessage(ChatColor.RED + "Invalid block!"); + } + break; + } + } + } + + if (args.length >= 3) + { + if (args[2].equalsIgnoreCase("water")) + { + innerMaterial = Material.STATIONARY_WATER; + } + else if (args[2].equalsIgnoreCase("lava")) + { + innerMaterial = Material.STATIONARY_LAVA; + } + } + + Location targetPos = player.getLocation().clone().add(0, 1, 0); + playerdata.getCageData().cage(targetPos, outerMaterial, innerMaterial); + + player.setGameMode(GameMode.SURVIVAL); + + if (outerMaterial != Material.SKULL) + { + FUtil.adminAction(sender.getName(), "Caging " + player.getName(), true); + } + else + { + FUtil.adminAction(sender.getName(), "Caging " + player.getName() + " in " + playerSkullName, true); + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cake.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cake.java new file mode 100644 index 000000000..0178ce106 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cake.java @@ -0,0 +1,54 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.Random; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Achievement; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "For the people that are still alive.", usage = "/") +public class Command_cake extends FreedomCommand +{ + + public static final String CAKE_LYRICS = "But there's no sense crying over every mistake. You just keep on trying till you run out of cake."; + private final Random random = new Random(); + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + final StringBuilder output = new StringBuilder(); + + final String[] words = CAKE_LYRICS.split(" "); + for (final String word : words) + { + output.append(ChatColor.COLOR_CHAR).append(Integer.toHexString(1 + random.nextInt(14))).append(word).append(" "); + } + + final ItemStack heldItem = new ItemStack(Material.CAKE); + final ItemMeta heldItemMeta = heldItem.getItemMeta(); + heldItemMeta.setDisplayName((new StringBuilder()).append(ChatColor.WHITE).append("The ").append(ChatColor.DARK_GRAY).append("Lie").toString()); + heldItem.setItemMeta(heldItemMeta); + + for (final Player player : server.getOnlinePlayers()) + { + final int firstEmpty = player.getInventory().firstEmpty(); + if (firstEmpty >= 0) + { + player.getInventory().setItem(firstEmpty, heldItem); + } + + player.awardAchievement(Achievement.BAKE_CAKE); + } + + FUtil.bcastMsg(output.toString()); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cartsit.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cartsit.java new file mode 100644 index 000000000..b9e0a07dd --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cartsit.java @@ -0,0 +1,82 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Minecart; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.BOTH) +@CommandParameters(description = "Sit in nearest minecart. If target is in a minecart already, they will disembark.", usage = "/ [partialname]") +public class Command_cartsit extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + Player targetPlayer = playerSender; + + if (args.length == 1) + { + + targetPlayer = getPlayer(args[0]); + + if (targetPlayer == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + } + + if (senderIsConsole) + { + if (targetPlayer == null) + { + sender.sendMessage("When used from the console, you must define a target player: /cartsit "); + return true; + } + } + else if (targetPlayer != playerSender && !isAdmin(sender)) + { + sender.sendMessage("Only superadmins can select another player as a /cartsit target."); + return true; + } + + if (targetPlayer.isInsideVehicle()) + { + targetPlayer.getVehicle().eject(); + } + else + { + Minecart nearest_cart = null; + for (Minecart cart : targetPlayer.getWorld().getEntitiesByClass(Minecart.class)) + { + if (cart.isEmpty()) + { + if (nearest_cart == null) + { + nearest_cart = cart; + } + else + { + if (cart.getLocation().distanceSquared(targetPlayer.getLocation()) < nearest_cart.getLocation().distanceSquared(targetPlayer.getLocation())) + { + nearest_cart = cart; + } + } + } + } + + if (nearest_cart != null) + { + nearest_cart.setPassenger(targetPlayer); + } + else + { + sender.sendMessage("There are no empty minecarts in the target world."); + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cbtool.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cbtool.java new file mode 100644 index 000000000..2c809112f --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cbtool.java @@ -0,0 +1,218 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.DepreciationAggregator; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.BOTH) +@CommandParameters(description = "No Description Yet", usage = "/") +public class Command_cbtool extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + if ("targetblock".equalsIgnoreCase(args[0]) && sender instanceof Player) + { + Block targetBlock = DepreciationAggregator.getTargetBlock(playerSender, null, 100); + msg("Your target block: " + targetBlock.getLocation().toString()); + return true; + } + + try + { + final StringBuffer generatedCommand = new StringBuffer(); + + final Matcher matcher = Pattern.compile("\\[(.+?)\\]").matcher(StringUtils.join(args, " ").trim()); + while (matcher.find()) + { + matcher.appendReplacement(generatedCommand, processSubCommand(matcher.group(1))); + } + matcher.appendTail(generatedCommand); + + if (plugin.cb.isCommandBlocked(generatedCommand.toString(), sender, false)) + { + return true; + } + + server.dispatchCommand(sender, generatedCommand.toString()); + } + catch (SubCommandFailureException ex) + { + } + catch (Exception ex) + { + FLog.severe(ex); + } + + return true; + } + + private String processSubCommand(final String subcommand) throws SubCommandFailureException + { + final String[] args = StringUtils.split(subcommand, " "); + + if (args.length == 1) + { + throw new SubCommandFailureException("Invalid subcommand name."); + } + + return SubCommand.getByName(args[0]).getExecutable().execute(ArrayUtils.remove(args, 0)); + } + + private static enum SubCommand + { + + PLAYER_DETECT("playerdetect", new SubCommandExecutable() + { + @Override + public String execute(String[] args) throws SubCommandFailureException + { + if (args.length != 5) + { + throw new SubCommandFailureException("Invalid # of arguments."); + } + + double x, y, z; + try + { + x = Double.parseDouble(args[0].trim()); + y = Double.parseDouble(args[1].trim()); + z = Double.parseDouble(args[2].trim()); + } + catch (NumberFormatException ex) + { + throw new SubCommandFailureException("Invalid coordinates."); + } + + World world = null; + final String needleWorldName = args[3].trim(); + final List worlds = Bukkit.getWorlds(); + for (final World testWorld : worlds) + { + if (testWorld.getName().trim().equalsIgnoreCase(needleWorldName)) + { + world = testWorld; + break; + } + } + + if (world == null) + { + throw new SubCommandFailureException("Invalid world name."); + } + + final Location testLocation = new Location(world, x, y, z); + + double radius; + try + { + radius = Double.parseDouble(args[4].trim()); + } + catch (NumberFormatException ex) + { + throw new SubCommandFailureException("Invalid radius."); + } + + final double radiusSq = radius * radius; + + final List worldPlayers = testLocation.getWorld().getPlayers(); + for (final Player testPlayer : worldPlayers) + { + if (testPlayer.getLocation().distanceSquared(testLocation) < radiusSq) + { + return testPlayer.getName(); + } + } + + throw new SubCommandFailureException("No player found in range."); + } + }), + PLAYER_DETECT_BOOLEAN("playerdetectboolean", new SubCommandExecutable() + { + @Override + public String execute(String[] args) throws SubCommandFailureException + { + try + { + PLAYER_DETECT.getExecutable().execute(args); + } + catch (SubCommandFailureException ex) + { + return "0"; + } + + return "1"; + } + }); + // + private final String name; + private final SubCommandExecutable executable; + + private SubCommand(String subCommandName, SubCommandExecutable subCommandImpl) + { + this.name = subCommandName; + this.executable = subCommandImpl; + } + + public SubCommandExecutable getExecutable() + { + return executable; + } + + public String getName() + { + return name; + } + + public static SubCommand getByName(String needle) throws SubCommandFailureException + { + needle = needle.trim(); + for (SubCommand subCommand : values()) + { + if (subCommand.getName().equalsIgnoreCase(needle)) + { + return subCommand; + } + } + throw new SubCommandFailureException("Invalid subcommand name."); + } + } + + private interface SubCommandExecutable + { + + public String execute(String[] args) throws SubCommandFailureException; + } + + private static class SubCommandFailureException extends Exception + { + + public SubCommandFailureException() + { + } + + public SubCommandFailureException(String message) + { + super(message); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cmdspy.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cmdspy.java new file mode 100644 index 000000000..c316a46ae --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_cmdspy.java @@ -0,0 +1,24 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Spy on commands", usage = "/", aliases = "commandspy") +public class Command_cmdspy extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + + FPlayer playerdata = plugin.pl.getPlayer(playerSender); + playerdata.setCommandSpy(!playerdata.cmdspyEnabled()); + msg("CommandSpy " + (playerdata.cmdspyEnabled() ? "enabled." : "disabled.")); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_colorme.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_colorme.java new file mode 100644 index 000000000..b6734dcf1 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_colorme.java @@ -0,0 +1,59 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.Iterator; +import java.util.Map; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +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 = "Essentials Interface Command - Color your current nickname.", usage = "/ ") +public class Command_colorme extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if ("list".equalsIgnoreCase(args[0])) + { + msg("Colors: " + StringUtils.join(FUtil.CHAT_COLOR_NAMES.keySet(), ", ")); + return true; + } + + final String needle = args[0].trim().toLowerCase(); + ChatColor color = null; + final Iterator> it = FUtil.CHAT_COLOR_NAMES.entrySet().iterator(); + while (it.hasNext()) + { + final Map.Entry entry = it.next(); + if (entry.getKey().contains(needle)) + { + color = entry.getValue(); + break; + } + } + + if (color == null) + { + msg("Invalid color: " + needle + " - Use \"/colorme list\" to list colors."); + return true; + } + + final String newNick = color + ChatColor.stripColor(playerSender.getDisplayName()).trim() + ChatColor.WHITE; + + plugin.esb.setNickname(sender.getName(), newNick); + + msg("Your nickname is now: " + newNick); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_commandlist.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_commandlist.java new file mode 100644 index 000000000..21176b4ba --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_commandlist.java @@ -0,0 +1,53 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.BOTH) +@CommandParameters(description = "Show all commands for all server plugins.", usage = "/", aliases = "cmdlist") +public class Command_commandlist extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + List commands = new ArrayList<>(); + + for (Plugin targetPlugin : server.getPluginManager().getPlugins()) + { + try + { + PluginDescriptionFile desc = targetPlugin.getDescription(); + Map> map = (Map>) desc.getCommands(); + + if (map != null) + { + for (Entry> entry : map.entrySet()) + { + String command_name = (String) entry.getKey(); + commands.add(command_name); + } + } + } + catch (Throwable ex) + { + } + } + + Collections.sort(commands); + + sender.sendMessage(StringUtils.join(commands, ",")); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_consolesay.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_consolesay.java new file mode 100644 index 000000000..e692cac85 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_consolesay.java @@ -0,0 +1,24 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_CONSOLE) +@CommandParameters(description = "Telnet command - Send a chat message with chat formatting over telnet.", usage = "/ ", aliases = "csay") +public class Command_consolesay extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length > 0) + { + FUtil.bcastMsg(String.format("§7[CONSOLE]§f<§c%s§f> %s", sender.getName(), StringUtils.join(args, " "))); + } + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_creative.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_creative.java new file mode 100644 index 000000000..1bed3abf5 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_creative.java @@ -0,0 +1,58 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Quickly change your own gamemode to creative, or define someone's username to change theirs.", usage = "/ <-a | [partialname]>", aliases = "gmc") +public class Command_creative extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + if (isConsole()) + { + sender.sendMessage("When used from the console, you must define a target player."); + return true; + } + + playerSender.setGameMode(GameMode.CREATIVE); + msg("Gamemode set to creative."); + return true; + } + + checkRank(Rank.SUPER_ADMIN); + + if (args[0].equals("-a")) + { + for (Player targetPlayer : server.getOnlinePlayers()) + { + targetPlayer.setGameMode(GameMode.CREATIVE); + } + + FUtil.adminAction(sender.getName(), "Changing everyone's gamemode to creative", false); + return true; + } + + Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + msg("Setting " + player.getName() + " to game mode creative"); + msg(player, sender.getName() + " set your game mode to creative"); + player.setGameMode(GameMode.CREATIVE); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deafen.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deafen.java new file mode 100644 index 000000000..622145ae8 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deafen.java @@ -0,0 +1,52 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.Random; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Make some noise.", usage = "/") +public class Command_deafen extends FreedomCommand +{ + + private static final Random random = new Random(); + public static final double STEPS = 10.0; + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + for (final Player player : server.getOnlinePlayers()) + { + for (double percent = 0.0; percent <= 1.0; percent += (1.0 / STEPS)) + { + final float pitch = (float) (percent * 2.0); + + new BukkitRunnable() + { + @Override + public void run() + { + player.playSound(randomOffset(player.getLocation(), 5.0), Sound.values()[random.nextInt(Sound.values().length)], 100.0f, pitch); + } + }.runTaskLater(plugin, Math.round(20.0 * percent * 2.0)); + } + } + + return true; + } + + private static Location randomOffset(Location a, double magnitude) + { + return a.clone().add(randomDoubleRange(-1.0, 1.0) * magnitude, randomDoubleRange(-1.0, 1.0) * magnitude, randomDoubleRange(-1.0, 1.0) * magnitude); + } + + private static Double randomDoubleRange(double min, double max) + { + return min + (random.nextDouble() * ((max - min) + 1.0)); + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_debug.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_debug.java new file mode 100644 index 000000000..83467786b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_debug.java @@ -0,0 +1,113 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.lang.reflect.Field; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.ONLY_CONSOLE) +@CommandParameters(description = "For developers only - debug things via reflection.", usage = "/") +public class Command_debug extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 3) + { + return false; + } + + try + { + String className = args[0]; + String fieldName = args[1]; + String newValue = StringUtils.join(ArrayUtils.subarray(args, 2, args.length), " "); + + if (className.equalsIgnoreCase("_")) + { + className = "me.StevenLawson.TotalFreedomMod.TotalFreedomMod"; + } + + setStaticValue(className, fieldName, newValue); + + sender.sendMessage("Debug: OK"); + } + catch (Exception ex) + { + sender.sendMessage(ex.getMessage()); + } + + return true; + } + + public static void setStaticValue(final String className, final String fieldName, final String newValueString) throws Exception + { + Class forName = Class.forName(className); + if (forName != null) + { + final Field field = forName.getDeclaredField(fieldName); + if (field != null) + { + Object newValue; + + Class type = field.getType(); + if (type.isPrimitive()) + { + if (type.getName().equals("int")) + { + newValue = Integer.parseInt(newValueString); + } + else if (type.getName().equals("double")) + { + newValue = Double.parseDouble(newValueString); + } + else if (type.getName().equals("boolean")) + { + newValue = Boolean.parseBoolean(newValueString); + } + else + { + throw new Exception("Unknown primitive field type."); + } + } + else + { + if (type.isAssignableFrom(Integer.class)) + { + newValue = new Integer(newValueString); + } + else if (type.isAssignableFrom(Double.class)) + { + newValue = new Double(newValueString); + } + else if (type.isAssignableFrom(Boolean.class)) + { + newValue = Boolean.valueOf(newValueString); + } + else if (type.isAssignableFrom(String.class)) + { + newValue = newValueString; + } + else + { + throw new Exception("Unknown complex field type."); + } + } + + field.setAccessible(true); + + final Object oldValue = field.get(Class.forName(className)); + if (oldValue != null) + { + field.set(oldValue, newValue); + } + + field.setAccessible(false); + } + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_denick.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_denick.java new file mode 100644 index 000000000..697a93885 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_denick.java @@ -0,0 +1,26 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Essentials Interface Command - Remove the nickname of all players on the server.", usage = "/") +public class Command_denick extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Removing all nicknames", false); + + for (Player player : server.getOnlinePlayers()) + { + plugin.esb.setNickname(player.getName(), null); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java new file mode 100644 index 000000000..0a2d92482 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deop.java @@ -0,0 +1,46 @@ +package me.totalfreedom.totalfreedommod.command; + +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; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Deop a player.", usage = "/ ") +public class Command_deop extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + OfflinePlayer player = null; + + for (Player onlinePlayer : server.getOnlinePlayers()) + { + if (args[0].equalsIgnoreCase(onlinePlayer.getName())) + { + player = onlinePlayer; + } + } + + // if the player is not online + if (player == null) + { + player = DepreciationAggregator.getOfflinePlayer(server, args[0]); + } + + FUtil.adminAction(sender.getName(), "De-opping " + player.getName(), false); + + player.setOp(false); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java new file mode 100644 index 000000000..1eb990cf3 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_deopall.java @@ -0,0 +1,27 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Deop everyone on the server.", usage = "/") +public class Command_deopall extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "De-opping all players on the server", true); + + for (Player player : server.getOnlinePlayers()) + { + player.setOp(false); + player.sendMessage(FreedomCommand.YOU_ARE_NOT_OP); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_disguisetoggle.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_disguisetoggle.java new file mode 100644 index 000000000..eee8958c0 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_disguisetoggle.java @@ -0,0 +1,41 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.libraryaddict.disguise.DisallowedDisguises; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Toggle the disguise plugin", usage = "/", aliases = "dtoggle") +public class Command_disguisetoggle extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!plugin.ldb.isPluginEnabled()) + { + msg(ChatColor.RED + "LibsDisguises is not enabled."); + return true; + } + + FUtil.adminAction(sender.getName(), (DisallowedDisguises.disabled ? "Enabling" : "Disabling") + " Disguises", false); + + if (plugin.ldb.isDisguisesEnabled()) + { + plugin.ldb.undisguiseAll(true); + plugin.ldb.setDisguisesEnabled(false); + } + else + { + plugin.ldb.setDisguisesEnabled(true); + } + + msg("Disguises are currently " + (DisallowedDisguises.disabled ? "disabled." : "enabled.")); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_dispfill.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_dispfill.java new file mode 100644 index 000000000..8d0e12e33 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_dispfill.java @@ -0,0 +1,112 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.List; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.DepreciationAggregator; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Dispenser; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Fill nearby dispensers with a set of items of your choice.", usage = "/ ") +public class Command_dispfill extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 2) + { + int radius; + + try + { + radius = Math.max(5, Math.min(25, Integer.parseInt(args[0]))); + } + catch (NumberFormatException ex) + { + sender.sendMessage("Invalid radius."); + return true; + } + + final List items = new ArrayList<>(); + + final String[] itemsRaw = StringUtils.split(args[1], ","); + for (final String searchItem : itemsRaw) + { + Material material = Material.matchMaterial(searchItem); + if (material == null) + { + try + { + material = DepreciationAggregator.getMaterial(Integer.parseInt(searchItem)); + } + catch (NumberFormatException ex) + { + } + } + + if (material != null) + { + items.add(new ItemStack(material, 64)); + } + else + { + sender.sendMessage("Skipping invalid item: " + searchItem); + } + } + + final ItemStack[] itemsArray = items.toArray(new ItemStack[items.size()]); + + int affected = 0; + final Location centerLocation = playerSender.getLocation(); + final Block centerBlock = centerLocation.getBlock(); + for (int xOffset = -radius; xOffset <= radius; xOffset++) + { + for (int yOffset = -radius; yOffset <= radius; yOffset++) + { + for (int zOffset = -radius; zOffset <= radius; zOffset++) + { + final Block targetBlock = centerBlock.getRelative(xOffset, yOffset, zOffset); + if (targetBlock.getLocation().distanceSquared(centerLocation) < (radius * radius)) + { + if (targetBlock.getType().equals(Material.DISPENSER)) + { + sender.sendMessage("Filling dispenser @ " + FUtil.formatLocation(targetBlock.getLocation())); + setDispenserContents(targetBlock, itemsArray); + affected++; + } + } + } + } + } + + sender.sendMessage("Done. " + affected + " dispenser(s) filled."); + } + else + { + return false; + } + + return true; + } + + private static void setDispenserContents(final Block targetBlock, final ItemStack[] items) + { + if (targetBlock.getType() == Material.DISPENSER) + { + final Inventory dispenserInv = ((Dispenser) targetBlock.getState()).getInventory(); + dispenserInv.clear(); + dispenserInv.addItem(items); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_doom.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_doom.java new file mode 100644 index 000000000..61e6306de --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_doom.java @@ -0,0 +1,111 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.banning.Ban; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.ONLY_CONSOLE, blockHostConsole = true) +@CommandParameters(description = "For the bad admins", usage = "/ ") +public class Command_doom extends FreedomCommand +{ + + @Override + public boolean run(final CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + FUtil.adminAction(sender.getName(), "Casting oblivion over " + player.getName(), true); + FUtil.bcastMsg(player.getName() + " will be completely obliviated!", ChatColor.RED); + + final String ip = player.getAddress().getAddress().getHostAddress().trim(); + + // Remove from superadmin + Admin admin = getAdmin(player); + if (admin != null) + { + FUtil.adminAction(sender.getName(), "Removing " + player.getName() + " from the superadmin list", true); + plugin.al.removeAdmin(admin); + } + + // Remove from whitelist + player.setWhitelisted(false); + + // Deop + player.setOp(false); + + // Ban player + Ban ban = Ban.forPlayer(player, sender); + ban.setReason("&cFUCKOFF"); + for (String playerIp : plugin.pl.getData(player).getIps()) + { + ban.addIp(playerIp); + } + plugin.bm.addBan(ban); + + // Set gamemode to survival + player.setGameMode(GameMode.SURVIVAL); + + // Clear inventory + player.closeInventory(); + player.getInventory().clear(); + + // Ignite player + player.setFireTicks(10000); + + // Generate explosion + player.getWorld().createExplosion(player.getLocation(), 0F, false); + + // Shoot the player in the sky + player.setVelocity(player.getVelocity().clone().add(new Vector(0, 20, 0))); + + new BukkitRunnable() + { + @Override + public void run() + { + // strike lightning + player.getWorld().strikeLightning(player.getLocation()); + + // kill (if not done already) + player.setHealth(0.0); + } + }.runTaskLater(plugin, 2L * 20L); + + new BukkitRunnable() + { + @Override + public void run() + { + // message + FUtil.adminAction(sender.getName(), "Banning " + player.getName() + ", IP: " + ip, true); + + // generate explosion + player.getWorld().createExplosion(player.getLocation(), 0F, false); + + // kick player + player.kickPlayer(ChatColor.RED + "FUCKOFF, and get your shit together!"); + } + }.runTaskLater(plugin, 3L * 20L); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_enchant.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_enchant.java new file mode 100644 index 000000000..f7d1f4fe2 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_enchant.java @@ -0,0 +1,129 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Enchant items.", usage = "/ | remove >") +public class Command_enchant extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + ItemStack item = playerSender.getEquipment().getItemInMainHand(); + + if (item == null || item.getType() == Material.AIR) + { + msg("You have to hold an item to enchant it"); + return true; + } + + if (args[0].equalsIgnoreCase("list")) + { + boolean has_enchantments = false; + + StringBuilder possible_ench = new StringBuilder("Possible enchantments for held item: "); + for (Enchantment ench : Enchantment.values()) + { + if (ench.canEnchantItem(item)) + { + has_enchantments = true; + possible_ench.append(ench.getName()).append(", "); + } + } + + if (has_enchantments) + { + msg(possible_ench.toString()); + } + else + { + msg("The held item has no enchantments."); + } + } + else if (args[0].equalsIgnoreCase("addall")) + { + for (Enchantment ench : Enchantment.values()) + { + try + { + if (ench.canEnchantItem(item)) + { + item.addEnchantment(ench, ench.getMaxLevel()); + } + } + catch (Exception ex) + { + msg("Could not add enchantment: " + ench.getName()); + } + } + + msg("Added all possible enchantments for this item."); + } + else if (args[0].equalsIgnoreCase("reset")) + { + for (Enchantment ench : item.getEnchantments().keySet()) + { + item.removeEnchantment(ench); + } + + msg("Removed all enchantments."); + } + else + { + if (args.length < 2) + { + return false; + } + + Enchantment ench = null; + + try + { + ench = Enchantment.getByName(args[1]); + } + catch (Exception ex) + { + } + + if (ench == null) + { + msg(args[1] + " is an invalid enchantment for the held item. Type \"/enchant list\" for valid enchantments for this item."); + return true; + } + + if (args[0].equalsIgnoreCase("add")) + { + if (ench.canEnchantItem(item)) + { + item.addEnchantment(ench, ench.getMaxLevel()); + + msg("Added enchantment: " + ench.getName()); + } + else + { + msg("Can't use this enchantment on held item."); + } + } + else if (args[0].equals("remove")) + { + item.removeEnchantment(ench); + + msg("Removed enchantment: " + ench.getName()); + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ender.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ender.java new file mode 100644 index 000000000..522c36e5d --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ender.java @@ -0,0 +1,20 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Goto the ender / \"The End\".", usage = "/") +public class Command_ender extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + plugin.wm.gotoWorld(playerSender, server.getWorlds().get(0).getName() + "_the_end"); + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_entitywipe.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_entitywipe.java new file mode 100644 index 000000000..d6eaf9bb2 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_entitywipe.java @@ -0,0 +1,22 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Remove various server entities that may cause lag, such as dropped items, minecarts, and boats.", usage = "/ ", aliases = "ew,rd") +public class Command_entitywipe extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Removing all server entities.", true); + msg((plugin.ew.wipeEntities(true)) + " entities removed."); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_expel.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_expel.java new file mode 100644 index 000000000..0285ff05a --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_expel.java @@ -0,0 +1,90 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.List; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Push people away from you.", usage = "/ [radius] [strength]") +public class Command_expel extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + double radius = 20.0; + double strength = 5.0; + + if (args.length >= 1) + { + try + { + radius = Math.max(1.0, Math.min(100.0, Double.parseDouble(args[0]))); + } + catch (NumberFormatException ex) + { + } + } + + if (args.length >= 2) + { + try + { + strength = Math.max(0.0, Math.min(50.0, Double.parseDouble(args[1]))); + } + catch (NumberFormatException ex) + { + } + } + + List pushedPlayers = new ArrayList<>(); + + final Vector senderPos = playerSender.getLocation().toVector(); + final List players = playerSender.getWorld().getPlayers(); + for (final Player player : players) + { + if (player.equals(playerSender)) + { + continue; + } + + final Location targetPos = player.getLocation(); + final Vector targetPosVec = targetPos.toVector(); + + boolean inRange = false; + try + { + inRange = targetPosVec.distanceSquared(senderPos) < (radius * radius); + } + catch (IllegalArgumentException ex) + { + } + + if (inRange) + { + player.getWorld().createExplosion(targetPos, 0.0f, false); + FUtil.setFlying(player, false); + player.setVelocity(targetPosVec.subtract(senderPos).normalize().multiply(strength)); + pushedPlayers.add(player.getName()); + } + } + + if (pushedPlayers.isEmpty()) + { + msg("No players pushed."); + } + else + { + msg("Pushed " + pushedPlayers.size() + " players: " + StringUtils.join(pushedPlayers, ", ")); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_findip.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_findip.java new file mode 100644 index 000000000..6c209106b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_findip.java @@ -0,0 +1,35 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Shows all IPs registered to a player", usage = "/ ") +public class Command_findip extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + + msg(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + msg("Player IPs: " + StringUtils.join(plugin.pl.getData(player).getIps(), ", ")); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_flatlands.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_flatlands.java new file mode 100644 index 000000000..ac3fb5c67 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_flatlands.java @@ -0,0 +1,27 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Goto the flatlands.", usage = "/") +public class Command_flatlands extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (ConfigEntry.FLATLANDS_GENERATE.getBoolean()) + { + plugin.wm.flatlands.sendToWorld(playerSender); + } + else + { + msg("Flatlands is currently disabled."); + } + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_freeze.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_freeze.java new file mode 100644 index 000000000..63316d3ad --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_freeze.java @@ -0,0 +1,67 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.freeze.FreezeData; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Freeze players (toggles on and off).", usage = "/ [target | purge]", aliases = "fr") +public class Command_freeze extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + boolean gFreeze = !plugin.fm.isGlobalFreeze(); + plugin.fm.setGlobalFreeze(gFreeze); + + if (!gFreeze) + { + FUtil.adminAction(sender.getName(), "Disabling global player freeze", false); + msg("Players are now free to move."); + return true; + } + + FUtil.adminAction(sender.getName(), "Enabling global player freeze", false); + for (Player player : server.getOnlinePlayers()) + { + if (!isAdmin(player)) + { + msg(player, "You have been frozen due to rulebreakers, you will be unfrozen soon.", ChatColor.RED); + } + } + msg("Players are now frozen."); + + return true; + } + + if (args[0].equals("purge")) + { + FUtil.adminAction(sender.getName(), "Unfreezing all players", false); + plugin.fm.purge(); + return true; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND, ChatColor.RED); + return true; + } + + final FreezeData fd = plugin.pl.getPlayer(player).getFreezeData(); + fd.setFrozen(!fd.isFrozen()); + + msg(player.getName() + " has been " + (fd.isFrozen() ? "frozen" : "unfrozen") + "."); + msg(player, "You have been " + (fd.isFrozen() ? "frozen" : "unfrozen") + ".", ChatColor.AQUA); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_fuckoff.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_fuckoff.java new file mode 100644 index 000000000..a931bf2a8 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_fuckoff.java @@ -0,0 +1,50 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "You'll never even see it coming.", usage = "/ ") +public class Command_fuckoff extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + FPlayer player = plugin.pl.getPlayer(playerSender); + + if (!args[0].equals("on")) + { + player.disableFuckoff(); + } + else + { + + double radius = 25.0; + if (args.length >= 2) + { + try + { + radius = Math.max(5.0, Math.min(50, Double.parseDouble(args[1]))); + } + catch (NumberFormatException ex) + { + } + } + + player.setFuckoff(radius); + } + + msg("Fuckoff " + (player.isFuckOff() ? ("enabled. Radius: " + player.getFuckoffRadius() + ".") : "disabled.")); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gadmin.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gadmin.java new file mode 100644 index 000000000..adb3e44e8 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gadmin.java @@ -0,0 +1,209 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.nio.charset.StandardCharsets; +import java.util.Iterator; +import java.util.UUID; +import me.totalfreedom.totalfreedommod.banning.Ban; +import me.totalfreedom.totalfreedommod.freeze.FreezeData; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters( + description = "Use admin commands on someone by hash. Use mode 'list' to get a player's hash. Other modes are kick, nameban, ipban, ban, op, deop, ci, fr, smite.", + usage = "/ [list | [ ] ]") +public class Command_gadmin extends FreedomCommand +{ + + private enum GadminMode + { + + LIST("list"), + KICK("kick"), + NAMEBAN("nameban"), + IPBAN("ipban"), + BAN("ban"), + OP("op"), + DEOP("deop"), + CI("ci"), + FR("fr"), + SMITE("smite"); + private final String modeName; + + private GadminMode(String command) + { + this.modeName = command; + } + + public String getModeName() + { + return modeName; + } + + public static GadminMode findMode(String needle) + { + for (final GadminMode mode : GadminMode.values()) + { + if (needle.equalsIgnoreCase(mode.getModeName())) + { + return mode; + } + } + return null; + } + } + + public String getPlayerHash(Player player) + { + return UUID.nameUUIDFromBytes(player.getName().toLowerCase().getBytes(StandardCharsets.UTF_8)).toString().substring(0, 4); + } + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + final GadminMode mode = GadminMode.findMode(args[0].toLowerCase()); + if (mode == null) + { + msg("Invalid mode: " + args[0], ChatColor.RED); + return true; + } + + final Iterator it = server.getOnlinePlayers().iterator(); + + if (mode == GadminMode.LIST) + { + msg("[ Real Name ] : [ Display Name ] - Hash:"); + while (it.hasNext()) + { + final Player player = it.next(); + sender.sendMessage(ChatColor.GRAY + String.format("[ %s ] : [ %s ] - %s", + player.getName(), + ChatColor.stripColor(player.getDisplayName()), + getPlayerHash(player))); + } + return true; + } + + if (args.length < 2) + { + return false; + } + + Player target = null; + while (it.hasNext() && target == null) + { + final Player player = it.next(); + final String hash = getPlayerHash(player); + + if (hash.equalsIgnoreCase(args[1])) + { + target = player; + } + } + + if (target == null) + { + msg("Invalid player hash: " + args[1], ChatColor.RED); + return true; + } + + switch (mode) + { + case KICK: + { + FUtil.adminAction(sender.getName(), String.format("Kicking: %s.", target.getName()), false); + target.kickPlayer("Kicked by Administrator"); + + break; + } + case NAMEBAN: + { + FUtil.adminAction(sender.getName(), String.format("Banning Name: %s.", target.getName()), true); + plugin.bm.addBan(Ban.forPlayerName(target, sender, null, null)); + target.kickPlayer("Username banned by Administrator."); + + break; + } + case IPBAN: + { + String ip = target.getAddress().getAddress().getHostAddress(); + String[] ip_parts = ip.split("\\."); + if (ip_parts.length == 4) + { + ip = String.format("%s.%s.*.*", ip_parts[0], ip_parts[1]); + } + FUtil.adminAction(sender.getName(), String.format("Banning IP: %s.", ip), true); + plugin.bm.addBan(Ban.forPlayerIp(ip, sender, null, null)); + + target.kickPlayer("IP address banned by Administrator."); + + break; + } + case BAN: + { + String ip = target.getAddress().getAddress().getHostAddress(); + String[] ip_parts = ip.split("\\."); + if (ip_parts.length == 4) + { + ip = String.format("%s.%s.*.*", ip_parts[0], ip_parts[1]); + } + FUtil.adminAction(sender.getName(), String.format("Banning Name: %s, IP: %s.", target.getName(), ip), true); + + plugin.bm.addBan(Ban.forPlayer(target, sender)); + + target.kickPlayer("IP and username banned by Administrator."); + + break; + } + case OP: + { + FUtil.adminAction(sender.getName(), String.format("Opping %s.", target.getName()), false); + target.setOp(true); + target.sendMessage(FreedomCommand.YOU_ARE_OP); + + break; + } + case DEOP: + { + FUtil.adminAction(sender.getName(), String.format("Deopping %s.", target.getName()), false); + target.setOp(false); + target.sendMessage(FreedomCommand.YOU_ARE_NOT_OP); + + break; + } + case CI: + { + target.getInventory().clear(); + + break; + } + case FR: + { + FreezeData fd = plugin.pl.getPlayer(target).getFreezeData(); + fd.setFrozen(!fd.isFrozen()); + + msg(target.getName() + " has been " + (fd.isFrozen() ? "frozen" : "unfrozen") + "."); + target.sendMessage(ChatColor.AQUA + "You have been " + (fd.isFrozen() ? "frozen" : "unfrozen") + "."); + + break; + } + case SMITE: + { + Command_smite.smite(target, sender); + + break; + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gcmd.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gcmd.java new file mode 100644 index 000000000..d4c179de5 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gcmd.java @@ -0,0 +1,56 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Send a command as someone else.", usage = "/ ") +public class Command_gcmd extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 2) + { + return false; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + final String outCommand = StringUtils.join(args, " ", 1, args.length); + + if (plugin.cb.isCommandBlocked(outCommand, sender)) + { + return true; + } + + try + { + msg("Sending command as " + player.getName() + ": " + outCommand); + if (server.dispatchCommand(player, outCommand)) + { + msg("Command sent."); + } + else + { + msg("Unknown error sending command."); + } + } + catch (Throwable ex) + { + msg("Error sending command: " + ex.getMessage()); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_glist.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_glist.java new file mode 100644 index 000000000..116b4187a --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_glist.java @@ -0,0 +1,172 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.List; +import me.totalfreedom.totalfreedommod.banning.Ban; +import me.totalfreedom.totalfreedommod.player.PlayerData; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Bans or unbans any player, even those who are not logged in anymore.", usage = "/ [reason] | unban | banip | unbanip >") +public class Command_glist extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + if (args.length == 1) + { + if ("purge".equals(args[0])) + { + checkRank(Rank.SENIOR_ADMIN); + plugin.pl.purgeAllData(); + msg("Purged playerbase."); + + return true; + } + + return false; + } + + if (args.length < 2) + { + return false; + } + + String username = null; + final List ips = new ArrayList<>(); + boolean usingIp = false; + String banIp = null; + if (args[1].matches("^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$") || args[1].matches("^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\.([*])\\.([*])$")) + { + usingIp = true; + banIp = args[1]; + } + final Player player = getPlayer(args[1]); + + if (player == null && !usingIp) + { + final PlayerData entry = plugin.pl.getData(args[1]); + + if (entry == null) + { + msg("Can't find that user. If target is not logged in, make sure that you spelled the name exactly."); + return true; + } + + username = entry.getUsername(); + ips.addAll(entry.getIps()); + } + + else if (player != null && !usingIp) + { + final PlayerData entry = plugin.pl.getData(player); + username = entry.getUsername(); + ips.addAll(entry.getIps()); + } + + if ("ban".equals(args[0])) + { + if (usingIp) + { + msg("Please specify a player, not an ip."); + return true; + } + final String reason = args.length > 2 ? StringUtils.join(args, " ", 2, args.length) : null; + Ban ban = Ban.forPlayerName(username, sender, null, reason); + for (String ip : ips) + { + ban.addIp(ip); + ban.addIp(FUtil.getFuzzyIp(ip)); + } + FUtil.adminAction(sender.getName(), "Banning " + username + " and IPs: " + StringUtils.join(ips, ", "), true); + + plugin.bm.addBan(ban); + + if (player != null) + { + player.kickPlayer(ban.bakeKickMessage()); + } + return true; + } + + if ("unban".equals(args[0])) + { + if (usingIp) + { + msg("Please specify a player, not an ip."); + return true; + } + FUtil.adminAction(sender.getName(), "Unbanning " + username + " and IPs: " + StringUtils.join(ips, ", "), true); + plugin.bm.removeBan(plugin.bm.getByUsername(username)); + + for (String ip : ips) + { + Ban ban = plugin.bm.getByIp(ip); + if (ban != null) + { + plugin.bm.removeBan(ban); + } + ban = plugin.bm.getByIp(FUtil.getFuzzyIp(ip)); + if (ban != null) + { + plugin.bm.removeBan(ban); + } + } + + return true; + } + + if ("banip".equals(args[0]) || "ipban".equals(args[0])) + { + if (banIp == null) + { + msg("Please specify an IP"); + return true; + } + + final String reason = args.length > 2 ? StringUtils.join(args, " ", 2, args.length) : null; + Ban ban = Ban.forPlayerIp(banIp, sender, null, reason); + plugin.bm.addBan(ban); + FUtil.adminAction(sender.getName(), "Banning IP: " + banIp, true); + return true; + } + + if ("unbanip".equals(args[0]) || "pardonip".equals(args[0])) + { + if (banIp == null) + { + msg("Please specify an IP"); + return true; + } + + FUtil.adminAction(sender.getName(), "Unbanning IP: " + banIp, true); + Ban ban = plugin.bm.getByIp(banIp); + if (ban != null) + { + plugin.bm.removeBan(ban); + plugin.bm.unbanIp(banIp); + } + ban = plugin.bm.getByIp(FUtil.getFuzzyIp(banIp)); + if (ban != null) + { + plugin.bm.removeBan(ban); + plugin.bm.unbanIp(banIp); + } + return true; + } + + return true; + } + +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gtfo.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gtfo.java new file mode 100644 index 000000000..cc4c1e9ff --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_gtfo.java @@ -0,0 +1,103 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.banning.Ban; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Makes someone GTFO (deop and ip ban by username).", usage = "/ ") +public class Command_gtfo extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND, ChatColor.RED); + return true; + } + + String reason = null; + if (args.length >= 2) + { + reason = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " "); + } + + FUtil.bcastMsg(player.getName() + " has been a VERY naughty, naughty boy.", ChatColor.RED); + + // Undo WorldEdits + try + { + plugin.web.undo(player, 15); + } + catch (NoClassDefFoundError ex) + { + } + + // Rollback + plugin.rb.rollback(player.getName()); + + // Deop + player.setOp(false); + + // Gamemode suvival + player.setGameMode(GameMode.SURVIVAL); + + // Clear inventory + player.getInventory().clear(); + + // Strike with lightning + final Location targetPos = player.getLocation(); + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + final Location strike_pos = new Location(targetPos.getWorld(), targetPos.getBlockX() + x, targetPos.getBlockY(), targetPos.getBlockZ() + z); + targetPos.getWorld().strikeLightningEffect(strike_pos); + } + } + + String ip = FUtil.getFuzzyIp(Ips.getIp(player)); + + // Broadcast + final StringBuilder bcast = new StringBuilder() + .append(ChatColor.RED) + .append("Banning: ") + .append(player.getName()) + .append(", IP: ") + .append(ip); + if (reason != null) + { + bcast.append(" - Reason: ").append(ChatColor.YELLOW).append(reason); + } + FUtil.bcastMsg(bcast.toString()); + + // Ban player + plugin.bm.addBan(Ban.forPlayerFuzzy(player, sender, null, reason)); + + // Kill player + player.setHealth(0.0); + + // Kick player + player.kickPlayer(ChatColor.RED + "GTFO"); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_health.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_health.java new file mode 100644 index 000000000..b9412b321 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_health.java @@ -0,0 +1,111 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.text.DecimalFormat; +import java.util.concurrent.atomic.AtomicInteger; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.apache.commons.lang.math.DoubleRange; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "View ticks-per-second", usage = "/") +public class Command_health extends FreedomCommand +{ + + private static final int BYTES_PER_MB = 1024 * 1024; + private static final DoubleRange TPS_RANGE = new DoubleRange(20.0 - 0.1, 20.0 + 0.1); + + @Override + public boolean run(final CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + Runtime runtime = Runtime.getRuntime(); + long usedMem = runtime.totalMemory() - runtime.freeMemory(); + + msg("Reserved Memory: " + (double) runtime.totalMemory() / (double) BYTES_PER_MB + "mb"); + msg("Used Memory: " + new DecimalFormat("#").format((double) usedMem / (double) BYTES_PER_MB) + + "mb (" + new DecimalFormat("#").format(((double) usedMem / (double) runtime.totalMemory()) * 100.0) + "%)"); + msg("Max Memory: " + (double) runtime.maxMemory() / (double) BYTES_PER_MB + "mb"); + msg("Calculating ticks per second, please wait..."); + + new BukkitRunnable() + { + @Override + public void run() + { + try + { + TFM_TickMeter tickMeter = new TFM_TickMeter(plugin); + tickMeter.startTicking(); + Thread.sleep(2500); + final double ticksPerSecond = tickMeter.stopTicking(); + + // Plugin was disabled during async task + if (!plugin.isEnabled()) + { + return; + } + + new BukkitRunnable() + { + @Override + public void run() + { + msg("Ticks per second: " + (TPS_RANGE.containsDouble(ticksPerSecond) ? ChatColor.GREEN : ChatColor.RED) + ticksPerSecond); + } + }.runTask(plugin); + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + }.runTaskAsynchronously(plugin); + + return true; + } + + private class TFM_TickMeter + { + + private final AtomicInteger ticks = new AtomicInteger(); + private final TotalFreedomMod plugin; + private long startTime; + private BukkitTask task; + + public TFM_TickMeter(TotalFreedomMod plugin) + { + this.plugin = plugin; + } + + public void startTicking() + { + startTime = System.currentTimeMillis(); + ticks.set(0); + + task = new BukkitRunnable() + { + @Override + public void run() + { + ticks.incrementAndGet(); + } + }.runTaskTimer(plugin, 0L, 1L); + } + + public double stopTicking() + { + task.cancel(); + long elapsed = System.currentTimeMillis() - startTime; + int tickCount = ticks.get(); + + return (double) tickCount / ((double) elapsed / 1000.0); + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java new file mode 100644 index 000000000..8fb8bb4b6 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invis.java @@ -0,0 +1,68 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.List; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Shows (optionally smites) invisisible players", usage = "/ (smite)") +public class Command_invis extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + boolean smite = false; + if (args.length >= 1) + { + if (args[0].equalsIgnoreCase("smite")) + { + FUtil.adminAction(sender.getName(), "Smiting all invisible players", true); + smite = true; + } + else + { + return false; + } + } + + List players = new ArrayList<>(); + int smites = 0; + + for (Player player : server.getOnlinePlayers()) + { + if (player.hasPotionEffect(PotionEffectType.INVISIBILITY)) + { + players.add(player.getName()); + if (smite && !plugin.al.isAdmin(player)) + { + player.setHealth(0.0); + smites++; + } + } + } + + if (players.isEmpty()) + { + msg("There are no invisible players"); + return true; + } + + if (smite) + { + msg("Smitten " + smites + " players"); + } + else + { + msg("Invisible players (" + players.size() + "): " + StringUtils.join(players, ", ")); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invsee.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invsee.java new file mode 100644 index 000000000..1e95c274b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_invsee.java @@ -0,0 +1,54 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = " Look into another player's inventory, optionally take items out.", usage = "/ ", aliases = "inv,insee") +public class Command_invsee extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + + if (args.length != 1) + { + msg("You need to specify a player."); + return false; + } + + Player player = getPlayer(args[0]); + + if (player == null) + { + msg("This player is not online."); + return false; + } + + if (playerSender == player) + { + msg("You cannot invsee yourself."); + return true; + } + + if (plugin.al.isAdmin(player) && !plugin.al.isAdmin(playerSender)) + { + msg("You can't spy on admins!"); + return true; + + } + + playerSender.closeInventory(); + FPlayer fPlayer = plugin.pl.getPlayer(playerSender); + fPlayer.setInvsee(true); + Inventory playerInv = player.getInventory(); + playerSender.openInventory(playerInv); + return true; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_jumppads.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_jumppads.java new file mode 100644 index 000000000..1fa320246 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_jumppads.java @@ -0,0 +1,96 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.fun.Jumppads; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Manage jumppads", usage = "/ | strength >", aliases = "launchpads,jp") +public class Command_jumppads extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0 || args.length > 2) + { + return false; + } + + if (args.length == 1) + { + if (args[0].equalsIgnoreCase("info")) + { + msg("Jumppads: " + (plugin.jp.getMode().isOn() ? "Enabled" : "Disabled"), ChatColor.BLUE); + msg("Sideways: " + (plugin.jp.getMode() == Jumppads.JumpPadMode.NORMAL_AND_SIDEWAYS ? "Enabled" : "Disabled"), ChatColor.BLUE); + msg("Strength: " + (plugin.jp.getStrength() * 10 - 1), ChatColor.BLUE); + return true; + } + + if ("off".equals(args[0])) + { + FUtil.adminAction(sender.getName(), "Disabling Jumppads", false); + plugin.jp.setMode(Jumppads.JumpPadMode.OFF); + } + else + { + FUtil.adminAction(sender.getName(), "Enabling Jumppads", false); + plugin.jp.setMode(Jumppads.JumpPadMode.MADGEEK); + } + } + else + { + if (plugin.jp.getMode() == Jumppads.JumpPadMode.OFF) + { + msg("Jumppads are currently disabled, please enable them before changing jumppads settings."); + return true; + } + + if (args[0].equalsIgnoreCase("sideways")) + { + if ("off".equals(args[1])) + { + FUtil.adminAction(sender.getName(), "Setting Jumppads mode to: Madgeek", false); + plugin.jp.setMode(Jumppads.JumpPadMode.MADGEEK); + } + else + { + FUtil.adminAction(sender.getName(), "Setting Jumppads mode to: Normal and Sideways", false); + plugin.jp.setMode(Jumppads.JumpPadMode.NORMAL_AND_SIDEWAYS); + } + } + else if (args[0].equalsIgnoreCase("strength")) + { + final float strength; + try + { + strength = Float.parseFloat(args[1]); + } + catch (NumberFormatException ex) + { + msg("Invalid Strength"); + return true; + } + + if (strength > 10 || strength < 1) + { + msg("Invalid Strength: The strength may be 1 through 10."); + return true; + } + + FUtil.adminAction(sender.getName(), "Setting Jumppads strength to: " + String.valueOf(strength), false); + plugin.jp.setStrength((strength / 10) + 0.1F); + } + else + { + return false; + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_kick.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_kick.java new file mode 100644 index 000000000..6f2bf21ce --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_kick.java @@ -0,0 +1,61 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Kick a player.", usage = "/ [reason]", aliases = "k") +public class Command_kick extends FreedomCommand +{ + + @Override + protected boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + Player player = getPlayer(args[0]); + if (player == null) + { + msg(PLAYER_NOT_FOUND); + return true; + } + + if (isAdmin(player)) + { + msg("Admins can not be kicked", ChatColor.RED); + return true; + } + + String reason = null; + if (args.length > 1) + { + reason = StringUtils.join(args, " ", 1, args.length); + } + + StringBuilder builder = new StringBuilder() + .append(ChatColor.RED).append("You have been kicked from the server.") + .append("\n").append(ChatColor.RED).append("Kicked by: ").append(ChatColor.GOLD).append(sender.getName()); + + if (reason != null) + { + builder.append("\n").append(ChatColor.RED).append("Reason: ").append(ChatColor.GOLD).append(reason); + FUtil.adminAction(sender.getName(), "Kicking " + player.getName() + " - Reason: " + reason, true); + } + else + { + FUtil.adminAction(sender.getName(), "Kicking " + player.getName(), true); + } + + player.kickPlayer(builder.toString()); + return true; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_kicknoob.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_kicknoob.java new file mode 100644 index 000000000..382a5af7a --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_kicknoob.java @@ -0,0 +1,30 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.BOTH, blockHostConsole = true) +@CommandParameters(description = "Kick all non-superadmins on server.", usage = "/") +public class Command_kicknoob extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Disconnecting all non-superadmins.", true); + + for (Player player : server.getOnlinePlayers()) + { + if (!plugin.al.isAdmin(player)) + { + player.kickPlayer(ChatColor.RED + "All non-superadmins were kicked by " + sender.getName() + "."); + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_landmine.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_landmine.java new file mode 100644 index 000000000..4ef0ef2f7 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_landmine.java @@ -0,0 +1,67 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.Iterator; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.fun.Landminer.Landmine; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +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 = "Set a landmine trap.", usage = "/") +public class Command_landmine extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!ConfigEntry.LANDMINES_ENABLED.getBoolean()) + { + msg("The landmine is currently disabled.", ChatColor.GREEN); + return true; + } + + if (!ConfigEntry.ALLOW_EXPLOSIONS.getBoolean()) + { + msg("Explosions are currently disabled.", ChatColor.GREEN); + return true; + } + + double radius = 2.0; + + if (args.length >= 1) + { + if ("list".equals(args[0])) + { + final Iterator landmines = plugin.lm.getLandmines().iterator(); + while (landmines.hasNext()) + { + msg(landmines.next().toString()); + } + return true; + } + + try + { + radius = Math.max(2.0, Math.min(6.0, Double.parseDouble(args[0]))); + } + catch (NumberFormatException ex) + { + } + } + + final Block landmine = playerSender.getLocation().getBlock().getRelative(BlockFace.DOWN); + landmine.setType(Material.TNT); + plugin.lm.add(new Landmine(landmine.getLocation(), playerSender, radius)); + + msg("Landmine planted - Radius = " + radius + " blocks.", ChatColor.GREEN); + + return true; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_lastcmd.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_lastcmd.java new file mode 100644 index 000000000..f8d26a555 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_lastcmd.java @@ -0,0 +1,45 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Show the last command that someone used.", usage = "/ ") +public class Command_lastcmd extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + final Player player = getPlayer(args[0]); + + if (player == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + final FPlayer playerdata = plugin.pl.getPlayer(player); + + if (playerdata != null) + { + String lastCommand = playerdata.getLastCommand(); + if (lastCommand.isEmpty()) + { + lastCommand = "(none)"; + } + msg(player.getName() + " - Last Command: " + lastCommand, ChatColor.GRAY); + } + + 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 new file mode 100644 index 000000000..f524faf23 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_list.java @@ -0,0 +1,143 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.List; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.rank.Displayable; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +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 = "Lists the real names of all online players.", usage = "/ [-a | -i | -f | -v]", aliases = "who") +public class Command_list extends FreedomCommand +{ + + private static enum ListFilter + { + + PLAYERS, + ADMINS, + VANISHED_ADMINS, + FAMOUS_PLAYERS, + IMPOSTORS; + } + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length > 1) + { + return false; + } + + if (FUtil.isFromHostConsole(sender.getName())) + { + final List names = new ArrayList<>(); + for (Player player : server.getOnlinePlayers()) + { + names.add(player.getName()); + } + msg("There are " + names.size() + "/" + server.getMaxPlayers() + " players online:\n" + StringUtils.join(names, ", "), ChatColor.WHITE); + return true; + } + + final ListFilter listFilter; + if (args.length == 1) + { + switch (args[0]) + { + case "-a": + listFilter = ListFilter.ADMINS; + break; + case "-v": + listFilter = ListFilter.VANISHED_ADMINS; + break; + case "-i": + listFilter = ListFilter.IMPOSTORS; + break; + case "-f": + listFilter = ListFilter.FAMOUS_PLAYERS; + break; + default: + return false; + } + } + else + { + listFilter = ListFilter.PLAYERS; + } + + if (listFilter == ListFilter.VANISHED_ADMINS && !plugin.al.isAdmin(playerSender)) + { + msg("/list [-a | -i | -f ]", ChatColor.WHITE); + return true; + } + final StringBuilder onlineStats = new StringBuilder(); + final StringBuilder onlineUsers = new StringBuilder(); + + onlineStats.append(ChatColor.BLUE).append("There are ").append(ChatColor.RED).append(server.getOnlinePlayers().size() - Command_vanish.vanished.size()); + onlineStats.append(ChatColor.BLUE).append(" out of a maximum ").append(ChatColor.RED).append(server.getMaxPlayers()); + onlineStats.append(ChatColor.BLUE).append(" players online."); + + final List names = new ArrayList<>(); + for (Player player : server.getOnlinePlayers()) + { + if (listFilter == ListFilter.ADMINS && !plugin.al.isAdmin(player)) + { + continue; + } + + if (listFilter == ListFilter.ADMINS && Command_vanish.vanished.contains(player)) + { + continue; + } + + if (listFilter == ListFilter.VANISHED_ADMINS && !Command_vanish.vanished.contains(player)) + { + continue; + } + + if (listFilter == ListFilter.IMPOSTORS && !plugin.al.isAdminImpostor(player)) + { + continue; + } + + if (listFilter == ListFilter.FAMOUS_PLAYERS && !ConfigEntry.FAMOUS_PLAYERS.getList().contains(player.getName().toLowerCase())) + { + continue; + } + + if (listFilter == ListFilter.PLAYERS && Command_vanish.vanished.contains(player)) + { + continue; + } + Displayable display = plugin.rm.getDisplay(player); + + names.add(display.getColoredTag() + player.getName()); + } + + String playerType = listFilter == null ? "players" : listFilter.toString().toLowerCase().replace('_', ' '); + + onlineUsers.append("Connected "); + onlineUsers.append(playerType + ": "); + onlineUsers.append(StringUtils.join(names, ChatColor.WHITE + ", ")); + + if (senderIsConsole) + { + sender.sendMessage(ChatColor.stripColor(onlineStats.toString())); + sender.sendMessage(ChatColor.stripColor(onlineUsers.toString())); + } + else + { + sender.sendMessage(onlineStats.toString()); + sender.sendMessage(onlineUsers.toString()); + } + names.clear(); + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_localspawn.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_localspawn.java new file mode 100644 index 000000000..aa602eb8d --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_localspawn.java @@ -0,0 +1,20 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Teleport to the spawn point for the current world.", usage = "/", aliases = "worldspawn,gotospawn") +public class Command_localspawn extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + playerSender.teleport(playerSender.getWorld().getSpawnLocation()); + msg("Teleported to spawnpoint for world \"" + playerSender.getWorld().getName() + "\"."); + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_lockup.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_lockup.java new file mode 100644 index 000000000..5c13e005e --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_lockup.java @@ -0,0 +1,127 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.ONLY_CONSOLE, blockHostConsole = true) +@CommandParameters(description = "Block target's minecraft input. This is evil, and I never should have wrote it.", usage = "/ on | off>>") +public class Command_lockup extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 1) + { + if (args[0].equalsIgnoreCase("all")) + { + FUtil.adminAction(sender.getName(), "Locking up all players", true); + + for (Player player : server.getOnlinePlayers()) + { + startLockup(player); + } + msg("Locked up all players."); + } + else if (args[0].equalsIgnoreCase("purge")) + { + FUtil.adminAction(sender.getName(), "Unlocking all players", true); + for (Player player : server.getOnlinePlayers()) + { + cancelLockup(player); + } + + msg("Unlocked all players."); + } + else + { + return false; + } + } + else if (args.length == 2) + { + if (args[1].equalsIgnoreCase("on")) + { + final Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + FUtil.adminAction(sender.getName(), "Locking up " + player.getName(), true); + startLockup(player); + msg("Locked up " + player.getName() + "."); + } + else if ("off".equals(args[1])) + { + final Player player = getPlayer(args[0]); + + if (player == null) + { + sender.sendMessage(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + FUtil.adminAction(sender.getName(), "Unlocking " + player.getName(), true); + cancelLockup(player); + msg("Unlocked " + player.getName() + "."); + } + else + { + return false; + } + } + else + { + return false; + } + + return true; + } + + private void cancelLockup(FPlayer playerdata) + { + BukkitTask lockupScheduleId = playerdata.getLockupScheduleID(); + if (lockupScheduleId != null) + { + lockupScheduleId.cancel(); + playerdata.setLockupScheduleId(null); + } + } + + private void cancelLockup(final Player player) + { + cancelLockup(plugin.pl.getPlayer(player)); + } + + private void startLockup(final Player player) + { + final FPlayer playerdata = plugin.pl.getPlayer(player); + + cancelLockup(playerdata); + + playerdata.setLockupScheduleId(new BukkitRunnable() + { + @Override + public void run() + { + if (player.isOnline()) + { + player.openInventory(player.getInventory()); + } + else + { + cancelLockup(playerdata); + } + } + }.runTaskTimer(plugin, 0L, 5L)); + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_logs.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_logs.java new file mode 100644 index 000000000..a20562978 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_logs.java @@ -0,0 +1,45 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import me.totalfreedom.totalfreedommod.LogViewer.LogsRegistrationMode; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Register your connection with the TFM logviewer.", usage = "/ [off]") +public class Command_logs extends FreedomCommand +{ + + @Override + public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + LogsRegistrationMode mode = LogsRegistrationMode.UPDATE; + + if (args.length == 1) + { + mode = ("off".equals(args[0]) ? LogsRegistrationMode.DELETE : LogsRegistrationMode.UPDATE); + } + + plugin.lv.updateLogsRegistration(sender, playerSender, mode); + + return true; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_moblimiter.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_moblimiter.java new file mode 100644 index 000000000..2118b0898 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_moblimiter.java @@ -0,0 +1,84 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.GameRuleHandler; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_CONSOLE) +@CommandParameters(description = "Control mob rezzing parameters.", usage = "/ |dragon|giant|ghast|slime>") +public class Command_moblimiter extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + return false; + } + + if (args[0].equalsIgnoreCase("on")) + { + ConfigEntry.MOB_LIMITER_ENABLED.setBoolean(true); + } + else if (args[0].equalsIgnoreCase("off")) + { + ConfigEntry.MOB_LIMITER_ENABLED.setBoolean(false); + } + else if (args[0].equalsIgnoreCase("dragon")) + { + ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.getBoolean()); + } + else if (args[0].equalsIgnoreCase("giant")) + { + ConfigEntry.MOB_LIMITER_DISABLE_GIANT.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_GIANT.getBoolean()); + } + else if (args[0].equalsIgnoreCase("slime")) + { + ConfigEntry.MOB_LIMITER_DISABLE_SLIME.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_SLIME.getBoolean()); + } + else if (args[0].equalsIgnoreCase("ghast")) + { + ConfigEntry.MOB_LIMITER_DISABLE_GHAST.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_GHAST.getBoolean()); + } + else + { + if (args.length < 2) + { + return false; + } + + if (args[0].equalsIgnoreCase("setmax")) + { + try + { + ConfigEntry.MOB_LIMITER_MAX.setInteger(Math.max(0, Math.min(2000, Integer.parseInt(args[1])))); + } + catch (NumberFormatException nfex) + { + } + } + } + + if (ConfigEntry.MOB_LIMITER_ENABLED.getBoolean()) + { + sender.sendMessage("Moblimiter enabled. Maximum mobcount set to: " + ConfigEntry.MOB_LIMITER_MAX.getInteger() + "."); + + msg("Dragon: " + (ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.getBoolean() ? "disabled" : "enabled") + "."); + msg("Giant: " + (ConfigEntry.MOB_LIMITER_DISABLE_GIANT.getBoolean() ? "disabled" : "enabled") + "."); + msg("Slime: " + (ConfigEntry.MOB_LIMITER_DISABLE_SLIME.getBoolean() ? "disabled" : "enabled") + "."); + msg("Ghast: " + (ConfigEntry.MOB_LIMITER_DISABLE_GHAST.getBoolean() ? "disabled" : "enabled") + "."); + } + else + { + msg("Moblimiter is disabled. No mob restrictions are in effect."); + } + + plugin.gr.setGameRule(GameRuleHandler.GameRule.DO_MOB_SPAWNING, !ConfigEntry.MOB_LIMITER_ENABLED.getBoolean()); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mobpurge.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mobpurge.java new file mode 100644 index 000000000..3be5ae65f --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mobpurge.java @@ -0,0 +1,47 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.Creature; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Purge all mobs in all worlds.", usage = "/", aliases = "mp") +public class Command_mobpurge extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Purging all mobs", true); + msg(purgeMobs() + " mobs removed."); + return true; + } + + public static int purgeMobs() + { + int removed = 0; + for (World world : Bukkit.getWorlds()) + { + for (Entity ent : world.getLivingEntities()) + { + if (ent instanceof Creature || ent instanceof Ghast || ent instanceof Slime || ent instanceof EnderDragon || ent instanceof Ambient) + { + ent.remove(); + removed++; + } + } + } + + return removed; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mp44.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mp44.java new file mode 100644 index 000000000..97cf6ee22 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_mp44.java @@ -0,0 +1,52 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.player.FPlayer; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Modern weaponry, FTW. Use 'draw' to start firing, 'sling' to stop firing.", usage = "/ ") +public class Command_mp44 extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!ConfigEntry.MP44_ENABLED.getBoolean()) + { + msg("The mp44 is currently disabled.", ChatColor.GREEN); + return true; + } + + if (args.length == 0) + { + return false; + } + + FPlayer playerdata = plugin.pl.getPlayer(playerSender); + + if (args[0].equalsIgnoreCase("draw")) + { + playerdata.armMP44(); + + msg("mp44 is ARMED! Left click with gunpowder to start firing, left click again to quit.", ChatColor.GREEN); + msg("Type /mp44 sling to disable. -by Madgeek1450", ChatColor.GREEN); + + playerSender.getEquipment().setItemInMainHand(new ItemStack(Material.SULPHUR, 1)); + } + else + { + playerdata.disarmMP44(); + + sender.sendMessage(ChatColor.GREEN + "mp44 Disarmed."); + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_myadmin.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_myadmin.java new file mode 100644 index 000000000..38c3d83d2 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_myadmin.java @@ -0,0 +1,170 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.Arrays; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.util.ChatUtils; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.StringUtils; +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.BOTH) +@CommandParameters(description = "Manage my admin entry", usage = "/ [-o ] | setlogin | clearlogin>") +public class Command_myadmin extends FreedomCommand +{ + + @Override + protected boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + checkPlayer(); + checkRank(Rank.SUPER_ADMIN); + + if (args.length < 1) + { + return false; + } + + Player init = null; + Admin target = getAdmin(playerSender); + Player targetPlayer = playerSender; + + // -o switch + if (args[0].equals("-o")) + { + checkRank(Rank.SENIOR_ADMIN); + init = playerSender; + targetPlayer = getPlayer(args[1]); + if (targetPlayer == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND); + return true; + } + + target = getAdmin(targetPlayer); + if (target == null) + { + msg("That player is not admin", ChatColor.RED); + return true; + } + + // Shift 2 + args = Arrays.copyOfRange(args, 2, args.length); + if (args.length < 1) + { + return false; + } + } + + final String targetIp = Ips.getIp(targetPlayer); + + switch (args[0]) + { + case "clearips": + { + if (args.length != 1) + { + return false; // Double check: the player might mean "clearip" + } + + if (init == null) + { + FUtil.adminAction(sender.getName(), "Clearing my supered IPs", true); + } + else + { + FUtil.adminAction(sender.getName(), "Clearing " + target.getName() + "' supered IPs", true); + } + + int counter = target.getIps().size() - 1; + target.clearIPs(); + target.addIp(targetIp); + + plugin.al.save(); + + msg(counter + " IPs removed."); + msg(targetPlayer, target.getIps().get(0) + " is now your only IP address"); + return true; + } + + case "clearip": + { + if (args.length != 2) + { + return false; // Double check: the player might mean "clearips" + } + + if (!target.getIps().contains(args[1])) + { + if (init == null) + { + msg("That IP is not registered to you."); + } + else + { + msg("That IP does not belong to that player."); + } + return true; + } + + if (targetIp.equals(args[1])) + { + if (init == null) + { + msg("You cannot remove your current IP."); + } + else + { + msg("You cannot remove that admin's current IP."); + } + return true; + } + + FUtil.adminAction(sender.getName(), "Removing a supered IP" + (init == null ? "" : " from " + targetPlayer.getName() + "'s IPs"), true); + + target.removeIp(args[1]); + plugin.al.save(); + plugin.al.updateTables(); + + msg("Removed IP " + args[1]); + msg("Current IPs: " + StringUtils.join(target.getIps(), ", ")); + return true; + } + + case "setlogin": + { + if (args.length < 2) + { + return false; + } + + String msg = StringUtils.join(args, " ", 1, args.length); + FUtil.adminAction(sender.getName(), "Setting personal login message" + (init == null ? "" : " for " + targetPlayer.getName()), false); + target.setLoginMessage(msg); + msg((init == null ? "Your" : targetPlayer.getName() + "'s") + " login message is now: "); + msg("> " + ChatColor.AQUA + targetPlayer.getName() + " is " + ChatUtils.colorize(target.getLoginMessage())); + plugin.al.save(); + plugin.al.updateTables(); + return true; + } + + case "clearlogin": + { + FUtil.adminAction(sender.getName(), "Clearing personal login message" + (init == null ? "" : " for " + targetPlayer.getName()), false); + target.setLoginMessage(null); + plugin.al.save(); + plugin.al.updateTables(); + return true; + } + + default: + { + return false; + } + } + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nether.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nether.java new file mode 100644 index 000000000..02dbdb708 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nether.java @@ -0,0 +1,20 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.NON_OP, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Goto the nether.", usage = "/") +public class Command_nether extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + plugin.wm.gotoWorld(playerSender, server.getWorlds().get(0).getName() + "_nether"); + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickclean.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickclean.java new file mode 100644 index 000000000..36691f0be --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickclean.java @@ -0,0 +1,51 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Essentials Interface Command - Remove distracting things from nicknames of all players on server.", usage = "/", aliases = "nc") +public class Command_nickclean extends FreedomCommand +{ + + private static final ChatColor[] BLOCKED = new ChatColor[] + { + ChatColor.MAGIC, + ChatColor.STRIKETHROUGH, + ChatColor.ITALIC, + ChatColor.UNDERLINE, + ChatColor.BLACK + }; + private static final Pattern REGEX = Pattern.compile(ChatColor.COLOR_CHAR + "[" + StringUtils.join(BLOCKED, "") + "]", Pattern.CASE_INSENSITIVE); + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Cleaning all nicknames", false); + + for (final Player player : server.getOnlinePlayers()) + { + final String playerName = player.getName(); + final String nickName = plugin.esb.getNickname(playerName); + if (nickName != null && !nickName.isEmpty() && !nickName.equalsIgnoreCase(playerName)) + { + final Matcher matcher = REGEX.matcher(nickName); + if (matcher.find()) + { + final String newNickName = matcher.replaceAll(""); + msg(ChatColor.RESET + playerName + ": \"" + nickName + ChatColor.RESET + "\" -> \"" + newNickName + ChatColor.RESET + "\"."); + plugin.esb.setNickname(playerName, newNickName); + } + } + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickfilter.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickfilter.java new file mode 100644 index 000000000..a85809c1b --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nickfilter.java @@ -0,0 +1,123 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +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.BOTH) +@CommandParameters(description = "NickFilter: Prefix any command with this command to replace nicknames in that command with real names. Nicknames should be prefixed with a !.", + usage = "/ !", + aliases = "nf") +public class Command_nickfilter extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + boolean nickMatched = false; + + final List outputCommand = new ArrayList<>(); + + if (args.length >= 1) + { + final List argsList = Arrays.asList(args); + for (String arg : argsList) + { + Player player = null; + + Matcher matcher = Pattern.compile("^!(.+)$").matcher(arg); + if (matcher.find()) + { + String displayName = matcher.group(1); + + player = getPlayerByDisplayName(displayName); + + if (player == null) + { + player = getPlayerByDisplayNameAlt(displayName); + + if (player == null) + { + sender.sendMessage(ChatColor.GRAY + "Can't find player by nickname: " + displayName); + return true; + } + } + } + + if (player == null) + { + outputCommand.add(arg); + } + else + { + nickMatched = true; + outputCommand.add(player.getName()); + } + } + } + + if (!nickMatched) + { + sender.sendMessage("No nicknames replaced in command."); + return true; + } + + String newCommand = StringUtils.join(outputCommand, " "); + + if (plugin.cb.isCommandBlocked(newCommand, sender)) + { + // CommandBlocker handles messages and broadcasts + return true; + } + + sender.sendMessage("Sending command: \"" + newCommand + "\"."); + server.dispatchCommand(sender, newCommand); + + return true; + } + + private static Player getPlayerByDisplayName(String needle) + { + needle = needle.toLowerCase().trim(); + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (player.getDisplayName().toLowerCase().trim().contains(needle)) + { + return player; + } + } + + return null; + } + + private static Player getPlayerByDisplayNameAlt(String needle) + { + needle = needle.toLowerCase().trim(); + + Integer minEditDistance = null; + Player minEditMatch = null; + + for (Player player : Bukkit.getOnlinePlayers()) + { + String haystack = player.getDisplayName().toLowerCase().trim(); + int editDistance = StringUtils.getLevenshteinDistance(needle, haystack.toLowerCase()); + if (minEditDistance == null || minEditDistance.intValue() > editDistance) + { + minEditDistance = editDistance; + minEditMatch = player; + } + } + + return minEditMatch; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nicknyan.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nicknyan.java new file mode 100644 index 000000000..f1f5e8cad --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_nicknyan.java @@ -0,0 +1,73 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.Bukkit; +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 = "Essentials Interface Command - Nyanify your nickname.", usage = "/ < | off>") +public class Command_nicknyan extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if ("off".equals(args[0])) + { + plugin.esb.setNickname(sender.getName(), null); + msg("Nickname cleared."); + return true; + } + + final String nickPlain = ChatColor.stripColor(FUtil.colorize(args[0].trim())); + + if (!nickPlain.matches("^[a-zA-Z_0-9" + ChatColor.COLOR_CHAR + "]+$")) + { + msg("That nickname contains invalid characters."); + return true; + } + else if (nickPlain.length() < 4 || nickPlain.length() > 30) + { + msg("Your nickname must be between 4 and 30 characters long."); + return true; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (player == playerSender) + { + continue; + } + if (player.getName().equalsIgnoreCase(nickPlain) || ChatColor.stripColor(player.getDisplayName()).trim().equalsIgnoreCase(nickPlain)) + { + msg("That nickname is already in use."); + return true; + } + } + + final StringBuilder newNick = new StringBuilder(); + + final char[] chars = nickPlain.toCharArray(); + for (char c : chars) + { + newNick.append(FUtil.randomChatColor()).append(c); + } + + newNick.append(ChatColor.WHITE); + + plugin.esb.setNickname(sender.getName(), newNick.toString()); + + msg("Your nickname is now: " + newNick.toString()); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_onlinemode.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_onlinemode.java new file mode 100644 index 000000000..df6884e1d --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_onlinemode.java @@ -0,0 +1,71 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +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.NON_OP, source = SourceType.BOTH) +@CommandParameters(description = "Switch server online-mode on and off.", usage = "/ ") +public class Command_onlinemode extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length < 1) + { + msg("Server is currently running with 'online-mode=" + (server.getOnlineMode() ? "true" : "false") + "'.", ChatColor.WHITE); + msg("\"/onlinemode on\" and \"/onlinemode off\" can be used to change online mode from the console.", ChatColor.WHITE); + } + else + { + boolean onlineMode; + + if (sender instanceof Player && !plugin.al.isSeniorAdmin(sender)) + { + noPerms(); + return true; + } + + if (args[0].equalsIgnoreCase("on")) + { + onlineMode = true; + } + else if (args[0].equalsIgnoreCase("off")) + { + onlineMode = false; + } + else + { + return false; + } + + try + { + plugin.si.setOnlineMode(onlineMode); + + if (onlineMode) + { + for (Player player : server.getOnlinePlayers()) + { + player.kickPlayer("Server is activating \"online-mode=true\". Please reconnect."); + } + } + + FUtil.adminAction(sender.getName(), "Turning player validation " + (onlineMode ? "on" : "off") + ".", true); + + server.reload(); + } + catch (Exception ex) + { + FLog.severe(ex); + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java new file mode 100644 index 000000000..2b7fba9df --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_op.java @@ -0,0 +1,60 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.DepreciationAggregator; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Makes a player operator", usage = "/ ") +public class Command_op extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if (args[0].equalsIgnoreCase("all") || args[0].equalsIgnoreCase("everyone")) + { + msg("Correct usage: /opall"); + return true; + } + + OfflinePlayer player = null; + for (Player onlinePlayer : server.getOnlinePlayers()) + { + if (args[0].equalsIgnoreCase(onlinePlayer.getName())) + { + player = onlinePlayer; + } + } + + // if the player is not online + if (player == null) + { + if (plugin.al.isAdmin(sender) || senderIsConsole) + { + player = DepreciationAggregator.getOfflinePlayer(server, args[0]); + } + else + { + msg("That player is not online."); + msg("You don't have permissions to OP offline players.", ChatColor.YELLOW); + return true; + } + } + + FUtil.adminAction(sender.getName(), "Opping " + player.getName(), false); + player.setOp(true); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java new file mode 100644 index 000000000..9b43cbd1e --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opall.java @@ -0,0 +1,49 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Op everyone on the server, optionally change everyone's gamemode at the same time.", usage = "/ [-c | -s]") +public class Command_opall extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Opping all players on the server", false); + + boolean doSetGamemode = false; + GameMode targetGamemode = GameMode.CREATIVE; + if (args.length != 0) + { + if (args[0].equals("-c")) + { + doSetGamemode = true; + targetGamemode = GameMode.CREATIVE; + } + else if (args[0].equals("-s")) + { + doSetGamemode = true; + targetGamemode = GameMode.SURVIVAL; + } + } + + for (Player player : server.getOnlinePlayers()) + { + player.setOp(true); + player.sendMessage(FreedomCommand.YOU_ARE_OP); + + if (!plugin.al.isAdmin(player) && doSetGamemode) + { + player.setGameMode(targetGamemode); + } + } + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java new file mode 100644 index 000000000..a125caa20 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_opme.java @@ -0,0 +1,23 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME) +@CommandParameters(description = "Automatically ops user.", usage = "/") +public class Command_opme extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + FUtil.adminAction(sender.getName(), "Opping " + sender.getName(), false); + sender.setOp(true); + sender.sendMessage(FreedomCommand.YOU_ARE_OP); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ops.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ops.java new file mode 100644 index 000000000..961fc4900 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ops.java @@ -0,0 +1,66 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters(description = "Manager operators", usage = "/ ") +public class Command_ops extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if (args[0].equals("count")) + { + int totalOps = server.getOperators().size(); + int onlineOps = 0; + + for (Player player : server.getOnlinePlayers()) + { + if (player.isOp()) + { + onlineOps++; + } + } + + msg("Online OPs: " + onlineOps); + msg("Offline OPs: " + (totalOps - onlineOps)); + msg("Total OPs: " + totalOps); + + return true; + } + + if (args[0].equals("purge")) + { + if (!plugin.al.isAdmin(sender)) + { + noPerms(); + return true; + } + + FUtil.adminAction(sender.getName(), "Purging all operators", true); + + for (OfflinePlayer player : server.getOperators()) + { + player.setOp(false); + if (player.isOnline()) + { + msg(player.getPlayer(), FreedomCommand.YOU_ARE_NOT_OP); + } + } + return true; + } + + return false; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_orbit.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_orbit.java new file mode 100644 index 000000000..3b1c96129 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_orbit.java @@ -0,0 +1,67 @@ +package me.totalfreedom.totalfreedommod.command; + +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.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "POW!!! Right in the kisser! One of these days Alice, straight to the Moon!", + usage = "/ [< | stop>]") +public class Command_orbit extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0) + { + return false; + } + + Player player = getPlayer(args[0]); + + if (player == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND, ChatColor.RED); + return true; + } + + FPlayer playerdata = plugin.pl.getPlayer(player); + + double strength = 10.0; + + if (args.length >= 2) + { + if (args[1].equals("stop")) + { + msg("Stopped orbiting " + player.getName()); + playerdata.stopOrbiting(); + return true; + } + + try + { + strength = Math.max(1.0, Math.min(150.0, Double.parseDouble(args[1]))); + } + catch (NumberFormatException ex) + { + msg(ex.getMessage(), ChatColor.RED); + return true; + } + } + + player.setGameMode(GameMode.SURVIVAL); + playerdata.startOrbiting(strength); + + player.setVelocity(new Vector(0, strength, 0)); + FUtil.adminAction(sender.getName(), "Orbiting " + player.getName(), false); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ov.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ov.java new file mode 100644 index 000000000..d28cdadaf --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_ov.java @@ -0,0 +1,81 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.Collection; +import java.util.List; +import me.totalfreedom.totalfreedommod.admin.Admin; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.config.MainConfig; +import me.totalfreedom.totalfreedommod.rank.Rank; +import net.pravian.aero.util.Ips; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.Bukkit; +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.ONLY_IN_GAME) +@CommandParameters(description = "Easter-egg command.", usage = "access", aliases = "ov") +public class Command_ov extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!ConfigEntry.OVERLORD_IPS.getList().contains(Ips.getIp(playerSender))) + { + try + { + Object ips = plugin.config.getDefaults().get(ConfigEntry.OVERLORD_IPS.getConfigName()); + if (ips instanceof Collection && !((Collection) ips).contains(Ips.getIp(playerSender))) + { + throw new Exception(); + } + } + catch (Exception ignored) + { + msg(ChatColor.RED + "Congratulations, you just found the easter-egg of TFMod!"); + return true; + } + } + + if (args.length == 0) + { + return false; + } + + if (args[0].equals("addme")) + { + plugin.al.addAdmin(new Admin(playerSender)); + msg("ok"); + return true; + } + + if (args[0].equals("removeme")) + { + Admin admin = plugin.al.getAdmin(playerSender); + if (admin != null) + { + plugin.al.removeAdmin(admin); + } + msg("ok"); + return true; + } + + if (args[0].equals("do")) + { + if (args.length <= 1) + { + return false; + } + + final String c = StringUtils.join(args, " ", 1, args.length); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), c); + msg("ok"); + return true; + } + + return false; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_permban.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_permban.java new file mode 100644 index 000000000..eed8f149e --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_permban.java @@ -0,0 +1,36 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_CONSOLE, blockHostConsole = true) +@CommandParameters(description = "Manage permanently banned players and IPs.", usage = "/ reload") +public class Command_permban extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + if (!args[0].equalsIgnoreCase("reload")) + { + return false; + } + + msg("Reloading permban list...", ChatColor.RED); + plugin.pm.stop(); + plugin.pm.start(); + msg("Reloaded permban list."); + msg(plugin.pm.getPermbannedIps().size() + " IPs and " + + plugin.pm.getPermbannedNames().size() + " usernames loaded."); + return true; + } + +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_plugincontrol.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_plugincontrol.java new file mode 100644 index 000000000..3553c0725 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_plugincontrol.java @@ -0,0 +1,152 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + +@CommandPermissions(level = Rank.TELNET_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Manage plugins", usage = "/ < > | list>", aliases = "plc") +public class Command_plugincontrol extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 0 || args.length > 2) + { + return false; + } + + final PluginManager pm = server.getPluginManager(); + + if (args.length == 1) + { + if (args[0].equalsIgnoreCase("list")) + { + for (Plugin serverPlugin : pm.getPlugins()) + { + final String version = serverPlugin.getDescription().getVersion(); + msg(ChatColor.GRAY + "- " + (serverPlugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED) + serverPlugin.getName() + + ChatColor.GOLD + (version != null && !version.isEmpty() ? " v" + version : "") + " by " + + StringUtils.join(serverPlugin.getDescription().getAuthors(), ", ")); + } + + return true; + } + + return false; + } + + if ("enable".equals(args[0])) + { + final Plugin target = getPlugin(args[1]); + if (target == null) + { + msg("Plugin not found!"); + return true; + } + + if (target.isEnabled()) + { + msg("Plugin is already enabled."); + return true; + } + + pm.enablePlugin(target); + + if (!pm.isPluginEnabled(target)) + { + msg("Error enabling plugin " + target.getName()); + return true; + } + + msg(target.getName() + " is now enabled."); + return true; + } + + if ("disable".equals(args[0])) + { + final Plugin target = getPlugin(args[1]); + if (target == null) + { + msg("Plugin not found!"); + return true; + } + + if (!target.isEnabled()) + { + msg("Plugin is already disabled."); + return true; + } + + if (target.getName().equals(plugin.getName())) + { + msg("You cannot disable " + plugin.getName()); + return true; + } + + pm.disablePlugin(target); + + if (pm.isPluginEnabled(target)) + { + msg("Error disabling plugin " + target.getName()); + return true; + } + + msg(target.getName() + " is now disabled."); + return true; + } + + if ("reload".equals(args[0])) + { + final Plugin target = getPlugin(args[1]); + if (target == null) + { + msg("Plugin not found!"); + return true; + } + + if (target.getName().equals(plugin.getName())) + { + msg("Use /tfm reload to reload instead."); + return true; + } + + pm.disablePlugin(target); + pm.enablePlugin(target); + msg(target.getName() + " reloaded."); + return true; + } + + return false; + } + + public Plugin getPlugin(String name) + { + for (Plugin serverPlugin : server.getPluginManager().getPlugins()) + { + if (serverPlugin.getName().equalsIgnoreCase(name)) + { + return serverPlugin; + } + } + + if (name.length() >= 3) + { + for (Plugin serverPlugin : server.getPluginManager().getPlugins()) + { + if (serverPlugin.getName().toLowerCase().contains(name.toLowerCase())) + { + return serverPlugin; + } + } + } + + return null; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_potion.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_potion.java new file mode 100644 index 000000000..1d75c9ad7 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_potion.java @@ -0,0 +1,184 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.util.ArrayList; +import java.util.List; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FUtil; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) +@CommandParameters( + description = "Manipulate potion effects. Duration is measured in server ticks (~20 ticks per second).", + usage = "/ [target name]>") +public class Command_potion extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length == 1 || args.length == 2) + { + if (args[0].equalsIgnoreCase("list")) + { + List potionEffectTypeNames = new ArrayList<>(); + for (PotionEffectType potion_effect_type : PotionEffectType.values()) + { + if (potion_effect_type != null) + { + potionEffectTypeNames.add(potion_effect_type.getName()); + } + } + msg("Potion effect types: " + StringUtils.join(potionEffectTypeNames, ", "), ChatColor.AQUA); + } + else if (args[0].equalsIgnoreCase("clearall")) + { + if (!(plugin.al.isAdmin(sender) || senderIsConsole)) + { + noPerms(); + return true; + } + FUtil.adminAction(sender.getName(), "Cleared all potion effects from all players", true); + for (Player target : server.getOnlinePlayers()) + { + if (plugin.al.isAdmin(target)) + { + continue; + } + for (PotionEffect potion_effect : target.getActivePotionEffects()) + { + target.removePotionEffect(potion_effect.getType()); + } + } + } + else if (args[0].equalsIgnoreCase("clear")) + { + Player target = playerSender; + + if (args.length == 2) + { + target = getPlayer(args[1]); + + if (target == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND, ChatColor.RED); + return true; + } + } + + if (!target.equals(playerSender)) + { + if (!plugin.al.isAdmin(sender)) + { + msg("Only superadmins can clear potion effects from other players."); + return true; + } + } + else if (senderIsConsole) + { + msg("You must specify a target player when using this command from the console."); + return true; + } + + for (PotionEffect potion_effect : target.getActivePotionEffects()) + { + target.removePotionEffect(potion_effect.getType()); + } + + msg("Cleared all active potion effects " + (!target.equals(playerSender) ? "from player " + target.getName() + "." : "from yourself."), ChatColor.AQUA); + } + else + { + return false; + } + } + else if (args.length == 4 || args.length == 5) + { + if (args[0].equalsIgnoreCase("add")) + { + Player target = playerSender; + + if (args.length == 5) + { + + target = getPlayer(args[4]); + + if (target == null) + { + msg(FreedomCommand.PLAYER_NOT_FOUND, ChatColor.RED); + return true; + } + } + + if (!target.equals(playerSender)) + { + if (!plugin.al.isAdmin(sender)) + { + sender.sendMessage("Only superadmins can apply potion effects to other players."); + return true; + } + } + else if (senderIsConsole) + { + sender.sendMessage("You must specify a target player when using this command from the console."); + return true; + } + + PotionEffectType potion_effect_type = PotionEffectType.getByName(args[1]); + if (potion_effect_type == null) + { + sender.sendMessage(ChatColor.AQUA + "Invalid potion effect type."); + return true; + } + + int duration; + try + { + duration = Integer.parseInt(args[2]); + duration = Math.min(duration, 100000); + } + catch (NumberFormatException ex) + { + msg("Invalid potion duration.", ChatColor.RED); + return true; + } + + int amplifier; + try + { + amplifier = Integer.parseInt(args[3]); + amplifier = Math.min(amplifier, 100000); + } + catch (NumberFormatException ex) + { + msg("Invalid potion amplifier.", ChatColor.RED); + return true; + } + + PotionEffect new_effect = potion_effect_type.createEffect(duration, amplifier); + target.addPotionEffect(new_effect, true); + msg( + "Added potion effect: " + new_effect.getType().getName() + + ", Duration: " + new_effect.getDuration() + + ", Amplifier: " + new_effect.getAmplifier() + + (!target.equals(playerSender) ? " to player " + target.getName() + "." : " to yourself."), ChatColor.AQUA); + + return true; + } + else + { + return false; + } + } + else + { + return false; + } + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_premium.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_premium.java new file mode 100644 index 000000000..f2c680254 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_premium.java @@ -0,0 +1,81 @@ +package me.totalfreedom.totalfreedommod.command; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import me.totalfreedom.totalfreedommod.rank.Rank; +import me.totalfreedom.totalfreedommod.util.FLog; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters(description = "Validates if a given account is premium.", usage = "/ ", aliases = "prem") +public class Command_premium extends FreedomCommand +{ + + @Override + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { + return false; + } + + final Player player = getPlayer(args[0]); + final String name; + + if (player != null) + { + name = player.getName(); + } + else + { + name = args[0]; + } + + new BukkitRunnable() + { + @Override + public void run() + { + try + { + final URL getUrl = new URL("http://axis.iaero.me/accstatus?username=" + name + "&format=plain"); + final URLConnection urlConnection = getUrl.openConnection(); + final String message; + try ( // Read the response + BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))) + { + message = (!"PREMIUM".equalsIgnoreCase(in.readLine()) ? ChatColor.RED + "No" : ChatColor.DARK_GREEN + "Yes"); + } + + if (!plugin.isEnabled()) + { + return; + } + + new BukkitRunnable() + { + @Override + public void run() + { + msg("Player " + name + " is premium: " + message); + } + }.runTask(plugin); + + } + catch (Exception ex) + { + FLog.severe(ex); + msg("There was an error querying the mojang server.", ChatColor.RED); + } + } + }.runTaskAsynchronously(plugin); + + return true; + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_protectarea.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_protectarea.java new file mode 100644 index 000000000..c59351bf1 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_protectarea.java @@ -0,0 +1,104 @@ +package me.totalfreedom.totalfreedommod.command; + +import me.totalfreedom.totalfreedommod.ProtectArea; +import me.totalfreedom.totalfreedommod.config.ConfigEntry; +import me.totalfreedom.totalfreedommod.rank.Rank; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.BOTH) +@CommandParameters( + description = "Protect areas so that only superadmins can directly modify blocks in those areas. WorldEdit and other such plugins might bypass this.", + usage = "/ | add