MineAlert/src/main/java/xyz/etztech/orealert/listeners/BlockBreakListener.java

132 lines
4.6 KiB
Java

package xyz.etztech.orealert.listeners;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import xyz.etztech.orealert.Lang;
import xyz.etztech.orealert.OreAlert;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
public class BlockBreakListener implements Listener {
private final OreAlert plugin;
private final Map<Player, List<BlockEvent>> map = new HashMap<>();
private final Queue<BlockEvent> queue = new ConcurrentLinkedQueue<>();
public BlockBreakListener(OreAlert plugin) {
this.plugin = plugin;
this.plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, this::task);
this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, this::cleanup, 0,
20 * 60 * this.plugin.getConfig().getInt("cleanup", 5));
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
queue.add(new BlockEvent(event.getPlayer(), event.getBlock(), true));
int radius = this.plugin.getConfig().getInt("radius", 3);
for (int x = -radius; x < radius; x++) {
for (int y = -radius; y < radius; y++) {
for (int z = -radius; z < radius; z++) {
queue.add(new BlockEvent(event.getPlayer(), event.getBlock().getRelative(x, y, z), false));
}
}
}
}
private void task() {
while (true) {
BlockEvent event = this.queue.poll();
if (event != null) {
List<String> blocks = this.plugin.getConfig().getStringList("blocks");
for (String s: blocks) {
if (Lang.getMaterialKey(event.getBlock().getType()).equals(s)) {
addStrike(event);
check(event);
break;
}
}
}
}
}
private void addStrike(BlockEvent event) {
List<BlockEvent> events = map.getOrDefault(event.getPlayer(), new ArrayList<>());
events.add(event);
map.put(event.getPlayer(), events);
}
private void check(BlockEvent event) {
List<BlockEvent> events = map.getOrDefault(event.getPlayer(), new ArrayList<>());
FileConfiguration config = this.plugin.getConfig();
String blockKey = Lang.getMaterialKey(event.getBlock().getType());
int start = config.getInt(String.format("blocks.%s.start", blockKey), config.getInt("start", 5));
int each = config.getInt(String.format("blocks.%s.each", blockKey), config.getInt("each", 5));
int ping = config.getInt(String.format("blocks.%s.ping", blockKey), config.getInt("ping", 5));
purge(map.getOrDefault(event.getPlayer(), new ArrayList<>()).iterator());
int strikes = map.getOrDefault(event.getPlayer(), new ArrayList<>()).size();
}
private void cleanup() {
for (Iterator<Player> it = map.keySet().iterator(); it.hasNext(); ) {
Player player = it.next();
purge(map.get(player).iterator());
if (map.get(player).isEmpty()) {
it.remove();
}
}
}
private void purge(Iterator<BlockEvent> events) {
Date now = Calendar.getInstance().getTime();
int globalPurge = this.plugin.getConfig().getInt("purge", 30);
while (events.hasNext()) {
BlockEvent e = events.next();
int purge = 1000 * 60 * this.plugin.getConfig().getInt(String.format("blocks.%s.purge", Lang.getMaterialKey(e.getBlock().getType())), globalPurge);
if (new Date(e.getTime().getTime() + purge).before(now)) {
events.remove();
}
}
}
}
class BlockEvent {
private final Player player;
private final Block block;
private final Boolean parent;
private final Date time;
BlockEvent(Player player, Block block, Boolean parent) {
this.player = player;
this.block = block;
this.parent = parent;
this.time = Calendar.getInstance().getTime();
}
public Player getPlayer() {
return player;
}
public Block getBlock() {
return block;
}
public Boolean isParent() {
return parent;
}
public Date getTime() {
return time;
}
}