package de.steamwar.bausystem.tracer; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.tracer.manager.ShowManager; import de.steamwar.bausystem.tracer.trace.TNTTrace; import de.steamwar.core.Core; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.entity.Player; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import static de.steamwar.bausystem.tracer.TraceUtils.DEBUG; public class TNTTracer { private TNTTracer(){} private static final Object synchronizer = new Object(); private static final TraceCache traceCache = new TraceCache(); private static final TracerUpdater tracerUpdater = new TracerUpdater() { @Override public Set updateLocations(Player player) { Iterator traces = ShowManager.get(player).getTraces().descendingIterator(); Set locSet = new HashSet<>(); while (traces.hasNext()) { locSet.addAll(traces.next().locs()); } double radius = ShowManager.get(player).getShowRadius(); locSet.removeIf(loc -> loc.remove(player, radius)); return locSet; } @Override public Set updatePoints(Player player) { Iterator traces = ShowManager.get(player).getTraces().descendingIterator(); Set locSet = new HashSet<>(); while (traces.hasNext()) { locSet.addAll(traces.next().locsUpdate(ShowManager.get(player).getDisplayMode())); } double radius = ShowManager.get(player).getShowRadius(); locSet.removeIf(loc -> loc.remove(player, radius)); return locSet; } @Override public boolean needsUpdate(Player player) { return ShowManager.get(player).isDirty(); } @Override public DisplayMode getDisplayType(Player player) { switch (ShowManager.get(player).getDisplayType()) { case Block: return DisplayMode.Block; case Particle: return DisplayMode.Particle; default: break; } return DisplayMode.Particle; } @Override public String actionBar(Player player) { return TraceActionbar.traceMemory() + " " + TraceActionbar.traceSize() + " " + TraceActionbar.showRadius(player); } }; public static void init(){ Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> { synchronized (synchronizer) { synchronizer.notifyAll(); } }, 1, 20); Bukkit.getScheduler().runTaskAsynchronously(BauSystem.getPlugin(), () -> { while (true) { synchronized (synchronizer) { try { synchronizer.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } run(); } }); } private static void run(){ for (Player p : Bukkit.getOnlinePlayers()) { if (DEBUG) { String actionBar = tracerUpdater.actionBar(p); p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(actionBar)); } boolean dirty = tracerUpdater.needsUpdate(p); if (tracerUpdater.getDisplayType(p) == TracerUpdater.DisplayMode.Block && !dirty) { continue; } Set toHide = traceCache.update(p, tracerUpdater, dirty); Set toShow = traceCache.get(p); hideBlockTraces(toHide, p); showTraces(toShow, tracerUpdater.getDisplayType(p), p); } } private static void hideBlockTraces(Set locs, Player player) { if (locs.isEmpty()) return; for (TraceCache.Loc l : locs) { TraceUtils.hideBlock(player, l.x, l.y - 0.49F, l.z); } } private static void showTraces(Set locs, TracerUpdater.DisplayMode displayMode, Player player) { if (locs.isEmpty()) return; for (TraceCache.Loc l : locs) { if (displayMode == TracerUpdater.DisplayMode.Block) { TraceUtils.showBlock(player, l.x, l.y - 0.49F, l.z, getMaterial(l), (l.updatePoint ? (byte) 5 : (byte) 14)); } else { TraceUtils.showCorner(player, l.x - 0.49F, l.y, l.z - 0.49F, (l.updatePoint ? Particle.FLAME : Particle.VILLAGER_HAPPY)); } } } private static Material getMaterial(TraceCache.Loc l){ switch(Core.getVersion()){ case 15: return TNTTracer_15.getMaterial(l.updatePoint); default: return TNTTracer_12.getMaterial(); } } }