diff --git a/pom.xml b/pom.xml
index 04504f1..f036002 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
xyz.etztech
QoL
- 1.0
+ 1.2
jar
@@ -58,6 +58,16 @@
spigot-api
1.13.1-R0.1-SNAPSHOT
+
+ xyz.etztech
+ EtzCore
+ 1.0
+
+
+ net.ess3
+ Essentials
+ 2.14-SNAPSHOT
+
commons-lang
commons-lang
@@ -76,6 +86,14 @@
spigot-repo
https://hub.spigotmc.org/nexus/content/groups/public/
+
+ etztech-repo
+ http://repo.etztech.xyz
+
+
+ ess-repo
+ http://repo.ess3.net/content/groups/essentials
+
mvn-repo
https://mvnrepository.com/artifact/
diff --git a/src/main/java/xyz/etztech/qol/QoL.java b/src/main/java/xyz/etztech/qol/QoL.java
index 3aa3cc6..705ec9e 100644
--- a/src/main/java/xyz/etztech/qol/QoL.java
+++ b/src/main/java/xyz/etztech/qol/QoL.java
@@ -1,5 +1,7 @@
package xyz.etztech.qol;
+import com.earth2me.essentials.Essentials;
+import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
@@ -8,6 +10,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import xyz.etztech.qol.commands.*;
import xyz.etztech.qol.listeners.*;
import xyz.etztech.qol.other.LinkCommand;
+import xyz.etztech.qol.other.TPSRunnable;
import java.util.ArrayList;
import java.util.List;
@@ -16,9 +19,8 @@ import java.util.logging.Logger;
public class QoL extends JavaPlugin {
private static QoL instance;
- /**
- * Connection Pool
- */
+ private static IEssentials essentials = null;
+
public static FileConfiguration config;
private Logger log = Logger.getLogger( "Minecraft" );
@@ -35,6 +37,12 @@ public class QoL extends JavaPlugin {
reloadConfig();
saveResource("qol.png", false);
+ //Essentials hook
+ if (Bukkit.getPluginManager().isPluginEnabled("Essentials")) {
+ log("Hooked into Essentials for TPS alert.");
+ essentials = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials");
+ }
+
if( isEnabled() ) {
@@ -50,6 +58,8 @@ public class QoL extends JavaPlugin {
getServer().getPluginManager().registerEvents(blockIgniteListener, this);
CommandPreprocessListener commandPreprocessListener = new CommandPreprocessListener(this);
getServer().getPluginManager().registerEvents(commandPreprocessListener, this);
+ DeathListener deathListener = new DeathListener(this);
+ getServer().getPluginManager().registerEvents(deathListener, this);
// Add commands
MainCommand mainCommand = new MainCommand(this);
@@ -72,6 +82,8 @@ public class QoL extends JavaPlugin {
this.getCommand("timeout").setExecutor(timeoutCommand);
ColorsCommand colorsCommand = new ColorsCommand(this);
this.getCommand("colors").setExecutor(colorsCommand);
+ WorldInfoCommand worldInfoCommand = new WorldInfoCommand(this);
+ this.getCommand("worldinfo").setExecutor(worldInfoCommand);
@@ -111,6 +123,9 @@ public class QoL extends JavaPlugin {
}, 0, EtzTechUtil.minutesToTicks(frequency));
}
+ // TPS Check
+ Bukkit.getScheduler().scheduleSyncRepeatingTask(QoL.getInstance(), new TPSRunnable(this), 0, EtzTechUtil.minutesToTicks(1));
+
}
}
@@ -189,6 +204,8 @@ public class QoL extends JavaPlugin {
}
}
+
+
public static boolean hasSM(Player player) {
return mutes.contains(player.getUniqueId().toString());
}
@@ -221,6 +238,11 @@ public class QoL extends JavaPlugin {
return links;
}
+ public static IEssentials getEssentials() {
+ return essentials;
+ }
+
+
private void runTask(final String command) {
Bukkit.getScheduler().runTask(QoL.instance, new Runnable() {
@Override
diff --git a/src/main/java/xyz/etztech/qol/commands/WorldInfoCommand.java b/src/main/java/xyz/etztech/qol/commands/WorldInfoCommand.java
new file mode 100644
index 0000000..636feb3
--- /dev/null
+++ b/src/main/java/xyz/etztech/qol/commands/WorldInfoCommand.java
@@ -0,0 +1,59 @@
+package xyz.etztech.qol.commands;
+
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import xyz.etztech.qol.Lang;
+import xyz.etztech.qol.QoL;
+
+import java.util.*;
+
+public class WorldInfoCommand implements CommandExecutor {
+
+ QoL plugin;
+
+ public WorldInfoCommand(QoL plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!sender.hasPermission("qol.worldinfo")) {
+ sender.sendMessage(Lang.NO_PERMISSION.getDef());
+ }
+
+ Map> worlds = new HashMap<>();
+
+ for (World world : Bukkit.getServer().getWorlds()) {
+ for (Player player : world.getPlayers()) {
+ if (worlds.containsKey(world.getName())) {
+ worlds.get(world.getName()).add(getName(world.getName(), player));
+ } else {
+ worlds.put(world.getName(), new ArrayList<>(Arrays.asList(getName(world.getName(), player))));
+ }
+ }
+ }
+
+ StringBuilder message = new StringBuilder(ChatColor.GOLD + "===== World Info =====");
+ for (String world : worlds.keySet()) {
+ message.append("\n").append(ChatColor.YELLOW).append(world).append(": ").append(StringUtils.join(worlds.get(world).toArray(), ChatColor.YELLOW + ", "));
+ }
+ sender.sendMessage(message.toString());
+
+ return true;
+ }
+
+ private String getName(String world, Player player) {
+ int range = plugin.getConfig().getInt("worldinfo." + world, 0);
+ ChatColor color = ChatColor.GREEN;
+ if (range > 0 && (player.getLocation().getBlockX() > range || player.getLocation().getBlockZ() > range)) {
+ color = ChatColor.RED;
+ }
+ return color + player.getName();
+ }
+}
diff --git a/src/main/java/xyz/etztech/qol/listeners/CommandPreprocessListener.java b/src/main/java/xyz/etztech/qol/listeners/CommandPreprocessListener.java
index d98599a..64c0a2b 100644
--- a/src/main/java/xyz/etztech/qol/listeners/CommandPreprocessListener.java
+++ b/src/main/java/xyz/etztech/qol/listeners/CommandPreprocessListener.java
@@ -3,24 +3,17 @@ package xyz.etztech.qol.listeners;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.lang.StringUtils;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.message.BasicNameValuePair;
-import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import xyz.etztech.core.CoreUtils;
+import xyz.etztech.core.web.CoreWeb;
import xyz.etztech.qol.QoL;
import xyz.etztech.qol.other.LinkCommand;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
public class CommandPreprocessListener implements Listener {
@@ -41,13 +34,22 @@ public class CommandPreprocessListener implements Listener {
Player sender = event.getPlayer();
// Command Auditing
- if (plugin.getConfig().getBoolean("audit.enabled") && QoL.getAudits().contains(base)) {
- Map post = new HashMap<>();
- post.put("username", "QoL Auditor");
- post.put("content", sender.getName() + " executed command: " + command);
- String webhook = plugin.getConfig().getString("audit.webhook");
- if (StringUtils.isNotEmpty(webhook)) {
- POST(webhook, post);
+ if (sender.hasPermission("qol.audit") && plugin.getConfig().getBoolean("audit.enabled")) {
+ boolean auditable = false;
+ for (String audit : QoL.getAudits()) {
+ if (noSlash(command).startsWith(noSlash(audit))) {
+ auditable = true;
+ break;
+ }
+ }
+ if (auditable) {
+ Map post = new HashMap<>();
+ post.put("username", "QoL Auditor");
+ post.put("content", "[" + StringUtils.capitalize(sender.getGameMode().name().toLowerCase()) + "] " + sender.getName() + " executed command: " + command);
+ String webhook = plugin.getConfig().getString("audit.webhook");
+ if (StringUtils.isNotEmpty(webhook)) {
+ CoreWeb.asyncPost(plugin, webhook, post);
+ }
}
}
@@ -64,31 +66,11 @@ public class CommandPreprocessListener implements Listener {
}
- private static String POST(String url, Map data) {
- StringBuffer result = new StringBuffer();
- try {
- HttpClient client = HttpClients.createDefault();
- HttpPost post = new HttpPost(url);
- List params = new ArrayList<>();
- for (String key : data.keySet()) {
- params.add(new BasicNameValuePair(key, data.get(key)));
- }
- post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
- client.execute(post);
- } catch (Exception ex) {
- log("POST request failed. (" + url + ")");
- }
-
- return result.toString();
+ public String noSlash(String command) {
+ return command.startsWith("/") ? command.substring(1) : command;
}
- private static void log(String message) {
- try {
- Bukkit.getConsoleSender().sendMessage(message);
- } catch (Exception ex) {
- System.out.println(message);
- }
- }
+
diff --git a/src/main/java/xyz/etztech/qol/listeners/DeathListener.java b/src/main/java/xyz/etztech/qol/listeners/DeathListener.java
new file mode 100644
index 0000000..c958dae
--- /dev/null
+++ b/src/main/java/xyz/etztech/qol/listeners/DeathListener.java
@@ -0,0 +1,41 @@
+package xyz.etztech.qol.listeners;
+
+import net.md_5.bungee.api.chat.ComponentBuilder;
+import net.md_5.bungee.api.chat.HoverEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import xyz.etztech.qol.QoL;
+
+import java.util.Arrays;
+
+
+public class DeathListener implements Listener {
+
+ QoL plugin;
+
+ public DeathListener(QoL plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onDeath(PlayerDeathEvent event) {
+ String message = event.getDeathMessage();
+ event.setDeathMessage("");
+
+ Location location = event.getEntity().getLocation();
+ String coords = StringUtils.join(Arrays.asList(location.getBlockX(), location.getBlockY(), location.getBlockZ()), ", ");
+
+ TextComponent newMessage = new TextComponent(message);
+ newMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Location: " + coords).create()));
+
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ player.spigot().sendMessage(newMessage);
+ }
+ }
+}
diff --git a/src/main/java/xyz/etztech/qol/other/TPSRunnable.java b/src/main/java/xyz/etztech/qol/other/TPSRunnable.java
new file mode 100644
index 0000000..0d1c130
--- /dev/null
+++ b/src/main/java/xyz/etztech/qol/other/TPSRunnable.java
@@ -0,0 +1,38 @@
+package xyz.etztech.qol.other;
+
+import net.ess3.api.IEssentials;
+import org.apache.commons.lang.StringUtils;
+import xyz.etztech.core.web.CoreWeb;
+import xyz.etztech.qol.QoL;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TPSRunnable implements Runnable {
+ private QoL plugin;
+
+ public TPSRunnable(QoL plugin) {
+ this.plugin = plugin;
+ }
+
+
+ @Override
+ public void run() {
+ IEssentials essentials = QoL.getEssentials();
+ if (essentials != null) {
+ double tps = essentials.getTimer().getAverageTPS();
+ int threshold = plugin.getConfig().getInt("tps.threshold", 0);
+ String webhook = plugin.getConfig().getString("tps.webhook", "");
+ String message = "@here TPS has fallen below " + threshold + "!";
+ if (tps < threshold) {
+ plugin.log(message);
+ if (StringUtils.isNotEmpty(webhook)) {
+ Map data = new HashMap<>();
+ data.put("username", "TPS Alert");
+ data.put("content", message);
+ CoreWeb.asyncPost(plugin, webhook, data);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 07d4281..7f69269 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -18,6 +18,17 @@ audit:
- mute
- unban
+# TPS alert
+# Set to 0 to cancel
+tps:
+ threshold: 12
+ webhook: ''
+
+# The range after which a player will be marked as "outside the border"
+worldinfo:
+ world: 5000
+ world_nether: 500
+ world_the_end: 10000
# To disable, set minutes to 0
schedule:
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 36f5318..e438e4d 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -17,6 +17,9 @@ commands:
description: UUID utility command
portal:
description: Nether Portal utility command
+ worldinfo:
+ description: World Info utility command
+ aliases: [wi]
makeme:
description: MakeMe utility command
sudo:
@@ -30,29 +33,35 @@ commands:
description: Timeout command
permissions:
qol.admin:
- description: Ability to reload the plugin
- default: op
+ description: Ability to reload the plugin
+ default: op
qol.priority:
- description: Allows a player on past the player cap
- default: op
+ description: Allows a player on past the player cap
+ default: op
qol.uuid:
- description: Ability to use the UUID command
- default: op
+ description: Ability to use the UUID command
+ default: op
qol.history:
- description: Ability to use the Name History command
- default: op
+ description: Ability to use the Name History command
+ default: op
qol.portal:
- description: Ability to use the Portal command
- default: op
+ description: Ability to use the Portal command
+ default: op
+ qol.worldinfo:
+ description: Ability to use the World Info command
+ deafult: op
qol.sudo:
- description: Ability to use the Sudo command
- default: op
+ description: Ability to use the Sudo command
+ default: op
qol.makeme:
description: Ability to use the MakeMe command
default: true
qol.shadowmute:
description: Ability to use the Shadow Mute command
default: op
+ qol.audit:
+ description: Audits command usage
+ default: op
qol.whitelist.bypass:
description: Allows someone into the server when Whitelist is enabled
default: op