Rename to MineAlert and add config helpers

Signed-off-by: Etzelia <etzelia@hotmail.com>
grief
Etzelia 2020-07-29 12:31:54 -05:00
parent 5f19f7d026
commit 6f29b43193
No known key found for this signature in database
GPG Key ID: 3CAEB74806C4ADE5
11 changed files with 200 additions and 116 deletions

View File

@ -1 +1,14 @@
# OreAlert # MineAlert
MineAlert is a plugin for monitoring events and alerting users.
[Permissions and Commands](src/main/resources/plugin.yml)
## OreAlert
OreAlert monitors specific blocks and sends alerts when a player finds "too many" within a set timeframe.
## GriefAlert
TBA

10
pom.xml
View File

@ -1,16 +1,16 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>xyz.etztech</groupId> <groupId>xyz.etztech</groupId>
<artifactId>OreAlert</artifactId> <artifactId>MineAlert</artifactId>
<!-- Version is used in plugin.yml --> <!-- Version is used in plugin.yml -->
<version>0.0.1</version> <version>0.0.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<!-- Plugin Information --> <!-- Plugin Information -->
<!-- Name, Description, and URL are used in plugin.yml --> <!-- Name, Description, and URL are used in plugin.yml -->
<name>OreAlert</name> <name>MineAlert</name>
<description>Keep track of mining and alert if needed.</description> <description>Keep track of mining and alert if needed.</description>
<url>https://git.etztech.xyz/Minecraft/OreAlert</url> <url>https://git.etztech.xyz/Minecraft/MineAlert</url>
<developers> <developers>
@ -23,7 +23,7 @@
<properties> <properties>
<!-- Author and MainClass are used in plugin.yml --> <!-- Author and MainClass are used in plugin.yml -->
<author>EtzTech</author> <author>EtzTech</author>
<mainClass>xyz.etztech.orealert.OreAlert</mainClass> <mainClass>xyz.etztech.minealert.MineAlert</mainClass>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
@ -103,7 +103,7 @@
<manifest> <manifest>
<addClasspath>true</addClasspath> <addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix> <classpathPrefix>lib/</classpathPrefix>
<mainClass>xyz.etztech.orealert.OreAlert</mainClass> <mainClass>xyz.etztech.minealert.MineAlert</mainClass>
</manifest> </manifest>
</archive> </archive>
</configuration> </configuration>

View File

@ -1,4 +1,4 @@
package xyz.etztech.orealert; package xyz.etztech.minealert;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;

View File

