Upload files to "src/net/ardakaz/griefalert"

removed debug
changed needed to input world into options for ignore
This commit is contained in:
Kleedje30 2025-05-28 20:31:34 +00:00
parent 2bfe822fb1
commit 0ee14339b7

903
src/net/ardakaz/griefalert/GriefAlert.java Executable file → Normal file
View File

@ -1,473 +1,432 @@
package net.ardakaz.griefalert; package net.ardakaz.griefalert;
import net.coreprotect.CoreProtect; import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI; import net.coreprotect.CoreProtectAPI;
import net.coreprotect.CoreProtectAPI.ParseResult; import net.coreprotect.CoreProtectAPI.ParseResult;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player;
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 org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPlugin; import java.sql.Connection;
import org.bukkit.World; import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Connection; import java.sql.ResultSet;
import java.sql.DriverManager; import java.sql.SQLException;
import java.sql.PreparedStatement; import java.sql.Statement;
import java.sql.ResultSet; import java.util.Arrays;
import java.sql.SQLException; import java.util.List;
import java.sql.Statement; import java.util.Set;
import java.util.Arrays; import java.util.stream.Collectors;
import java.util.List;
import java.util.Set; public class GriefAlert extends JavaPlugin implements Listener {
import java.util.stream.Collectors;
private static CoreProtectAPI coreProtectAPI;
public class GriefAlert extends JavaPlugin implements Listener, TabCompleter { private Integer identicalAlerts = 1;
private String lastAlert;
private static CoreProtectAPI coreProtectAPI;
private Integer identicalAlerts = 1; private Set<Material> EXCLUDED_BLOCKS;
private String lastAlert; private Set<InventoryType> VALID_CONTAINERS;
private String MAP_LINK;
private Set<Material> EXCLUDED_BLOCKS; private Boolean ALLOW_STEALING;
private Set<InventoryType> VALID_CONTAINERS;
private String MAP_LINK; private Connection connection;
private Boolean ALLOW_STEALING; private final String DB_FILE = "ignored_locations.db";
private Connection connection; // Init GriefAlert
private final String DB_FILE = "ignored_locations.db"; @Override
public void onEnable() {
// Init GriefAlert
@Override coreProtectAPI = getCoreProtect();
public void onEnable() { if (coreProtectAPI == null) {
getLogger().severe("CoreProtect not found! Disabling plugin.");
coreProtectAPI = getCoreProtect(); getServer().getPluginManager().disablePlugin(this);
if (coreProtectAPI == null) { return;
getLogger().severe("CoreProtect not found! Disabling plugin."); }
getServer().getPluginManager().disablePlugin(this);
return; getServer().getPluginManager().registerEvents(this, this);
}
// Config
getServer().getPluginManager().registerEvents(this, this); saveDefaultConfig();
List<String> excludedBlocks = getConfig().getStringList("excluded-blocks");
// Config EXCLUDED_BLOCKS = excludedBlocks.stream().map(Material::valueOf).collect(Collectors.toSet());
saveDefaultConfig(); List<String> validContainers = getConfig().getStringList("valid-containers");
List<String> excludedBlocks = getConfig().getStringList("excluded-blocks"); VALID_CONTAINERS = validContainers.stream().map(InventoryType::valueOf).collect(Collectors.toSet());
EXCLUDED_BLOCKS = excludedBlocks.stream().map(Material::valueOf).collect(Collectors.toSet()); MAP_LINK = getConfig().getString("map-link");
List<String> validContainers = getConfig().getStringList("valid-containers"); ALLOW_STEALING = getConfig().getBoolean("allow-stealing");
VALID_CONTAINERS = validContainers.stream().map(InventoryType::valueOf).collect(Collectors.toSet());
MAP_LINK = getConfig().getString("map-link"); setupDatabase();
ALLOW_STEALING = getConfig().getBoolean("allow-stealing");
getCommand("griefalert").setTabCompleter(this);
setupDatabase();
getLogger().info("GriefAlert has been enabled.");
getCommand("griefalert").setTabCompleter(this); }
getLogger().info("GriefAlert has been enabled."); @Override
} public void onDisable() {
getLogger().info("GriefAlert has been disabled.");
@Override if (connection != null) {
public void onDisable() { try { connection.close(); } catch (SQLException ignored) {}
getLogger().info("GriefAlert has been disabled."); }
if (connection != null) { }
try { connection.close(); } catch (SQLException ignored) {}
} private void setupDatabase() {
} try {
connection = DriverManager.getConnection("jdbc:sqlite:" + getDataFolder().getAbsolutePath() + "/" + DB_FILE);
private void setupDatabase() { Statement stmt = connection.createStatement();
try { stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ignored_locations (x INTEGER, y INTEGER, z INTEGER, world TEXT, PRIMARY KEY (x, y, z, world))");
connection = DriverManager.getConnection("jdbc:sqlite:" + getDataFolder().getAbsolutePath() + "/" + DB_FILE); stmt.close();
Statement stmt = connection.createStatement(); } catch (SQLException e) {
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ignored_locations (x INTEGER, y INTEGER, z INTEGER, world TEXT, PRIMARY KEY (x, y, z, world))"); getLogger().severe("Could not set up SQLite database: " + e.getMessage());
stmt.close(); }
} catch (SQLException e) { }
getLogger().severe("Could not set up SQLite database: " + e.getMessage());
} private boolean isLocationIgnored(int x, int y, int z, String world) {
} try {
PreparedStatement ps = connection.prepareStatement("SELECT 1 FROM ignored_locations WHERE x=? AND y=? AND z=? AND world=?");
private boolean isLocationIgnored(int x, int y, int z, String world) { ps.setInt(1, x);
try { ps.setInt(2, y);
PreparedStatement ps = connection.prepareStatement("SELECT 1 FROM ignored_locations WHERE x=? AND y=? AND z=? AND world=?"); ps.setInt(3, z);
ps.setInt(1, x); ps.setString(4, world);
ps.setInt(2, y); ResultSet rs = ps.executeQuery();
ps.setInt(3, z); boolean exists = rs.next();
ps.setString(4, world); rs.close();
ResultSet rs = ps.executeQuery(); ps.close();
boolean exists = rs.next(); return exists;
rs.close(); } catch (SQLException e) {
ps.close(); getLogger().warning("DB error: " + e.getMessage());
return exists; return false;
} catch (SQLException e) { }
getLogger().warning("DB error: " + e.getMessage()); }
return false;
} private boolean addIgnoredLocation(int x, int y, int z, String world) {
} try {
PreparedStatement ps = connection.prepareStatement("INSERT OR IGNORE INTO ignored_locations (x, y, z, world) VALUES (?, ?, ?, ?)");
private boolean addIgnoredLocation(int x, int y, int z, String world) { ps.setInt(1, x);
try { ps.setInt(2, y);
PreparedStatement ps = connection.prepareStatement("INSERT OR IGNORE INTO ignored_locations (x, y, z, world) VALUES (?, ?, ?, ?)"); ps.setInt(3, z);
ps.setInt(1, x); ps.setString(4, world);
ps.setInt(2, y); int updated = ps.executeUpdate();
ps.setInt(3, z); ps.close();
ps.setString(4, world); return updated > 0;
int updated = ps.executeUpdate(); } catch (SQLException e) {
ps.close(); getLogger().warning("DB error: " + e.getMessage());
return updated > 0; return false;
} catch (SQLException e) { }
getLogger().warning("DB error: " + e.getMessage()); }
return false;
} private boolean removeIgnoredLocation(int x, int y, int z, String world) {
} try {
PreparedStatement ps = connection.prepareStatement("DELETE FROM ignored_locations WHERE x=? AND y=? AND z=? AND world=?");
private boolean removeIgnoredLocation(int x, int y, int z, String world) { ps.setInt(1, x);
try { ps.setInt(2, y);
PreparedStatement ps = connection.prepareStatement("DELETE FROM ignored_locations WHERE x=? AND y=? AND z=? AND world=?"); ps.setInt(3, z);
ps.setInt(1, x); ps.setString(4, world);
ps.setInt(2, y); int updated = ps.executeUpdate();
ps.setInt(3, z); ps.close();
ps.setString(4, world); return updated > 0;
int updated = ps.executeUpdate(); } catch (SQLException e) {
ps.close(); getLogger().warning("DB error: " + e.getMessage());
return updated > 0; return false;
} catch (SQLException e) { }
getLogger().warning("DB error: " + e.getMessage()); }
return false;
} private void listIgnoredLocations(CommandSender sender) {
} try {
Statement stmt = connection.createStatement();
private void clearIgnoredLocations() { ResultSet rs = stmt.executeQuery("SELECT x, y, z, world FROM ignored_locations");
try { sender.sendMessage(ChatColor.YELLOW + "Ignored Locations:");
Statement stmt = connection.createStatement(); while (rs.next()) {
stmt.executeUpdate("DELETE FROM ignored_locations"); sender.sendMessage(ChatColor.GRAY + "- " + rs.getInt("x") + ", " + rs.getInt("y") + ", " + rs.getInt("z") + " in " + rs.getString("world"));
stmt.close(); }
} catch (SQLException e) { rs.close();
getLogger().warning("DB error: " + e.getMessage()); stmt.close();
} } catch (SQLException e) {
} sender.sendMessage(ChatColor.RED + "DB error: " + e.getMessage());
}
private void listIgnoredLocations(CommandSender sender) { }
try {
Statement stmt = connection.createStatement(); @EventHandler (ignoreCancelled = true)
ResultSet rs = stmt.executeQuery("SELECT x, y, z, world FROM ignored_locations"); // Block break alerts
sender.sendMessage(ChatColor.YELLOW + "Ignored Locations:"); public void onBlockBreak(BlockBreakEvent event) {
while (rs.next()) { // Exclusion list
sender.sendMessage(ChatColor.GRAY + "- " + rs.getInt("x") + ", " + rs.getInt("y") + ", " + rs.getInt("z") + " in " + rs.getString("world")); if (EXCLUDED_BLOCKS.contains(event.getBlock().getType())) {
} return;
rs.close(); }
stmt.close();
} catch (SQLException e) { // Event parser
sender.sendMessage(ChatColor.RED + "DB error: " + e.getMessage()); String playerName = event.getPlayer().getName();
} String blockType = event.getBlock().getType().toString();
} int x = event.getBlock().getX();
int y = event.getBlock().getY();
@EventHandler (ignoreCancelled = true) int z = event.getBlock().getZ();
// Block break alerts String worldName = event.getBlock().getWorld().getName();
public void onBlockBreak(BlockBreakEvent event) {
// Exclusion list // Check if grief
if (EXCLUDED_BLOCKS.contains(event.getBlock().getType())) { String target = inspectBlock(event.getBlock(), event.getPlayer());
return; if (target != null) {
} String message = ChatColor.GRAY + playerName + " broke " + blockType + " placed by " + target + " at " + x + " " + y + " " + z + getHumanWorldName(worldName);
alert(message, playerName, "[Map Link](" + MAP_LINK + "/?worldname=" + worldName + "&zoom=7&x=" + x + "&y=" + y + "&z=" + z + ")", target, x, y, z, worldName);
// Event parser }
String playerName = event.getPlayer().getName(); }
String blockType = event.getBlock().getType().toString();
int x = event.getBlock().getX(); // Stealing alerts
int y = event.getBlock().getY(); @EventHandler (ignoreCancelled = true)
int z = event.getBlock().getZ(); public void onInventoryClick(InventoryClickEvent event) {
String worldName = event.getBlock().getWorld().getName(); if (ALLOW_STEALING) {
return;
// Check if grief }
String target = inspectBlock(event.getBlock(), event.getPlayer()); boolean stealing;
if (target != null) {
String message = ChatColor.GRAY + playerName + " broke " + blockType + " placed by " + target + " at " + x + " " + y + " " + z + getHumanWorldName(worldName); // Event parser for inv
alert(message, playerName, "[Map Link](" + MAP_LINK + "/?worldname=" + worldName + "&zoom=7&x=" + x + "&y=" + y + "&z=" + z + ")", target, x, y, z, worldName); if (!(event.getWhoClicked() instanceof Player)) return;
} Player player = (Player) event.getWhoClicked();
} Inventory inventory = event.getInventory();
Inventory clickedInventory = event.getClickedInventory();
// Stealing alerts ItemStack item = event.getCurrentItem();
@EventHandler (ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent event) { if (item == null || inventory.getLocation() == null || item.getType() == Material.AIR) {
if (ALLOW_STEALING) { return;
return; }
}
boolean stealing; // Exclusion list
if (!VALID_CONTAINERS.contains(inventory.getType())) {
// Event parser for inv return;
if (!(event.getWhoClicked() instanceof Player)) return; }
Player player = (Player) event.getWhoClicked();
Inventory inventory = event.getInventory(); // Inv actions (needs fixing)
Inventory clickedInventory = event.getClickedInventory(); InventoryAction action = event.getAction();
ItemStack item = event.getCurrentItem(); if ((action == InventoryAction.PICKUP_ALL || action == InventoryAction.PICKUP_HALF ||
action == InventoryAction.PICKUP_ONE || action == InventoryAction.PICKUP_SOME ||
if (item == null || inventory.getLocation() == null || item.getType() == Material.AIR) { action == InventoryAction.MOVE_TO_OTHER_INVENTORY) && clickedInventory == inventory) {
return; stealing = true;
} } else if (action == InventoryAction.PLACE_ALL || action == InventoryAction.PLACE_SOME ||
action == InventoryAction.PLACE_ONE || (action == InventoryAction.MOVE_TO_OTHER_INVENTORY && clickedInventory != inventory)) {
// Exclusion list stealing = false;
if (!VALID_CONTAINERS.contains(inventory.getType())) { } else {
return; return;
} }
// Inv actions (needs fixing) // Event parser for container + check if grief
InventoryAction action = event.getAction(); String target = inspectBlock(inventory.getLocation().getBlock(), player);
if ((action == InventoryAction.PICKUP_ALL || action == InventoryAction.PICKUP_HALF || if (target != null) {
action == InventoryAction.PICKUP_ONE || action == InventoryAction.PICKUP_SOME || String playerName = player.getName();
action == InventoryAction.MOVE_TO_OTHER_INVENTORY) && clickedInventory == inventory) { String itemName = item.getType().toString();
stealing = true; int amount = item.getAmount();
} else if (action == InventoryAction.PLACE_ALL || action == InventoryAction.PLACE_SOME || int x = inventory.getLocation().getBlockX();
action == InventoryAction.PLACE_ONE || (action == InventoryAction.MOVE_TO_OTHER_INVENTORY && clickedInventory != inventory)) { int y = inventory.getLocation().getBlockY();
stealing = false; int z = inventory.getLocation().getBlockZ();
} else { String worldName = inventory.getLocation().getWorld().getName();
return; if (stealing) {
} String message = ChatColor.GRAY + playerName + " took " + amount + " " + itemName + " from " + target + "'s container at " + x + " " + y + " " + z + getHumanWorldName(worldName);
alert(message, playerName, "[Map Link](" + MAP_LINK + "/?worldname=" + worldName + "&zoom=7&x=" + x + "&y=" + y + "&z=" + z + ")", target, x, y, z, worldName);
// Event parser for container + check if grief } else {
String target = inspectBlock(inventory.getLocation().getBlock(), player); String message = ChatColor.GRAY + playerName + " put " + amount + " " + itemName + " into " + target + "'s container at " + x + " " + y + " " + z + getHumanWorldName(worldName);
if (target != null) { alert(message, playerName, "[Map Link](" + MAP_LINK + "/?worldname=" + worldName + "&zoom=7&x=" + x + "&y=" + y + "&z=" + z + ")", target, x, y, z, worldName);
String playerName = player.getName(); }
String itemName = item.getType().toString(); }
int amount = item.getAmount(); }
int x = inventory.getLocation().getBlockX();
int y = inventory.getLocation().getBlockY(); @Override
int z = inventory.getLocation().getBlockZ(); public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
String worldName = inventory.getLocation().getWorld().getName(); if (!command.getName().equalsIgnoreCase("griefalert")) return false;
if (stealing) { if (args.length == 0) return false;
String message = ChatColor.GRAY + playerName + " took " + amount + " " + itemName + " from " + target + "'s container at " + x + " " + y + " " + z + getHumanWorldName(worldName); String sub = args[0].toLowerCase();
alert(message, playerName, "[Map Link](" + MAP_LINK + "/?worldname=" + worldName + "&zoom=7&x=" + x + "&y=" + y + "&z=" + z + ")", target, x, y, z, worldName); if (sub.equals("ignore")) {
} else { if (!sender.hasPermission("griefalert.staff.ignore")) {
String message = ChatColor.GRAY + playerName + " put " + amount + " " + itemName + " into " + target + "'s container at " + x + " " + y + " " + z + getHumanWorldName(worldName); sender.sendMessage(ChatColor.RED + "You do not have permission.");
alert(message, playerName, "[Map Link](" + MAP_LINK + "/?worldname=" + worldName + "&zoom=7&x=" + x + "&y=" + y + "&z=" + z + ")", target, x, y, z, worldName); return true;
} }
} if (args.length != 4) {
} sender.sendMessage(ChatColor.RED + "Usage: /griefalert ignore <x> <y> <z>");
return true;
@Override }
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (!(sender instanceof Player)) {
if (!command.getName().equalsIgnoreCase("griefalert")) return false; sender.sendMessage(ChatColor.RED + "Only players can use this command without specifying a world.");
if (args.length == 0) return false; return true;
String sub = args[0].toLowerCase(); }
if (sub.equals("ignore")) { try {
getLogger().info("[DEBUG] /griefalert ignore called by " + sender.getName() + " with args: " + String.join(" ", args)); int x = Integer.parseInt(args[1]);
if (!sender.hasPermission("griefalert.staff.ignore")) { int y = Integer.parseInt(args[2]);
sender.sendMessage(ChatColor.RED + "You do not have permission."); int z = Integer.parseInt(args[3]);
getLogger().info("[DEBUG] Permission denied for ignore"); String world = ((Player)sender).getWorld().getName();
return true; boolean result = addIgnoredLocation(x, y, z, world);
} if (result) {
if (args.length != 5) { sender.sendMessage(ChatColor.GREEN + "Location ignored.");
sender.sendMessage(ChatColor.RED + "Usage: /griefalert ignore <x> <y> <z> <world>"); } else {
getLogger().info("[DEBUG] Incorrect number of arguments for ignore: " + args.length); sender.sendMessage(ChatColor.YELLOW + "Location was already ignored.");
return true; }
} } catch (NumberFormatException e) {
try { sender.sendMessage(ChatColor.RED + "Coordinates must be numbers.");
int x = Integer.parseInt(args[1]); }
int y = Integer.parseInt(args[2]); return true;
int z = Integer.parseInt(args[3]); } else if (sub.equals("unignore")) {
String world = args[4]; if (!sender.hasPermission("griefalert.staff.UnIgnore")) {
boolean result = addIgnoredLocation(x, y, z, world); sender.sendMessage(ChatColor.RED + "You do not have permission.");
if (result) { return true;
sender.sendMessage(ChatColor.GREEN + "Location ignored."); }
getLogger().info("[DEBUG] Location ignored: " + x + "," + y + "," + z + "," + world); if (args.length != 4) {
} else { sender.sendMessage(ChatColor.RED + "Usage: /griefalert unignore <x> <y> <z>");
sender.sendMessage(ChatColor.YELLOW + "Location was already ignored."); return true;
getLogger().info("[DEBUG] Location already ignored: " + x + "," + y + "," + z + "," + world); }
} if (!(sender instanceof Player)) {
} catch (NumberFormatException e) { sender.sendMessage(ChatColor.RED + "Only players can use this command without specifying a world.");
sender.sendMessage(ChatColor.RED + "Coordinates must be numbers."); return true;
getLogger().info("[DEBUG] Invalid coordinates for ignore"); }
} try {
return true; int x = Integer.parseInt(args[1]);
} else if (sub.equals("unignore")) { int y = Integer.parseInt(args[2]);
getLogger().info("[DEBUG] /griefalert unignore called by " + sender.getName() + " with args: " + String.join(" ", args)); int z = Integer.parseInt(args[3]);
if (!sender.hasPermission("griefalert.staff.UnIgnore")) { String world = ((Player)sender).getWorld().getName();
sender.sendMessage(ChatColor.RED + "You do not have permission."); boolean result = removeIgnoredLocation(x, y, z, world);
getLogger().info("[DEBUG] Permission denied for unignore"); if (result) {
return true; sender.sendMessage(ChatColor.GREEN + "Location unignored.");
} } else {
if (args.length != 5) { sender.sendMessage(ChatColor.YELLOW + "Location was not ignored.");
sender.sendMessage(ChatColor.RED + "Usage: /griefalert unignore <x> <y> <z> <world>"); }
getLogger().info("[DEBUG] Incorrect number of arguments for unignore: " + args.length); } catch (NumberFormatException e) {
return true; sender.sendMessage(ChatColor.RED + "Coordinates must be numbers.");
} }
try { return true;
int x = Integer.parseInt(args[1]); } else if (sub.equals("list")) {
int y = Integer.parseInt(args[2]); if (!sender.hasPermission("griefalert.staff.list")) {
int z = Integer.parseInt(args[3]); sender.sendMessage(ChatColor.RED + "You do not have permission.");
String world = args[4]; return true;
boolean result = removeIgnoredLocation(x, y, z, world); }
if (result) { listIgnoredLocations(sender);
sender.sendMessage(ChatColor.GREEN + "Location unignored."); return true;
getLogger().info("[DEBUG] Location unignored: " + x + "," + y + "," + z + "," + world); }
} else { sender.sendMessage(ChatColor.RED + "Unknown subcommand. Use: ignore, unignore, list");
sender.sendMessage(ChatColor.YELLOW + "Location was not ignored."); return false;
getLogger().info("[DEBUG] Location was not ignored: " + x + "," + y + "," + z + "," + world); }
}
} catch (NumberFormatException e) { @Override
sender.sendMessage(ChatColor.RED + "Coordinates must be numbers."); public java.util.List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
getLogger().info("[DEBUG] Invalid coordinates for unignore"); if (!command.getName().equalsIgnoreCase("griefalert")) return null;
} java.util.List<String> completions = new java.util.ArrayList<>();
return true; if (args.length == 1) {
} else if (sub.equals("list")) { java.util.List<String> subs = java.util.Arrays.asList("ignore", "unignore", "list");
getLogger().info("[DEBUG] /griefalert list called by " + sender.getName()); for (String s : subs) {
if (!sender.hasPermission("griefalert.staff.list")) { if (s.startsWith(args[0].toLowerCase())) completions.add(s);
sender.sendMessage(ChatColor.RED + "You do not have permission."); }
getLogger().info("[DEBUG] Permission denied for list"); return completions;
return true; }
} // No world argument needed anymore
listIgnoredLocations(sender); return null;
sender.sendMessage(ChatColor.GRAY + "[DEBUG] Ignored locations listed in chat and console."); }
getLogger().info("[DEBUG] Ignored locations listed for " + sender.getName());
return true; // Sends the alert (or cancels it)
} else if (sub.equals("clear")) { private void alert(String message, String playerName, String mapLink, String target, int x, int y, int z, String world) {
getLogger().info("[DEBUG] /griefalert clear called by " + sender.getName()); // Exclude trusted people
if (!sender.hasPermission("griefalert.staff.clear")) { Player griefer = Bukkit.getPlayer(playerName);
sender.sendMessage(ChatColor.RED + "You do not have permission."); if (griefer.hasPermission("griefalert.exclude") || griefer.hasPermission("griefalert.exclude." + target)) {
getLogger().info("[DEBUG] Permission denied for clear"); return;
return true; }
} // Spam limiter
clearIgnoredLocations(); String realAlertMessage = message;
sender.sendMessage(ChatColor.GREEN + "All ignored locations cleared."); String[] alert1 = null;
getLogger().info("[DEBUG] All ignored locations cleared by " + sender.getName()); if (lastAlert != null) {
return true; alert1 = lastAlert.split(" ");
} }
getLogger().info("[DEBUG] Unknown subcommand: " + sub); String[] alert2 = message.split(" ");
sender.sendMessage(ChatColor.RED + "Unknown subcommand. Use: ignore, unignore, list, clear"); if (alert1 != null) {
return false; if (alert1[2].equals(alert2[2]) && alert1[5].equals(alert2[5]) && alert1[1].equals("broke") && alert2[1].equals("broke")) {
} identicalAlerts += 1;
} else if (Arrays.equals(alert1, alert2)) {
@Override identicalAlerts += 1;
public java.util.List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) { } else {
if (!command.getName().equalsIgnoreCase("griefalert")) return null; identicalAlerts = 1;
java.util.List<String> completions = new java.util.ArrayList<>(); }
if (args.length == 1) { }
java.util.List<String> subs = java.util.Arrays.asList("ignore", "unignore", "list", "clear"); if (identicalAlerts == 4) {
for (String s : subs) { message = ChatColor.GRAY + "Same behavior continues.";
if (s.startsWith(args[0].toLowerCase())) completions.add(s); mapLink = null;
} }
return completions; if (identicalAlerts > 4) {
} return;
if ((args[0].equalsIgnoreCase("ignore") || args[0].equalsIgnoreCase("unignore")) && args.length == 5) { }
// Suggest world names for the 5th argument // Use direct location check
for (World world : getServer().getWorlds()) { if (world != null && isLocationIgnored(x, y, z, world)) {
if (world.getName().toLowerCase().startsWith(args[4].toLowerCase())) { return; // Do not alert if location is ignored
completions.add(world.getName()); }
} // Send an event for external hooks
} GriefAlertEvent griefalert_event;
return completions; if (mapLink != null && !mapLink.isEmpty()) {
} griefalert_event = new GriefAlertEvent(message + " (" + mapLink + ")");
return null; } else {
} griefalert_event = new GriefAlertEvent(message);
}
// Sends the alert (or cancels it) getServer().getPluginManager().callEvent(griefalert_event);
private void alert(String message, String playerName, String mapLink, String target, int x, int y, int z, String world) { // Notify staff ingame
// Exclude trusted people for (Player player : Bukkit.getOnlinePlayers()) {
Player griefer = Bukkit.getPlayer(playerName); if (player.hasPermission("griefalert.notify")) {
if (griefer.hasPermission("griefalert.exclude") || griefer.hasPermission("griefalert.exclude." + target)) { player.sendMessage(message);
return; }
} }
// Spam limiter lastAlert = realAlertMessage;
String realAlertMessage = message; }
String[] alert1 = null;
if (lastAlert != null) { // Block inspector: only the most recent placement counts for ownership.
alert1 = lastAlert.split(" "); private static String inspectBlock(Block block, Player player) {
} List<String[]> lookup = coreProtectAPI.blockLookup(block, 50000000);
String[] alert2 = message.split(" "); if (lookup == null || lookup.size() == 0) {
if (alert1 != null) { // Natural block
if (alert1[2].equals(alert2[2]) && alert1[5].equals(alert2[5]) && alert1[1].equals("broke") && alert2[1].equals("broke")) { return null;
identicalAlerts += 1; }
} else if (Arrays.equals(alert1, alert2)) { // Find the most recent placement event only
identicalAlerts += 1; for (String[] result : lookup) {
} else { ParseResult parseResult = coreProtectAPI.parseResult(result);
identicalAlerts = 1; if (parseResult == null) continue;
} if (parseResult.getActionId() == 1 && !parseResult.isRolledBack() && !parseResult.getPlayer().startsWith("#")) {
} // If the current player placed it, it's theirs (no alert)
if (identicalAlerts == 4) { if (parseResult.getPlayer().equals(player.getName())) {
message = ChatColor.GRAY + "Same behavior continues."; return null;
mapLink = null; } else {
} return parseResult.getPlayer();
if (identicalAlerts > 4) { }
return; }
} // If we see a break before a placement, stop (block is gone)
// Use direct location check if (parseResult.getActionId() == 0) {
if (world != null && isLocationIgnored(x, y, z, world)) { break;
return; // Do not alert if location is ignored }
} }
// Send an event for external hooks // No valid placement found
GriefAlertEvent griefalert_event; return null;
if (mapLink != null && !mapLink.isEmpty()) { }
griefalert_event = new GriefAlertEvent(message + " (" + mapLink + ")");
} else { private static String getHumanWorldName(String worldName) {
griefalert_event = new GriefAlertEvent(message); String world = "";
}
getServer().getPluginManager().callEvent(griefalert_event); if (worldName.endsWith("_nether")) {
// Notify staff ingame world = " in the Nether";
for (Player player : Bukkit.getOnlinePlayers()) { }
if (player.hasPermission("griefalert.notify")) { else if (worldName.endsWith("_the_end")) {
player.sendMessage(message); world = " in the End";
} }
}
lastAlert = realAlertMessage; return world;
} }
// Block inspector: only the most recent placement counts for ownership. private CoreProtectAPI getCoreProtect() {
private static String inspectBlock(Block block, Player player) { Plugin plugin = getServer().getPluginManager().getPlugin("CoreProtect");
List<String[]> lookup = coreProtectAPI.blockLookup(block, 50000000);
if (lookup == null || lookup.size() == 0) { if (plugin == null || !(plugin instanceof CoreProtect)) {
// Natural block return null;
return null; }
}
// Find the most recent placement event only return ((CoreProtect) plugin).getAPI();
for (String[] result : lookup) { }
ParseResult parseResult = coreProtectAPI.parseResult(result);
if (parseResult == null) continue;
if (parseResult.getActionId() == 1 && !parseResult.isRolledBack() && !parseResult.getPlayer().startsWith("#")) {
// If the current player placed it, it's theirs (no alert)
if (parseResult.getPlayer().equals(player.getName())) {
return null;
} else {
return parseResult.getPlayer();
}
}
// If we see a break before a placement, stop (block is gone)
if (parseResult.getActionId() == 0) {
break;
}
}
// No valid placement found
return null;
}
private static String getHumanWorldName(String worldName) {
String world = "";
if (worldName.endsWith("_nether")) {
world = " in the Nether";
}
else if (worldName.endsWith("_the_end")) {
world = " in the End";
}
return world;
}
private CoreProtectAPI getCoreProtect() {
Plugin plugin = getServer().getPluginManager().getPlugin("CoreProtect");
if (plugin == null || !(plugin instanceof CoreProtect)) {
return null;
}
return ((CoreProtect) plugin).getAPI();
}
} }