package com.github.games647.lagmonitor.command; import com.github.games647.lagmonitor.LagMonitor; import com.github.games647.lagmonitor.graph.ClassesGraph; import com.github.games647.lagmonitor.graph.CombinedGraph; import com.github.games647.lagmonitor.graph.CpuGraph; import com.github.games647.lagmonitor.graph.GraphRenderer; import com.github.games647.lagmonitor.graph.HeapGraph; import com.github.games647.lagmonitor.graph.ThreadsGraph; import com.github.games647.lagmonitor.util.LagUtils; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.MapMeta; import org.bukkit.map.MapView; import static java.util.stream.Collectors.toList; public class GraphCommand extends LagCommand implements TabExecutor { private static final int MAX_COMBINED = 4; private final Map<String, GraphRenderer> graphTypes = new HashMap<>(); public GraphCommand(LagMonitor plugin) { super(plugin); graphTypes.put("classes", new ClassesGraph()); graphTypes.put("cpu", new CpuGraph(plugin, plugin.getNativeData())); graphTypes.put("heap", new HeapGraph()); graphTypes.put("threads", new ThreadsGraph()); } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (!canExecute(sender, command)) { return true; } if (sender instanceof Player) { Player player = (Player) sender; if (args.length > 0) { if (args.length > 1) { buildCombinedGraph(player, args); } else { String graph = args[0]; GraphRenderer renderer = graphTypes.get(graph); if (renderer == null) { sendError(sender, "Unknown graph type"); } else { giveMap(player, installRenderer(player, renderer)); } } return true; } //default is heap usage GraphRenderer graphRenderer = graphTypes.get("heap"); MapView mapView = installRenderer(player, graphRenderer); giveMap(player, mapView); } else { sendError(sender, "Not implemented for the console"); } return true; } @Override public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) { if (args.length != 1) { return Collections.emptyList(); } String lastArg = args[args.length - 1]; return graphTypes.keySet().stream() .filter(type -> type.startsWith(lastArg)) .sorted(String.CASE_INSENSITIVE_ORDER) .collect(toList()); } private void buildCombinedGraph(Player player, String[] args) { List<GraphRenderer> renderers = new ArrayList<>(); for (String arg : args) { GraphRenderer renderer = graphTypes.get(arg); if (renderer == null) { sendError(player, "Unknown graph type " + arg); return; } renderers.add(renderer); } if (renderers.size() > MAX_COMBINED) { sendError(player, "Too many graphs"); } else { CombinedGraph combinedGraph = new CombinedGraph(renderers.toArray(new GraphRenderer[0])); MapView view = installRenderer(player, combinedGraph); giveMap(player, view); } } private void giveMap(Player player, MapView mapView) { PlayerInventory inventory = player.getInventory(); ItemStack mapItem; if (LagUtils.isFilledMapSupported()) { mapItem = new ItemStack(Material.FILLED_MAP, 1); ItemMeta meta = mapItem.getItemMeta(); if (meta instanceof MapMeta) { MapMeta mapMeta = (MapMeta) meta; mapMeta.setMapView(mapView); mapItem.setItemMeta(meta); } } else { mapItem = new ItemStack(Material.MAP, 1, (short) mapView.getId()); } inventory.addItem(mapItem); player.sendMessage(ChatColor.DARK_GREEN + "You received a map with the graph"); } private MapView installRenderer(Player player, GraphRenderer graphType) { MapView mapView = Bukkit.createMap(player.getWorld()); mapView.getRenderers().forEach(mapView::removeRenderer); mapView.addRenderer(graphType); return mapView; } }