@ -1,4 +1,4 @@
package xyz.etztech.orealert; package xyz.etztech.minealert;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -10,7 +10,7 @@ import org.bukkit.command.CommandSender;
public enum Lang { public enum Lang {
NO_PERMISSION("You don't have permission to do that.", Color.ERROR), NO_PERMISSION("You don't have permission to do that.", Color.ERROR),
UNKNOWN_COMMAND("This command wasn't recognized.", Color.ERROR), UNKNOWN_COMMAND("This command wasn't recognized.", Color.ERROR),
PLUGIN_RELOADED("Plugin reloaded.", Color.INFO), PLUGIN_RELOADED("MineAlert reloaded.", Color.INFO),
ALERT("%s has found %d %s veins.", Color.DEFAULT); ALERT("%s has found %d %s veins.", Color.DEFAULT);
private final String message; private final String message;

View File

@ -0,0 +1,60 @@
package xyz.etztech.minealert;
import org.bukkit.plugin.java.JavaPlugin;
import xyz.etztech.minealert.commands.MainCommand;
import xyz.etztech.minealert.listeners.BlockBreakListener;
import java.util.logging.Logger;
public class MineAlert extends JavaPlugin {
private final Logger log = Logger.getLogger( "Minecraft" );
public void onEnable() {
saveDefaultConfig();
reloadConfig();
if (isEnabled()) {
new MainCommand(this);
new BlockBreakListener(this);
}
}
public void log(String message) {
log.info( "[MineAlert]: " + message );
}
/**
* @param def The default if no paths resolve
* @param path Config paths to check, from specific -> fallback
* @return The resolved String value
*/
public String getConfigStringFallback(String def, String ...path) {
String fallback = "";
for (String p : path) {
fallback = getConfig().getString(p, fallback);
if (!"".equals(fallback)) {
return fallback;
}
}
return def;
}
/**
* @param def The default if no paths resolve
* @param path Config paths to check, from specific -> fallback
* @return The resolved Int value
*/
public int getConfigIntFallback(int def, String ...path) {
int fallback = 0;
for (String p : path) {
fallback = getConfig().getInt(p, fallback);
if (fallback != 0) {
return fallback;
}
}
return def;
}
}

View File

@ -0,0 +1,27 @@
package xyz.etztech.minealert;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
public class Webhook {
public static void send(String webhook, String embed) throws Exception {
URL url = new URL(webhook);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setDoOutput(true);
byte[] out = embed.getBytes(StandardCharsets.UTF_8);
int length = out.length;
http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
OutputStream os = http.getOutputStream();
os.write(out);
}
}

View File

@ -1,4 +1,4 @@
package xyz.etztech.orealert.commands; package xyz.etztech.minealert.commands;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.ComponentBuilder;
@ -6,23 +6,23 @@ import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import xyz.etztech.orealert.Color; import xyz.etztech.minealert.Color;
import xyz.etztech.orealert.Lang; import xyz.etztech.minealert.Lang;
import xyz.etztech.orealert.OreAlert; import xyz.etztech.minealert.MineAlert;
public class MainCommand implements CommandExecutor { public class MainCommand implements CommandExecutor {
OreAlert plugin; MineAlert plugin;
public MainCommand(OreAlert plugin) { public MainCommand(MineAlert plugin) {
this.plugin = plugin; this.plugin = plugin;
this.plugin.getCommand("orealert").setExecutor(this); this.plugin.getCommand("minealert").setExecutor(this);
} }
@Override @Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
if (!commandSender.hasPermission("orealert.admin")) { if (!commandSender.hasPermission("minealert.admin")) {
Lang.NO_PERMISSION.sms(commandSender); Lang.NO_PERMISSION.sms(commandSender);
return true; return true;
} }
@ -45,11 +45,11 @@ public class MainCommand implements CommandExecutor {
} }
private void help(CommandSender commandSender) { private void help(CommandSender commandSender) {
String version = Bukkit.getPluginManager().getPlugin("OreAlert").getDescription().getVersion(); String version = Bukkit.getPluginManager().getPlugin("MineAlert").getDescription().getVersion();
BaseComponent[] message = new ComponentBuilder() BaseComponent[] message = new ComponentBuilder()
.append(String.format("===== OreAlert v%s =====", version)).color(Color.PRIMARY) .append(String.format("===== MineAlert v%s =====", version)).color(Color.PRIMARY)
.append("\n/orealert help - Show this message").color(Color.INFO) .append("\n/minealert help - Show this message").color(Color.INFO)
.append("\n/orealert reload - Reload the config").color(Color.INFO) .append("\n/minealert reload - Reload the config").color(Color.INFO)
.create(); .create();
commandSender.spigot().sendMessage(message); commandSender.spigot().sendMessage(message);
} }

View File

@ -1,4 +1,4 @@
package xyz.etztech.orealert.listeners; package xyz.etztech.minealert.listeners;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -12,9 +12,10 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import xyz.etztech.orealert.Color; import xyz.etztech.minealert.Color;
import xyz.etztech.orealert.Lang; import xyz.etztech.minealert.Lang;
import xyz.etztech.orealert.OreAlert; import xyz.etztech.minealert.MineAlert;
import xyz.etztech.minealert.Webhook;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
@ -26,23 +27,23 @@ import java.util.concurrent.ConcurrentLinkedQueue;
public class BlockBreakListener implements Listener { public class BlockBreakListener implements Listener {
private final OreAlert plugin; private final MineAlert plugin;
private final Map<Player, List<BlockEvent>> map = new HashMap<>(); private final Map<Player, List<BlockEvent>> map = new HashMap<>();
private final Queue<BlockEvent> queue = new ConcurrentLinkedQueue<>(); private final Queue<BlockEvent> queue = new ConcurrentLinkedQueue<>();
public BlockBreakListener(OreAlert plugin) { public BlockBreakListener(MineAlert plugin) {
this.plugin = plugin; this.plugin = plugin;
this.plugin.getServer().getPluginManager().registerEvents(this, plugin); this.plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, this::task); this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, this::task);
this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, this::cleanup, 0, this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, this::cleanup, 0,
20 * 60 * this.plugin.getConfig().getInt("cleanup", 5)); 20 * 60 * this.plugin.getConfig().getInt("ore.cleanup", 5));
} }
@EventHandler @EventHandler
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
queue.add(new BlockEvent(event.getPlayer(), event.getBlock().getType(), true)); queue.add(new BlockEvent(event.getPlayer(), event.getBlock().getType(), true));
int radius = this.plugin.getConfig().getInt("radius", 3); int radius = this.plugin.getConfig().getInt("ore.radius", 3);
for (int x = -radius; x < radius; x++) { for (int x = -radius; x < radius; x++) {
for (int y = -radius; y < radius; y++) { for (int y = -radius; y < radius; y++) {
for (int z = -radius; z < radius; z++) { for (int z = -radius; z < radius; z++) {
@ -56,7 +57,7 @@ public class BlockBreakListener implements Listener {
while (this.plugin.isEnabled()) { while (this.plugin.isEnabled()) {
BlockEvent event = this.queue.poll(); BlockEvent event = this.queue.poll();
if (event != null) { if (event != null) {
for (String s: this.plugin.getConfig().getConfigurationSection("blocks").getKeys(false)) { for (String s: this.plugin.getConfig().getConfigurationSection("ore.blocks").getKeys(false)) {
if (Lang.getMaterialKey(event.getMaterial()).equals(s)) { if (Lang.getMaterialKey(event.getMaterial()).equals(s)) {
addStrike(event); addStrike(event);
check(event); check(event);
@ -74,11 +75,22 @@ public class BlockBreakListener implements Listener {
} }
private void check(BlockEvent event) { private void check(BlockEvent event) {
FileConfiguration config = this.plugin.getConfig();
String blockKey = Lang.getMaterialKey(event.getMaterial()); String blockKey = Lang.getMaterialKey(event.getMaterial());
int start = config.getInt(String.format("blocks.%s.start", blockKey), config.getInt("start", 5)); int start = this.plugin.getConfigIntFallback(
int each = config.getInt(String.format("blocks.%s.each", blockKey), config.getInt("each", 5)); 5,
int ping = config.getInt(String.format("blocks.%s.ping", blockKey), config.getInt("ping", 5)); String.format("ore.blocks.%s.start", blockKey),
"ore.start"
);
int each = this.plugin.getConfigIntFallback(
5,
String.format("ore.blocks.%s.each", blockKey),
"ore.each"
);
int ping = this.plugin.getConfigIntFallback(
5,
String.format("ore.blocks.%s.ping", blockKey),
"ore.ping"
);
purge(map.getOrDefault(event.getPlayer(), new ArrayList<>()).iterator()); purge(map.getOrDefault(event.getPlayer(), new ArrayList<>()).iterator());
int strikes = 0; int strikes = 0;
@ -112,10 +124,13 @@ public class BlockBreakListener implements Listener {
private void purge(Iterator<BlockEvent> events) { private void purge(Iterator<BlockEvent> events) {
Date now = Calendar.getInstance().getTime(); Date now = Calendar.getInstance().getTime();
int globalPurge = this.plugin.getConfig().getInt("purge", 30);
while (events.hasNext()) { while (events.hasNext()) {
BlockEvent e = events.next(); BlockEvent e = events.next();
int purge = 1000 * 60 * this.plugin.getConfig().getInt(String.format("blocks.%s.purge", Lang.getMaterialKey(e.getMaterial())), globalPurge); int purge = 1000 * 60 * this.plugin.getConfigIntFallback(
30,
String.format("ore.blocks.%s.purge", Lang.getMaterialKey(e.getMaterial())),
"ore.purge"
);
if (new Date(e.getTime().getTime() + purge).before(now)) { if (new Date(e.getTime().getTime() + purge).before(now)) {
events.remove(); events.remove();
} }
@ -125,25 +140,33 @@ public class BlockBreakListener implements Listener {
private void alert(BlockEvent event, int strikes, boolean ping) { private void alert(BlockEvent event, int strikes, boolean ping) {
String message = String.format(Lang.ALERT.getMessage(), String message = String.format(Lang.ALERT.getMessage(),
event.getPlayer().getName(), strikes, Lang.getMaterialName(event.getMaterial())); event.getPlayer().getName(), strikes, Lang.getMaterialName(event.getMaterial()));
String hexColor = this.plugin.getConfig().getString(String.format("blocks.%s.color", Lang.getMaterialKey(event.getMaterial())), "#00ffff"); String hexColor = this.plugin.getConfigStringFallback(
"#AAAAAA",
String.format("ore.blocks.%s.color", Lang.getMaterialKey(event.getMaterial())),
"ore.color"
);
BaseComponent[] component = new ComponentBuilder() BaseComponent[] component = new ComponentBuilder()
.append(message).color(ChatColor.of(hexColor)) .append(message).color(ChatColor.of(hexColor))
.create(); .create();
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (player.hasPermission("orealert.alert")) { if (player.hasPermission("minealert.alert")) {
player.spigot().sendMessage(component); player.spigot().sendMessage(component);
} }
} }
// Webhook // Webhook
String globalWebhook = this.plugin.getConfig().getString("webhook", ""); String webhook = this.plugin.getConfigStringFallback(
String webhook = this.plugin.getConfig().getString(String.format("blocks.%s.webhook", Lang.getMaterialKey(event.getMaterial())), globalWebhook); "",
String.format("ore.blocks.%s.webhook", Lang.getMaterialKey(event.getMaterial())),
"ore.webhook",
"webhook"
);
if (!"".equals(webhook)) { if (!"".equals(webhook)) {
String embed = embed(event, message, ping, hexColor); String embed = embed(event, message, ping, hexColor);
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> { this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
try { try {
sendWebhook(webhook, embed); Webhook.send(webhook, embed);
} catch (Exception e) { } catch (Exception e) {
this.plugin.log(String.format("Could not send webhook: %s", e.getMessage())); this.plugin.log(String.format("Could not send webhook: %s", e.getMessage()));
} }
@ -172,23 +195,6 @@ public class BlockBreakListener implements Listener {
return json.toString(); return json.toString();
} }
private void sendWebhook(String webhook, String embed) throws Exception {
URL url = new URL(webhook);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setDoOutput(true);
byte[] out = embed.getBytes(StandardCharsets.UTF_8);
int length = out.length;
http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
OutputStream os = http.getOutputStream();
os.write(out);
}
} }
class BlockEvent { class BlockEvent {

View File

@ -1,30 +0,0 @@
package xyz.etztech.orealert;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import xyz.etztech.orealert.commands.MainCommand;
import xyz.etztech.orealert.listeners.BlockBreakListener;
import java.util.logging.Logger;
public class OreAlert extends JavaPlugin {
private final Logger log = Logger.getLogger( "Minecraft" );
public void onEnable() {
saveDefaultConfig();
reloadConfig();
if (isEnabled()) {
new MainCommand(this);
new BlockBreakListener(this);
}
}
public void log(String message) {
log.info( "[OreAlert]: " + message );
}
}

View File

@ -1,26 +1,34 @@
# Radius to search around block for similar blocks in the "vein" # Global Discord webhook
radius: 3 # This can be set as a global fallback
# How often to run cleanup task (in minutes)
cleanup: 5
# Global notification settings, for less arthritis
# How long until we purge a node strike (in minutes)
purge: 30
# How many veins found within the above purge minutes to notify
start: 5
# After the initial alert, how many should be found in addition before more alerts?
each: 1
# After the initial alert, how many should be found in addition before more pings?
ping: 5
# Discord webhook
webhook: '' webhook: ''
# Only blocks listed here will be monitored # OreAlert
# Each of the above notify settings can be overridden per-block if needed ore:
# Anything not overridden will default to the global setting # Radius to search around block for similar blocks in the "vein"
blocks: radius: 3
diamond_ore: # How often to run cleanup task (in minutes)
color: '#b9f2ff' cleanup: 5
ancient_debris:
color: '#933A16' # Default notification settings, for less arthritis
purge: 45 # The color to use in chat and webhook alerts
color: '#AAAAAA'
# How long until we purge a node strike (in minutes)
purge: 30
# How many veins found within the above purge minutes to notify
start: 5
# After the initial alert, how many should be found in addition before more alerts?
each: 1
# After the initial alert, how many should be found in addition before more pings?
ping: 5
# Discord webhook
webhook: ''
# Only blocks listed here will be monitored
# Each of the above notify settings can be overridden per-block if needed
# Anything not overridden will use the default setting
blocks:
diamond_ore:
color: '#B9F2FF'
ancient_debris:
color: '#933A16'
purge: 45

View File

@ -6,13 +6,13 @@ website: ${url}
main: ${mainClass} main: ${mainClass}
api-version: 1.16 api-version: 1.16
commands: commands:
orealert: minealert:
aliases: oa aliases: ma
description: Base command description: Base command
permissions: permissions:
orealert.admin: minealert.admin:
description: Ability to reload the plugin description: Ability to reload the plugin
default: op default: op
orealert.alert: minealert.alert:
description: Get alerts description: Get alerts
default: op default: op