package mcjty.rftools.items.netmonitor; import mcjty.lib.base.StyleConfig; import mcjty.lib.gui.GuiItemScreen; import mcjty.lib.gui.Window; import mcjty.lib.gui.events.ButtonEvent; import mcjty.lib.gui.events.DefaultSelectionEvent; import mcjty.lib.gui.events.TextEvent; import mcjty.lib.gui.layout.HorizontalAlignment; import mcjty.lib.gui.layout.HorizontalLayout; import mcjty.lib.gui.layout.VerticalLayout; import mcjty.lib.gui.widgets.*; import mcjty.lib.gui.widgets.Label; import mcjty.lib.gui.widgets.Panel; import mcjty.lib.gui.widgets.TextField; import mcjty.lib.varia.Coordinate; import mcjty.lib.varia.Logging; import mcjty.rftools.BlockInfo; import mcjty.rftools.RFTools; import mcjty.rftools.network.RFToolsMessages; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import java.awt.*; import java.util.HashMap; import java.util.Map; public class GuiNetworkMonitor extends GuiItemScreen { private static final int MONITOR_XSIZE = 356; private static final int MONITOR_YSIZE = 206; // A copy of the connected blocks we're currently showing private Map<Coordinate, BlockInfo> connectedBlocks; // The labels in our list containing the RF information. private Map<Coordinate, EnergyBar> labelMap; // Previous rf for a given coordinate. private Map<Coordinate, Integer> previousRf = null; private long previousRfMillis = 0; // A map mapping index in our widget list to coordinates. private Map<Integer, Coordinate> indexToCoordinate; // The result of the server. private static Map<Coordinate, BlockInfo> serverConnectedBlocks = null; private static int selectedX; private static int selectedY; private static int selectedZ; public static final int TEXT_COLOR = 0x000000; public static final int SEL_TEXT_COLOR = 0xffffff; private ToggleButton showRfPerTick; private WidgetList list; private TextField filterTextField; private int listDirty; private String filter = null; public static void setSelected(int x, int y, int z) { selectedX = x; selectedY = y; selectedZ = z; } public GuiNetworkMonitor() { super(RFTools.instance, RFToolsMessages.INSTANCE, MONITOR_XSIZE, MONITOR_YSIZE, RFTools.GUI_MANUAL_MAIN, "netmon"); listDirty = 0; previousRfMillis = 0; } public static void setServerConnectedBlocks(Map<Coordinate, BlockInfo> serverConnectedBlocks) { GuiNetworkMonitor.serverConnectedBlocks = new HashMap<Coordinate, BlockInfo>(serverConnectedBlocks); } private void requestConnectedBlocksFromServer() { RFToolsMessages.INSTANCE.sendToServer(new PacketGetConnectedBlocks(selectedX, selectedY, selectedZ)); } @Override public void initGui() { super.initGui(); list = new WidgetList(mc, this).addSelectionEvent(new DefaultSelectionEvent() { @Override public void doubleClick(Widget parent, int index) { hilightBlock(index); } }); listDirty = 0; Slider listSlider = new Slider(mc, this).setDesiredWidth(11).setVertical().setScrollable(list); Panel listPanel = new Panel(mc, this).setLayout(new HorizontalLayout().setSpacing(1).setHorizontalMargin(3)).addChild(list).addChild(listSlider); showRfPerTick = new ToggleButton(mc, this).setCheckMarker(true).setText("RF/tick").setDesiredWidth(80).addButtonEvent(new ButtonEvent() { @Override public void buttonClicked(Widget parent) { previousRfMillis = 0; } }).setDesiredHeight(14); filterTextField = new TextField(mc, this).setDesiredHeight(14).addTextEvent(new TextEvent() { @Override public void textChanged(Widget parent, String newText) { filter = filterTextField.getText(); if (filter.trim().isEmpty()) { filter = null; } connectedBlocks = null; } }); Panel buttonPanel = new Panel(mc, this).setLayout(new HorizontalLayout()).addChild(showRfPerTick).addChild(new Label(mc, this).setText("Filter:")).addChild(filterTextField).setDesiredHeight(17); Widget toplevel = new Panel(mc, this).setFilledRectThickness(2).setLayout(new VerticalLayout().setVerticalMargin(3)).addChild(listPanel).addChild(buttonPanel); toplevel.setBounds(new Rectangle(guiLeft, guiTop, xSize, ySize)); window = new Window(this, toplevel); serverConnectedBlocks = null; } private void hilightBlock(int index) { if (index == -1) { return; } Coordinate c = indexToCoordinate.get(index); RFTools.instance.clientInfo.hilightBlock(c, System.currentTimeMillis()+1000* NetworkMonitorConfiguration.hilightTime); Logging.message(mc.thePlayer, "The block is now highlighted"); Minecraft.getMinecraft().thePlayer.closeScreen(); } private void refreshList(boolean recalcPerTick) { long millis = System.currentTimeMillis(); boolean rftick = showRfPerTick.isPressed(); for (Map.Entry<Coordinate,BlockInfo> me : connectedBlocks.entrySet()) { BlockInfo blockInfo = me.getValue(); int energy = blockInfo.getEnergyStored(); int maxEnergy = blockInfo.getMaxEnergyStored(); EnergyBar energyLabel = labelMap.get(me.getKey()); // First test if this label isn't filtered out. if (energyLabel != null) { setEnergyLabel(millis, rftick, recalcPerTick, me, energy, maxEnergy, energyLabel); } } } private void setEnergyLabel(long millis, boolean rftick, boolean recalcPerTick, Map.Entry<Coordinate, BlockInfo> me, int energy, int maxEnergy, EnergyBar energyLabel) { energyLabel.setValue(energy).setMaxValue(maxEnergy).setShowRfPerTick(rftick); if (rftick && recalcPerTick) { long dt = millis - previousRfMillis; int rft = 0; if (dt > 0 && previousRf != null && previousRf.containsKey(me.getKey())) { rft = energy - previousRf.get(me.getKey()); rft = rft * 50 / (int)dt; } energyLabel.setRfPerTick(rft); } } private void populateList() { requestConnectedBlocksFromServer(); if (serverConnectedBlocks == null) { return; } boolean rftick = showRfPerTick.isPressed(); long millis = System.currentTimeMillis(); boolean recalcPerTick = previousRfMillis == 0 || (millis - previousRfMillis) > 1000; if (serverConnectedBlocks.equals(connectedBlocks)) { refreshList(recalcPerTick); } else { connectedBlocks = new HashMap<Coordinate, BlockInfo>(serverConnectedBlocks); Map<Coordinate, EnergyBar> oldLabelMap = labelMap; labelMap = new HashMap<Coordinate, EnergyBar>(); indexToCoordinate = new HashMap<Integer, Coordinate>(); list.removeChildren(); int index = 0; for (Map.Entry<Coordinate, BlockInfo> me : connectedBlocks.entrySet()) { BlockInfo blockInfo = me.getValue(); Coordinate coordinate = me.getKey(); Block block = mc.theWorld.getBlock(coordinate.getX(), coordinate.getY(), coordinate.getZ()); if (block == null || block.isAir(mc.theWorld, coordinate.getX(), coordinate.getY(), coordinate.getZ())) { continue; } int energy = blockInfo.getEnergyStored(); int maxEnergy = blockInfo.getMaxEnergyStored(); int color = getTextColor(blockInfo); int meta = mc.theWorld.getBlockMetadata(coordinate.getX(), coordinate.getY(), coordinate.getZ()); String displayName = BlockInfo.getReadableName(block, coordinate, meta, mc.theWorld); if (filter != null) { if (!displayName.toLowerCase().contains(filter)) { continue; } } Panel panel = new Panel(mc, this).setLayout(new HorizontalLayout()); panel.addChild(new BlockRender(mc, this).setRenderItem(block)); panel.addChild(new Label(mc, this).setColor(StyleConfig.colorTextInListNormal).setHorizontalAlignment(HorizontalAlignment.ALIGH_LEFT).setText(displayName).setColor(color).setDesiredWidth(100)); panel.addChild(new Label(mc, this).setColor(StyleConfig.colorTextInListNormal).setHorizontalAlignment(HorizontalAlignment.ALIGH_LEFT).setText(coordinate.toString()).setColor(color).setDesiredWidth(75)); EnergyBar energyLabel = oldLabelMap == null ? null : oldLabelMap.get(coordinate); if (energyLabel == null) { energyLabel = new EnergyBar(mc, this).setHorizontal(); } setEnergyLabel(millis, rftick, recalcPerTick, me, energy, maxEnergy, energyLabel); panel.addChild(energyLabel); list.addChild(panel); labelMap.put(coordinate, energyLabel); indexToCoordinate.put(index, coordinate); index++; } } if (rftick && recalcPerTick) { previousRfMillis = millis; previousRf = new HashMap<Coordinate, Integer>(connectedBlocks.size()); for (Map.Entry<Coordinate, BlockInfo> me : connectedBlocks.entrySet()) { previousRf.put(me.getKey(), me.getValue().getEnergyStored()); } } } @Override public void drawScreen(int xSize_lo, int ySize_lo, float par3) { super.drawScreen(xSize_lo, ySize_lo, par3); listDirty--; if (listDirty <= 0) { populateList(); listDirty = 10; } drawWindow(); } private int getTextColor(BlockInfo blockInfo) { int color; Coordinate c = blockInfo.getCoordinate(); if (c.getX() == selectedX && c.getY() == selectedY && c.getZ() == selectedZ) { color = SEL_TEXT_COLOR; } else { color = TEXT_COLOR; } return color; } }