package me.mrCookieSlime.Slimefun.api; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import me.mrCookieSlime.CSCoreLibPlugin.general.Chat.TellRawMessage; import me.mrCookieSlime.CSCoreLibPlugin.general.Chat.TellRawMessage.HoverAction; import me.mrCookieSlime.Slimefun.SlimefunStartup; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.handlers.BlockTicker; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; public class TickerTask implements Runnable { public Map move = new HashMap(); public Map delete = new HashMap(); private Set tickers = new HashSet(); private int skipped = 0, chunks = 0, machines = 0; private long time = 0; private Map map_chunk = new HashMap(); private Map map_machine = new HashMap(); private Map map_machinetime = new HashMap(); private Map map_chunktime = new HashMap(); private Set skipped_chunks = new HashSet(); public static Map block_timings = new HashMap(); public static Map bugged_blocks = new HashMap(); @Override public void run() { long timestamp = System.currentTimeMillis(); skipped = 0; chunks = 0; machines = 0; map_chunk.clear(); map_machine.clear(); time = 0; map_chunktime.clear(); skipped_chunks.clear(); map_machinetime.clear(); block_timings.clear(); Map bugged = new HashMap(bugged_blocks); bugged_blocks.clear(); Map remove = new HashMap(delete); for (Map.Entry entry: remove.entrySet()) { BlockStorage._integrated_removeBlockInfo(entry.getKey(), entry.getValue()); delete.remove(entry.getKey()); } for (final String c: BlockStorage.getTickingChunks()) { long timestamp2 = System.currentTimeMillis(); chunks++; blocks: for (final Block b: BlockStorage.getTickingBlocks(c)) { if (b.getChunk().isLoaded()) { final Location l = b.getLocation(); final SlimefunItem item = BlockStorage.check(l); if (item != null) { machines++; try { item.getTicker().update(); if (item.getTicker().isSynchronized()) { Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunStartup.instance, new Runnable() { @Override public void run() { long timestamp3 = System.currentTimeMillis(); item.getTicker().tick(b, item, BlockStorage.getBlockInfo(l)); map_machinetime.put(item.getName(), (map_machinetime.containsKey(item.getName()) ? map_machinetime.get(item.getName()): 0) + (System.currentTimeMillis() - timestamp3)); map_chunk.put(c, (map_chunk.containsKey(c) ? map_chunk.get(c): 0) + 1); map_machine.put(item.getName(), (map_machine.containsKey(item.getName()) ? map_machine.get(item.getName()): 0) + 1); block_timings.put(l, System.currentTimeMillis() - timestamp3); } }); } else { long timestamp3 = System.currentTimeMillis(); item.getTicker().tick(b, item, BlockStorage.getBlockInfo(l)); map_machinetime.put(item.getName(), (map_machinetime.containsKey(item.getName()) ? map_machinetime.get(item.getName()): 0) + (System.currentTimeMillis() - timestamp3)); map_chunk.put(c, (map_chunk.containsKey(c) ? map_chunk.get(c): 0) + 1); map_machine.put(item.getName(), (map_machine.containsKey(item.getName()) ? map_machine.get(item.getName()): 0) + 1); block_timings.put(l, System.currentTimeMillis() - timestamp3); } tickers.add(item.getTicker()); } catch(Exception x) { int errors = 0; if (bugged.containsKey(l)) errors = bugged.get(l); errors++; if (errors == 1) { System.err.println("[Slimefun] Exception caught while ticking a Block:"); System.err.println("[Slimefun] X: " + l.getBlockX() + " Y: " + l.getBlockY() + " Z: " + l.getBlockZ()); System.err.println("[Slimefun] Type: " + item.getName()); System.err.println("[Slimefun] " + BlockStorage.getBlockInfoAsJson(l)); System.err.println("[Slimefun] "); System.err.println("[Slimefun] IGNORE THIS ERROR - Fixing it automatically..."); System.err.println("[Slimefun] "); x.printStackTrace(); bugged_blocks.put(l, errors); } else if (errors == 2) { System.err.println("[Slimefun] X: " + l.getBlockX() + " Y: " + l.getBlockY() + " Z: " + l.getBlockZ() + "(" + item.getName() + ")"); System.err.println("[Slimefun] 2x " + x.getClass().getName()); System.err.println("[Slimefun] "); bugged_blocks.put(l, errors); } else if (errors == 3) { System.err.println("[Slimefun] X: " + l.getBlockX() + " Y: " + l.getBlockY() + " Z: " + l.getBlockZ() + "(" + item.getName() + ")"); System.err.println("[Slimefun] 3x " + x.getClass().getName()); System.err.println("[Slimefun] "); bugged_blocks.put(l, errors); } else if (errors == 4) { System.err.println("[Slimefun] X: " + l.getBlockX() + " Y: " + l.getBlockY() + " Z: " + l.getBlockZ() + "(" + item.getName() + ")"); System.err.println("[Slimefun] has thrown 4 Exceptions in the last 4 Ticks, the Block has been terminated."); System.err.println("[Slimefun] "); BlockStorage._integrated_removeBlockInfo(l, true); } } } else skipped++; } else { skipped += BlockStorage.getTickingBlocks(c).size(); skipped_chunks.add(c); chunks--; break blocks; } } map_chunktime.put(c, System.currentTimeMillis() - timestamp2); } for (Map.Entry entry: move.entrySet()) { BlockStorage._integrated_moveBlockInfo(entry.getKey(), entry.getValue()); } move.clear(); for (BlockTicker ticker: tickers) { ticker.unique = true; } tickers.clear(); time = System.currentTimeMillis() - timestamp; } public void info(CommandSender sender) { sender.sendMessage("§2== §aSlimefun Diagnostic Tool §2=="); sender.sendMessage("§6Impact: §e" + time + "ms / 50-750ms"); sender.sendMessage("§6Ticked Chunks: §e" + chunks); sender.sendMessage("§6Ticked Machines: §e" + machines); sender.sendMessage("§6Skipped Machines: §e" + skipped); sender.sendMessage(""); sender.sendMessage("§6Ticking Machines:"); if (sender instanceof Player) { TellRawMessage tellraw = new TellRawMessage(); tellraw.addText(" §7§oHover for more Info"); StringBuilder hover = new StringBuilder(); int hidden = 0; for (String item: map_machine.keySet()) { if (map_machinetime.get(item) > 0) hover.append("\n§c" + item + " - " + map_machine.get(item) + "x §7(" + map_machinetime.get(item) + "ms)"); else hidden++; } hover.append("\n\n§c+ §4" + hidden + " Hidden"); tellraw.addHoverEvent(HoverAction.SHOW_TEXT, hover.toString()); try { tellraw.send((Player) sender); } catch (Exception e) { e.printStackTrace(); } } else { int hidden = 0; for (String item: map_machine.keySet()) { if (map_machinetime.get(item) > 0) sender.sendMessage(" §e" + item + " - " + map_machine.get(item) + "x §7(" + map_machinetime.get(item) + "ms)"); else hidden++; } sender.sendMessage("§c+ §4" + hidden + " Hidden"); } sender.sendMessage(""); sender.sendMessage("§6Ticking Chunks:"); if (sender instanceof Player) { TellRawMessage tellraw = new TellRawMessage(); tellraw.addText(" §7§oHover for more Info"); StringBuilder hover = new StringBuilder(); int hidden = 0; for (String c: map_chunktime.keySet()) { if (!skipped_chunks.contains(c)) { if (map_chunktime.get(c) > 0) hover.append("\n§c" + c.replace("CraftChunk", "") + " - " + (map_chunk.containsKey(c) ? map_chunk.get(c): 0) + "x §7(" + map_chunktime.get(c) + "ms)"); else hidden++; } } hover.append("\n\n§c+ §4" + hidden + " Hidden"); tellraw.addHoverEvent(HoverAction.SHOW_TEXT, hover.toString()); try { tellraw.send((Player) sender); } catch (Exception e) { e.printStackTrace(); } } else { int hidden = 0; for (String c: map_chunktime.keySet()) { if (!skipped_chunks.contains(c)) { if (map_chunktime.get(c) > 0) sender.sendMessage(" §c" + c.replace("CraftChunk", "") + " - " + (map_chunk.containsKey(c) ? map_chunk.get(c): 0) + "x §7(" + map_chunktime.get(c) + "ms)"); else hidden++; } } sender.sendMessage("§c+ §4" + hidden + " Hidden"); } } public long getTimings(Block b) { return block_timings.containsKey(b.getLocation()) ? block_timings.get(b.getLocation()): 0L; } public long getTimings(String item) { return map_machinetime.containsKey(item) ? map_machinetime.get(item): 0L; } public long getTimings(Chunk c) { return map_chunktime.containsKey(c.toString()) ? map_chunktime.get(c.toString()): 0L; } }