map = Minecraft.getMinecraft().getSkinManager().loadSkinFromCache(gameprofile);
-
- if (map.containsKey(MinecraftProfileTexture.Type.SKIN)) {
- MinecraftProfileTexture profTex = map.get(MinecraftProfileTexture.Type.SKIN);
- event.toolTip.add(EnumChatFormatting.AQUA+"Skull Texture Link: "+EnumChatFormatting.GRAY+profTex.getUrl()+EnumChatFormatting.GOLD+" [N]");
-
- if(!copied && n) {
- MiscUtils.copyToClipboard(profTex.getUrl());
- }
- }
- }
- }
- }
-
- if(k || m || n) {
- copied = true;
- } else {
- copied = false;
- }
- }
- }
-
- @SubscribeEvent
- public void onRenderLast(RenderWorldLastEvent event){
- CrystalMetalDetectorSolver.render(event.partialTicks);
- }
+ private IChatComponent processChatComponent(IChatComponent chatComponent) {
+ IChatComponent newComponent;
+ if (chatComponent instanceof ChatComponentText) {
+ ChatComponentText text = (ChatComponentText) chatComponent;
+
+ newComponent = new ChatComponentText(processText(text.getUnformattedTextForChat()));
+ newComponent.setChatStyle(text.getChatStyle().createShallowCopy());
+
+ for (IChatComponent sibling : text.getSiblings()) {
+ newComponent.appendSibling(processChatComponent(sibling));
+ }
+ } else if (chatComponent instanceof ChatComponentTranslation) {
+ ChatComponentTranslation trans = (ChatComponentTranslation) chatComponent;
+
+ Object[] args = trans.getFormatArgs();
+ Object[] newArgs = new Object[args.length];
+ for (int i = 0; i < trans.getFormatArgs().length; i++) {
+ if (args[i] instanceof IChatComponent) {
+ newArgs[i] = processChatComponent((IChatComponent) args[i]);
+ } else {
+ newArgs[i] = args[i];
+ }
+ }
+ newComponent = new ChatComponentTranslation(trans.getKey(), newArgs);
+
+ for (IChatComponent sibling : trans.getSiblings()) {
+ newComponent.appendSibling(processChatComponent(sibling));
+ }
+ } else {
+ newComponent = chatComponent.createCopy();
+ }
+
+ return newComponent;
+ }
+
+ private String processText(String text) {
+ if (SBInfo.getInstance().getLocation() == null) return text;
+ if (!SBInfo.getInstance().getLocation().startsWith("mining_") &&
+ !SBInfo.getInstance().getLocation().equals("crystal_hollows"))
+ return text;
+
+ if (Minecraft.getMinecraft().thePlayer == null) return text;
+ if (!NotEnoughUpdates.INSTANCE.config.mining.drillFuelBar) return text;
+
+ return Utils.trimIgnoreColour(text.replaceAll(EnumChatFormatting.DARK_GREEN + "\\S+ Drill Fuel", ""));
+ }
+
+ private IChatComponent replaceSocialControlsWithPV(IChatComponent chatComponent) {
+
+ if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 > 0 && chatComponent.getChatStyle() != null &&
+ chatComponent.getChatStyle().getChatClickEvent() != null &&
+ chatComponent.getChatStyle().getChatClickEvent().getAction() == ClickEvent.Action.RUN_COMMAND &&
+ NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) {
+ if (chatComponent.getChatStyle().getChatClickEvent().getValue().startsWith("/socialoptions")) {
+ String username = chatComponent.getChatStyle().getChatClickEvent().getValue().substring(15);
+ if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 == 1) {
+ chatComponent.setChatStyle(Utils.createClickStyle(
+ ClickEvent.Action.RUN_COMMAND,
+ "/pv " + username,
+ "" + EnumChatFormatting.YELLOW + "Click to open " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD +
+ username + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + "'s profile in " +
+ EnumChatFormatting.DARK_PURPLE + EnumChatFormatting.BOLD + "NEU's" + EnumChatFormatting.RESET +
+ EnumChatFormatting.YELLOW + " profile viewer."
+ ));
+ return chatComponent;
+ } else if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 == 2) {
+ chatComponent.setChatStyle(Utils.createClickStyle(
+ ClickEvent.Action.RUN_COMMAND,
+ "/ah " + username,
+ "" + EnumChatFormatting.YELLOW + "Click to open " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD +
+ username + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + "'s /ah page"
+ ));
+ return chatComponent;
+ }
+ } // wanted to add this for guild but guild uses uuid :sad:
+ }
+ return chatComponent;
+ }
+
+ /**
+ * 1) When receiving "You are playing on profile" messages, will set the current profile.
+ * 2) When a /viewrecipe command fails (i.e. player does not have recipe unlocked, will open the custom recipe GUI)
+ * 3) Replaces lobby join notifications when streamer mode is active
+ */
+ @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
+ public void onGuiChat(ClientChatReceivedEvent e) {
+ if (e.type == 2) {
+ CrystalMetalDetectorSolver.process(e.message);
+ e.message = processChatComponent(e.message);
+ return;
+ } else if (e.type == 0) {
+ e.message = replaceSocialControlsWithPV(e.message);
+ }
+
+ DungeonWin.onChatMessage(e);
+
+ String r = null;
+ String unformatted = Utils.cleanColour(e.message.getUnformattedText());
+ Matcher matcher = SLAYER_XP.matcher(unformatted);
+ if (unformatted.startsWith("You are playing on profile: ")) {
+ neu.manager.setCurrentProfile(unformatted
+ .substring("You are playing on profile: ".length())
+ .split(" ")[0].trim());
+ } else if (unformatted.startsWith("Your profile was changed to: ")) {//Your profile was changed to:
+ neu.manager.setCurrentProfile(unformatted
+ .substring("Your profile was changed to: ".length())
+ .split(" ")[0].trim());
+ } else if (unformatted.startsWith("Your new API key is ")) {
+ NotEnoughUpdates.INSTANCE.config.apiKey.apiKey = unformatted.substring("Your new API key is ".length());
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
+ "[NEU] API Key automatically configured"));
+ NotEnoughUpdates.INSTANCE.config.apiKey.apiKey = NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.substring(0, 36);
+ } else if (unformatted.startsWith("Player List Info is now disabled!")) {
+ SBInfo.getInstance().hasNewTab = false;
+ } else if (unformatted.startsWith("Player List Info is now enabled!")) {
+ SBInfo.getInstance().hasNewTab = true;
+ }
+ if (e.message.getFormattedText().equals(EnumChatFormatting.RESET.toString() +
+ EnumChatFormatting.RED + "You haven't unlocked this recipe!" + EnumChatFormatting.RESET)) {
+ r = EnumChatFormatting.RED + "You haven't unlocked this recipe!";
+ } else if (e.message.getFormattedText().startsWith(EnumChatFormatting.RESET.toString() +
+ EnumChatFormatting.RED + "Invalid recipe ")) {
+ r = "";
+ } else if (unformatted.equals(" NICE! SLAYER BOSS SLAIN!")) {
+ SlayerOverlay.isSlain = true;
+ } else if (unformatted.equals(" SLAYER QUEST STARTED!")) {
+ SlayerOverlay.isSlain = false;
+ if (timeSinceLastBoss == 0) {
+ SlayerOverlay.timeSinceLastBoss = System.currentTimeMillis();
+ } else {
+ timeSinceLastBoss2 = timeSinceLastBoss;
+ timeSinceLastBoss = System.currentTimeMillis();
+ }
+ } else if (unformatted.startsWith(" RNGesus Meter:")) {
+ RNGMeter = unformatted.substring(" RNGesus Meter: -------------------- ".length());
+ } else if (matcher.matches()) {
+ //matcher.group(1);
+ SlayerOverlay.slayerLVL = matcher.group(2);
+ if (!SlayerOverlay.slayerLVL.equals("9")) {
+ SlayerOverlay.slayerXp = matcher.group(3);
+ } else {
+ slayerXp = "maxed";
+ }
+ } else if (unformatted.startsWith("Sending to server") ||
+ (unformatted.startsWith("Your Slayer Quest has been cancelled!"))) {
+ SlayerOverlay.slayerQuest = false;
+ SlayerOverlay.unloadOverlayTimer = System.currentTimeMillis();
+ }
+ if (e.message
+ .getFormattedText()
+ .contains(EnumChatFormatting.YELLOW + "Visit the Auction House to collect your item!")) {
+ if (NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBid != null &&
+ System.currentTimeMillis() - NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBidMillis < 5000) {
+ NotEnoughUpdates.INSTANCE.sendChatMessage("/viewauction " +
+ NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.niceAucId(
+ NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBid));
+ }
+ }
+ if (r != null) {
+ if (neu.manager.failViewItem(r)) {
+ e.setCanceled(true);
+ }
+ missingRecipe.set(true);
+ }
+ //System.out.println(e.message);
+ if (unformatted.startsWith("Sending to server") &&
+ neu.isOnSkyblock() && NotEnoughUpdates.INSTANCE.config.misc.streamerMode &&
+ e.message instanceof ChatComponentText) {
+ String m = e.message.getFormattedText();
+ String m2 = StreamerMode.filterChat(e.message.getFormattedText());
+ if (!m.equals(m2)) {
+ e.message = new ChatComponentText(m2);
+ }
+ }
+ if (unformatted.startsWith("You found ") && SBInfo.getInstance().getLocation() != null &&
+ SBInfo.getInstance().getLocation().equals("crystal_hollows")) {
+ CrystalMetalDetectorSolver.reset(true);
+ }
+ if (unformatted.startsWith("[NPC] Keeper of ") | unformatted.startsWith("[NPC] Professor Robot: ") ||
+ unformatted.startsWith(" ") || unformatted.startsWith("✦") ||
+ unformatted.equals(" You've earned a Crystal Loot Bundle!"))
+ OverlayManager.crystalHollowOverlay.message(unformatted);
+ }
+
+ public static boolean drawingGuiScreen = false;
+
+ /**
+ * Sets hoverInv and focusInv variables, representing whether the NEUOverlay should render behind the inventory when
+ * (hoverInv == true) and whether mouse/kbd inputs shouldn't be sent to NEUOverlay (focusInv == true).
+ *
+ * If hoverInv is true, will render the overlay immediately (resulting in the inventory being drawn over the GUI)
+ * If hoverInv is false, the overlay will render in #onGuiScreenDraw (resulting in the GUI being drawn over the inv)
+ *
+ * All of this only matters if players are using gui scale auto which may result in the inventory being drawn
+ * over the various panes.
+ */
+ @SubscribeEvent
+ public void onGuiBackgroundDraw(GuiScreenEvent.BackgroundDrawnEvent event) {
+ if (showNotificationOverInv) {
+
+ renderNotification();
+
+ }
+ if ((shouldRenderOverlay(event.gui) || event.gui instanceof CustomAHGui) && neu.isOnSkyblock()) {
+ ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledresolution.getScaledWidth();
+
+ boolean hoverPane = event.getMouseX() < width * neu.overlay.getInfoPaneOffsetFactor() ||
+ event.getMouseX() > width * neu.overlay.getItemPaneOffsetFactor();
+
+ if (event.gui instanceof GuiContainer) {
+ try {
+ int xSize = ((GuiContainer) event.gui).xSize;
+ int ySize = ((GuiContainer) event.gui).ySize;
+ int guiLeft = ((GuiContainer) event.gui).guiLeft;
+ int guiTop = ((GuiContainer) event.gui).guiTop;
+
+ hoverInv = event.getMouseX() > guiLeft && event.getMouseX() < guiLeft + xSize &&
+ event.getMouseY() > guiTop && event.getMouseY() < guiTop + ySize;
+
+ if (hoverPane) {
+ if (!hoverInv) focusInv = false;
+ } else {
+ focusInv = true;
+ }
+ } catch (NullPointerException npe) {
+ focusInv = !hoverPane;
+ }
+ }
+ if (event.gui instanceof GuiItemRecipe) {
+ GuiItemRecipe guiItemRecipe = ((GuiItemRecipe) event.gui);
+ hoverInv = event.getMouseX() > guiItemRecipe.guiLeft &&
+ event.getMouseX() < guiItemRecipe.guiLeft + guiItemRecipe.xSize &&
+ event.getMouseY() > guiItemRecipe.guiTop && event.getMouseY() < guiItemRecipe.guiTop + guiItemRecipe.ySize;
+
+ if (hoverPane) {
+ if (!hoverInv) focusInv = false;
+ } else {
+ focusInv = true;
+ }
+ }
+ if (focusInv) {
+ try {
+ neu.overlay.render(hoverInv);
+ } catch (ConcurrentModificationException e) {
+ e.printStackTrace();
+ }
+ GL11.glTranslatef(0, 0, 10);
+ }
+ if (hoverInv) {
+ renderDungeonChestOverlay(event.gui);
+ if (NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay) {
+ AccessoryBagOverlay.renderOverlay();
+ }
+ }
+ }
+
+ drawingGuiScreen = true;
+ }
+
+ private boolean doInventoryButtons = false;
+
+ @SubscribeEvent
+ public void onGuiScreenDrawPre(GuiScreenEvent.DrawScreenEvent.Pre event) {
+ doInventoryButtons = false;
+
+ if (AuctionSearchOverlay.shouldReplace()) {
+ AuctionSearchOverlay.render();
+ event.setCanceled(true);
+ return;
+ }
+ if (RancherBootOverlay.shouldReplace()) {
+ RancherBootOverlay.render();
+ event.setCanceled(true);
+ return;
+ }
+
+ String containerName = null;
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+ if (guiScreen instanceof GuiChest) {
+ GuiChest eventGui = (GuiChest) guiScreen;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText();
+ }
+
+ if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) {
+ GuiCustomEnchant.getInstance().render(event.renderPartialTicks);
+ event.setCanceled(true);
+ return;
+ }
+
+ boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
+ boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
+ boolean customAhActive =
+ event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView();
+
+ if (storageOverlayActive) {
+ StorageOverlay.getInstance().render();
+ event.setCanceled(true);
+ return;
+ }
+
+ if (tradeWindowActive || customAhActive) {
+ event.setCanceled(true);
+
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+
+ //Dark background
+ Utils.drawGradientRect(0, 0, width, height, -1072689136, -804253680);
+
+ if (event.mouseX < width * neu.overlay.getWidthMult() / 3 ||
+ event.mouseX > width - width * neu.overlay.getWidthMult() / 3) {
+ if (customAhActive) {
+ neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY);
+ } else if (tradeWindowActive) {
+ TradeWindow.render(event.mouseX, event.mouseY);
+ }
+ neu.overlay.render(false);
+ } else {
+ neu.overlay.render(false);
+ if (customAhActive) {
+ neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY);
+ } else if (tradeWindowActive) {
+ TradeWindow.render(event.mouseX, event.mouseY);
+ }
+ }
+ }
+
+ if (CalendarOverlay.isEnabled() || event.isCanceled()) return;
+ if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui)
+ && event.gui instanceof GuiContainer) {
+ doInventoryButtons = true;
+
+ int zOffset = 50;
+
+ GlStateManager.translate(0, 0, zOffset);
+
+ int xSize = ((GuiContainer) event.gui).xSize;
+ int ySize = ((GuiContainer) event.gui).ySize;
+ int guiLeft = ((GuiContainer) event.gui).guiLeft;
+ int guiTop = ((GuiContainer) event.gui).guiTop;
+
+ if (!NEUApi.disableInventoryButtons) {
+ for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) {
+ if (!button.isActive()) continue;
+ if (button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue;
+
+ int x = guiLeft + button.x;
+ int y = guiTop + button.y;
+ if (button.anchorRight) {
+ x += xSize;
+ }
+ if (button.anchorBottom) {
+ y += ySize;
+ }
+ if (AccessoryBagOverlay.isInAccessoryBag()) {
+ if (x > guiLeft + xSize && x < guiLeft + xSize + 80 + 28 + 5 && y > guiTop - 18 && y < guiTop + 150) {
+ x += 80 + 28;
+ }
+ }
+ if (NEUOverlay.isRenderingArmorHud()) {
+ if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) {
+ x -= 25;
+ }
+ }
+ if (NEUOverlay.isRenderingPetHud()) {
+ if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) {
+ x -= 25;
+ }
+ }
+
+ GlStateManager.color(1, 1, 1, 1f);
+
+ GlStateManager.enableDepth();
+ GlStateManager.enableAlpha();
+ Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR);
+ Utils.drawTexturedRect(x, y, 18, 18,
+ button.backgroundIndex * 18 / 256f, (button.backgroundIndex * 18 + 18) / 256f,
+ 18 / 256f, 36 / 256f, GL11.GL_NEAREST
+ );
+
+ if (button.icon != null && !button.icon.trim().isEmpty()) {
+ GuiInvButtonEditor.renderIcon(button.icon, x + 1, y + 1);
+ }
+ }
+ }
+ GlStateManager.translate(0, 0, -zOffset);
+ }
+ }
+
+ private static boolean shouldRenderOverlay(Gui gui) {
+ boolean validGui = gui instanceof GuiContainer || gui instanceof GuiItemRecipe;
+ if (gui instanceof GuiChest) {
+ GuiChest eventGui = (GuiChest) gui;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText();
+ if (containerName.trim().equals("Fast Travel")) {
+ validGui = false;
+ }
+ }
+ return validGui;
+ }
+
+ private static final ResourceLocation EDITOR = new ResourceLocation("notenoughupdates:invbuttons/editor.png");
+ private NEUConfig.InventoryButton buttonHovered = null;
+ private long buttonHoveredMillis = 0;
+ public static boolean disableCraftingText = false;
+
+ /**
+ * Will draw the NEUOverlay over the inventory if focusInv == false. (z-translation of 300 is so that NEUOverlay
+ * will draw over Items in the inventory (which render at a z value of about 250))
+ */
+ @SubscribeEvent
+ public void onGuiScreenDrawPost(GuiScreenEvent.DrawScreenEvent.Post event) {
+ drawingGuiScreen = false;
+ disableCraftingText = false;
+
+ String containerName = null;
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+ if (guiScreen instanceof GuiChest) {
+ GuiChest eventGui = (GuiChest) guiScreen;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText();
+
+ if (GuiCustomEnchant.getInstance().shouldOverride(containerName))
+ return;
+ }
+
+ boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
+ boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
+ boolean customAhActive =
+ event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView();
+
+ if (!(tradeWindowActive || storageOverlayActive || customAhActive)) {
+ if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) {
+ GlStateManager.pushMatrix();
+ if (!focusInv) {
+ GL11.glTranslatef(0, 0, 300);
+ neu.overlay.render(hoverInv && focusInv);
+ GL11.glTranslatef(0, 0, -300);
+ }
+ GlStateManager.popMatrix();
+ }
+ }
+
+ if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock() && !hoverInv) {
+ renderDungeonChestOverlay(event.gui);
+ if (NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay) {
+ AccessoryBagOverlay.renderOverlay();
+ }
+ }
+
+ boolean hoveringButton = false;
+ if (!doInventoryButtons) return;
+ if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) &&
+ event.gui instanceof GuiContainer) {
+ int xSize = ((GuiContainer) event.gui).xSize;
+ int ySize = ((GuiContainer) event.gui).ySize;
+ int guiLeft = ((GuiContainer) event.gui).guiLeft;
+ int guiTop = ((GuiContainer) event.gui).guiTop;
+
+ if (!NEUApi.disableInventoryButtons) {
+ for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) {
+ if (!button.isActive()) continue;
+ if (button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue;
+
+ int x = guiLeft + button.x;
+ int y = guiTop + button.y;
+ if (button.anchorRight) {
+ x += xSize;
+ }
+ if (button.anchorBottom) {
+ y += ySize;
+ }
+ if (AccessoryBagOverlay.isInAccessoryBag()) {
+ if (x > guiLeft + xSize && x < guiLeft + xSize + 80 + 28 + 5 && y > guiTop - 18 && y < guiTop + 150) {
+ x += 80 + 28;
+ }
+ }
+ if (NEUOverlay.isRenderingArmorHud()) {
+ if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) {
+ x -= 25;
+ }
+ }
+ if (NEUOverlay.isRenderingPetHud()) {
+ if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) {
+ x -= 25;
+ }
+ }
+
+ if (x - guiLeft >= 85 && x - guiLeft <= 115 && y - guiTop >= 4 && y - guiTop <= 25) {
+ disableCraftingText = true;
+ }
+
+ if (event.mouseX >= x && event.mouseX <= x + 18 &&
+ event.mouseY >= y && event.mouseY <= y + 18) {
+ hoveringButton = true;
+ long currentTime = System.currentTimeMillis();
+
+ if (buttonHovered != button) {
+ buttonHoveredMillis = currentTime;
+ buttonHovered = button;
+ }
+
+ if (currentTime - buttonHoveredMillis > 600) {
+ String command = button.command.trim();
+ if (!command.startsWith("/")) {
+ command = "/" + command;
+ }
+
+ Utils.drawHoveringText(Lists.newArrayList("\u00a77" + command), event.mouseX, event.mouseY,
+ event.gui.width, event.gui.height, -1, Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+ }
+ }
+ }
+ }
+ if (!hoveringButton) buttonHovered = null;
+
+ if (AuctionBINWarning.getInstance().shouldShow()) {
+ AuctionBINWarning.getInstance().render();
+ }
+ }
+
+ private void renderDungeonChestOverlay(GuiScreen gui) {
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 3) return;
+
+ if (gui instanceof GuiChest && NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc != 2) {
+ try {
+ int xSize = ((GuiContainer) gui).xSize;
+ int ySize = ((GuiContainer) gui).ySize;
+ int guiLeft = ((GuiContainer) gui).guiLeft;
+ int guiTop = ((GuiContainer) gui).guiTop;
+
+ GuiChest eventGui = (GuiChest) gui;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ IInventory lower = cc.getLowerChestInventory();
+
+ ItemStack rewardChest = lower.getStackInSlot(31);
+ if (rewardChest != null &&
+ rewardChest.getDisplayName().endsWith(EnumChatFormatting.GREEN + "Open Reward Chest")) {
+ int chestCost = 0;
+ try {
+ String line6 = Utils.cleanColour(neu.manager.getLoreFromNBT(rewardChest.getTagCompound())[6]);
+ StringBuilder cost = new StringBuilder();
+ for (int i = 0; i < line6.length(); i++) {
+ char c = line6.charAt(i);
+ if ("0123456789".indexOf(c) >= 0) {
+ cost.append(c);
+ }
+ }
+ if (cost.length() > 0) {
+ chestCost = Integer.parseInt(cost.toString());
+ }
+ } catch (Exception ignored) {
+ }
+
+ String missingItem = null;
+ int totalValue = 0;
+ HashMap itemValues = new HashMap<>();
+ for (int i = 0; i < 5; i++) {
+ ItemStack item = lower.getStackInSlot(11 + i);
+ String internal = neu.manager.getInternalNameForItem(item);
+ if (internal != null) {
+ internal = internal.replace("\u00CD", "I").replace("\u0130", "I");
+ float bazaarPrice = -1;
+ JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal);
+ if (bazaarInfo != null && bazaarInfo.has("curr_sell")) {
+ bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat();
+ }
+ if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000;
+
+ float worth = -1;
+ if (bazaarPrice > 0) {
+ worth = bazaarPrice;
+ } else {
+ switch (NotEnoughUpdates.INSTANCE.config.dungeons.profitType) {
+ case 1:
+ worth = neu.manager.auctionManager.getItemAvgBin(internal);
+ break;
+ case 2:
+ JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal);
+ if (auctionInfo != null) {
+ if (auctionInfo.has("clean_price")) {
+ worth = (int) auctionInfo.get("clean_price").getAsFloat();
+ } else {
+ worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ }
+ }
+ break;
+ default:
+ worth = neu.manager.auctionManager.getLowestBin(internal);
+ }
+ if (worth <= 0) {
+ worth = neu.manager.auctionManager.getLowestBin(internal);
+ if (worth <= 0) {
+ worth = neu.manager.auctionManager.getItemAvgBin(internal);
+ if (worth <= 0) {
+ JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal);
+ if (auctionInfo != null) {
+ if (auctionInfo.has("clean_price")) {
+ worth = (int) auctionInfo.get("clean_price").getAsFloat();
+ } else {
+ worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (worth > 0 && totalValue >= 0) {
+ totalValue += worth;
+ String display = item.getDisplayName();
+
+ if (display.contains("Enchanted Book")) {
+ NBTTagCompound tag = item.getTagCompound();
+ if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+ NBTTagCompound enchants = ea.getCompoundTag("enchantments");
+
+ int highestLevel = -1;
+ for (String enchname : enchants.getKeySet()) {
+ int level = enchants.getInteger(enchname);
+ if (level > highestLevel) {
+ display = EnumChatFormatting.BLUE + WordUtils.capitalizeFully(
+ enchname.replace("_", " ")
+ .replace("Ultimate", "")
+ .trim()) + " " + level;
+ }
+ }
+ }
+ }
+
+ itemValues.put(display, worth);
+ } else {
+ if (totalValue != -1) {
+ missingItem = internal;
+ }
+ totalValue = -1;
+ }
+ }
+ }
+
+ NumberFormat format = NumberFormat.getInstance(Locale.US);
+ String valueStringBIN1;
+ String valueStringBIN2;
+ if (totalValue >= 0) {
+ valueStringBIN1 = EnumChatFormatting.YELLOW + "Value (BIN): ";
+ valueStringBIN2 = EnumChatFormatting.GOLD + format.format(totalValue) + " coins";
+ } else {
+ valueStringBIN1 = EnumChatFormatting.YELLOW + "Can't find BIN: ";
+ valueStringBIN2 = missingItem;
+ }
+
+ int profitLossBIN = totalValue - chestCost;
+
+ boolean kismetUsed = false;
+ // checking for kismet
+ Slot slot = (eventGui.inventorySlots.getSlot(50));
+ if (slot.getHasStack()) {
+ String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(slot.getStack().getTagCompound());
+ for (String line : lore) {
+ if (line.contains("You already rerolled a chest!")) {
+ kismetUsed = true;
+ break;
+ }
+ }
+ }
+ int kismetPrice = neu.manager.auctionManager.getLowestBin("KISMET_FEATHER");
+ String kismetStr = EnumChatFormatting.RED + format.format(kismetPrice) + " coins";
+ if (neu.config.dungeons.useKismetOnDungeonProfit)
+ profitLossBIN = kismetUsed ? profitLossBIN - kismetPrice : profitLossBIN;
+
+ String profitPrefix = EnumChatFormatting.DARK_GREEN.toString();
+ String lossPrefix = EnumChatFormatting.RED.toString();
+ String prefix = profitLossBIN >= 0 ? profitPrefix : lossPrefix;
+
+ String plStringBIN;
+ if (profitLossBIN >= 0) {
+ plStringBIN = prefix + "+" + format.format(profitLossBIN) + " coins";
+ } else {
+ plStringBIN = prefix + "-" + format.format(-profitLossBIN) + " coins";
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 1 && !valueStringBIN2.equals(missingItem)) {
+ int w = Minecraft.getMinecraft().fontRendererObj.getStringWidth(plStringBIN);
+ GlStateManager.disableLighting();
+ GlStateManager.translate(0, 0, 200);
+ Minecraft.getMinecraft().fontRendererObj.drawString(plStringBIN, guiLeft + xSize - 5 - w, guiTop + 5,
+ 0xffffffff, true
+ );
+ GlStateManager.translate(0, 0, -200);
+ return;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(dungeon_chest_worth);
+ GL11.glColor4f(1, 1, 1, 1);
+ GlStateManager.disableLighting();
+ Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 180, 101, 0, 180 / 256f, 0, 101 / 256f, GL11.GL_NEAREST);
+
+ Utils.renderAlignedString(valueStringBIN1, valueStringBIN2,
+ guiLeft + xSize + 4 + 10, guiTop + 14, 160
+ );
+ if (neu.config.dungeons.useKismetOnDungeonProfit && kismetUsed) {
+ Utils.renderAlignedString(EnumChatFormatting.YELLOW + "Kismet Feather: ", kismetStr,
+ guiLeft + xSize + 4 + 10, guiTop + 24, 160
+ );
+ }
+ if (totalValue >= 0) {
+ Utils.renderAlignedString(
+ EnumChatFormatting.YELLOW + "Profit/Loss: ",
+ plStringBIN,
+ guiLeft + xSize + 4 + 10,
+ guiTop + (neu.config.dungeons.useKismetOnDungeonProfit ? (kismetUsed ? 34 : 24) : 24),
+ 160
+ );
+ }
+
+ int index = 0;
+ for (Map.Entry entry : itemValues.entrySet()) {
+ Utils.renderAlignedString(
+ entry.getKey(),
+ prefix +
+ format.format(entry.getValue().intValue()),
+ guiLeft + xSize + 4 + 10,
+ guiTop + (neu.config.dungeons.useKismetOnDungeonProfit ? (kismetUsed ? 39 : 29) : 29) + (++index) * 10,
+ 160
+ );
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void drawStringShadow(String str, float x, float y, int len) {
+ for (int xOff = -2; xOff <= 2; xOff++) {
+ for (int yOff = -2; yOff <= 2; yOff++) {
+ if (Math.abs(xOff) != Math.abs(yOff)) {
+ Utils.drawStringCenteredScaledMaxWidth(Utils.cleanColourNotModifiers(str),
+ Minecraft.getMinecraft().fontRendererObj,
+ x + xOff / 2f, y + yOff / 2f, false, len,
+ new Color(20, 20, 20, 100 / Math.max(Math.abs(xOff), Math.abs(yOff))).getRGB()
+ );
+ }
+ }
+ }
+
+ Utils.drawStringCenteredScaledMaxWidth(str,
+ Minecraft.getMinecraft().fontRendererObj,
+ x, y, false, len,
+ new Color(64, 64, 64, 255).getRGB()
+ );
+ }
+
+ /**
+ * Sends a mouse event to NEUOverlay if the inventory isn't hovered AND focused.
+ * Will also cancel the event if if NEUOverlay#mouseInput returns true.
+ */
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) {
+ if (Mouse.getEventButtonState() && StorageManager.getInstance().onAnyClick()) {
+ event.setCanceled(true);
+ return;
+ }
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+ if (AuctionBINWarning.getInstance().shouldShow()) {
+ AuctionBINWarning.getInstance().mouseInput(mouseX, mouseY);
+ event.setCanceled(true);
+ return;
+ }
+
+ if (!event.isCanceled()) {
+ Utils.scrollTooltip(Mouse.getEventDWheel());
+ }
+ if (AuctionSearchOverlay.shouldReplace()) {
+ AuctionSearchOverlay.mouseEvent();
+ event.setCanceled(true);
+ return;
+ }
+ if (RancherBootOverlay.shouldReplace()) {
+ RancherBootOverlay.mouseEvent();
+ event.setCanceled(true);
+ return;
+ }
+
+ String containerName = null;
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+ if (guiScreen instanceof GuiChest) {
+ GuiChest eventGui = (GuiChest) guiScreen;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText();
+ if (containerName.contains(" Profile") && BetterContainers.profileViewerStackIndex != -1 &&
+ eventGui.isMouseOverSlot(cc.inventorySlots.get(BetterContainers.profileViewerStackIndex), mouseX, mouseY) &&
+ Mouse.getEventButton() >= 0) {
+ event.setCanceled(true);
+ if (Mouse.getEventButtonState() && eventGui.inventorySlots.inventorySlots.get(22).getStack() != null &&
+ eventGui.inventorySlots.inventorySlots.get(22).getStack().getTagCompound() != null) {
+ NBTTagCompound tag = eventGui.inventorySlots.inventorySlots.get(22).getStack().getTagCompound();
+ if (tag.hasKey("SkullOwner") && tag.getCompoundTag("SkullOwner").hasKey("Name")) {
+ String username = tag.getCompoundTag("SkullOwner").getString("Name");
+ Utils.playPressSound();
+ ViewProfileCommand.RUNNABLE.accept(new String[]{username});
+ }
+ }
+ }
+ }
+
+ if (GuiCustomEnchant.getInstance().shouldOverride(containerName) &&
+ GuiCustomEnchant.getInstance().mouseInput(mouseX, mouseY)) {
+ event.setCanceled(true);
+ return;
+ }
+
+ boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
+ boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
+ boolean customAhActive =
+ event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView();
+
+ if (storageOverlayActive) {
+ if (StorageOverlay.getInstance().mouseInput(mouseX, mouseY)) {
+ event.setCanceled(true);
+ }
+ return;
+ }
+
+ if (tradeWindowActive || customAhActive) {
+ event.setCanceled(true);
+ if (customAhActive) {
+ neu.manager.auctionManager.customAH.handleMouseInput();
+ } else if (tradeWindowActive) {
+ TradeWindow.handleMouseInput();
+ }
+ neu.overlay.mouseInput();
+ return;
+ }
+
+ if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) {
+ if (!NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay || !AccessoryBagOverlay.mouseClick()) {
+ if (!(hoverInv && focusInv)) {
+ if (neu.overlay.mouseInput()) {
+ event.setCanceled(true);
+ }
+ } else {
+ neu.overlay.mouseInputInv();
+ }
+ }
+ }
+ if (event.isCanceled()) return;
+ if (!doInventoryButtons) return;
+ if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) &&
+ Mouse.getEventButton() >= 0
+ && event.gui instanceof GuiContainer) {
+ int xSize = ((GuiContainer) event.gui).xSize;
+ int ySize = ((GuiContainer) event.gui).ySize;
+ int guiLeft = ((GuiContainer) event.gui).guiLeft;
+ int guiTop = ((GuiContainer) event.gui).guiTop;
+ if (!NEUApi.disableInventoryButtons) {
+ for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) {
+ if (!button.isActive()) continue;
+ if (button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue;
+
+ int x = guiLeft + button.x;
+ int y = guiTop + button.y;
+ if (button.anchorRight) {
+ x += xSize;
+ }
+ if (button.anchorBottom) {
+ y += ySize;
+ }
+ if (AccessoryBagOverlay.isInAccessoryBag()) {
+ if (x > guiLeft + xSize && x < guiLeft + xSize + 80 + 28 + 5 && y > guiTop - 18 && y < guiTop + 150) {
+ x += 80 + 28;
+ }
+ }
+ if (NEUOverlay.isRenderingArmorHud()) {
+ if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) {
+ x -= 25;
+ }
+ }
+ if (NEUOverlay.isRenderingPetHud()) {
+ if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) {
+ x -= 25;
+ }
+ }
+
+ if (mouseX >= x && mouseX <= x + 18 && mouseY >= y && mouseY <= y + 18) {
+ if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) {
+ int clickType = NotEnoughUpdates.INSTANCE.config.inventoryButtons.clickType;
+ if ((clickType == 0 && Mouse.getEventButtonState()) || (clickType == 1 && !Mouse.getEventButtonState())) {
+ String command = button.command.trim();
+ if (!command.startsWith("/")) {
+ command = "/" + command;
+ }
+ if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, command) == 0) {
+ NotEnoughUpdates.INSTANCE.sendChatMessage(command);
+ }
+ }
+ } else {
+ event.setCanceled(true);
+ }
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
+
+ JsonObject essenceJson = new JsonObject();
+
+ /**
+ * Sends a kbd event to NEUOverlay, cancelling if NEUOverlay#keyboardInput returns true.
+ * Also includes a dev function used for creating custom named json files with recipes.
+ */
+ @SubscribeEvent
+ public void onGuiScreenKeyboard(GuiScreenEvent.KeyboardInputEvent.Pre event) {
+ if (AuctionBINWarning.getInstance().shouldShow()) {
+ AuctionBINWarning.getInstance().keyboardInput();
+ event.setCanceled(true);
+ return;
+ }
+
+ if (AuctionSearchOverlay.shouldReplace()) {
+ AuctionSearchOverlay.keyEvent();
+ event.setCanceled(true);
+ return;
+ }
+ if (RancherBootOverlay.shouldReplace()) {
+ RancherBootOverlay.keyEvent();
+ event.setCanceled(true);
+ return;
+ }
+
+ String containerName = null;
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+
+ if (guiScreen instanceof GuiChest) {
+ containerName = ((ContainerChest) ((GuiChest) guiScreen).inventorySlots)
+ .getLowerChestInventory()
+ .getDisplayName()
+ .getUnformattedText();
+ }
+
+ if (GuiCustomEnchant.getInstance().shouldOverride(containerName) &&
+ GuiCustomEnchant.getInstance().keyboardInput()) {
+ event.setCanceled(true);
+ return;
+ }
+
+ boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
+ boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
+ boolean customAhActive =
+ event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView();
+
+ if (storageOverlayActive) {
+ if (StorageOverlay.getInstance().keyboardInput()) {
+ event.setCanceled(true);
+ return;
+ }
+ }
+
+ if (tradeWindowActive || customAhActive) {
+ if (customAhActive) {
+ if (neu.manager.auctionManager.customAH.keyboardInput()) {
+ event.setCanceled(true);
+ Minecraft.getMinecraft().dispatchKeypresses();
+ } else if (neu.overlay.keyboardInput(focusInv)) {
+ event.setCanceled(true);
+ }
+ } else if (tradeWindowActive) {
+ TradeWindow.keyboardInput();
+ if (Keyboard.getEventKey() != Keyboard.KEY_ESCAPE) {
+ event.setCanceled(true);
+ Minecraft.getMinecraft().dispatchKeypresses();
+ neu.overlay.keyboardInput(focusInv);
+ }
+ }
+ return;
+ }
+
+ if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) {
+ if (neu.overlay.keyboardInput(focusInv)) {
+ event.setCanceled(true);
+ }
+ }
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev && NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing &&
+ Minecraft.getMinecraft().theWorld != null &&
+ Keyboard.getEventKey() == Keyboard.KEY_N && Keyboard.getEventKeyState()) {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (gui instanceof GuiChest) {
+ GuiChest eventGui = (GuiChest) event.gui;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ IInventory lower = cc.getLowerChestInventory();
+
+ if (!lower.getDisplayName().getUnformattedText().endsWith("Essence")) return;
+
+ for (int i = 0; i < lower.getSizeInventory(); i++) {
+ ItemStack stack = lower.getStackInSlot(i);
+
+ String internalname = neu.manager.getInternalNameForItem(stack);
+ if (internalname != null) {
+ String[] lore = neu.manager.getLoreFromNBT(stack.getTagCompound());
+
+ for (String line : lore) {
+ if (line.contains(":") && (line.startsWith("\u00A77Upgrade to") ||
+ line.startsWith("\u00A77Convert to Dungeon Item"))) {
+ String[] split = line.split(":");
+ String after = Utils.cleanColour(split[1]);
+ StringBuilder costS = new StringBuilder();
+ for (char c : after.toCharArray()) {
+ if (c >= '0' && c <= '9') {
+ costS.append(c);
+ }
+ }
+ int cost = Integer.parseInt(costS.toString());
+ String[] afterSplit = after.split(" ");
+ String type = afterSplit[afterSplit.length - 2];
+
+ if (!essenceJson.has(internalname)) {
+ essenceJson.add(internalname, new JsonObject());
+ }
+ JsonObject obj = essenceJson.get(internalname).getAsJsonObject();
+ obj.addProperty("type", type);
+
+ if (line.startsWith("\u00A77Convert to Dungeon Item")) {
+ obj.addProperty("dungeonize", cost);
+ } else if (line.startsWith("\u00A77Upgrade to")) {
+ int stars = 0;
+ for (char c : line.toCharArray()) {
+ if (c == '\u272A') stars++;
+ }
+ if (stars > 0) {
+ obj.addProperty(stars + "", cost);
+ }
+ }
+ }
+ }
+ }
+ }
+ System.out.println(essenceJson);
+ }
+ }
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev && NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing &&
+ Minecraft.getMinecraft().theWorld != null &&
+ Keyboard.getEventKey() == Keyboard.KEY_O && Keyboard.getEventKeyState()) {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (gui instanceof GuiChest) {
+ GuiChest eventGui = (GuiChest) event.gui;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ IInventory lower = cc.getLowerChestInventory();
+
+ if (lower.getStackInSlot(23) != null &&
+ lower.getStackInSlot(23).getDisplayName().endsWith("Crafting Table")) {
+ ItemStack res = lower.getStackInSlot(25);
+ String resInternalname = neu.manager.getInternalNameForItem(res);
+ JTextField tf = new JTextField();
+ tf.setText(resInternalname);
+ tf.addAncestorListener(new RequestFocusListener());
+ JOptionPane.showOptionDialog(null,
+ tf,
+ "Enter Name:",
+ JOptionPane.NO_OPTION,
+ JOptionPane.PLAIN_MESSAGE,
+ null, new String[]{"Enter"}, "Enter"
+ );
+ resInternalname = tf.getText();
+ if (resInternalname.trim().length() == 0) {
+ return;
+ }
+
+ JsonObject recipe = new JsonObject();
+
+ String[] x = {"1", "2", "3"};
+ String[] y = {"A", "B", "C"};
+
+ for (int i = 0; i <= 18; i += 9) {
+ for (int j = 0; j < 3; j++) {
+ ItemStack stack = lower.getStackInSlot(10 + i + j);
+ String internalname = "";
+ if (stack != null) {
+ internalname = neu.manager.getInternalNameForItem(stack);
+ if (!neu.manager.getItemInformation().containsKey(internalname)) {
+ neu.manager.writeItemToFile(stack);
+ }
+ internalname += ":" + stack.stackSize;
+ }
+ recipe.addProperty(y[i / 9] + x[j], internalname);
+ }
+ }
+
+ JsonObject json = neu.manager.getJsonForItem(res);
+ json.add("recipe", recipe);
+ json.addProperty("internalname", resInternalname);
+ json.addProperty("clickcommand", "viewrecipe");
+ json.addProperty("modver", NotEnoughUpdates.VERSION);
+ try {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname));
+ neu.manager.writeJsonDefaultDir(json, resInternalname + ".json");
+ neu.manager.loadItem(resInternalname);
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+ }
+
+ private final HashSet percentStats = new HashSet<>();
+
+ {
+ percentStats.add("bonus_attack_speed");
+ percentStats.add("crit_damage");
+ percentStats.add("crit_chance");
+ percentStats.add("sea_creature_chance");
+ percentStats.add("ability_damage");
+ }
+
+ private String currentRarity = "COMMON";
+ private boolean showReforgeStoneStats = true;
+ private boolean pressedArrowLast = false;
+ private boolean pressedShiftLast = false;
+
+ private boolean copied = false;
+
+ //just to try and optimize it a bit
+ private int sbaloaded = -1;
+
+ private boolean isSbaloaded() {
+ if (sbaloaded == -1) {
+ if (Loader.isModLoaded("skyblockaddons")) {
+ sbaloaded = 1;
+ } else {
+ sbaloaded = 0;
+ }
+ }
+ return sbaloaded == 1;
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void onItemTooltipLow(ItemTooltipEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return;
+
+ String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack);
+ if (internalname == null) {
+ onItemToolTipInternalNameNull(event);
+ return;
+ }
+
+ boolean hasEnchantments =
+ event.itemStack.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("enchantments", 10);
+ Set enchantIds = new HashSet<>();
+ if (hasEnchantments)
+ enchantIds =
+ event.itemStack.getTagCompound().getCompoundTag("ExtraAttributes").getCompoundTag("enchantments").getKeySet();
+
+ JsonObject enchantsConst = Constants.ENCHANTS;
+ JsonArray allItemEnchs = null;
+ Set ignoreFromPool = new HashSet<>();
+ if (enchantsConst != null && hasEnchantments && NotEnoughUpdates.INSTANCE.config.tooltipTweaks.missingEnchantList) {
+ try {
+ JsonArray enchantPools = enchantsConst.get("enchant_pools").getAsJsonArray();
+ for (JsonElement element : enchantPools) {
+ Set currentPool = new HashSet<>();
+ for (JsonElement poolElement : element.getAsJsonArray()) {
+ String poolS = poolElement.getAsString();
+ currentPool.add(poolS);
+ }
+ for (JsonElement poolElement : element.getAsJsonArray()) {
+ String poolS = poolElement.getAsString();
+ if (enchantIds.contains(poolS)) {
+ ignoreFromPool.addAll(currentPool);
+ break;
+ }
+ }
+ }
+
+ JsonObject enchantsObj = enchantsConst.get("enchants").getAsJsonObject();
+ NBTTagCompound tag = event.itemStack.getTagCompound();
+ if (tag != null) {
+ NBTTagCompound display = tag.getCompoundTag("display");
+ if (display.hasKey("Lore", 9)) {
+ NBTTagList list = display.getTagList("Lore", 8);
+ out:
+ for (int i = list.tagCount(); i >= 0; i--) {
+ String line = list.getStringTagAt(i);
+ for (int j = 0; j < Utils.rarityArrC.length; j++) {
+ for (Map.Entry entry : enchantsObj.entrySet()) {
+ if (line.contains(Utils.rarityArrC[j] + " " + entry.getKey()) ||
+ line.contains(Utils.rarityArrC[j] + " DUNGEON " + entry.getKey())) {
+ allItemEnchs = entry.getValue().getAsJsonArray();
+ break out;
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception ignored) {
+ }
+ }
+
+ boolean gotToEnchants = false;
+ boolean passedEnchants = false;
+
+ boolean dungeonProfit = false;
+ int index = 0;
+ List newTooltip = new ArrayList<>();
+
+ for (String line : event.toolTip) {
+ if (line.endsWith(EnumChatFormatting.DARK_GRAY + "Reforge Stone") &&
+ NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showReforgeStats) {
+ JsonObject reforgeStones = Constants.REFORGESTONES;
+
+ if (reforgeStones != null && reforgeStones.has(internalname)) {
+ boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
+ if (!pressedShiftLast && shift) {
+ showReforgeStoneStats = !showReforgeStoneStats;
+ }
+ pressedShiftLast = shift;
+
+ newTooltip.add(line);
+ newTooltip.add("");
+ if (!showReforgeStoneStats) {
+ newTooltip.add(EnumChatFormatting.DARK_GRAY + "[Press SHIFT to show extra info]");
+ } else {
+ newTooltip.add(EnumChatFormatting.DARK_GRAY + "[Press SHIFT to hide extra info]");
+ }
+
+ JsonObject reforgeInfo = reforgeStones.get(internalname).getAsJsonObject();
+ JsonArray requiredRaritiesArray = reforgeInfo.get("requiredRarities").getAsJsonArray();
+
+ if (showReforgeStoneStats && requiredRaritiesArray.size() > 0) {
+ String reforgeName = Utils.getElementAsString(reforgeInfo.get("reforgeName"), "");
+
+ String[] requiredRarities = new String[requiredRaritiesArray.size()];
+ for (int i = 0; i < requiredRaritiesArray.size(); i++) {
+ requiredRarities[i] = requiredRaritiesArray.get(i).getAsString();
+ }
+
+ int rarityIndex = requiredRarities.length - 1;
+ String rarity = requiredRarities[rarityIndex];
+ for (int i = 0; i < requiredRarities.length; i++) {
+ String rar = requiredRarities[i];
+ if (rar.equalsIgnoreCase(currentRarity)) {
+ rarity = rar;
+ rarityIndex = i;
+ break;
+ }
+ }
+
+ boolean left = Keyboard.isKeyDown(Keyboard.KEY_LEFT);
+ boolean right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT);
+ if (!pressedArrowLast && (left || right)) {
+ if (left) {
+ rarityIndex--;
+ } else if (right) {
+ rarityIndex++;
+ }
+ if (rarityIndex < 0) rarityIndex = 0;
+ if (rarityIndex >= requiredRarities.length) rarityIndex = requiredRarities.length - 1;
+ currentRarity = requiredRarities[rarityIndex];
+ rarity = currentRarity;
+ }
+ pressedArrowLast = left || right;
+
+ JsonElement statsE = reforgeInfo.get("reforgeStats");
+
+ String rarityFormatted = Utils.rarityArrMap.getOrDefault(rarity, rarity);
+
+ JsonElement reforgeAbilityE = reforgeInfo.get("reforgeAbility");
+ String reforgeAbility = null;
+ if (reforgeAbilityE != null) {
+ if (reforgeAbilityE.isJsonPrimitive() && reforgeAbilityE.getAsJsonPrimitive().isString()) {
+ reforgeAbility = Utils.getElementAsString(reforgeInfo.get("reforgeAbility"), "");
+
+ } else if (reforgeAbilityE.isJsonObject()) {
+ if (reforgeAbilityE.getAsJsonObject().has(rarity)) {
+ reforgeAbility = reforgeAbilityE.getAsJsonObject().get(rarity).getAsString();
+ }
+ }
+ }
+
+ if (reforgeAbility != null && !reforgeAbility.isEmpty()) {
+ String text = EnumChatFormatting.BLUE + (reforgeName.isEmpty() ? "Bonus: " : reforgeName + " Bonus: ") +
+ EnumChatFormatting.GRAY + reforgeAbility;
+ boolean first = true;
+ for (String s : Minecraft.getMinecraft().fontRendererObj.listFormattedStringToWidth(text, 150)) {
+ newTooltip.add((first ? "" : " ") + s);
+ first = false;
+ }
+ newTooltip.add("");
+ }
+
+ newTooltip.add(EnumChatFormatting.BLUE + "Stats for " + rarityFormatted +
+ "\u00a79: [\u00a7l\u00a7m< \u00a79Switch\u00a7l\u27a1\u00a79]");
+
+ if (statsE != null && statsE.isJsonObject()) {
+ JsonObject stats = statsE.getAsJsonObject();
+
+ JsonElement statsRarE = stats.get(rarity);
+ if (statsRarE != null && statsRarE.isJsonObject()) {
+
+ JsonObject statsRar = statsRarE.getAsJsonObject();
+
+ TreeSet> sorted = new TreeSet<>(Map.Entry.comparingByKey());
+ sorted.addAll(statsRar.entrySet());
+
+ for (Map.Entry entry : sorted) {
+ if (entry.getValue().isJsonPrimitive() && ((JsonPrimitive) entry.getValue()).isNumber()) {
+ float statNumF = entry.getValue().getAsFloat();
+ String statNumS;
+ if (statNumF % 1 == 0) {
+ statNumS = String.valueOf(Math.round(statNumF));
+ } else {
+ statNumS = Utils.floatToString(statNumF, 1);
+ }
+ String reforgeNamePretty = WordUtils.capitalizeFully(entry.getKey().replace("_", " "));
+ String text =
+ EnumChatFormatting.GRAY + reforgeNamePretty + ": " + EnumChatFormatting.GREEN + "+" + statNumS;
+ if (percentStats.contains(entry.getKey())) {
+ text += "%";
+ }
+ newTooltip.add(" " + text);
+ }
+ }
+ }
+ }
+
+ JsonElement reforgeCostsE = reforgeInfo.get("reforgeCosts");
+ int reforgeCost = -1;
+ if (reforgeCostsE != null) {
+ if (reforgeCostsE.isJsonPrimitive() && reforgeCostsE.getAsJsonPrimitive().isNumber()) {
+ reforgeCost = (int) Utils.getElementAsFloat(reforgeInfo.get("reforgeAbility"), -1);
+
+ } else if (reforgeCostsE.isJsonObject()) {
+ if (reforgeCostsE.getAsJsonObject().has(rarity)) {
+ reforgeCost = (int) Utils.getElementAsFloat(reforgeCostsE.getAsJsonObject().get(rarity), -1);
+ }
+ }
+ }
+
+ if (reforgeCost >= 0) {
+ String text = EnumChatFormatting.BLUE + "Apply Cost: " + EnumChatFormatting.GOLD +
+ NumberFormat.getNumberInstance().format(reforgeCost) + " coins";
+ newTooltip.add("");
+ newTooltip.add(text);
+ }
+
+ }
+
+ continue;
+ }
+
+ } else if (line.contains("\u00A7cR\u00A76a\u00A7ei\u00A7an\u00A7bb\u00A79o\u00A7dw\u00A79 Rune")) {
+ line = line.replace(
+ "\u00A7cR\u00A76a\u00A7ei\u00A7an\u00A7bb\u00A79o\u00A7dw\u00A79 Rune",
+ Utils.chromaString("Rainbow Rune", index, false) + EnumChatFormatting.BLUE
+ );
+ } else if (hasEnchantments) {
+ if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) &&
+ NotEnoughUpdates.INSTANCE.config.tooltipTweaks.missingEnchantList) {
+ boolean lineHasEnch = false;
+ for (String s : enchantIds) {
+ String enchantName = WordUtils.capitalizeFully(s.replace("_", " "));
+ if (line.contains(enchantName)) {
+ lineHasEnch = true;
+ break;
+ }
+ }
+ if (lineHasEnch) {
+ gotToEnchants = true;
+ } else {
+ if (gotToEnchants && !passedEnchants && Utils.cleanColour(line).trim().length() == 0) {
+ if (enchantsConst != null && allItemEnchs != null) {
+ List missing = new ArrayList<>();
+ for (JsonElement enchIdElement : allItemEnchs) {
+ String enchId = enchIdElement.getAsString();
+ if (!enchId.startsWith("ultimate_") && !ignoreFromPool.contains(enchId) &&
+ !enchantIds.contains(enchId)) {
+ missing.add(enchId);
+ }
+ }
+ if (!missing.isEmpty()) {
+ newTooltip.add("");
+ StringBuilder currentLine =
+ new StringBuilder(EnumChatFormatting.RED + "Missing: " + EnumChatFormatting.GRAY);
+ for (int i = 0; i < missing.size(); i++) {
+ String enchName = WordUtils.capitalizeFully(missing.get(i).replace("_", " "));
+ if (currentLine.length() != 0 &&
+ (Utils.cleanColour(currentLine.toString()).length() + enchName.length()) > 40) {
+ newTooltip.add(currentLine.toString());
+ currentLine = new StringBuilder();
+ }
+ if (currentLine.length() != 0 && i != 0) {
+ currentLine.append(", ").append(enchName);
+ } else {
+ currentLine.append(EnumChatFormatting.GRAY).append(enchName);
+ }
+ }
+ if (currentLine.length() != 0) {
+ newTooltip.add(currentLine.toString());
+ }
+ }
+ }
+ passedEnchants = true;
+ }
+ }
+ }
+ for (String op : NotEnoughUpdates.INSTANCE.config.hidden.enchantColours) {
+ List colourOps = GuiEnchantColour.splitter.splitToList(op);
+ String enchantName = GuiEnchantColour.getColourOpIndex(colourOps, 0);
+ String comparator = GuiEnchantColour.getColourOpIndex(colourOps, 1);
+ String comparison = GuiEnchantColour.getColourOpIndex(colourOps, 2);
+ String colourCode = GuiEnchantColour.getColourOpIndex(colourOps, 3);
+ String modifier = GuiEnchantColour.getColourOpIndex(colourOps, 4);
+
+ int modifierI = GuiEnchantColour.getIntModifier(modifier);
+
+ if (enchantName.length() == 0) continue;
+ if (comparator.length() == 0) continue;
+ if (comparison.length() == 0) continue;
+ if (colourCode.length() == 0) continue;
+
+ int comparatorI = ">=<".indexOf(comparator.charAt(0));
+
+ int levelToFind = -1;
+ try {
+ levelToFind = Integer.parseInt(comparison);
+ } catch (Exception e) {
+ continue;
+ }
+
+ if (comparatorI < 0) continue;
+ String regexText = "0123456789abcdefz";
+ if (isSbaloaded()) {
+ regexText = regexText + "Z";
+ }
+
+ if (regexText.indexOf(colourCode.charAt(0)) < 0) continue;
+
+ //item_lore = item_lore.replaceAll("\\u00A79("+lvl4Max+" IV)", EnumChatFormatting.DARK_PURPLE+"$1");
+ //9([a-zA-Z ]+?) ([0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X))(,|$)
+ Pattern pattern;
+ try {
+ pattern = Pattern.compile("(\\u00A79|\\u00A7(9|l)\\u00A7d\\u00A7l)(?" + enchantName + ") " +
+ "(?[0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X|XI|XII|XIII|XIV|XV|XVI|XVII|XVIII|XIX|XX))((\\u00A79)?,|( \\u00A78(?:,?[0-9]+)*)?$)");
+ } catch (Exception e) {
+ continue;
+ } //malformed regex
+ Matcher matcher = pattern.matcher(line);
+ int matchCount = 0;
+ while (matcher.find() && matchCount < 5) {
+ if (Utils.cleanColour(matcher.group("enchantName")).startsWith(" ")) continue;
+
+ matchCount++;
+ int level = -1;
+ String levelStr = matcher.group("level");
+ if (levelStr == null) continue;
+ try {
+ level = Integer.parseInt(levelStr);
+ } catch (Exception e) {
+ switch (levelStr) {
+ case "I":
+ level = 1;
+ break;
+ case "II":
+ level = 2;
+ break;
+ case "III":
+ level = 3;
+ break;
+ case "IV":
+ level = 4;
+ break;
+ case "V":
+ level = 5;
+ break;
+ case "VI":
+ level = 6;
+ break;
+ case "VII":
+ level = 7;
+ break;
+ case "VIII":
+ level = 8;
+ break;
+ case "IX":
+ level = 9;
+ break;
+ case "X":
+ level = 10;
+ break;
+ case "XI":
+ level = 11;
+ break;
+ case "XII":
+ level = 12;
+ break;
+ case "XIII":
+ level = 13;
+ break;
+ case "XIV":
+ level = 14;
+ break;
+ case "XV":
+ level = 15;
+ break;
+ case "XVI":
+ level = 16;
+ break;
+ case "XVII":
+ level = 17;
+ break;
+ case "XVIII":
+ level = 18;
+ break;
+ case "XIX":
+ level = 19;
+ break;
+ case "XX":
+ level = 20;
+ break;
+ }
+ }
+ boolean matches = false;
+ if (level > 0) {
+ switch (comparator) {
+ case ">":
+ matches = level > levelToFind;
+ break;
+ case "=":
+ matches = level == levelToFind;
+ break;
+ case "<":
+ matches = level < levelToFind;
+ break;
+ }
+ }
+ if (matches) {
+ String enchantText = matcher.group("enchantName");
+ StringBuilder extraModifiersBuilder = new StringBuilder();
+
+ if ((modifierI & GuiEnchantColour.BOLD_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.BOLD);
+ }
+ if ((modifierI & GuiEnchantColour.ITALIC_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.ITALIC);
+ }
+ if ((modifierI & GuiEnchantColour.UNDERLINE_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.UNDERLINE);
+ }
+ if ((modifierI & GuiEnchantColour.OBFUSCATED_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.OBFUSCATED);
+ }
+ if ((modifierI & GuiEnchantColour.STRIKETHROUGH_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.STRIKETHROUGH);
+ }
+
+ String extraMods = extraModifiersBuilder.toString();
+
+ if (!colourCode.equals("z")) {
+ line = line.replace(
+ "\u00A79" + enchantText,
+ "\u00A7" + colourCode + extraMods + enchantText
+ );
+ line = line.replace(
+ "\u00A79\u00A7d\u00A7l" + enchantText,
+ "\u00A7" + colourCode + extraMods + enchantText
+ );
+ line = line.replace(
+ "\u00A7l\u00A7d\u00A7l" + enchantText,
+ "\u00A7" + colourCode + extraMods + enchantText
+ );
+ } else {
+ int offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll(
+ "\\u00A79" + enchantText + ".*", ""));
+ line =
+ line.replace("\u00A79" + enchantText, Utils.chromaString(enchantText, offset / 12f + index, false));
+
+ offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll(
+ "\\u00A79\\u00A7d\\u00A7l" + enchantText + ".*", ""));
+ line = line.replace("\u00A79\u00A7d\u00A7l" + enchantText, Utils.chromaString(enchantText,
+ offset / 12f + index, true
+ ));
+ offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll(
+ "\\u00A7l\\u00A7d\\u00A7l" + enchantText + ".*", ""));
+ line = line.replace("\u00A7l\u00A7d\u00A7l" + enchantText, Utils.chromaString(enchantText,
+ offset / 12f + index, true
+ ));
+ }
+ }
+ }
+ }
+ }
+
+ newTooltip.add(line);
+
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoAucItem) {
+ if (line.contains(EnumChatFormatting.GRAY + "Buy it now: ") ||
+ line.contains(EnumChatFormatting.GRAY + "Bidder: ") ||
+ line.contains(EnumChatFormatting.GRAY + "Starting bid: ")) {
+
+ if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
+ newTooltip.add("");
+ newTooltip.add(EnumChatFormatting.GRAY + "[SHIFT for Price Info]");
+ } else {
+ ItemPriceInformation.addToTooltip(newTooltip, internalname, event.itemStack);
+ }
+ }
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 2 &&
+ Minecraft.getMinecraft().currentScreen instanceof GuiChest) {
+ if (line.contains(EnumChatFormatting.GREEN + "Open Reward Chest")) {
+ dungeonProfit = true;
+ } else if (index == 7 && dungeonProfit) {
+ GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen;
+ ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
+ IInventory lower = cc.getLowerChestInventory();
+
+ int chestCost = 0;
+ try {
+ String line6 = Utils.cleanColour(line);
+ StringBuilder cost = new StringBuilder();
+ for (int i = 0; i < line6.length(); i++) {
+ char c = line6.charAt(i);
+ if ("0123456789".indexOf(c) >= 0) {
+ cost.append(c);
+ }
+ }
+ if (cost.length() > 0) {
+ chestCost = Integer.parseInt(cost.toString());
+ }
+ } catch (Exception ignored) {
+ }
+
+ String missingItem = null;
+ int totalValue = 0;
+ HashMap itemValues = new HashMap<>();
+ for (int i = 0; i < 5; i++) {
+ ItemStack item = lower.getStackInSlot(11 + i);
+ String internal = neu.manager.getInternalNameForItem(item);
+ if (internal != null) {
+ internal = internal.replace("\u00CD", "I").replace("\u0130", "I");
+ float bazaarPrice = -1;
+ JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal);
+ if (bazaarInfo != null && bazaarInfo.has("curr_sell")) {
+ bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat();
+ }
+ if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000;
+
+ float worth = -1;
+ if (bazaarPrice > 0) {
+ worth = bazaarPrice;
+ } else {
+ switch (NotEnoughUpdates.INSTANCE.config.dungeons.profitType) {
+ case 1:
+ worth = neu.manager.auctionManager.getItemAvgBin(internal);
+ break;
+ case 2:
+ JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal);
+ if (auctionInfo != null) {
+ if (auctionInfo.has("clean_price")) {
+ worth = (int) auctionInfo.get("clean_price").getAsFloat();
+ } else {
+ worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ }
+ }
+ break;
+ default:
+ worth = neu.manager.auctionManager.getLowestBin(internal);
+ }
+ if (worth <= 0) {
+ worth = neu.manager.auctionManager.getLowestBin(internal);
+ if (worth <= 0) {
+ worth = neu.manager.auctionManager.getItemAvgBin(internal);
+ if (worth <= 0) {
+ JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal);
+ if (auctionInfo != null) {
+ if (auctionInfo.has("clean_price")) {
+ worth = (int) auctionInfo.get("clean_price").getAsFloat();
+ } else {
+ worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (worth > 0 && totalValue >= 0) {
+ totalValue += worth;
+
+ String display = item.getDisplayName();
+
+ if (display.contains("Enchanted Book")) {
+ NBTTagCompound tag = item.getTagCompound();
+ if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+ NBTTagCompound enchants = ea.getCompoundTag("enchantments");
+
+ int highestLevel = -1;
+ for (String enchname : enchants.getKeySet()) {
+ int level = enchants.getInteger(enchname);
+ if (level > highestLevel) {
+ display = EnumChatFormatting.BLUE + WordUtils.capitalizeFully(
+ enchname.replace("_", " ")
+ .replace("Ultimate", "")
+ .trim()) + " " + level;
+ }
+ }
+ }
+ }
+
+ itemValues.put(display, worth);
+ } else {
+ if (totalValue != -1) {
+ missingItem = internal;
+ }
+ totalValue = -1;
+ }
+ }
+ }
+
+ NumberFormat format = NumberFormat.getInstance(Locale.US);
+ String valueStringBIN1;
+ String valueStringBIN2;
+ if (totalValue >= 0) {
+ valueStringBIN1 = EnumChatFormatting.YELLOW + "Value (BIN): ";
+ valueStringBIN2 = EnumChatFormatting.GOLD + format.format(totalValue) + " coins";
+ } else {
+ valueStringBIN1 = EnumChatFormatting.YELLOW + "Can't find BIN: ";
+ valueStringBIN2 = missingItem;
+ }
+
+ int profitLossBIN = totalValue - chestCost;
+ String profitPrefix = EnumChatFormatting.DARK_GREEN.toString();
+ String lossPrefix = EnumChatFormatting.RED.toString();
+ String prefix = profitLossBIN >= 0 ? profitPrefix : lossPrefix;
+
+ String plStringBIN;
+ if (profitLossBIN >= 0) {
+ plStringBIN = prefix + "+" + format.format(profitLossBIN) + " coins";
+ } else {
+ plStringBIN = prefix + "-" + format.format(-profitLossBIN) + " coins";
+ }
+
+ String neu = EnumChatFormatting.YELLOW + "[NEU] ";
+
+ newTooltip.add(neu + valueStringBIN1 + " " + valueStringBIN2);
+ if (totalValue >= 0) {
+ newTooltip.add(neu + EnumChatFormatting.YELLOW + "Profit/Loss: " + plStringBIN);
+ }
+
+ for (Map.Entry entry : itemValues.entrySet()) {
+ newTooltip.add(neu + entry.getKey() + prefix + "+" +
+ format.format(entry.getValue().intValue()));
+ }
+ }
+ }
+
+ index++;
+ }
+
+ for (int i = newTooltip.size() - 1; i >= 0; i--) {
+ String line = Utils.cleanColour(newTooltip.get(i));
+ for (int i1 = 0; i1 < Utils.rarityArr.length; i1++) {
+ if (line.equals(Utils.rarityArr[i1])) {
+ if (i - 2 < 0) {
+ break;
+ }
+ newTooltip.addAll(i - 1, petToolTipXPExtend(event));
+ break;
+ }
+ }
+ }
+
+ pressedShiftLast = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
+ pressedArrowLast = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_RIGHT);
+
+ event.toolTip.clear();
+ event.toolTip.addAll(newTooltip);
+
+ HashMap> loreBuckets = new HashMap<>();
+
+ List hypixelOrder = new ArrayList<>();
+
+ hypixelOrder.add("attributes");
+ hypixelOrder.add("enchants");
+ hypixelOrder.add("ability");
+ hypixelOrder.add("reforge_bonus");
+ hypixelOrder.add("rarity");
+
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoInvItem) {
+ ItemPriceInformation.addToTooltip(event.toolTip, internalname, event.itemStack);
+ }
+
+ if (event.itemStack.getTagCompound() != null && event.itemStack.getTagCompound().getBoolean("NEUHIDEPETTOOLTIP") &&
+ NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip) {
+ event.toolTip.clear();
+ }
+ }
+
+ private final Pattern xpLevelPattern = Pattern.compile("(.*) (\\xA7e(.*)\\xA76/\\xA7e(.*))");
+
+ private void onItemToolTipInternalNameNull(ItemTooltipEvent event) {
+ petToolTipXPExtendPetMenu(event);
+ }
+
+ private List petToolTipXPExtend(ItemTooltipEvent event) {
+ List tooltipText = new ArrayList<>();
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) {
+ if (event.itemStack.getTagCompound().hasKey("DisablePetExp")) {
+ if (event.itemStack.getTagCompound().getBoolean("DisablePetExp")) {
+ return tooltipText;
+ }
+ }
+ //7 is just a random number i chose, prob no pets with less lines than 7
+ if (event.toolTip.size() > 7) {
+ if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) {
+
+ GuiProfileViewer.PetLevel petlevel = null;
+
+ //this is the item itself
+ NBTTagCompound tag = event.itemStack.getTagCompound();
+ if (tag.hasKey("ExtraAttributes")) {
+ if (tag.getCompoundTag("ExtraAttributes").hasKey("petInfo")) {
+ JsonObject petInfo = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
+ tag.getCompoundTag("ExtraAttributes").getString("petInfo"), JsonObject.class);
+ if (petInfo.has("exp") && petInfo.get("exp").isJsonPrimitive()) {
+ JsonPrimitive exp = petInfo.getAsJsonPrimitive("exp");
+ String petName = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack);
+ //Utils.getRarityFromInt(Utils.checkItemTypePet(event.toolTip))).getAsInt();
+ petlevel = GuiProfileViewer.getPetLevel(
+ petName,
+ Utils.getRarityFromInt(Utils.checkItemTypePet(event.toolTip)),
+ exp.getAsLong()
+ );
+ }
+ }
+ }
+
+ if (petlevel != null) {
+ tooltipText.add("");
+ if (petlevel.totalXp > petlevel.maxXP) {
+ tooltipText.add(EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "MAX LEVEL");
+ } else {
+ tooltipText.add(
+ EnumChatFormatting.GRAY + "Progress to Level " + (int) Math.floor(petlevel.level + 1) + ": " +
+ EnumChatFormatting.YELLOW + Utils.round(petlevel.levelPercentage * 100, 1) + "%");
+ int levelpercentage = Math.round(petlevel.levelPercentage * 20);
+ tooltipText.add(
+ EnumChatFormatting.DARK_GREEN + String.join("", Collections.nCopies(levelpercentage, "-")) +
+ EnumChatFormatting.WHITE + String.join("", Collections.nCopies(20 - levelpercentage, "-")));
+ tooltipText.add(
+ EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petlevel.levelXp) +
+ EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW +
+ myFormatter.format(petlevel.currentLevelRequirement) + " EXP");
+ }
+ }
+ }
+ }
+ }
+ return tooltipText;
+ }
+
+ private static final String petToolTipRegex =
+ "((Farming)|(Combat)|(Fishing)|(Mining)|(Foraging)|(Enchanting)|(Alchemy)) ((Mount)|(Pet)|(Morph)).*";
+
+ private void petToolTipXPExtendPetMenu(ItemTooltipEvent event) {
+ if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) {
+ //7 is just a random number i chose, prob no pets with less lines than 7
+ if (event.toolTip.size() > 7) {
+ if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) {
+ GuiProfileViewer.PetLevel petlevel = null;
+
+ int xpLine = -1;
+ for (int i = event.toolTip.size() - 1; i >= 0; i--) {
+ Matcher matcher = xpLevelPattern.matcher(event.toolTip.get(i));
+ if (matcher.matches()) {
+ xpLine = i;
+ event.toolTip.set(xpLine, matcher.group(1));
+ break;
+ } else if (event.toolTip.get(i).matches("MAX LEVEL")) {
+ return;
+ }
+ }
+
+ PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack(
+ event.itemStack.getDisplayName(),
+ NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(event.itemStack.getTagCompound())
+ );
+ if (pet == null) {
+ return;
+ }
+ petlevel = pet.petLevel;
+
+ if (petlevel == null || xpLine == -1) {
+ return;
+ }
+
+ event.toolTip.add(
+ xpLine + 1,
+ EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petlevel.levelXp) +
+ EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW +
+ myFormatter.format(petlevel.currentLevelRequirement)
+ );
+
+ }
+ }
+ }
+ }
+
+ DecimalFormat myFormatter = new DecimalFormat("###,###.###");
+
+ /**
+ * This method does the following:
+ * Move the pet inventory display tooltip to the left to avoid conflicts
+ * Remove reforge stats for Legendary items from Hypixel if enabled
+ * Show NBT data when holding LCONTROL
+ */
+ @SubscribeEvent
+ public void onItemTooltip(ItemTooltipEvent event) {
+ if (!neu.isOnSkyblock()) return;
+ if (event.toolTip == null) return;
+ //Render the pet inventory display tooltip to the left to avoid things from other mods rendering over the tooltip
+ if (event.itemStack.getTagCompound() != null && event.itemStack.getTagCompound().getBoolean("NEUPETINVDISPLAY")) {
+ GlStateManager.translate(-200, 0, 0);
+ }
+
+ if (event.toolTip.size() > 2 && NotEnoughUpdates.INSTANCE.config.tooltipTweaks.hideDefaultReforgeStats) {
+ String secondLine = StringUtils.stripControlCodes(event.toolTip.get(1));
+ if (secondLine.equals("Reforge Stone")) {
+ Integer startIndex = null;
+ Integer cutoffIndex = null;
+ //loop from the back of the List to find the wanted index sooner
+ for (int i = event.toolTip.size() - 1; i >= 0; i--) {
+ //rarity or mining level requirement
+ String line = StringUtils.stripControlCodes(event.toolTip.get(i));
+ if (line.contains("REFORGE STONE") || line.contains("Requires Mining Skill Level")) {
+ cutoffIndex = i;
+ }
+
+ //The line where the Hypixel stats start
+ if (line.contains("(Legendary):")) {
+ startIndex = i;
+ break;
+ }
+ }
+ if (startIndex != null && cutoffIndex != null && startIndex < cutoffIndex) {
+ event.toolTip.subList(startIndex, cutoffIndex).clear();
+ }
+ }
+ }
+
+ if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && NotEnoughUpdates.INSTANCE.config.hidden.dev &&
+ event.toolTip.size() > 0 &&
+ event.toolTip.get(event.toolTip.size() - 1).startsWith(EnumChatFormatting.DARK_GRAY + "NBT: ")) {
+ event.toolTip.remove(event.toolTip.size() - 1);
+
+ StringBuilder sb = new StringBuilder();
+ String nbt = event.itemStack.getTagCompound().toString();
+ int indent = 0;
+ for (char c : nbt.toCharArray()) {
+ boolean newline = false;
+ if (c == '{' || c == '[') {
+ indent++;
+ newline = true;
+ } else if (c == '}' || c == ']') {
+ indent--;
+ sb.append("\n");
+ for (int i = 0; i < indent; i++) sb.append(" ");
+ } else if (c == ',') {
+ newline = true;
+ } else if (c == '\"') {
+ sb.append(EnumChatFormatting.RESET.toString() + EnumChatFormatting.GRAY);
+ }
+
+ sb.append(c);
+ if (newline) {
+ sb.append("\n");
+ for (int i = 0; i < indent; i++) sb.append(" ");
+ }
+ }
+ event.toolTip.add(sb.toString());
+ if (Keyboard.isKeyDown(Keyboard.KEY_H)) {
+ if (!copied) {
+ copied = true;
+ StringSelection selection = new StringSelection(sb.toString());
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
+ }
+ } else {
+ copied = false;
+ }
+ } else if (NotEnoughUpdates.INSTANCE.packDevEnabled) {
+ event.toolTip.add("");
+ event.toolTip.add(EnumChatFormatting.AQUA + "NEU Pack Dev Info:");
+ event.toolTip.add("Press " + EnumChatFormatting.GOLD + "[KEY]" + EnumChatFormatting.GRAY + " to copy line");
+
+ String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack);
+
+ boolean k = Keyboard.isKeyDown(Keyboard.KEY_K);
+ boolean m = Keyboard.isKeyDown(Keyboard.KEY_M);
+ boolean n = Keyboard.isKeyDown(Keyboard.KEY_N);
+
+ event.toolTip.add(
+ EnumChatFormatting.AQUA + "Internal Name: " + EnumChatFormatting.GRAY + internal + EnumChatFormatting.GOLD +
+ " [K]");
+ if (!copied && k) {
+ MiscUtils.copyToClipboard(internal);
+ }
+
+ if (event.itemStack.getTagCompound() != null) {
+ NBTTagCompound tag = event.itemStack.getTagCompound();
+
+ if (tag.hasKey("SkullOwner", 10)) {
+ GameProfile gameprofile = NBTUtil.readGameProfileFromNBT(tag.getCompoundTag("SkullOwner"));
+
+ if (gameprofile != null) {
+ event.toolTip.add(EnumChatFormatting.AQUA + "Skull UUID: " + EnumChatFormatting.GRAY + gameprofile.getId() +
+ EnumChatFormatting.GOLD + " [M]");
+ if (!copied && m) {
+ MiscUtils.copyToClipboard(gameprofile.getId().toString());
+ }
+
+ Map map =
+ Minecraft.getMinecraft().getSkinManager().loadSkinFromCache(gameprofile);
+
+ if (map.containsKey(MinecraftProfileTexture.Type.SKIN)) {
+ MinecraftProfileTexture profTex = map.get(MinecraftProfileTexture.Type.SKIN);
+ event.toolTip.add(
+ EnumChatFormatting.AQUA + "Skull Texture Link: " + EnumChatFormatting.GRAY + profTex.getUrl() +
+ EnumChatFormatting.GOLD + " [N]");
+
+ if (!copied && n) {
+ MiscUtils.copyToClipboard(profTex.getUrl());
+ }
+ }
+ }
+ }
+ }
+
+ copied = k || m || n;
+ }
+ }
+
+ @SubscribeEvent
+ public void onRenderLast(RenderWorldLastEvent event) {
+ CrystalMetalDetectorSolver.render(event.partialTicks);
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 5fef4c62e6..df31834f99 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -1,14 +1,14 @@
package io.github.moulberry.notenoughupdates;
-import com.google.common.collect.Lists;
import com.google.gson.*;
import io.github.moulberry.notenoughupdates.auction.APIManager;
import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe;
-import io.github.moulberry.notenoughupdates.overlays.CraftingOverlay;
-import io.github.moulberry.notenoughupdates.util.Constants;
-import io.github.moulberry.notenoughupdates.util.HypixelApi;
-import io.github.moulberry.notenoughupdates.util.SBInfo;
-import io.github.moulberry.notenoughupdates.util.Utils;
+import io.github.moulberry.notenoughupdates.miscgui.KatSitterOverlay;
+import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay;
+import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe;
+import io.github.moulberry.notenoughupdates.recipes.Ingredient;
+import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
+import io.github.moulberry.notenoughupdates.util.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.init.Blocks;
@@ -17,113 +17,153 @@
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.*;
-import net.minecraft.network.play.client.C0DPacketCloseWindow;
import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.common.ProgressManager;
import org.apache.commons.io.FileUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
-import javax.swing.*;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.*;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class NEUManager {
-
- private final NotEnoughUpdates neu;
- public final Gson gson;
- public final APIManager auctionManager;
-
- private TreeMap itemMap = new TreeMap<>();
-
- private TreeMap>> titleWordMap = new TreeMap<>();
- private TreeMap>> loreWordMap = new TreeMap<>();
-
- public final KeyBinding keybindGive = new KeyBinding("Add item to inventory (Creative-only)", Keyboard.KEY_L, "NotEnoughUpdates");
- public final KeyBinding keybindFavourite = new KeyBinding("Set item as favourite", Keyboard.KEY_F, "NotEnoughUpdates");
- public final KeyBinding keybindViewUsages = new KeyBinding("Show usages for item", Keyboard.KEY_U, "NotEnoughUpdates");
- public final KeyBinding keybindViewRecipe = new KeyBinding("Show recipe for item", Keyboard.KEY_R, "NotEnoughUpdates");
- public final KeyBinding keybindToggleDisplay = new KeyBinding("Toggle NEU overlay", 0, "NotEnoughUpdates");
- public final KeyBinding keybindClosePanes = new KeyBinding("Close NEU panes", 0, "NotEnoughUpdates");
- public final KeyBinding keybindItemSelect = new KeyBinding("Select Item", -98 /*middle*/, "NotEnoughUpdates");
- public final KeyBinding[] keybinds = new KeyBinding[]{ keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe,
- keybindToggleDisplay, keybindClosePanes, keybindItemSelect};
-
- public String viewItemAttemptID = null;
- public long viewItemAttemptTime = 0;
-
- private String currentProfile = "";
- private String currentProfileBackup = "";
- public final HypixelApi hypixelApi = new HypixelApi();
-
- private Map itemstackCache = new HashMap<>();
-
- private ExecutorService repoLoaderES = Executors.newSingleThreadExecutor();
-
- private static String GIT_COMMITS_URL;
-
- private HashMap> usagesMap = new HashMap<>();
-
- public String latestRepoCommit = null;
-
- public File configLocation;
- public File repoLocation;
- public File configFile;
-
- public NEUManager(NotEnoughUpdates neu, File configLocation) {
- this.neu = neu;
- this.configLocation = configLocation;
- this.auctionManager = new APIManager(this);
- GIT_COMMITS_URL = neu.config.hidden.repoCommitsURL;
-
- gson = new GsonBuilder().setPrettyPrinting().create();
-
- this.repoLocation = new File(configLocation, "repo");
- repoLocation.mkdir();
- }
-
- public void setCurrentProfile(String currentProfile) {
- this.currentProfile = currentProfile;
- }
-
- public String getCurrentProfile() {
- return SBInfo.getInstance().currentProfile;
- }
-
- public T getJsonFromFile(File file, Class clazz) {
- try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
- T obj = gson.fromJson(reader, clazz);
- return obj;
- } catch(Exception e) { return null; }
- }
-
- /**
- * Parses a file in to a JsonObject.
- */
- public JsonObject getJsonFromFile(File file) {
- try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
- JsonObject json = gson.fromJson(reader, JsonObject.class);
- return json;
- } catch(Exception e) { return null; }
- }
-
- public void resetRepo() {
- try { Utils.recursiveDelete(new File(configLocation, "repo")); } catch(Exception e) {}
- try { new File(configLocation, "currentCommit.json").delete(); } catch(Exception e) {}
- }
-
- /**
- * Called when the game is first loaded. Compares the local repository to the github repository and handles
- * the downloading of new/updated files. This then calls the "loadItem" method for every item in the local
- * repository.
- */
- public void loadItemInformation() {
+ private final NotEnoughUpdates neu;
+ public final Gson gson;
+ public final APIManager auctionManager;
+
+ private final TreeMap itemMap = new TreeMap<>();
+
+ private final TreeMap>> titleWordMap = new TreeMap<>();
+ private final TreeMap>> loreWordMap = new TreeMap<>();
+
+ public final KeyBinding keybindGive =
+ new KeyBinding("Add item to inventory (Creative-only)", Keyboard.KEY_L, "NotEnoughUpdates");
+ public final KeyBinding keybindFavourite =
+ new KeyBinding("Set item as favourite", Keyboard.KEY_F, "NotEnoughUpdates");
+ public final KeyBinding keybindViewUsages =
+ new KeyBinding("Show usages for item", Keyboard.KEY_U, "NotEnoughUpdates");
+ public final KeyBinding keybindViewRecipe =
+ new KeyBinding("Show recipe for item", Keyboard.KEY_R, "NotEnoughUpdates");
+ public final KeyBinding keybindToggleDisplay = new KeyBinding("Toggle NEU overlay", 0, "NotEnoughUpdates");
+ public final KeyBinding keybindClosePanes = new KeyBinding("Close NEU panes", 0, "NotEnoughUpdates");
+ public final KeyBinding keybindItemSelect = new KeyBinding("Select Item", -98 /*middle*/, "NotEnoughUpdates");
+ public final KeyBinding[] keybinds = new KeyBinding[]{
+ keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe,
+ keybindToggleDisplay, keybindClosePanes, keybindItemSelect
+ };
+
+ public String viewItemAttemptID = null;
+ public long viewItemAttemptTime = 0;
+
+ private final String currentProfile = "";
+ private final String currentProfileBackup = "";
+ public final HypixelApi hypixelApi = new HypixelApi();
+
+ private final Map itemstackCache = new HashMap<>();
+
+ private final ExecutorService repoLoaderES = Executors.newSingleThreadExecutor();
+
+ private static String GIT_COMMITS_URL;
+
+ // TODO: private final Map
+
+ private final Set recipes = new HashSet<>();
+ private final HashMap> recipesMap = new HashMap<>();
+ private final HashMap> usagesMap = new HashMap<>();
+
+ public String latestRepoCommit = null;
+
+ public File configLocation;
+ public File repoLocation;
+ public File configFile;
+ public HotmInformation hotm;
+
+ public KatSitterOverlay katSitterOverlay;
+
+ public CraftingOverlay craftingOverlay;
+
+ public NEUManager(NotEnoughUpdates neu, File configLocation) {
+ this.neu = neu;
+ this.configLocation = configLocation;
+ this.auctionManager = new APIManager(this);
+ this.hotm = new HotmInformation(neu);
+ this.craftingOverlay = new CraftingOverlay(this);
+ this.katSitterOverlay = new KatSitterOverlay();
+
+ GIT_COMMITS_URL = neu.config.hidden.repoCommitsURL;
+
+ gson = new GsonBuilder().setPrettyPrinting().create();
+
+ this.repoLocation = new File(configLocation, "repo");
+ repoLocation.mkdir();
+ }
+
+ public void setCurrentProfile(String currentProfile) {
+ SBInfo.getInstance().currentProfile = currentProfile;
+ }
+
+ public String getCurrentProfile() {
+ return SBInfo.getInstance().currentProfile;
+ }
+
+ public T getJsonFromFile(File file, Class clazz) {
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(file),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ T obj = gson.fromJson(reader, clazz);
+ return obj;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Parses a file in to a JsonObject.
+ */
+ public JsonObject getJsonFromFile(File file) {
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(file),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ JsonObject json = gson.fromJson(reader, JsonObject.class);
+ return json;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void resetRepo() {
+ try {
+ Utils.recursiveDelete(new File(configLocation, "repo"));
+ } catch (Exception ignored) {
+ }
+ try {
+ new File(configLocation, "currentCommit.json").delete();
+ } catch (Exception ignored) {
+ }
+ }
+
+ /**
+ * Called when the game is first loaded. Compares the local repository to the github repository and handles the
+ * downloading of new/updated files. This then calls the "loadItem" method for every item in the local repository.
+ */
+ public void loadItemInformation() {
/*File repoFile = new File(configLocation, "repo2");
repoFile.mkdirs();
@@ -155,1297 +195,1377 @@ public void loadItemInformation() {
}*/
- repoLoaderES.submit(() -> {
- JDialog dialog = null;
- try {
- if(NotEnoughUpdates.INSTANCE.config.hidden.autoupdate) {
- JOptionPane pane = new JOptionPane("Getting items to download from remote repository.");
- dialog = pane.createDialog("NotEnoughUpdates Remote Sync");
- dialog.setModal(false);
- if(NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true);
-
- if (Display.isActive()) dialog.toFront();
-
- JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json"));
-
- latestRepoCommit = null;
- try(Reader inReader = new InputStreamReader(new URL(GIT_COMMITS_URL).openStream())) {
- JsonObject commits = gson.fromJson(inReader, JsonObject.class);
- latestRepoCommit = commits.get("sha").getAsString();
- } catch (Exception e) {
- e.printStackTrace();
- }
- if(latestRepoCommit == null || latestRepoCommit.isEmpty()) return;
-
- if(new File(configLocation, "repo").exists() && new File(configLocation, "repo/items").exists()) {
- if(currentCommitJSON != null && currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) {
- dialog.setVisible(false);
- return;
- }
- }
-
- if (Display.isActive()) dialog.toFront();
-
- Utils.recursiveDelete(repoLocation);
- repoLocation.mkdirs();
-
-
- String dlUrl = neu.config.hidden.repoURL;
-
- pane.setMessage("Downloading NEU Master Archive. (DL# >20)");
- dialog.pack();
- if(NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true);
- if (Display.isActive()) dialog.toFront();
-
- File itemsZip = new File(repoLocation, "neu-items-master.zip");
- try {
- itemsZip.createNewFile();
- } catch (IOException e) {
- return;
- }
-
-
- URL url = new URL(dlUrl);
- URLConnection urlConnection = url.openConnection();
- urlConnection.setConnectTimeout(15000);
- urlConnection.setReadTimeout(30000);
-
- try(InputStream is = urlConnection.getInputStream()) {
- FileUtils.copyInputStreamToFile(is, itemsZip);
- } catch (IOException e) {
- dialog.dispose();
- e.printStackTrace();
- System.err.println("Failed to download NEU Repo! Please report this issue to the mod creator");
- return;
- }
- /*try (BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream());
- FileOutputStream fileOutputStream = new FileOutputStream(itemsZip)) {
- byte dataBuffer[] = new byte[1024];
- int bytesRead;
- while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) {
- fileOutputStream.write(dataBuffer, 0, bytesRead);
- }
- } catch (IOException e) {
- dialog.dispose();
- return;
- }*/
-
- pane.setMessage("Unzipping NEU Master Archive.");
- dialog.pack();
- //dialog.setVisible(true);
- if (Display.isActive()) dialog.toFront();
-
- unzipIgnoreFirstFolder(itemsZip.getAbsolutePath(), repoLocation.getAbsolutePath());
-
- if(currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) {
- JsonObject newCurrentCommitJSON = new JsonObject();
- newCurrentCommitJSON.addProperty("sha", latestRepoCommit);
- try {
- writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json"));
- } catch (IOException e) {
- }
- }
- }
- } catch(Exception e) {
- e.printStackTrace();
- } finally {
- if(dialog != null) dialog.dispose();
- }
-
- File items = new File(repoLocation, "items");
- if(items.exists()) {
- File[] itemFiles = new File(repoLocation, "items").listFiles();
- if(itemFiles != null) {
- for(File f : itemFiles) {
- String internalname = f.getName().substring(0, f.getName().length()-5);
- synchronized(itemMap) {
- if(!itemMap.keySet().contains(internalname)) {
- loadItem(internalname);
- }
- }
- }
- }
- }
-
- try {
- Constants.reload();
- } catch(Exception e) {
- e.printStackTrace();
- }
- });
-
- File items = new File(repoLocation, "items");
- if(items.exists()) {
- File[] itemFiles = new File(repoLocation, "items").listFiles();
- if(itemFiles != null) {
- for(File f : itemFiles) {
- String internalname = f.getName().substring(0, f.getName().length()-5);
- synchronized(itemMap) {
- if(!itemMap.keySet().contains(internalname)) {
- loadItem(internalname);
- }
- }
- }
- }
- }
-
- try {
- Constants.reload();
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Loads the item in to the itemMap and also stores various words associated with this item
- * in to titleWordMap and loreWordMap. These maps are used in the searching algorithm.
- * @param internalName
- */
- public void loadItem(String internalName) {
- itemstackCache.remove(internalName);
- try {
- JsonObject json = getJsonFromFile(new File(new File(repoLocation, "items"), internalName + ".json"));
- if(json == null) {
- return;
- }
-
- if(json.get("itemid") == null) return;
-
- String itemid = json.get("itemid").getAsString();
- Item mcitem = Item.getByNameOrId(itemid);
- if(mcitem != null) {
- itemid = mcitem.getRegistryName();
- }
- json.addProperty("itemid", itemid);
-
- itemMap.put(internalName, json);
-
- if(json.has("recipe")) {
- synchronized(usagesMap) {
- JsonObject recipe = json.get("recipe").getAsJsonObject();
-
- String[] x = {"1","2","3"};
- String[] y = {"A","B","C"};
- for(int i=0; i<9; i++) {
- String name = y[i/3]+x[i%3];
- String itemS = recipe.get(name).getAsString();
- if(itemS != null && itemS.split(":").length == 2) {
- itemS = itemS.split(":")[0];
- }
-
- if(!usagesMap.containsKey(itemS)) {
- usagesMap.put(itemS, new HashSet<>());
- }
- usagesMap.get(itemS).add(internalName);
- }
- }
- }
-
- if(json.has("displayname")) {
- synchronized(titleWordMap) {
- int wordIndex=0;
- for(String str : json.get("displayname").getAsString().split(" ")) {
- str = clean(str);
- if(!titleWordMap.containsKey(str)) {
- titleWordMap.put(str, new HashMap<>());
- }
- if(!titleWordMap.get(str).containsKey(internalName)) {
- titleWordMap.get(str).put(internalName, new ArrayList<>());
- }
- titleWordMap.get(str).get(internalName).add(wordIndex);
- wordIndex++;
- }
- }
- }
-
- if(json.has("lore")) {
- synchronized(loreWordMap) {
- int wordIndex=0;
- for(JsonElement element : json.get("lore").getAsJsonArray()) {
- for(String str : element.getAsString().split(" ")) {
- str = clean(str);
- if(!loreWordMap.containsKey(str)) {
- loreWordMap.put(str, new HashMap<>());
- }
- if(!loreWordMap.get(str).containsKey(internalName)) {
- loreWordMap.get(str).put(internalName, new ArrayList<>());
- }
- loreWordMap.get(str).get(internalName).add(wordIndex);
- wordIndex++;
- }
- }
- }
- }
- } catch(Exception e) {
- synchronized(loreWordMap) {
- System.out.println("loreWordMap is : " + loreWordMap);
- }
- synchronized(titleWordMap) {
- System.out.println("titleWordMap is : " + titleWordMap);
- }
- System.out.println("internalName is : " + internalName);
- e.printStackTrace();
- }
- }
-
- /**
- * Searches a string for a query. This method is used to mimic the behaviour of the
- * more complex map-based search function. This method is used for the chest-item-search feature.
- */
- public boolean searchString(String toSearch, String query) {
- int lastMatch = -1;
-
- toSearch = clean(toSearch).toLowerCase();
- query = clean(query).toLowerCase();
- String[] splitToSeach = toSearch.split(" ");
- out:
- for(String s : query.split(" ")) {
- for(int i=0; i search(String query, boolean multi) {
- if(multi) {
- Set result = new HashSet<>();
-
- StringBuilder query2 = new StringBuilder();
- char lastOp = '|';
- for(char c : query.toCharArray()) {
- if(c == '|' || c == '&') {
- if(lastOp == '|') {
- result.addAll(search(query2.toString()));
- } else if(lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- query2 = new StringBuilder();
- lastOp = c;
- } else {
- query2.append(c);
- }
- }
- if(lastOp == '|') {
- result.addAll(search(query2.toString()));
- } else if(lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- return result;
- } else {
- return search(query);
- }
- }
-
- /*public TreeMap searchForStacks(String query, Set stacks, boolean multi) {
- if(multi) {
- Set result = new HashSet<>();
-
- StringBuilder query2 = new StringBuilder();
- char lastOp = '|';
- for(char c : query.toCharArray()) {
- if(c == '|' || c == '&') {
- if(lastOp == '|') {
- result.addAll(doesStackMatchSearch(stack, query2.toString()));
- } else if(lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- query2 = new StringBuilder();
- lastOp = c;
- } else {
- query2.append(c);
- }
- }
- if(lastOp == '|') {
- result.addAll(search(query2.toString()));
- } else if(lastOp == '&') {
- result.retainAll(search(query2.toString()));
- }
-
- return result;
- } else {
- return search(query);
- }
- }*/
-
- /**
- * Returns the name of items which match a certain search query.
- */
- public Set search(String query) {
- query = query.trim();
- boolean negate = query.startsWith("!");
- if(negate) query = query.substring(1);
-
- LinkedHashSet results = new LinkedHashSet<>();
- if(query.startsWith("title:")) {
- query = query.substring(6);
- results.addAll(new TreeSet<>(search(query, titleWordMap)));
- } else if(query.startsWith("desc:")) {
- query = query.substring(5);
- results.addAll(new TreeSet<>(search(query, loreWordMap)));
- } else if(query.startsWith("id:")) {
- query = query.substring(3);
- results.addAll(new TreeSet<>(subMapWithKeysThatAreSuffixes(query.toUpperCase(), itemMap).keySet()));
- } else {
- if(!query.trim().contains(" ")) {
- StringBuilder sb = new StringBuilder();
- for(char c : query.toCharArray()) {
- sb.append(c).append(" ");
- }
- results.addAll(new TreeSet<>(search(sb.toString(), titleWordMap)));
- }
- results.addAll(new TreeSet<>(search(query, titleWordMap)));
- results.addAll(new TreeSet<>(search(query, loreWordMap)));
- }
- if(!negate) {
- return results;
- } else {
- Set negatedResults = new HashSet<>();
- for(String internalname : itemMap.keySet()) {
- negatedResults.add(internalname);
- }
- negatedResults.removeAll(results);
- return negatedResults;
- }
- }
-
- /**
- * Splits a search query into an array of strings delimited by a space character. Then, matches the query to
- * the start of words in the various maps (title & lore). The small query does not need to match the whole entry
- * of the map, only the beginning. eg. "ench" and "encha" will both match "enchanted". All sub queries must
- * follow a word matching the previous sub query. eg. "ench po" will match "enchanted pork" but will not match
- * "pork enchanted".
- */
- public Set search(String query, TreeMap>> wordMap) {
- HashMap> matches = null;
-
- query = clean(query).toLowerCase();
- for(String queryWord : query.split(" ")) {
- HashMap> matchesToKeep = new HashMap<>();
- for(HashMap> wordMatches : subMapWithKeysThatAreSuffixes(queryWord, wordMap).values()) {
- if(wordMatches != null && !wordMatches.isEmpty()) {
- if(matches == null) {
- //Copy all wordMatches to titleMatches
- for(String internalname : wordMatches.keySet()) {
- if(!matchesToKeep.containsKey(internalname)) {
- matchesToKeep.put(internalname, new ArrayList<>());
- }
- matchesToKeep.get(internalname).addAll(wordMatches.get(internalname));
- }
- } else {
- for(String internalname : matches.keySet()) {
- if(wordMatches.containsKey(internalname)) {
- for(Integer newIndex : wordMatches.get(internalname)) {
- if(matches.get(internalname).contains(newIndex-1)) {
- if(!matchesToKeep.containsKey(internalname)) {
- matchesToKeep.put(internalname, new ArrayList<>());
- }
- matchesToKeep.get(internalname).add(newIndex);
- }
- }
- }
- }
- }
- }
- }
- if(matchesToKeep.isEmpty()) return new HashSet<>();
- matches = matchesToKeep;
- }
-
- return matches.keySet();
- }
-
- /**
- * From https://stackoverflow.com/questions/10711494/get-values-in-treemap-whose-string-keys-start-with-a-pattern
- */
- public Map subMapWithKeysThatAreSuffixes(String prefix, NavigableMap map) {
- if ("".equals(prefix)) return map;
- String lastKey = createLexicographicallyNextStringOfTheSameLength(prefix);
- return map.subMap(prefix, true, lastKey, false);
- }
-
- public String createLexicographicallyNextStringOfTheSameLength(String input) {
- final int lastCharPosition = input.length()-1;
- String inputWithoutLastChar = input.substring(0, lastCharPosition);
- char lastChar = input.charAt(lastCharPosition) ;
- char incrementedLastChar = (char) (lastChar + 1);
- return inputWithoutLastChar+incrementedLastChar;
- }
-
- public JsonObject getJsonFromItemBytes(String item_bytes) {
- try {
- NBTTagCompound tag = CompressedStreamTools.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(item_bytes)));
- //System.out.println(tag.toString());
- return getJsonFromNBT(tag);
- } catch(IOException e) {
- return null;
- }
- }
-
- public String getUUIDFromNBT(NBTTagCompound tag) {
- String uuid = null;
- if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- if (ea.hasKey("uuid", 8)) {
- uuid = ea.getString("uuid");
- }
- }
- return uuid;
- }
-
- public String getInternalnameFromNBT(NBTTagCompound tag) {
- String internalname = null;
- if(tag != null && tag.hasKey("ExtraAttributes", 10)) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
-
- if(ea.hasKey("id", 8)) {
- internalname = ea.getString("id").replaceAll(":", "-");
- } else {
- return null;
- }
-
- if("PET".equals(internalname)) {
- String petInfo = ea.getString("petInfo");
- if(petInfo.length() > 0) {
- JsonObject petInfoObject = gson.fromJson(petInfo, JsonObject.class);
- internalname = petInfoObject.get("type").getAsString();
- String tier = petInfoObject.get("tier").getAsString();
- switch(tier) {
- case "COMMON":
- internalname += ";0"; break;
- case "UNCOMMON":
- internalname += ";1"; break;
- case "RARE":
- internalname += ";2"; break;
- case "EPIC":
- internalname += ";3"; break;
- case "LEGENDARY":
- internalname += ";4"; break;
- case "MYTHIC":
- internalname += ";5"; break;
- }
- }
- }
- if("ENCHANTED_BOOK".equals(internalname)) {
- NBTTagCompound enchants = ea.getCompoundTag("enchantments");
-
- for(String enchname : enchants.getKeySet()) {
- internalname = enchname.toUpperCase() + ";" + enchants.getInteger(enchname);
- break;
- }
- }
- }
-
- return internalname;
- }
-
- public String[] getLoreFromNBT(NBTTagCompound tag) {
- String[] lore = new String[0];
- NBTTagCompound display = tag.getCompoundTag("display");
-
- if(display.hasKey("Lore", 9)) {
- NBTTagList list = display.getTagList("Lore", 8);
- lore = new String[list.tagCount()];
- for(int k=0; k 0) {
- JsonArray jsonLore = new JsonArray();
- for (String line : lore) {
- jsonLore.add(new JsonPrimitive(line));
- }
- item.add("lore", jsonLore);
- }
-
- item.addProperty("damage", damage);
- if(count > 1) item.addProperty("count", count);
- item.addProperty("nbttag", tag.toString());
-
- return item;
- }
-
- private String clean(String str) {
- return str.replaceAll("(\u00a7.)|[^0-9a-zA-Z ]", "").toLowerCase().trim();
- }
-
- public void showRecipe(JsonObject item) {
- ContainerChest container = null;
- if(Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest)
- container = (ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer;
- if (item.has("recipe") && container != null && container.getLowerChestInventory().getDisplayName().getUnformattedText().equals("Craft Item")) {
- CraftingOverlay.updateItem(item);
- } else if(item.has("useneucraft") && item.get("useneucraft").getAsBoolean()) {
- displayGuiItemRecipe(item.get("internalname").getAsString(), "");
- } else if(item.has("clickcommand")) {
- String clickcommand = item.get("clickcommand").getAsString();
-
- if(clickcommand.equals("viewrecipe")) {
- neu.sendChatMessage(
- "/" + clickcommand + " " +
- item.get("internalname").getAsString().split(";")[0]);
- viewItemAttemptID = item.get("internalname").getAsString();
- viewItemAttemptTime = System.currentTimeMillis();
- } else if(clickcommand.equals("viewpotion")) {
- neu.sendChatMessage(
- "/" + clickcommand + " " +
- item.get("internalname").getAsString().split(";")[0].toLowerCase());
- viewItemAttemptID = item.get("internalname").getAsString();
- viewItemAttemptTime = System.currentTimeMillis();
- }
- }
- }
-
- /**
- * Takes an item stack and produces a JsonObject.
- */
- public JsonObject getJsonForItem(ItemStack stack) {
- NBTTagCompound tag = stack.getTagCompound() == null ? new NBTTagCompound() : stack.getTagCompound();
-
- //Item lore
- String[] lore = new String[0];
- if(tag.hasKey("display", 10)) {
- NBTTagCompound display = tag.getCompoundTag("display");
-
- if(display.hasKey("Lore", 9)) {
- NBTTagList list = display.getTagList("Lore", 8);
- lore = new String[list.tagCount()];
- for(int i=0; i 0 && (lore[lore.length-1].contains("Click to view recipes!") ||
- lore[lore.length-1].contains("Click to view recipe!"))) {
- String[] lore2 = new String[lore.length-2];
- System.arraycopy(lore, 0, lore2, 0, lore.length-2);
- lore = lore2;
- }
-
- JsonObject json = new JsonObject();
- json.addProperty("itemid", stack.getItem().getRegistryName());
- json.addProperty("displayname", stack.getDisplayName());
- json.addProperty("nbttag", tag.toString());
- json.addProperty("damage", stack.getItemDamage());
-
- JsonArray jsonlore = new JsonArray();
- for(String line : lore) {
- jsonlore.add(new JsonPrimitive(line));
- }
- json.add("lore", jsonlore);
-
- return json;
- }
-
- public String getInternalNameForItem(ItemStack stack) {
- if(stack == null) return null;
- NBTTagCompound tag = stack.getTagCompound();
- return getInternalnameFromNBT(tag);
- }
-
- public String getUUIDForItem(ItemStack stack) {
- if(stack == null) return null;
- NBTTagCompound tag = stack.getTagCompound();
- return getUUIDFromNBT(tag);
- }
-
- public void writeItemToFile(ItemStack stack) {
- String internalname = getInternalNameForItem(stack);
-
- if(internalname == null) {
- return;
- }
-
- JsonObject json = getJsonForItem(stack);
- json.addProperty("internalname", internalname);
- json.addProperty("clickcommand", "");
- json.addProperty("modver", NotEnoughUpdates.VERSION);
-
- try {
- writeJson(json, new File(new File(repoLocation, "items"), internalname+".json"));
- } catch (IOException e) {}
-
- loadItem(internalname);
- }
-
- /**
- * Constructs a GuiItemUsages from the recipe usage data (see #usagesMap) of a given item
- */
- public boolean displayGuiItemUsages(String internalName) {
- List craftMatrices = new ArrayList<>();
- List results = new ArrayList<>();
-
- if(!usagesMap.containsKey(internalName)) {
- return false;
- }
-
- for(String internalNameResult : usagesMap.get(internalName)) {
- JsonObject item = getItemInformation().get(internalNameResult);
- results.add(item);
-
- if(item != null && item.has("recipe")) {
- JsonObject recipe = item.get("recipe").getAsJsonObject();
-
- ItemStack[] craftMatrix = new ItemStack[9];
-
- String[] x = {"1","2","3"};
- String[] y = {"A","B","C"};
- for(int i=0; i<9; i++) {
- String name = y[i/3]+x[i%3];
- String itemS = recipe.get(name).getAsString();
- int count = 1;
- if(itemS != null && itemS.split(":").length == 2) {
- count = Integer.valueOf(itemS.split(":")[1]);
- itemS = itemS.split(":")[0];
- }
- JsonObject craft = getItemInformation().get(itemS);
- if(craft != null) {
- ItemStack stack = jsonToStack(craft);
- stack.stackSize = count;
- craftMatrix[i] = stack;
- }
- }
-
- craftMatrices.add(craftMatrix);
- }
- }
-
- if(craftMatrices.size() > 0) {
- Minecraft.getMinecraft().displayGuiScreen(new GuiItemRecipe("Item Usages", craftMatrices, results, this));
- return true;
- }
- return false;
- }
-
- /**
- * Constructs a GuiItemRecipeOld from the recipe data of a given item.
- */
- public boolean displayGuiItemRecipe(String internalName, String text) {
- JsonObject item = getItemInformation().get(internalName);
- if(item != null && item.has("recipe")) {
- JsonObject recipe = item.get("recipe").getAsJsonObject();
-
- ItemStack[] craftMatrix = new ItemStack[9];
-
- String[] x = {"1","2","3"};
- String[] y = {"A","B","C"};
- for(int i=0; i<9; i++) {
- String name = y[i/3]+x[i%3];
- String itemS = recipe.get(name).getAsString();
- int count = 1;
- if(itemS != null && itemS.split(":").length == 2) {
- count = Integer.valueOf(itemS.split(":")[1]);
- itemS = itemS.split(":")[0];
- }
- JsonObject craft = getItemInformation().get(itemS);
- if(craft != null) {
- ItemStack stack = jsonToStack(craft);
- stack.stackSize = count;
- craftMatrix[i] = stack;
- }
- }
-
- Minecraft.getMinecraft().thePlayer.sendQueue.addToSendQueue(new C0DPacketCloseWindow(
- Minecraft.getMinecraft().thePlayer.openContainer.windowId));
- Minecraft.getMinecraft().displayGuiScreen(new GuiItemRecipe(text!=null?text:"Item Recipe",
- Lists.newArrayList(craftMatrix), Lists.newArrayList(item), this));
- return true;
- }
- return false;
- }
-
- /**
- * Will display guiItemRecipe if a player attempted to view the recipe to an item but they didn't have the recipe
- * unlocked. See NotEnoughUpdates#onGuiChat for where this method is called.
- */
- public boolean failViewItem(String text) {
- if(viewItemAttemptID != null && !viewItemAttemptID.isEmpty()) {
- if(System.currentTimeMillis() - viewItemAttemptTime < 500) {
- return displayGuiItemRecipe(viewItemAttemptID, text);
- }
- }
- return false;
- }
-
- /**
- * Downloads a web file, appending some HTML attributes that makes wikia give us the raw wiki syntax.
- */
- public File getWebFile(String url) {
- File f = new File(configLocation, "tmp/"+Base64.getEncoder().encodeToString(url.getBytes())+".html");
- if(f.exists()) {
- return f;
- }
-
- try {
- f.getParentFile().mkdirs();
- f.createNewFile();
- f.deleteOnExit();
- } catch (IOException e) {
- return null;
- }
- try (BufferedInputStream inStream = new BufferedInputStream(new URL(url+"?action=raw&templates=expand").openStream());
- FileOutputStream fileOutputStream = new FileOutputStream(f)) {
- byte dataBuffer[] = new byte[1024];
- int bytesRead;
- while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) {
- fileOutputStream.write(dataBuffer, 0, bytesRead);
- }
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
-
- return f;
- }
-
-
- /**
- * Modified from https://www.journaldev.com/960/java-unzip-file-example
- */
- private static void unzipIgnoreFirstFolder(String zipFilePath, String destDir) {
- File dir = new File(destDir);
- // create output directory if it doesn't exist
- if(!dir.exists()) dir.mkdirs();
- FileInputStream fis;
- //buffer for read and write data to file
- byte[] buffer = new byte[1024];
- try {
- fis = new FileInputStream(zipFilePath);
- ZipInputStream zis = new ZipInputStream(fis);
- ZipEntry ze = zis.getNextEntry();
- while(ze != null){
- if(!ze.isDirectory()) {
- String fileName = ze.getName();
- fileName = fileName.substring(fileName.split("/")[0].length()+1);
- File newFile = new File(destDir + File.separator + fileName);
- //create directories for sub directories in zip
- new File(newFile.getParent()).mkdirs();
- FileOutputStream fos = new FileOutputStream(newFile);
- int len;
- while ((len = zis.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
- }
- fos.close();
- }
- //close this ZipEntry
- zis.closeEntry();
- ze = zis.getNextEntry();
- }
- //close last ZipEntry
- zis.closeEntry();
- zis.close();
- fis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Modified from https://www.journaldev.com/960/java-unzip-file-example
- */
- public static void unzip(InputStream src, File dest) {
- //buffer for read and write data to file
- byte[] buffer = new byte[1024];
- try {
- ZipInputStream zis = new ZipInputStream(src);
- ZipEntry ze = zis.getNextEntry();
- while(ze != null){
- if(!ze.isDirectory()) {
- String fileName = ze.getName();
- File newFile = new File(dest, fileName);
- //create directories for sub directories in zip
- new File(newFile.getParent()).mkdirs();
- FileOutputStream fos = new FileOutputStream(newFile);
- int len;
- while ((len = zis.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
- }
- fos.close();
- }
- //close this ZipEntry
- zis.closeEntry();
- ze = zis.getNextEntry();
- }
- //close last ZipEntry
- zis.closeEntry();
- zis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * From here to the end of the file are various helper functions for creating and writing json files,
- * in particular json files representing skyblock item data.
- */
- public JsonObject createItemJson(String internalname, String itemid, String displayname, String[] lore,
- String crafttext, String infoType, String[] info,
- String clickcommand, int damage, NBTTagCompound nbttag) {
- return createItemJson(new JsonObject(), internalname, itemid, displayname, lore, crafttext, infoType, info, clickcommand, damage, nbttag);
- }
-
- public JsonObject createItemJson(JsonObject base, String internalname, String itemid, String displayname, String[] lore,
- String crafttext, String infoType, String[] info,
- String clickcommand, int damage, NBTTagCompound nbttag) {
- if(internalname == null || internalname.isEmpty()) {
- return null;
- }
-
- JsonObject json = gson.fromJson(gson.toJson(base, JsonObject.class), JsonObject.class);
- json.addProperty("internalname", internalname);
- json.addProperty("itemid", itemid);
- json.addProperty("displayname", displayname);
- json.addProperty("crafttext", crafttext);
- json.addProperty("clickcommand", clickcommand);
- json.addProperty("damage", damage);
- json.addProperty("nbttag", nbttag.toString());
- json.addProperty("modver", NotEnoughUpdates.VERSION);
- json.addProperty("infoType", infoType.toString());
-
- if(info != null && info.length > 0) {
- JsonArray jsoninfo = new JsonArray();
- for (String line : info) {
- jsoninfo.add(new JsonPrimitive(line));
- }
- json.add("info", jsoninfo);
- }
-
- JsonArray jsonlore = new JsonArray();
- for(String line : lore) {
- jsonlore.add(new JsonPrimitive(line));
- }
- json.add("lore", jsonlore);
-
- return json;
- }
-
- public boolean writeItemJson(String internalname, String itemid, String displayname, String[] lore, String crafttext,
- String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag) {
- return writeItemJson(new JsonObject(), internalname, itemid, displayname, lore, crafttext, infoType, info, clickcommand, damage, nbttag);
- }
-
- public boolean writeItemJson(JsonObject base, String internalname, String itemid, String displayname, String[] lore,
- String crafttext, String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag) {
- JsonObject json = createItemJson(base, internalname, itemid, displayname, lore, crafttext, infoType, info, clickcommand, damage, nbttag);
- if(json == null) {
- return false;
- }
-
- try {
- writeJsonDefaultDir(json, internalname+".json");
- } catch(IOException e) {
- return false;
- }
-
- loadItem(internalname);
- return true;
- }
-
- public void writeJson(JsonObject json, File file) throws IOException {
- file.createNewFile();
-
- try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
- writer.write(gson.toJson(json));
- }
- }
-
- public void writeJsonDefaultDir(JsonObject json, String filename) throws IOException {
- File file = new File(new File(repoLocation, "items"), filename);
- writeJson(json, file);
- }
-
- public TreeMap getItemInformation() {
- return itemMap;
- }
-
- public String removeUnusedDecimal(double num) {
- if(num % 1 == 0) {
- return String.valueOf((int)num);
- } else {
- return String.valueOf(num);
- }
- }
-
- public HashMap getLoreReplacements(String petname, String tier, int level) {
- JsonObject petnums = null;
- if(petname != null && tier != null) {
- petnums = Constants.PETNUMS;
- }
-
- HashMap replacements = new HashMap<>();
- if(level < 1) {
- if (Constants.PETS.has("custom_pet_leveling") && Constants.PETS.getAsJsonObject("custom_pet_leveling").has(petname) && Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(petname).has("max_level")){
- int maxLvl = Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(petname).get("max_level").getAsInt();
- replacements.put("LVL", "1\u27A1"+maxLvl);
- } else {
- replacements.put("LVL", "1\u27A1100");
- }
- } else {
- replacements.put("LVL", ""+level);
- }
-
-
- if(petnums != null) {
- if(petnums.has(petname)) {
- JsonObject petInfo = petnums.get(petname).getAsJsonObject();
- if(petInfo.has(tier)) {
- JsonObject petInfoTier = petInfo.get(tier).getAsJsonObject();
- if(petInfoTier == null || !petInfoTier.has("1") || !petInfoTier.has("100")) {
- return replacements;
- }
-
- JsonObject min = petInfoTier.get("1").getAsJsonObject();
- JsonObject max = petInfoTier.get("100").getAsJsonObject();
-
- if(level < 1) {
- JsonArray otherNumsMin = min.get("otherNums").getAsJsonArray();
- JsonArray otherNumsMax = max.get("otherNums").getAsJsonArray();
- boolean addZero = false;
- if(petInfoTier.has("stats_levelling_curve")){
- String[] stringArray = petInfoTier.get("stats_levelling_curve").getAsString().split(":");
- if(stringArray.length == 3) {
- int type = Integer.parseInt(stringArray[2]);
- if(type == 1){
- addZero = true;
- }
- }
- }
- for(int i=0; i entry : max.get("statNums").getAsJsonObject().entrySet()) {
- int statMax = (int)Math.floor(entry.getValue().getAsFloat());
- int statMin = (int)Math.floor(min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat());
- String statStr = (statMin>0?"+":"")+statMin+"\u27A1"+statMax;
- statStr = (addZero?"0\u27A1":"")+statStr;
- replacements.put(entry.getKey(), statStr);
- }
- } else {
-
- int minStatsLevel = 0;
- int maxStatsLevel = 100;
- int statsLevelingType = -1;
-
- int statsLevel = level;
-
-
- if(petInfoTier.has("stats_levelling_curve")) {
- String[] stringArray = petInfoTier.get("stats_levelling_curve").getAsString().split(":");
- if (stringArray.length == 3) {
- minStatsLevel = Integer.parseInt(stringArray[0]);
- maxStatsLevel = Integer.parseInt(stringArray[1]);
- statsLevelingType = Integer.parseInt(stringArray[2]);
- switch (statsLevelingType) {
- //Case for maybe a pet that might exist
- case 0:
- case 1:
- if (level < minStatsLevel) {
- statsLevel = 1;
- } else if (level < maxStatsLevel) {
- statsLevel = level - minStatsLevel + 1;
- } else {
- statsLevel = maxStatsLevel - minStatsLevel + 1;
- }
- break;
-
- }
- }
- }
- float minMix = (maxStatsLevel-(minStatsLevel-(statsLevelingType==-1?0:1))-statsLevel)/99f;
- float maxMix = (statsLevel-1)/99f;
-
- JsonArray otherNumsMin = min.get("otherNums").getAsJsonArray();
- JsonArray otherNumsMax = max.get("otherNums").getAsJsonArray();
- for(int i=0; i entry : max.get("statNums").getAsJsonObject().entrySet()) {
- if(statsLevelingType == 1 && level < minStatsLevel) {
- replacements.put(entry.getKey(), "0");
- } else {
- float statMax = entry.getValue().getAsFloat();
- float statMin = min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat();
- float val = statMin * minMix + statMax * maxMix;
- String statStr = (statMin > 0 ? "+" : "") + (int) Math.floor(val);
- replacements.put(entry.getKey(), statStr);
- }
- }
- }
- }
- }
- }
-
- return replacements;
- }
-
- public HashMap getLoreReplacements(NBTTagCompound tag, int level) {
- String petname = null;
- String tier = null;
- if(tag != null && tag.hasKey("ExtraAttributes")) {
- NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
- if(ea.hasKey("petInfo")) {
- String petInfoStr = ea.getString("petInfo");
- JsonObject petInfo = gson.fromJson(petInfoStr, JsonObject.class);
- petname = petInfo.get("type").getAsString();
- tier = petInfo.get("tier").getAsString();
- if(petInfo.has("heldItem")) {
- String heldItem = petInfo.get("heldItem").getAsString();
- if(heldItem.equals("PET_ITEM_TIER_BOOST")) {
- switch(tier) {
- case "COMMON":
- tier = "UNCOMMON"; break;
- case "UNCOMMON":
- tier = "RARE"; break;
- case "RARE":
- tier = "EPIC"; break;
- case "EPIC":
- tier = "LEGENDARY"; break;
- case "LEGENDARY":
- tier = "MYTHIC"; break;
- }
- }
- }
- }
- }
- return getLoreReplacements(petname, tier, level);
- }
-
- public NBTTagList processLore(JsonArray lore, HashMap replacements) {
- NBTTagList nbtLore = new NBTTagList();
- for(JsonElement line : lore) {
- String lineStr = line.getAsString();
- if(!lineStr.contains("Click to view recipes!") &&
- !lineStr.contains("Click to view recipe!")) {
- for(Map.Entry entry : replacements.entrySet()) {
- lineStr = lineStr.replace("{"+entry.getKey()+"}", entry.getValue());
- }
- nbtLore.appendTag(new NBTTagString(lineStr));
- }
- }
- return nbtLore;
- }
-
- public ItemStack jsonToStack(JsonObject json) {
- return jsonToStack(json, true);
- }
-
- public ItemStack jsonToStack(JsonObject json, boolean useCache) {
- return jsonToStack(json, useCache, true);
- }
-
- public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements) {
- return jsonToStack(json, useCache, useReplacements, true);
- }
-
- public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean copyStack) {
- if(json == null) return new ItemStack(Items.painting, 1, 10);
- String internalname = json.get("internalname").getAsString();
-
- if(useCache) {
- ItemStack stack = itemstackCache.get(internalname);
- if(stack != null) {
- if(copyStack) {
- return stack.copy();
- } else {
- return stack;
- }
- }
- }
-
- ItemStack stack = new ItemStack(Item.itemRegistry.getObject(
- new ResourceLocation(json.get("itemid").getAsString())));
-
- if(json.has("count")) {
- stack.stackSize = json.get("count").getAsInt();
- }
-
- if(stack.getItem() == null) {
- stack = new ItemStack(Item.getItemFromBlock(Blocks.stone), 0, 255); //Purple broken texture item
- } else {
- if(json.has("damage")) {
- stack.setItemDamage(json.get("damage").getAsInt());
- }
-
- if(json.has("nbttag")) {
- try {
- NBTTagCompound tag = JsonToNBT.getTagFromJson(json.get("nbttag").getAsString());
- stack.setTagCompound(tag);
- } catch(NBTException e) {
- }
- }
-
- HashMap replacements = new HashMap<>();
-
- if(useReplacements) {
- replacements = getLoreReplacements(stack.getTagCompound(), -1);
-
- String displayname = json.get("displayname").getAsString();
- for(Map.Entry entry : replacements.entrySet()) {
- displayname = displayname.replace("{"+entry.getKey()+"}", entry.getValue());
- }
- stack.setStackDisplayName(displayname);
- }
-
- if(json.has("lore")) {
- NBTTagCompound display = new NBTTagCompound();
- if(stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) {
- display = stack.getTagCompound().getCompoundTag("display");
- }
- display.setTag("Lore", processLore(json.get("lore").getAsJsonArray(), replacements));
- NBTTagCompound tag = stack.getTagCompound() != null ? stack.getTagCompound() : new NBTTagCompound();
- tag.setTag("display", display);
- stack.setTagCompound(tag);
- }
- }
-
- if(useCache) itemstackCache.put(internalname, stack);
- if(copyStack) {
- return stack.copy();
- } else {
- return stack;
- }
- }
-
+ repoLoaderES.submit(() -> {
+ JDialog dialog = null;
+ try {
+ if (NotEnoughUpdates.INSTANCE.config.hidden.autoupdate) {
+ JOptionPane pane = new JOptionPane("Getting items to download from remote repository.");
+ dialog = pane.createDialog("NotEnoughUpdates Remote Sync");
+ dialog.setModal(false);
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true);
+
+ if (Display.isActive()) dialog.toFront();
+
+ JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json"));
+
+ latestRepoCommit = null;
+ try (Reader inReader = new InputStreamReader(new URL(GIT_COMMITS_URL).openStream())) {
+ JsonObject commits = gson.fromJson(inReader, JsonObject.class);
+ latestRepoCommit = commits.get("sha").getAsString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (latestRepoCommit == null || latestRepoCommit.isEmpty()) return;
+
+ if (new File(configLocation, "repo").exists() && new File(configLocation, "repo/items").exists()) {
+ if (currentCommitJSON != null && currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) {
+ dialog.setVisible(false);
+ return;
+ }
+ }
+
+ if (Display.isActive()) dialog.toFront();
+
+ Utils.recursiveDelete(repoLocation);
+ repoLocation.mkdirs();
+
+ String dlUrl = neu.config.hidden.repoURL;
+
+ pane.setMessage("Downloading NEU Master Archive. (DL# >20)");
+ dialog.pack();
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true);
+ if (Display.isActive()) dialog.toFront();
+
+ File itemsZip = new File(repoLocation, "neu-items-master.zip");
+ try {
+ itemsZip.createNewFile();
+ } catch (IOException e) {
+ return;
+ }
+
+ URL url = new URL(dlUrl);
+ URLConnection urlConnection = url.openConnection();
+ urlConnection.setConnectTimeout(15000);
+ urlConnection.setReadTimeout(30000);
+
+ try (InputStream is = urlConnection.getInputStream()) {
+ FileUtils.copyInputStreamToFile(is, itemsZip);
+ } catch (IOException e) {
+ dialog.dispose();
+ e.printStackTrace();
+ System.err.println("Failed to download NEU Repo! Please report this issue to the mod creator");
+ return;
+ }
+ /*try (
+ BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream());
+ FileOutputStream fileOutputStream = new FileOutputStream(itemsZip)
+ ) {
+ byte dataBuffer[] = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) {
+ fileOutputStream.write(dataBuffer, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ dialog.dispose();
+ return;
+ }*/
+
+ pane.setMessage("Unzipping NEU Master Archive.");
+ dialog.pack();
+ //dialog.setVisible(true);
+ if (Display.isActive()) dialog.toFront();
+
+ unzipIgnoreFirstFolder(itemsZip.getAbsolutePath(), repoLocation.getAbsolutePath());
+
+ if (currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) {
+ JsonObject newCurrentCommitJSON = new JsonObject();
+ newCurrentCommitJSON.addProperty("sha", latestRepoCommit);
+ try {
+ writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json"));
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (dialog != null) dialog.dispose();
+ }
+
+ File items = new File(repoLocation, "items");
+ if (items.exists()) {
+ File[] itemFiles = new File(repoLocation, "items").listFiles();
+ if (itemFiles != null) {
+ ProgressManager.ProgressBar bar = ProgressManager.push("Loading recipes", itemFiles.length);
+ for (File f : itemFiles) {
+ String internalname = f.getName().substring(0, f.getName().length() - 5);
+ bar.step(internalname);
+ synchronized (itemMap) {
+ if (!itemMap.containsKey(internalname)) {
+ loadItem(internalname);
+ }
+ }
+ }
+ ProgressManager.pop(bar);
+ }
+ }
+
+ try {
+ Constants.reload();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+
+ File items = new File(repoLocation, "items");
+ if (items.exists()) {
+ File[] itemFiles = new File(repoLocation, "items").listFiles();
+ if (itemFiles != null) {
+ ProgressManager.ProgressBar bar = ProgressManager.push("Loading items", itemFiles.length);
+ for (File f : itemFiles) {
+ String internalname = f.getName().substring(0, f.getName().length() - 5);
+ bar.step(internalname);
+ synchronized (itemMap) {
+ if (!itemMap.containsKey(internalname)) {
+ loadItem(internalname);
+ }
+ }
+ }
+ ProgressManager.pop(bar);
+ }
+ }
+
+ try {
+ Constants.reload();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Loads the item in to the itemMap and also stores various words associated with this item in to titleWordMap and
+ * loreWordMap. These maps are used in the searching algorithm.
+ */
+ public void loadItem(String internalName) {
+ itemstackCache.remove(internalName);
+ try {
+ JsonObject json = getJsonFromFile(new File(new File(repoLocation, "items"), internalName + ".json"));
+ if (json == null) {
+ return;
+ }
+
+ if (json.get("itemid") == null) return;
+
+ String itemid = json.get("itemid").getAsString();
+ Item mcitem = Item.getByNameOrId(itemid);
+ if (mcitem != null) {
+ itemid = mcitem.getRegistryName();
+ }
+ json.addProperty("itemid", itemid);
+
+ itemMap.put(internalName, json);
+
+ if (json.has("recipe")) {
+ JsonObject recipe = json.getAsJsonObject("recipe");
+ NeuRecipe neuRecipe = NeuRecipe.parseRecipe(this, recipe, json);
+ if (neuRecipe != null)
+ registerNeuRecipe(neuRecipe);
+ }
+ if (json.has("recipes")) {
+ for (JsonElement element : json.getAsJsonArray("recipes")) {
+ JsonObject recipe = element.getAsJsonObject();
+ NeuRecipe neuRecipe = NeuRecipe.parseRecipe(this, recipe, json);
+ if (neuRecipe != null)
+ registerNeuRecipe(neuRecipe);
+ }
+ }
+
+ if (json.has("displayname")) {
+ synchronized (titleWordMap) {
+ int wordIndex = 0;
+ for (String str : json.get("displayname").getAsString().split(" ")) {
+ str = clean(str);
+ if (!titleWordMap.containsKey(str)) {
+ titleWordMap.put(str, new HashMap<>());
+ }
+ if (!titleWordMap.get(str).containsKey(internalName)) {
+ titleWordMap.get(str).put(internalName, new ArrayList<>());
+ }
+ titleWordMap.get(str).get(internalName).add(wordIndex);
+ wordIndex++;
+ }
+ }
+ }
+
+ if (json.has("lore")) {
+ synchronized (loreWordMap) {
+ int wordIndex = 0;
+ for (JsonElement element : json.get("lore").getAsJsonArray()) {
+ for (String str : element.getAsString().split(" ")) {
+ str = clean(str);
+ if (!loreWordMap.containsKey(str)) {
+ loreWordMap.put(str, new HashMap<>());
+ }
+ if (!loreWordMap.get(str).containsKey(internalName)) {
+ loreWordMap.get(str).put(internalName, new ArrayList<>());
+ }
+ loreWordMap.get(str).get(internalName).add(wordIndex);
+ wordIndex++;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ synchronized (loreWordMap) {
+ System.out.println("loreWordMap is : " + loreWordMap);
+ }
+ synchronized (titleWordMap) {
+ System.out.println("titleWordMap is : " + titleWordMap);
+ }
+ System.out.println("internalName is : " + internalName);
+ e.printStackTrace();
+ }
+ }
+
+ public void registerNeuRecipe(NeuRecipe recipe) {
+ recipes.add(recipe);
+ for (Ingredient output : recipe.getOutputs()) {
+ recipesMap.computeIfAbsent(output.getInternalItemId(), ignored -> new HashSet<>()).add(recipe);
+ }
+ for (Ingredient input : recipe.getIngredients()) {
+ usagesMap.computeIfAbsent(input.getInternalItemId(), ignored -> new HashSet<>()).add(recipe);
+ }
+ }
+
+ public Set getRecipesFor(String internalName) {
+ return recipesMap.getOrDefault(internalName, Collections.emptySet());
+ }
+
+ public List getAvailableRecipesFor(String internalname) {
+ return getRecipesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList());
+ }
+
+ public Set getUsagesFor(String internalName) {
+ return usagesMap.getOrDefault(internalName, Collections.emptySet());
+ }
+
+ public List getAvailableUsagesFor(String internalname) {
+ return getUsagesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList());
+ }
+
+ /**
+ * Searches a string for a query. This method is used to mimic the behaviour of the more complex map-based search
+ * function. This method is used for the chest-item-search feature.
+ */
+ public boolean searchString(String toSearch, String query) {
+ int lastMatch = -1;
+
+ toSearch = clean(toSearch).toLowerCase();
+ query = clean(query).toLowerCase();
+ String[] splitToSeach = toSearch.split(" ");
+ out:
+ for (String s : query.split(" ")) {
+ for (int i = 0; i < splitToSeach.length; i++) {
+ if (!(lastMatch == -1 || lastMatch == i - 1)) continue;
+ if (splitToSeach[i].startsWith(s)) {
+ lastMatch = i;
+ continue out;
+ }
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether an itemstack matches a certain query, following the same rules implemented by the more complex
+ * map-based search function.
+ */
+ public boolean doesStackMatchSearch(ItemStack stack, String query) {
+ if (query.startsWith("title:")) {
+ query = query.substring(6);
+ return searchString(stack.getDisplayName(), query);
+ } else if (query.startsWith("desc:")) {
+ query = query.substring(5);
+ String lore = "";
+ NBTTagCompound tag = stack.getTagCompound();
+ if (tag != null) {
+ NBTTagCompound display = tag.getCompoundTag("display");
+ if (display.hasKey("Lore", 9)) {
+ NBTTagList list = display.getTagList("Lore", 8);
+ for (int i = 0; i < list.tagCount(); i++) {
+ lore += list.getStringTagAt(i) + " ";
+ }
+ }
+ }
+ return searchString(lore, query);
+ } else if (query.startsWith("id:")) {
+ query = query.substring(3);
+ String internalName = getInternalNameForItem(stack);
+ return query.equalsIgnoreCase(internalName);
+ } else {
+ boolean result = false;
+ if (!query.trim().contains(" ")) {
+ StringBuilder sb = new StringBuilder();
+ for (char c : query.toCharArray()) {
+ sb.append(c).append(" ");
+ }
+ result = result || searchString(stack.getDisplayName(), sb.toString());
+ }
+ result = result || searchString(stack.getDisplayName(), query);
+
+ String lore = "";
+ NBTTagCompound tag = stack.getTagCompound();
+ if (tag != null) {
+ NBTTagCompound display = tag.getCompoundTag("display");
+ if (display.hasKey("Lore", 9)) {
+ NBTTagList list = display.getTagList("Lore", 8);
+ for (int i = 0; i < list.tagCount(); i++) {
+ lore += list.getStringTagAt(i) + " ";
+ }
+ }
+ }
+
+ result = result || searchString(lore, query);
+
+ return result;
+ }
+ }
+
+ /**
+ * Calls search for each query, separated by | eg. search(A|B) = search(A) + search(B)
+ */
+ public Set search(String query, boolean multi) {
+ if (multi) {
+ Set result = new HashSet<>();
+
+ StringBuilder query2 = new StringBuilder();
+ char lastOp = '|';
+ for (char c : query.toCharArray()) {
+ if (c == '|' || c == '&') {
+ if (lastOp == '|') {
+ result.addAll(search(query2.toString()));
+ } else if (lastOp == '&') {
+ result.retainAll(search(query2.toString()));
+ }
+
+ query2 = new StringBuilder();
+ lastOp = c;
+ } else {
+ query2.append(c);
+ }
+ }
+ if (lastOp == '|') {
+ result.addAll(search(query2.toString()));
+ } else if (lastOp == '&') {
+ result.retainAll(search(query2.toString()));
+ }
+
+ return result;
+ } else {
+ return search(query);
+ }
+ }
+
+ /*public TreeMap searchForStacks(String query, Set stacks, boolean multi) {
+ if (multi) {
+ Set result = new HashSet<>();
+
+ StringBuilder query2 = new StringBuilder();
+ char lastOp = '|';
+ for (char c : query.toCharArray()) {
+ if (c == '|' || c == '&') {
+ if (lastOp == '|') {
+ result.addAll(doesStackMatchSearch(stack, query2.toString()));
+ } else if (lastOp == '&') {
+ result.retainAll(search(query2.toString()));
+ }
+
+ query2 = new StringBuilder();
+ lastOp = c;
+ } else {
+ query2.append(c);
+ }
+ }
+ if (lastOp == '|') {
+ result.addAll(search(query2.toString()));
+ } else if (lastOp == '&') {
+ result.retainAll(search(query2.toString()));
+ }
+
+ return result;
+ } else {
+ return search(query);
+ }
+ }*/
+
+ /**
+ * Returns the name of items which match a certain search query.
+ */
+ public Set search(String query) {
+ query = query.trim();
+ boolean negate = query.startsWith("!");
+ if (negate) query = query.substring(1);
+
+ LinkedHashSet results = new LinkedHashSet<>();
+ if (query.startsWith("title:")) {
+ query = query.substring(6);
+ results.addAll(new TreeSet<>(search(query, titleWordMap)));
+ } else if (query.startsWith("desc:")) {
+ query = query.substring(5);
+ results.addAll(new TreeSet<>(search(query, loreWordMap)));
+ } else if (query.startsWith("id:")) {
+ query = query.substring(3);
+ results.addAll(new TreeSet<>(subMapWithKeysThatAreSuffixes(query.toUpperCase(), itemMap).keySet()));
+ } else {
+ if (!query.trim().contains(" ")) {
+ StringBuilder sb = new StringBuilder();
+ for (char c : query.toCharArray()) {
+ sb.append(c).append(" ");
+ }
+ results.addAll(new TreeSet<>(search(sb.toString(), titleWordMap)));
+ }
+ results.addAll(new TreeSet<>(search(query, titleWordMap)));
+ results.addAll(new TreeSet<>(search(query, loreWordMap)));
+ }
+ if (!negate) {
+ return results;
+ } else {
+ Set negatedResults = new HashSet<>();
+ for (String internalname : itemMap.keySet()) {
+ negatedResults.add(internalname);
+ }
+ negatedResults.removeAll(results);
+ return negatedResults;
+ }
+ }
+
+ /**
+ * Splits a search query into an array of strings delimited by a space character. Then, matches the query to the
+ * start of words in the various maps (title & lore). The small query does not need to match the whole entry of the
+ * map, only the beginning. eg. "ench" and "encha" will both match "enchanted". All sub queries must follow a word
+ * matching the previous sub query. eg. "ench po" will match "enchanted pork" but will not match "pork enchanted".
+ */
+ public Set search(String query, TreeMap>> wordMap) {
+ HashMap> matches = null;
+
+ query = clean(query).toLowerCase();
+ for (String queryWord : query.split(" ")) {
+ HashMap> matchesToKeep = new HashMap<>();
+ for (HashMap> wordMatches : subMapWithKeysThatAreSuffixes(queryWord, wordMap).values()) {
+ if (!(wordMatches != null && !wordMatches.isEmpty())) continue;
+ if (matches == null) {
+ //Copy all wordMatches to titleMatches
+ for (String internalname : wordMatches.keySet()) {
+ if (!matchesToKeep.containsKey(internalname)) {
+ matchesToKeep.put(internalname, new ArrayList<>());
+ }
+ matchesToKeep.get(internalname).addAll(wordMatches.get(internalname));
+ }
+ } else {
+ for (String internalname : matches.keySet()) {
+ if (!wordMatches.containsKey(internalname)) continue;
+ for (Integer newIndex : wordMatches.get(internalname)) {
+ if (!matches.get(internalname).contains(newIndex - 1)) continue;
+ if (!matchesToKeep.containsKey(internalname)) {
+ matchesToKeep.put(internalname, new ArrayList<>());
+ }
+ matchesToKeep.get(internalname).add(newIndex);
+ }
+ }
+ }
+ }
+ if (matchesToKeep.isEmpty()) return new HashSet<>();
+ matches = matchesToKeep;
+ }
+
+ return matches.keySet();
+ }
+
+ /**
+ * From https://stackoverflow.com/questions/10711494/get-values-in-treemap-whose-string-keys-start-with-a-pattern
+ */
+ public Map subMapWithKeysThatAreSuffixes(String prefix, NavigableMap map) {
+ if ("".equals(prefix)) return map;
+ String lastKey = createLexicographicallyNextStringOfTheSameLength(prefix);
+ return map.subMap(prefix, true, lastKey, false);
+ }
+
+ public String createLexicographicallyNextStringOfTheSameLength(String input) {
+ final int lastCharPosition = input.length() - 1;
+ String inputWithoutLastChar = input.substring(0, lastCharPosition);
+ char lastChar = input.charAt(lastCharPosition);
+ char incrementedLastChar = (char) (lastChar + 1);
+ return inputWithoutLastChar + incrementedLastChar;
+ }
+
+ public JsonObject getJsonFromItemBytes(String item_bytes) {
+ try {
+ NBTTagCompound tag =
+ CompressedStreamTools.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(item_bytes)));
+ //System.out.println(tag.toString());
+ return getJsonFromNBT(tag);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ public String getUUIDFromNBT(NBTTagCompound tag) {
+ String uuid = null;
+ if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+
+ if (ea.hasKey("uuid", 8)) {
+ uuid = ea.getString("uuid");
+ }
+ }
+ return uuid;
+ }
+
+ public String getInternalnameFromNBT(NBTTagCompound tag) {
+ String internalname = null;
+ if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+
+ if (ea.hasKey("id", 8)) {
+ internalname = ea.getString("id").replaceAll(":", "-");
+ } else {
+ return null;
+ }
+
+ if ("PET".equals(internalname)) {
+ String petInfo = ea.getString("petInfo");
+ if (petInfo.length() > 0) {
+ JsonObject petInfoObject = gson.fromJson(petInfo, JsonObject.class);
+ internalname = petInfoObject.get("type").getAsString();
+ String tier = petInfoObject.get("tier").getAsString();
+ switch (tier) {
+ case "COMMON":
+ internalname += ";0";
+ break;
+ case "UNCOMMON":
+ internalname += ";1";
+ break;
+ case "RARE":
+ internalname += ";2";
+ break;
+ case "EPIC":
+ internalname += ";3";
+ break;
+ case "LEGENDARY":
+ internalname += ";4";
+ break;
+ case "MYTHIC":
+ internalname += ";5";
+ break;
+ }
+ }
+ }
+ if ("ENCHANTED_BOOK".equals(internalname) && ea.hasKey("enchantments", 10)) {
+ NBTTagCompound enchants = ea.getCompoundTag("enchantments");
+
+ for (String enchname : enchants.getKeySet()) {
+ internalname = enchname.toUpperCase() + ";" + enchants.getInteger(enchname);
+ break;
+ }
+ }
+ if ("RUNE".equals(internalname) && ea.hasKey("runes", 10)) {
+ NBTTagCompound rune = ea.getCompoundTag("runes");
+
+ for (String runename : rune.getKeySet()) {
+ internalname = runename.toUpperCase() + "_RUNE" + ";" + rune.getInteger(runename);
+ break;
+ }
+ }
+ if ("PARTY_HAT_CRAB".equals(internalname) && (ea.getString("party_hat_color") != null)) {
+ String crabhat = ea.getString("party_hat_color");
+ internalname = "PARTY_HAT_CRAB" + "_" + crabhat.toUpperCase();
+ }
+ }
+
+ return internalname;
+ }
+
+ public String[] getLoreFromNBT(NBTTagCompound tag) {
+ String[] lore = new String[0];
+ NBTTagCompound display = tag.getCompoundTag("display");
+
+ if (display.hasKey("Lore", 9)) {
+ NBTTagList list = display.getTagList("Lore", 8);
+ lore = new String[list.tagCount()];
+ for (int k = 0; k < list.tagCount(); k++) {
+ lore[k] = list.getStringTagAt(k);
+ }
+ }
+ return lore;
+ }
+
+ public JsonObject getJsonFromNBT(NBTTagCompound tag) {
+ return getJsonFromNBTEntry(tag.getTagList("i", 10).getCompoundTagAt(0));
+ }
+
+ public JsonObject getJsonFromNBTEntry(NBTTagCompound tag) {
+ if (tag.getKeySet().size() == 0) return null;
+
+ int id = tag.getShort("id");
+ int damage = tag.getShort("Damage");
+ int count = tag.getShort("Count");
+ tag = tag.getCompoundTag("tag");
+
+ if (id == 141) id = 391; //for some reason hypixel thinks carrots have id 141
+
+ String internalname = getInternalnameFromNBT(tag);
+ if (internalname == null) return null;
+
+ NBTTagCompound display = tag.getCompoundTag("display");
+ String[] lore = getLoreFromNBT(tag);
+
+ Item itemMc = Item.getItemById(id);
+ String itemid = "null";
+ if (itemMc != null) {
+ itemid = itemMc.getRegistryName();
+ }
+ String displayname = display.getString("Name");
+ String[] info = new String[0];
+ String clickcommand = "";
+
+ JsonObject item = new JsonObject();
+ item.addProperty("internalname", internalname);
+ item.addProperty("itemid", itemid);
+ item.addProperty("displayname", displayname);
+
+ if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+
+ byte[] bytes = null;
+ for (String key : ea.getKeySet()) {
+ if (key.endsWith("backpack_data") || key.equals("new_year_cake_bag_data")) {
+ bytes = ea.getByteArray(key);
+ break;
+ }
+ }
+ if (bytes != null) {
+ JsonArray bytesArr = new JsonArray();
+ for (byte b : bytes) {
+ bytesArr.add(new JsonPrimitive(b));
+ }
+ item.add("item_contents", bytesArr);
+ }
+ if (ea.hasKey("dungeon_item_level")) {
+ item.addProperty("dungeon_item_level", ea.getInteger("dungeon_item_level"));
+ }
+ }
+
+ if (lore != null && lore.length > 0) {
+ JsonArray jsonLore = new JsonArray();
+ for (String line : lore) {
+ jsonLore.add(new JsonPrimitive(line));
+ }
+ item.add("lore", jsonLore);
+ }
+
+ item.addProperty("damage", damage);
+ if (count > 1) item.addProperty("count", count);
+ item.addProperty("nbttag", tag.toString());
+
+ return item;
+ }
+
+ private String clean(String str) {
+ return str.replaceAll("(\u00a7.)|[^0-9a-zA-Z ]", "").toLowerCase().trim();
+ }
+
+ public void showRecipe(JsonObject item) {
+ ContainerChest container = null;
+ if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest)
+ container = (ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer;
+ String internalName = item.get("internalname").getAsString();
+ Set recipesFor = getRecipesFor(internalName);
+ if (container != null &&
+ container.getLowerChestInventory().getDisplayName().getUnformattedText().equals("Craft Item")) {
+ Optional recipe = recipesFor.stream().filter(it -> it instanceof CraftingRecipe).findAny();
+ if (recipe.isPresent()) {
+ craftingOverlay.setShownRecipe((CraftingRecipe) recipe.get());
+ return;
+ }
+ }
+ if (!item.has("clickcommand")) return;
+ String clickcommand = item.get("clickcommand").getAsString();
+ switch (clickcommand.intern()) {
+ case "viewrecipe":
+ displayGuiItemRecipe(internalName, null);
+ break;
+ case "viewoption":
+ neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT));
+ }
+ displayGuiItemRecipe(internalName, "");
+ }
+
+ public void showRecipe(String internalName) {
+ showRecipe(getItemInformation().get(internalName));
+ }
+
+ /**
+ * Takes an item stack and produces a JsonObject.
+ */
+ public JsonObject getJsonForItem(ItemStack stack) {
+ NBTTagCompound tag = stack.getTagCompound() == null ? new NBTTagCompound() : stack.getTagCompound();
+
+ //Item lore
+ String[] lore = new String[0];
+ if (tag.hasKey("display", 10)) {
+ NBTTagCompound display = tag.getCompoundTag("display");
+
+ if (display.hasKey("Lore", 9)) {
+ NBTTagList list = display.getTagList("Lore", 8);
+ lore = new String[list.tagCount()];
+ for (int i = 0; i < list.tagCount(); i++) {
+ lore[i] = list.getStringTagAt(i);
+ }
+ }
+ }
+
+ if (stack.getDisplayName().endsWith(" Recipes")) {
+ stack.setStackDisplayName(stack.getDisplayName().substring(0, stack.getDisplayName().length() - 8));
+ }
+
+ if (lore.length > 0 && (lore[lore.length - 1].contains("Click to view recipes!") ||
+ lore[lore.length - 1].contains("Click to view recipe!"))) {
+ String[] lore2 = new String[lore.length - 2];
+ System.arraycopy(lore, 0, lore2, 0, lore.length - 2);
+ lore = lore2;
+ }
+
+ JsonObject json = new JsonObject();
+ json.addProperty("itemid", stack.getItem().getRegistryName());
+ json.addProperty("displayname", stack.getDisplayName());
+ json.addProperty("nbttag", tag.toString());
+ json.addProperty("damage", stack.getItemDamage());
+
+ JsonArray jsonlore = new JsonArray();
+ for (String line : lore) {
+ jsonlore.add(new JsonPrimitive(line));
+ }
+ json.add("lore", jsonlore);
+
+ return json;
+ }
+
+ public String getInternalNameForItem(ItemStack stack) {
+ if (stack == null) return null;
+ NBTTagCompound tag = stack.getTagCompound();
+ return getInternalnameFromNBT(tag);
+ }
+
+ public String getUUIDForItem(ItemStack stack) {
+ if (stack == null) return null;
+ NBTTagCompound tag = stack.getTagCompound();
+ return getUUIDFromNBT(tag);
+ }
+
+ public void writeItemToFile(ItemStack stack) {
+ String internalname = getInternalNameForItem(stack);
+
+ if (internalname == null) {
+ return;
+ }
+
+ JsonObject json = getJsonForItem(stack);
+ json.addProperty("internalname", internalname);
+ json.addProperty("clickcommand", "");
+ json.addProperty("modver", NotEnoughUpdates.VERSION);
+
+ try {
+ writeJson(json, new File(new File(repoLocation, "items"), internalname + ".json"));
+ } catch (IOException ignored) {
+ }
+
+ loadItem(internalname);
+ }
+
+ public boolean displayGuiItemUsages(String internalName) {
+ if (!usagesMap.containsKey(internalName)) return false;
+ List usages = getAvailableUsagesFor(internalName);
+ if (usages.isEmpty()) return false;
+ Minecraft.getMinecraft().displayGuiScreen(
+ new GuiItemRecipe("Item Usages", usages, this));
+ return true;
+ }
+
+ public boolean displayGuiItemRecipe(String internalName, String text) {
+ if (!recipesMap.containsKey(internalName)) return false;
+ List recipes = getAvailableRecipesFor(internalName);
+ if (recipes.isEmpty()) return false;
+ Minecraft.getMinecraft().displayGuiScreen(
+ new GuiItemRecipe(text != null ? text : "Item Recipe", recipes, this));
+ return true;
+ }
+
+ /**
+ * Will display guiItemRecipe if a player attempted to view the recipe to an item but they didn't have the recipe
+ * unlocked. See NotEnoughUpdates#onGuiChat for where this method is called.
+ */
+ public boolean failViewItem(String text) {
+ if (viewItemAttemptID != null && !viewItemAttemptID.isEmpty()) {
+ if (System.currentTimeMillis() - viewItemAttemptTime < 500) {
+ return displayGuiItemRecipe(viewItemAttemptID, text);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Downloads a web file, appending some HTML attributes that makes wikia give us the raw wiki syntax.
+ */
+ public CompletableFuture getWebFile(String url) {
+ return CompletableFuture.supplyAsync(() -> {
+ File f = new File(configLocation, "tmp/" + Base64.getEncoder().encodeToString(url.getBytes()) + ".html");
+ if (f.exists()) {
+ return f;
+ }
+
+ try {
+ f.getParentFile().mkdirs();
+ f.createNewFile();
+ f.deleteOnExit();
+ } catch (IOException e) {
+ return null;
+ }
+ try (
+ BufferedInputStream inStream = new BufferedInputStream(new URL(
+ url + "?action=raw&templates=expand").openStream());
+ FileOutputStream fileOutputStream = new FileOutputStream(f)
+ ) {
+ byte[] dataBuffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) {
+ fileOutputStream.write(dataBuffer, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ return f;
+ });
+ }
+
+ /**
+ * Modified from https://www.journaldev.com/960/java-unzip-file-example
+ */
+ private static void unzipIgnoreFirstFolder(String zipFilePath, String destDir) {
+ File dir = new File(destDir);
+ // create output directory if it doesn't exist
+ if (!dir.exists()) dir.mkdirs();
+ FileInputStream fis;
+ //buffer for read and write data to file
+ byte[] buffer = new byte[1024];
+ try {
+ fis = new FileInputStream(zipFilePath);
+ ZipInputStream zis = new ZipInputStream(fis);
+ ZipEntry ze = zis.getNextEntry();
+ while (ze != null) {
+ if (!ze.isDirectory()) {
+ String fileName = ze.getName();
+ fileName = fileName.substring(fileName.split("/")[0].length() + 1);
+ File newFile = new File(destDir + File.separator + fileName);
+ //create directories for sub directories in zip
+ new File(newFile.getParent()).mkdirs();
+ if (!isInTree(dir, newFile)) {
+ throw new RuntimeException(
+ "Not Enough Updates detected an invalid zip file. This is a potential security risk, please report this in the Moulberry discord.");
+ }
+ FileOutputStream fos = new FileOutputStream(newFile);
+ int len;
+ while ((len = zis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+ fos.close();
+ }
+ //close this ZipEntry
+ zis.closeEntry();
+ ze = zis.getNextEntry();
+ }
+ //close last ZipEntry
+ zis.closeEntry();
+ zis.close();
+ fis.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static boolean isInTree(File rootDirectory, File file) throws IOException {
+ file = file.getCanonicalFile();
+ rootDirectory = rootDirectory.getCanonicalFile();
+ while (file != null) {
+ if (file.equals(rootDirectory)) return true;
+ file = file.getParentFile();
+ }
+ return false;
+ }
+
+ /**
+ * Modified from https://www.journaldev.com/960/java-unzip-file-example
+ */
+ public static void unzip(InputStream src, File dest) {
+ //buffer for read and write data to file
+ byte[] buffer = new byte[1024];
+ try {
+ ZipInputStream zis = new ZipInputStream(src);
+ ZipEntry ze = zis.getNextEntry();
+ while (ze != null) {
+ if (!ze.isDirectory()) {
+ String fileName = ze.getName();
+ File newFile = new File(dest, fileName);
+ if (!isInTree(dest, newFile)) {
+ throw new RuntimeException(
+ "Not Enough Updates detected an invalid zip file. This is a potential security risk, please report this in the Moulberry discord.");
+ }
+ //create directories for sub directories in zip
+ new File(newFile.getParent()).mkdirs();
+ FileOutputStream fos = new FileOutputStream(newFile);
+ int len;
+ while ((len = zis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+ fos.close();
+ }
+ //close this ZipEntry
+ zis.closeEntry();
+ ze = zis.getNextEntry();
+ }
+ //close last ZipEntry
+ zis.closeEntry();
+ zis.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * From here to the end of the file are various helper functions for creating and writing json files, in particular
+ * json files representing skyblock item data.
+ */
+ public JsonObject createItemJson(
+ String internalname, String itemid, String displayname, String[] lore,
+ String crafttext, String infoType, String[] info,
+ String clickcommand, int damage, NBTTagCompound nbttag
+ ) {
+ return createItemJson(
+ new JsonObject(),
+ internalname,
+ itemid,
+ displayname,
+ lore,
+ crafttext,
+ infoType,
+ info,
+ clickcommand,
+ damage,
+ nbttag
+ );
+ }
+
+ public JsonObject createItemJson(
+ JsonObject base, String internalname, String itemid, String displayname, String[] lore,
+ String crafttext, String infoType, String[] info,
+ String clickcommand, int damage, NBTTagCompound nbttag
+ ) {
+ if (internalname == null || internalname.isEmpty()) {
+ return null;
+ }
+
+ JsonObject json = gson.fromJson(gson.toJson(base, JsonObject.class), JsonObject.class);
+ json.addProperty("internalname", internalname);
+ json.addProperty("itemid", itemid);
+ json.addProperty("displayname", displayname);
+ json.addProperty("crafttext", crafttext);
+ json.addProperty("clickcommand", clickcommand);
+ json.addProperty("damage", damage);
+ json.addProperty("nbttag", nbttag.toString());
+ json.addProperty("modver", NotEnoughUpdates.VERSION);
+ json.addProperty("infoType", infoType);
+
+ if (info != null && info.length > 0) {
+ JsonArray jsoninfo = new JsonArray();
+ for (String line : info) {
+ jsoninfo.add(new JsonPrimitive(line));
+ }
+ json.add("info", jsoninfo);
+ }
+
+ JsonArray jsonlore = new JsonArray();
+ for (String line : lore) {
+ jsonlore.add(new JsonPrimitive(line));
+ }
+ json.add("lore", jsonlore);
+
+ return json;
+ }
+
+ public boolean writeItemJson(
+ String internalname, String itemid, String displayname, String[] lore, String crafttext,
+ String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag
+ ) {
+ return writeItemJson(
+ new JsonObject(),
+ internalname,
+ itemid,
+ displayname,
+ lore,
+ crafttext,
+ infoType,
+ info,
+ clickcommand,
+ damage,
+ nbttag
+ );
+ }
+
+ public boolean writeItemJson(
+ JsonObject base, String internalname, String itemid, String displayname, String[] lore,
+ String crafttext, String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag
+ ) {
+ JsonObject json = createItemJson(
+ base,
+ internalname,
+ itemid,
+ displayname,
+ lore,
+ crafttext,
+ infoType,
+ info,
+ clickcommand,
+ damage,
+ nbttag
+ );
+ if (json == null) {
+ return false;
+ }
+
+ try {
+ writeJsonDefaultDir(json, internalname + ".json");
+ } catch (IOException e) {
+ return false;
+ }
+
+ loadItem(internalname);
+ return true;
+ }
+
+ public void writeJson(JsonObject json, File file) throws IOException {
+ file.createNewFile();
+
+ try (
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(file),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ writer.write(gson.toJson(json));
+ }
+ }
+
+ public void writeJsonDefaultDir(JsonObject json, String filename) throws IOException {
+ File file = new File(new File(repoLocation, "items"), filename);
+ writeJson(json, file);
+ }
+
+ public JsonObject readJsonDefaultDir(String filename) throws IOException {
+ File f = new File(new File(repoLocation, "items"), filename);
+ if (f.exists() && f.isFile() && f.canRead())
+ try (Reader reader = new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8)) {
+ return gson.fromJson(reader, JsonObject.class);
+ } // rethrow io exceptions
+ return null;
+ }
+
+ public TreeMap getItemInformation() {
+ return itemMap;
+ }
+
+ public String removeUnusedDecimal(double num) {
+ if (num % 1 == 0) {
+ return String.valueOf((int) num);
+ } else {
+ return String.valueOf(num);
+ }
+ }
+
+ public HashMap getLoreReplacements(String petname, String tier, int level) {
+ JsonObject petnums = null;
+ if (petname != null && tier != null) {
+ petnums = Constants.PETNUMS;
+ }
+
+ HashMap replacements = new HashMap<>();
+ if (level < 1) {
+ if (Constants.PETS != null && Constants.PETS.has("custom_pet_leveling") &&
+ Constants.PETS.getAsJsonObject("custom_pet_leveling").has(petname) &&
+ Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(petname).has("max_level")) {
+ int maxLvl =
+ Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(petname).get("max_level").getAsInt();
+ replacements.put("LVL", "1\u27A1" + maxLvl);
+ } else {
+ replacements.put("LVL", "1\u27A1100");
+ }
+ } else {
+ replacements.put("LVL", "" + level);
+ }
+
+ if (petnums != null) {
+ if (petnums.has(petname)) {
+ JsonObject petInfo = petnums.get(petname).getAsJsonObject();
+ if (petInfo.has(tier)) {
+ JsonObject petInfoTier = petInfo.get(tier).getAsJsonObject();
+ if (petInfoTier == null || !petInfoTier.has("1") || !petInfoTier.has("100")) {
+ return replacements;
+ }
+
+ JsonObject min = petInfoTier.get("1").getAsJsonObject();
+ JsonObject max = petInfoTier.get("100").getAsJsonObject();
+
+ if (level < 1) {
+ JsonArray otherNumsMin = min.get("otherNums").getAsJsonArray();
+ JsonArray otherNumsMax = max.get("otherNums").getAsJsonArray();
+ boolean addZero = false;
+ if (petInfoTier.has("stats_levelling_curve")) {
+ String[] stringArray = petInfoTier.get("stats_levelling_curve").getAsString().split(":");
+ if (stringArray.length == 3) {
+ int type = Integer.parseInt(stringArray[2]);
+ if (type == 1) {
+ addZero = true;
+ }
+ }
+ }
+ for (int i = 0; i < otherNumsMax.size(); i++) {
+ replacements.put(
+ "" + i,
+ (addZero ? "0\u27A1" : "") +
+ removeUnusedDecimal(Math.floor(otherNumsMin.get(i).getAsFloat() * 10) / 10f) +
+ "\u27A1" + removeUnusedDecimal(Math.floor(otherNumsMax.get(i).getAsFloat() * 10) / 10f)
+ );
+ }
+
+ for (Map.Entry entry : max.get("statNums").getAsJsonObject().entrySet()) {
+ int statMax = (int) Math.floor(entry.getValue().getAsFloat());
+ int statMin = (int) Math.floor(min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat());
+ String statStr = (statMin > 0 ? "+" : "") + statMin + "\u27A1" + statMax;
+ statStr = (addZero ? "0\u27A1" : "") + statStr;
+ replacements.put(entry.getKey(), statStr);
+ }
+ } else {
+
+ int minStatsLevel = 0;
+ int maxStatsLevel = 100;
+ int statsLevelingType = -1;
+
+ int statsLevel = level;
+
+ if (petInfoTier.has("stats_levelling_curve")) {
+ String[] stringArray = petInfoTier.get("stats_levelling_curve").getAsString().split(":");
+ if (stringArray.length == 3) {
+ minStatsLevel = Integer.parseInt(stringArray[0]);
+ maxStatsLevel = Integer.parseInt(stringArray[1]);
+ statsLevelingType = Integer.parseInt(stringArray[2]);
+ switch (statsLevelingType) {
+ //Case for maybe a pet that might exist
+ case 0:
+ case 1:
+ if (level < minStatsLevel) {
+ statsLevel = 1;
+ } else if (level < maxStatsLevel) {
+ statsLevel = level - minStatsLevel + 1;
+ } else {
+ statsLevel = maxStatsLevel - minStatsLevel + 1;
+ }
+ break;
+
+ }
+ }
+ }
+ float minMix = (maxStatsLevel - (minStatsLevel - (statsLevelingType == -1 ? 0 : 1)) - statsLevel) / 99f;
+ float maxMix = (statsLevel - 1) / 99f;
+
+ JsonArray otherNumsMin = min.get("otherNums").getAsJsonArray();
+ JsonArray otherNumsMax = max.get("otherNums").getAsJsonArray();
+ for (int i = 0; i < otherNumsMax.size(); i++) {
+ float val = otherNumsMin.get(i).getAsFloat() * minMix + otherNumsMax.get(i).getAsFloat() * maxMix;
+ if (statsLevelingType == 1 && level < minStatsLevel) {
+ replacements.put("" + i, "0");
+ } else {
+ replacements.put("" + i, removeUnusedDecimal(Math.floor(val * 10) / 10f));
+ }
+ }
+
+ for (Map.Entry entry : max.get("statNums").getAsJsonObject().entrySet()) {
+ if (statsLevelingType == 1 && level < minStatsLevel) {
+ replacements.put(entry.getKey(), "0");
+ } else {
+ float statMax = entry.getValue().getAsFloat();
+ float statMin = min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat();
+ float val = statMin * minMix + statMax * maxMix;
+ String statStr = (statMin > 0 ? "+" : "") + (int) Math.floor(val);
+ replacements.put(entry.getKey(), statStr);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return replacements;
+ }
+
+ public HashMap getLoreReplacements(NBTTagCompound tag, int level) {
+ String petname = null;
+ String tier = null;
+ if (tag != null && tag.hasKey("ExtraAttributes")) {
+ NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
+ if (ea.hasKey("petInfo")) {
+ String petInfoStr = ea.getString("petInfo");
+ JsonObject petInfo = gson.fromJson(petInfoStr, JsonObject.class);
+ petname = petInfo.get("type").getAsString();
+ tier = petInfo.get("tier").getAsString();
+ if (petInfo.has("heldItem")) {
+ String heldItem = petInfo.get("heldItem").getAsString();
+ if (heldItem.equals("PET_ITEM_TIER_BOOST")) {
+ switch (tier) {
+ case "COMMON":
+ tier = "UNCOMMON";
+ break;
+ case "UNCOMMON":
+ tier = "RARE";
+ break;
+ case "RARE":
+ tier = "EPIC";
+ break;
+ case "EPIC":
+ tier = "LEGENDARY";
+ break;
+ case "LEGENDARY":
+ tier = "MYTHIC";
+ break;
+ }
+ }
+ }
+ }
+ }
+ return getLoreReplacements(petname, tier, level);
+ }
+
+ public NBTTagList processLore(JsonArray lore, HashMap replacements) {
+ NBTTagList nbtLore = new NBTTagList();
+ for (JsonElement line : lore) {
+ String lineStr = line.getAsString();
+ if (!lineStr.contains("Click to view recipes!") &&
+ !lineStr.contains("Click to view recipe!")) {
+ for (Map.Entry entry : replacements.entrySet()) {
+ lineStr = lineStr.replace("{" + entry.getKey() + "}", entry.getValue());
+ }
+ nbtLore.appendTag(new NBTTagString(lineStr));
+ }
+ }
+ return nbtLore;
+ }
+
+ public ItemStack jsonToStack(JsonObject json) {
+ return jsonToStack(json, true);
+ }
+
+ public ItemStack jsonToStack(JsonObject json, boolean useCache) {
+ return jsonToStack(json, useCache, true);
+ }
+
+ public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements) {
+ return jsonToStack(json, useCache, useReplacements, true);
+ }
+
+ public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean copyStack) {
+ if (json == null) return new ItemStack(Items.painting, 1, 10);
+ String internalname = json.get("internalname").getAsString();
+
+ if (useCache) {
+ ItemStack stack = itemstackCache.get(internalname);
+ if (stack != null) {
+ if (copyStack) {
+ return stack.copy();
+ } else {
+ return stack;
+ }
+ }
+ }
+
+ ItemStack stack = new ItemStack(Item.itemRegistry.getObject(
+ new ResourceLocation(json.get("itemid").getAsString())));
+
+ if (json.has("count")) {
+ stack.stackSize = json.get("count").getAsInt();
+ }
+
+ if (stack.getItem() == null) {
+ stack = new ItemStack(Item.getItemFromBlock(Blocks.stone), 0, 255); //Purple broken texture item
+ } else {
+ if (json.has("damage")) {
+ stack.setItemDamage(json.get("damage").getAsInt());
+ }
+
+ if (json.has("nbttag")) {
+ try {
+ NBTTagCompound tag = JsonToNBT.getTagFromJson(json.get("nbttag").getAsString());
+ stack.setTagCompound(tag);
+ } catch (NBTException ignored) {
+ }
+ }
+
+ HashMap replacements = new HashMap<>();
+
+ if (useReplacements) {
+ replacements = getLoreReplacements(stack.getTagCompound(), -1);
+
+ String displayname = json.get("displayname").getAsString();
+ for (Map.Entry entry : replacements.entrySet()) {
+ displayname = displayname.replace("{" + entry.getKey() + "}", entry.getValue());
+ }
+ stack.setStackDisplayName(displayname);
+ }
+
+ if (json.has("lore")) {
+ NBTTagCompound display = new NBTTagCompound();
+ if (stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) {
+ display = stack.getTagCompound().getCompoundTag("display");
+ }
+ display.setTag("Lore", processLore(json.get("lore").getAsJsonArray(), replacements));
+ NBTTagCompound tag = stack.getTagCompound() != null ? stack.getTagCompound() : new NBTTagCompound();
+ tag.setTag("display", display);
+ stack.setTagCompound(tag);
+ }
+ }
+
+ if (useCache) itemstackCache.put(internalname, stack);
+ if (copyStack) {
+ return stack.copy();
+ } else {
+ return stack;
+ }
+ }
+
+ public void reloadRepository() {
+ File items = new File(repoLocation, "items");
+ if (items.exists()) {
+ recipes.clear();
+ recipesMap.clear();
+ usagesMap.clear();
+
+ File[] itemFiles = new File(repoLocation, "items").listFiles();
+ if (itemFiles != null) {
+ for (File f : itemFiles) {
+ String internalname = f.getName().substring(0, f.getName().length() - 5);
+ loadItem(internalname);
+ }
+ }
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
index 080353a78d..d1bfed14d1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
@@ -8,18 +8,30 @@
import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper;
import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger;
-import io.github.moulberry.notenoughupdates.infopanes.*;
+import io.github.moulberry.notenoughupdates.infopanes.DevInfoPane;
+import io.github.moulberry.notenoughupdates.infopanes.InfoPane;
+import io.github.moulberry.notenoughupdates.infopanes.TextInfoPane;
import io.github.moulberry.notenoughupdates.itemeditor.NEUItemEditor;
import io.github.moulberry.notenoughupdates.mbgui.MBAnchorPoint;
import io.github.moulberry.notenoughupdates.mbgui.MBGuiElement;
import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupAligned;
import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupFloating;
+import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu;
+import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph;
import io.github.moulberry.notenoughupdates.options.NEUConfigEditor;
-import io.github.moulberry.notenoughupdates.util.*;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.LerpingFloat;
+import io.github.moulberry.notenoughupdates.util.SpecialColour;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.*;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.GuiTextField;
+import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.entity.RenderManager;
@@ -31,6 +43,8 @@
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Items;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -42,17 +56,16 @@
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.ClientCommandHandler;
-import org.apache.commons.lang3.StringUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.util.vector.Vector2f;
-import java.awt.*;
+import java.awt.Color;
import java.lang.reflect.InvocationTargetException;
-import java.util.List;
import java.util.*;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -61,2276 +74,2800 @@
import static io.github.moulberry.notenoughupdates.util.GuiTextures.*;
public class NEUOverlay extends Gui {
-
- private static final ResourceLocation SUPERGEHEIMNISVERMOGEN = new ResourceLocation("notenoughupdates:supersecretassets/bald.png");
- private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png");
- private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png");
-
- private NEUManager manager;
-
- private String mobRegex = ".*?((_MONSTER)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$";
- private String petRegex = ".*?;[0-5]$";
-
- private ResourceLocation[] sortIcons = new ResourceLocation[] {
- sort_all, sort_mob, sort_pet, sort_tool, sort_armor, sort_accessory
- };
- private ResourceLocation[] sortIconsActive = new ResourceLocation[] {
- sort_all_active, sort_mob_active, sort_pet_active, sort_tool_active, sort_armor_active, sort_accessory_active
- };
-
- private ResourceLocation[] orderIcons = new ResourceLocation[] {
- order_alphabetical, order_rarity, order_value
- };
- private ResourceLocation[] orderIconsActive = new ResourceLocation[] {
- order_alphabetical_active, order_rarity_active, order_value_active
- };
-
- //Various constants used for GUI structure
- private final int searchBarYOffset = 10;
- private final int searchBarPadding = 2;
-
- private float oldWidthMult = 0;
-
- public static final int ITEM_PADDING = 4;
- public static final int ITEM_SIZE = 16;
-
- private Color bg = new Color(90, 90, 140, 50);
- private Color fg = new Color(100,100,100, 255);
-
- private InfoPane activeInfoPane = null;
-
- private TreeSet searchedItems = null;
- private final List searchedItemsArr = new ArrayList<>();
-
- private HashMap> searchedItemsSubgroup = new HashMap<>();
-
- private long selectedItemMillis = 0;
- private int selectedItemGroupX = -1;
- private int selectedItemGroupY = -1;
- private List selectedItemGroup = null;
-
- private boolean itemPaneOpen = false;
-
- private int page = 0;
-
- private LerpingFloat itemPaneOffsetFactor = new LerpingFloat(1);
- private LerpingInteger itemPaneTabOffset = new LerpingInteger(20, 50);
- private LerpingFloat infoPaneOffsetFactor = new LerpingFloat(0);
-
- public boolean searchMode = false;
- private long millisLastLeftClick = 0;
- private long millisLastMouseMove = 0;
- private int lastMouseX = 0;
- private int lastMouseY = 0;
-
- public static final int overlayColourDark = new Color(0, 0, 0, 120).getRGB();
- public static final int overlayColourLight = new Color(255, 255, 255, 120).getRGB();
-
- boolean mouseDown = false;
-
- private boolean redrawItems = false;
-
- private boolean searchBarHasFocus = false;
- private GuiTextField textField = new GuiTextField(0, null, 0, 0, 0, 0);
-
- private static final int COMPARE_MODE_ALPHABETICAL = 0;
- private static final int COMPARE_MODE_RARITY = 1;
- private static final int COMPARE_MODE_VALUE = 2;
-
- private static final int SORT_MODE_ALL = 0;
- private static final int SORT_MODE_MOB = 1;
- private static final int SORT_MODE_PET = 2;
- private static final int SORT_MODE_TOOL = 3;
- private static final int SORT_MODE_ARMOR = 4;
- private static final int SORT_MODE_ACCESSORY = 5;
-
- private boolean disabled = false;
-
- private int lastScreenWidth;
- private int lastScreenHeight;
- private int lastScale;
-
- private List textToDisplay = null;
-
- public MBGuiGroupFloating guiGroup = null;
-
- public NEUOverlay(NEUManager manager) {
- this.manager = manager;
- textField.setFocused(true);
- textField.setCanLoseFocus(false);
-
- guiGroup = createGuiGroup();
- }
-
- private MBGuiElement createSearchBar() {
- return new MBGuiElement() {
- public int getWidth() {
- int paddingUnscaled = getPaddingUnscaled();
-
- return getSearchBarXSize() + 2*paddingUnscaled;
- }
-
- public int getHeight() {
- int paddingUnscaled = getPaddingUnscaled();
-
- return getSearchBarYSize() + 2*paddingUnscaled;
- }
-
- @Override
- public void mouseClick(float x, float y, int mouseX, int mouseY) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- return;
- }
- if(Mouse.getEventButtonState()) {
- setSearchBarFocus(true);
- if(Mouse.getEventButton() == 1) { //Right mouse button down
- textField.setText("");
- updateSearch();
- } else {
- if(System.currentTimeMillis() - millisLastLeftClick < 300) {
- searchMode = !searchMode;
- if (searchMode && NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus) {
- NEUEventListener.displayNotification(Lists.newArrayList(
- "\u00a7eSearch Highlight",
- "\u00a77In this mode NEU will gray out non matching items in",
- "\u00a77your inventory or chests.",
- "\u00a77This allows you easily find items as the item will stand out.",
- "\u00a77To toggle this please double click on the search bar in your inventory.",
- "\u00a77",
- "\u00a77Press X on your keyboard to close this notifcation"), true, true);
- NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus = false;
-
- }
- }
- textField.setCursorPosition(getClickedIndex(mouseX, mouseY));
- millisLastLeftClick = System.currentTimeMillis();
- }
- }
- }
-
- @Override
- public void mouseClickOutside() {
- setSearchBarFocus(false);
- }
-
- @Override
- public void render(float x, float y) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- return;
- }
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- int paddingUnscaled = getPaddingUnscaled();
-
- GlStateManager.color(1, 1, 1, 1);
- if(searchMode) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_BAR_GOLD);
- } else {
- Minecraft.getMinecraft().getTextureManager().bindTexture(SEARCH_BAR);
- }
-
- int w = getWidth();
- int h = getHeight();
-
- for(int yIndex=0; yIndex<=2; yIndex++) {
- for(int xIndex=0; xIndex<=2; xIndex++) {
- float uMin = 0;
- float uMax = 4/20f;
- int partX = (int)x;
- int partW = 4;
- if(xIndex == 1) {
- partX += 4;
- uMin = 4/20f;
- uMax = 16/20f;
- partW = w-8;
- } else if(xIndex == 2) {
- partX += w-4;
- uMin = 16/20f;
- uMax = 20/20f;
- }
-
- float vMin = 0;
- float vMax = 4/20f;
- int partY = (int)y;
- int partH = 4;
- if(yIndex == 1) {
- partY += 4;
- vMin = 4/20f;
- vMax = 16/20f;
- partH = h-8;
- } else if(yIndex == 2) {
- partY += h-4;
- vMin = 16/20f;
- vMax = 20/20f;
- }
-
- Utils.drawTexturedRect(partX, partY, partW, partH, uMin, uMax, vMin, vMax, GL11.GL_NEAREST);
- }
- }
-
- //Search bar text
- fr.drawString(textField.getText(), (int)x + 5,
- (int) y-4 + getHeight()/2, Color.WHITE.getRGB());
-
- //Determines position of cursor. Cursor blinks on and off every 500ms.
- if(searchBarHasFocus && System.currentTimeMillis()%1000>500) {
- String textBeforeCursor = textField.getText().substring(0, textField.getCursorPosition());
- int textBeforeCursorWidth = fr.getStringWidth(textBeforeCursor);
- drawRect((int)x + 5 + textBeforeCursorWidth,
- (int)y-5 + getHeight()/2,
- (int)x + 5 + textBeforeCursorWidth+1,
- (int)y-4+9 + getHeight()/2, Color.WHITE.getRGB());
- }
-
- String selectedText = textField.getSelectedText();
- if(!selectedText.isEmpty()) {
- int selectionWidth = fr.getStringWidth(selectedText);
-
- int leftIndex = Math.min(textField.getCursorPosition(), textField.getSelectionEnd());
- String textBeforeSelection = textField.getText().substring(0, leftIndex);
- int textBeforeSelectionWidth = fr.getStringWidth(textBeforeSelection);
-
- drawRect((int)x + 5 + textBeforeSelectionWidth,
- (int)y-5 + getHeight()/2,
- (int)x + 5 + textBeforeSelectionWidth + selectionWidth,
- (int)y-4+9 + getHeight()/2, Color.LIGHT_GRAY.getRGB());
-
- fr.drawString(selectedText,
- (int)x + 5 + textBeforeSelectionWidth,
- (int)y-4 + getHeight()/2, Color.BLACK.getRGB());
- }
-
- }
-
- @Override
- public void recalculate() {
- }
- };
- }
-
- private MBGuiElement createSettingsButton(NEUOverlay overlay) {
- return new MBGuiElement() {
- @Override
- public int getWidth() {
- return getSearchBarYSize()+getPaddingUnscaled()*2;
- }
-
- @Override
- public int getHeight() {
- return getWidth();
- }
-
- @Override
- public void recalculate() {
- }
-
- @Override
- public void mouseClick(float x, float y, int mouseX, int mouseY) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.enableSettingsButton) {
- return;
- }
- if(Mouse.getEventButtonState()) {
- NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(NEUConfigEditor.editor);
- }
- }
-
- @Override
- public void mouseClickOutside() {
- }
-
- @Override
- public void render(float x, float y) {
- int paddingUnscaled = getPaddingUnscaled();
- int searchYSize = getSearchBarYSize();
-
-
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.enableSettingsButton) {
- return;
- }
- Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(x, y,
- searchYSize + paddingUnscaled * 2, searchYSize + paddingUnscaled * 2, GL11.GL_NEAREST);
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(settings);
- GlStateManager.color(1f, 1f, 1f, 1f);
- Utils.drawTexturedRect((int) x + paddingUnscaled, (int) y + paddingUnscaled,
- searchYSize, searchYSize);
-
- GlStateManager.bindTexture(0);
- }
- };
- }
-
- private MBGuiElement createHelpButton(NEUOverlay overlay) {
- return new MBGuiElement() {
- @Override
- public int getWidth() {
- return getSearchBarYSize()+getPaddingUnscaled()*2;
- }
-
- @Override
- public int getHeight() {
- return getWidth();
- }
-
- @Override
- public void recalculate() {
- }
-
- @Override
- public void mouseClick(float x, float y, int mouseX, int mouseY) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.enableHelpButton){
- return;
- }
- if(Mouse.getEventButtonState()) {
- //displayInformationPane(HTMLInfoPane.createFromWikiUrl(overlay, manager, "Help",
- // "https://moulberry.github.io/files/neu_help.html"));
- //Minecraft.getMinecraft().displayGuiScreen(new HelpGUI());
- ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/neuhelp");
- Utils.playPressSound();
- }
- }
-
- @Override
- public void mouseClickOutside() {
- }
-
- @Override
- public void render(float x, float y) {
- int paddingUnscaled = getPaddingUnscaled();
- int searchYSize = getSearchBarYSize();
-
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.enableHelpButton) {
- return;
- }
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(x, y,
- searchYSize + paddingUnscaled * 2, searchYSize + paddingUnscaled * 2, GL11.GL_NEAREST);
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(help);
- GlStateManager.color(1f, 1f, 1f, 1f);
- Utils.drawTexturedRect((int) x + paddingUnscaled, (int) y + paddingUnscaled,
- getSearchBarYSize(), getSearchBarYSize());
- GlStateManager.bindTexture(0);
-
- }
- };
- }
-
- private MBGuiElement createQuickCommand(String quickCommandStr) {
- return new MBGuiElement() {
- @Override
- public int getWidth() {
- return getSearchBarYSize()+getPaddingUnscaled()*2;
- }
-
- @Override
- public int getHeight() {
- return getWidth();
- }
-
- @Override
- public void recalculate() {
- }
-
- @Override
- public void mouseClick(float x, float y, int mouseX, int mouseY) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.quickCommands) return;
-
- if((NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType != 0 && Mouse.getEventButtonState()) ||
- (NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType == 0 && !Mouse.getEventButtonState() && Mouse.getEventButton() != -1)) {
- if(quickCommandStr.contains(":")) {
- String command = quickCommandStr.split(":")[0].trim();
- if(command.startsWith("/")) {
- NotEnoughUpdates.INSTANCE.sendChatMessage(command);
- } else {
- ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/"+command);
- }
- Utils.playPressSound();
- }
- }
- }
-
- @Override
- public void mouseClickOutside() {
- }
-
- @Override
- public void render(float x, float y) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.quickCommands) return;
-
- int paddingUnscaled = getPaddingUnscaled();
- int bigItemSize = getSearchBarYSize();
-
- String[] quickCommandStrSplit = quickCommandStr.split(":");
- if(quickCommandStrSplit.length!=3) {
- return;
- }
- String display = quickCommandStrSplit[2];
- ItemStack render = null;
- float extraScale = 1;
- if(display.length() > 20) { //Custom head
- render = new ItemStack(Items.skull, 1, 3);
- NBTTagCompound nbt = new NBTTagCompound();
- NBTTagCompound skullOwner = new NBTTagCompound();
- NBTTagCompound properties = new NBTTagCompound();
- NBTTagList textures = new NBTTagList();
- NBTTagCompound textures_0 = new NBTTagCompound();
-
- String uuid = UUID.nameUUIDFromBytes(display.getBytes()).toString();
- skullOwner.setString("Id", uuid);
- skullOwner.setString("Name", uuid);
-
- textures_0.setString("Value", display);
- textures.appendTag(textures_0);
-
- properties.setTag("textures", textures);
- skullOwner.setTag("Properties", properties);
- nbt.setTag("SkullOwner", skullOwner);
- render.setTagCompound(nbt);
-
- extraScale = 1.3f;
- } else if(manager.getItemInformation().containsKey(display)) {
- render = manager.jsonToStack(manager.getItemInformation().get(display), true, true);
- } else {
- Item item = Item.itemRegistry.getObject(new ResourceLocation(display.toLowerCase()));
- if(item != null) {
- render = new ItemStack(item);
- }
- }
- if(render != null) {
- NBTTagCompound tag = render.getTagCompound() != null ? render.getTagCompound() : new NBTTagCompound();
- tag.setString("qc_id", quickCommandStrSplit[0].toLowerCase().trim());
- render.setTagCompound(tag);
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(x, y,
- bigItemSize + paddingUnscaled*2, bigItemSize + paddingUnscaled*2, GL11.GL_NEAREST);
-
- int mouseX = Mouse.getX() * Utils.peekGuiScale().getScaledWidth() / Minecraft.getMinecraft().displayWidth;
- int mouseY = Utils.peekGuiScale().getScaledHeight() - Mouse.getY() * Utils.peekGuiScale().getScaledHeight() / Minecraft.getMinecraft().displayHeight - 1;
-
- if(mouseX > x && mouseX < x+bigItemSize) {
- if(mouseY > y && mouseY < y+bigItemSize) {
- textToDisplay = new ArrayList<>();
- textToDisplay.add(EnumChatFormatting.GRAY+quickCommandStrSplit[1]);
- }
- }
-
- GlStateManager.enableDepth();
- float itemScale = bigItemSize/(float)ITEM_SIZE*extraScale;
- GlStateManager.pushMatrix();
- GlStateManager.scale(itemScale, itemScale, 1);
- GlStateManager.translate((x-(extraScale-1)*bigItemSize/2+paddingUnscaled) /itemScale,
- (y-(extraScale-1)*bigItemSize/2+paddingUnscaled)/itemScale, 0f);
- Utils.drawItemStack(render, 0, 0);
- GlStateManager.popMatrix();
- }
- }
- };
- }
-
- private MBGuiGroupAligned createQuickCommandGroup() {
- List children = new ArrayList<>();
- for(String quickCommand : NotEnoughUpdates.INSTANCE.config.hidden.quickCommands) {
- children.add(createQuickCommand(quickCommand));
- }
- return new MBGuiGroupAligned(children, false) {
- public int getPadding() {
- return getPaddingUnscaled()*4;
- }
- };
- }
-
- private MBGuiGroupAligned createSearchBarGroup() {
- List children = Lists.newArrayList(createSettingsButton(this), createSearchBar(), createHelpButton(this));
- return new MBGuiGroupAligned(children, false) {
- public int getPadding() {
- return getPaddingUnscaled()*4;
- }
- };
- }
-
- private MBGuiGroupFloating createGuiGroup() {
- LinkedHashMap map = new LinkedHashMap<>();
-
- MBAnchorPoint searchBarAnchor = MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlaySearchBar);
- MBAnchorPoint quickCommandAnchor = MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlayQuickCommand);
-
- searchBarAnchor = searchBarAnchor != null ? searchBarAnchor :
- new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0, -searchBarYOffset));
- quickCommandAnchor = quickCommandAnchor != null ? quickCommandAnchor :
- new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0,
- -searchBarYOffset-getSearchBarYSize()-getPaddingUnscaled()*4));
-
- map.put(createSearchBarGroup(), searchBarAnchor);
- map.put(createQuickCommandGroup(), quickCommandAnchor);
-
- return new MBGuiGroupFloating(Utils.peekGuiScale().getScaledWidth(), Utils.peekGuiScale().getScaledHeight(), map);
- }
-
- public void resetAnchors(boolean onlyIfNull) {
- MBAnchorPoint searchBarAnchor = MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlaySearchBar);
- MBAnchorPoint quickCommandAnchor = MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlayQuickCommand);
-
- if(onlyIfNull) {
- searchBarAnchor = searchBarAnchor != null ? null :
- new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0, -searchBarYOffset));
- quickCommandAnchor = quickCommandAnchor != null ? null :
- new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0,
- -searchBarYOffset-getSearchBarYSize()-getPaddingUnscaled()*4));
- } else {
- searchBarAnchor = searchBarAnchor != null ? searchBarAnchor :
- new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0, -searchBarYOffset));
- quickCommandAnchor = quickCommandAnchor != null ? quickCommandAnchor :
- new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0,
- -searchBarYOffset-getSearchBarYSize()-getPaddingUnscaled()*4));
- }
-
-
- int index = 0;
- Set set = new LinkedHashSet<>(guiGroup.getChildrenMap().keySet());
- for(MBGuiElement element : set) {
- switch(index) {
- case 0:
- if(searchBarAnchor == null) continue;
- guiGroup.getChildrenMap().get(element).anchorPoint = searchBarAnchor.anchorPoint;
- guiGroup.getChildrenMap().get(element).offset = searchBarAnchor.offset;
- break;
- case 1:
- if(quickCommandAnchor == null) continue;
- guiGroup.getChildrenMap().get(element).anchorPoint = quickCommandAnchor.anchorPoint;
- guiGroup.getChildrenMap().get(element).offset = quickCommandAnchor.offset;
- break;
- }
- index++;
- }
- }
-
- /**
- * Disables searchBarFocus and resets the item pane position. Called whenever NEUOverlay is opened.
- */
- public void reset() {
- searchBarHasFocus = false;
- if(!(searchMode || (NotEnoughUpdates.INSTANCE.config.itemlist.keepopen && itemPaneOpen))) {
- itemPaneOpen = false;
- itemPaneOffsetFactor.setValue(1);
- itemPaneTabOffset.setValue(20);
- }
- if(activeInfoPane != null) activeInfoPane.reset();
- guiGroup.recalculate();
- }
-
- /**
- * Calls #displayInformationPane with a HTMLInfoPane created from item.info and item.infoType.
- */
- public void showInfo(JsonObject item) {
- if(item.has("info") && item.has("infoType")) {
- JsonArray lore = item.get("info").getAsJsonArray();
- String[] loreA = new String[lore.size()];
- for (int i = 0; i < lore.size(); i++) loreA[i] = lore.get(i).getAsString();
- String loreS = StringUtils.join(loreA, "\n");
-
- String internalname = item.get("internalname").getAsString();
- String name = item.get("displayname").getAsString();
- switch(item.get("infoType").getAsString()) {
- case "WIKI_URL":
- displayInformationPane(HTMLInfoPane.createFromWikiUrl(this, manager, name, loreS));
- return;
- case "WIKI":
- displayInformationPane(HTMLInfoPane.createFromWiki(this, manager, name, internalname, loreS));
- return;
- case "HTML":
- displayInformationPane(new HTMLInfoPane(this, manager, name, internalname, loreS));
- return;
- }
- displayInformationPane(new TextInfoPane(this, manager, name, loreS));
- }
- }
-
- public void mouseInputInv() {
- if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer) {
- if(Mouse.getEventButton() == manager.keybindItemSelect.getKeyCode()+100 && NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- Slot slot = Utils.getSlotUnderMouse((GuiContainer)Minecraft.getMinecraft().currentScreen);
- if(slot != null) {
- ItemStack hover = slot.getStack();
- if(hover != null) {
- textField.setText("id:"+manager.getInternalNameForItem(hover));
- itemPaneOpen = true;
- updateSearch();
- }
- }
- }
- }
- }
-
- /**
- * Handles the mouse input, cancelling the forge event if a NEU gui element is clicked.
- */
- public boolean mouseInput() {
- if(disabled) {
- return false;
- }
-
- Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
-
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
-
- //if(lastMouseX != mouseX || lastMouseY != mouseY) {
- // millisLastMouseMove = System.currentTimeMillis();
- //}
-
- lastMouseX = mouseX;
- lastMouseY = mouseY;
-
- if(Mouse.getEventButtonState()) {
- mouseDown = true;
- } else if(Mouse.getEventButton() != -1) {
- mouseDown = false;
- }
-
- //Unfocuses the search bar by default. Search bar is focused if the click is on the bar itself.
- if(Mouse.getEventButtonState()) setSearchBarFocus(false);
-
- guiGroup.mouseClick(0, 0, mouseX, mouseY);
-
- if(selectedItemGroup != null) {
- int selectedX = Math.min(selectedItemGroupX, width-getBoxPadding()-18*selectedItemGroup.size());
- if(mouseY > selectedItemGroupY+17 && mouseY < selectedItemGroupY+35) {
- for(int i=0; i= selectedX-1+18*i && mouseX <= selectedX+17+18*i) {
- JsonObject item = selectedItemGroup.get(i);
- if (item != null) {
- if(Mouse.getEventButton() == 0) {
- manager.showRecipe(item);
- } else if(Mouse.getEventButton() == 1) {
- showInfo(item);
- } else if(Mouse.getEventButton() == manager.keybindItemSelect.getKeyCode()+100 && NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- textField.setText("id:"+item.get("internalname").getAsString());
- updateSearch();
- searchMode = true;
- }
- }
- Utils.pushGuiScale(-1);
- return true;
- }
- }
- }
- }
-
- //Item selection (right) gui
- if(mouseX > width*getItemPaneOffsetFactor()) {
- if(!Mouse.getEventButtonState()) {
- Utils.pushGuiScale(-1);
- return true; //End early if the mouse isn't pressed, but still cancel event.
- }
-
- AtomicBoolean clickedItem = new AtomicBoolean(false);
- iterateItemSlots(new ItemSlotConsumer() {
- public void consume(int x, int y, int id) {
- if(mouseX >= x-1 && mouseX <= x+ITEM_SIZE+1) {
- if(mouseY >= y-1 && mouseY <= y+ITEM_SIZE+1) {
- clickedItem.set(true);
-
- JsonObject item = getSearchedItemPage(id);
- if (item != null) {
- if(Mouse.getEventButton() == 0) {
- manager.showRecipe(item);
- } else if(Mouse.getEventButton() == 1) {
- showInfo(item);
- } else if(Mouse.getEventButton() == manager.keybindItemSelect.getKeyCode()+100 && NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- textField.setText("id:"+item.get("internalname").getAsString());
- updateSearch();
- searchMode = true;
- }
- }
- }
- }
- }
- });
- if(!clickedItem.get()) {
- int paneWidth = (int)(width/3*getWidthMult());
- int leftSide = (int)(width*getItemPaneOffsetFactor());
- int rightSide = leftSide+paneWidth-getBoxPadding()-getItemBoxXPadding();
- leftSide = leftSide+getBoxPadding()+getItemBoxXPadding();
-
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- int maxPages = getMaxPages();
- String name = Utils.peekGuiScale().getScaleFactor()<4?"Page: ":"";
- float maxStrLen = fr.getStringWidth(EnumChatFormatting.BOLD+name + maxPages + "/" + maxPages);
- float maxButtonXSize = (rightSide-leftSide+2 - maxStrLen*0.5f - 10)/2f;
- int buttonXSize = (int)Math.min(maxButtonXSize, getSearchBarYSize()*480/160f);
- int ySize = (int)(buttonXSize/480f*160);
- int yOffset = (int)((getSearchBarYSize()-ySize)/2f);
- int top = getBoxPadding()+yOffset;
-
- if(mouseY >= top && mouseY <= top+ySize) {
- int leftPrev = leftSide-1;
- if(mouseX > leftPrev && mouseX < leftPrev+buttonXSize) { //"Previous" button
- setPage(page-1);
- Utils.playPressSound();
- }
- int leftNext = rightSide+1-buttonXSize;
- if(mouseX > leftNext && mouseX < leftNext+buttonXSize) { //"Next" button
- setPage(page+1);
- Utils.playPressSound();
- }
- }
-
- float sortIconsMinX = (sortIcons.length+orderIcons.length)*(ITEM_SIZE+ITEM_PADDING)+ITEM_SIZE;
- float availableX = rightSide-leftSide;
- float sortOrderScaleFactor = Math.min(1, availableX / sortIconsMinX);
-
- int scaledITEM_SIZE = (int)(ITEM_SIZE*sortOrderScaleFactor);
- int scaledItemPaddedSize = (int)((ITEM_SIZE+ITEM_PADDING)*sortOrderScaleFactor);
- int iconTop = height-getBoxPadding()-(ITEM_SIZE+scaledITEM_SIZE)/2-1;
-
- if(mouseY >= iconTop && mouseY <= iconTop+scaledITEM_SIZE) {
- for(int i=0; i= orderIconX && mouseX <= orderIconX+scaledITEM_SIZE) {
- if(Mouse.getEventButton() == 0) {
- NotEnoughUpdates.INSTANCE.config.hidden.compareMode = i;
- updateSearch();
- Utils.playPressSound();
- } else if(Mouse.getEventButton() == 1) {
- NotEnoughUpdates.INSTANCE.config.hidden.compareAscending.set(i,
- !NotEnoughUpdates.INSTANCE.config.hidden.compareAscending.get(i));
- updateSearch();
- Utils.playPressSound();
- }
- }
- }
-
- for(int i=0; i= sortIconX && mouseX <= sortIconX+scaledITEM_SIZE) {
- NotEnoughUpdates.INSTANCE.config.hidden.sortMode = i;
- updateSearch();
- Utils.playPressSound();
- }
- }
- }
- }
- Utils.pushGuiScale(-1);
- return true;
- }
-
- //Clicking on "close info pane" button
- if(mouseX > width*getInfoPaneOffsetFactor()-getBoxPadding()-8 && mouseX < width*getInfoPaneOffsetFactor()-getBoxPadding()+8) {
- if(mouseY > getBoxPadding()-8 && mouseY < getBoxPadding()+8) {
- if(Mouse.getEventButtonState() && Mouse.getEventButton() < 2) { //Left or right click up
- displayInformationPane(null);
- Utils.pushGuiScale(-1);
- return true;
- }
- }
- }
-
- if(activeInfoPane != null) {
- if(mouseX < width*getInfoPaneOffsetFactor()) {
- activeInfoPane.mouseInput(width, height, mouseX, mouseY, mouseDown);
- Utils.pushGuiScale(-1);
- return true;
- } else if(Mouse.getEventButton() <= 1 && Mouse.getEventButtonState()) { //Left or right click
- activeInfoPane.mouseInputOutside();
- }
- }
-
- Utils.pushGuiScale(-1);
- return false;
- }
-
- public int getPaddingUnscaled() {
- int paddingUnscaled = searchBarPadding/Utils.peekGuiScale().getScaleFactor();
- if(paddingUnscaled < 1) paddingUnscaled = 1;
-
- return paddingUnscaled;
- }
-
- public GuiTextField getTextField() {
- return textField;
- }
-
- /**
- * Returns searchBarXSize, scaled by 0.8 if gui scale == AUTO.
- */
- public int getSearchBarXSize() {
- int searchBarXSize = NotEnoughUpdates.INSTANCE.config.toolbar.searchBarWidth;
- if(Utils.peekGuiScale().getScaleFactor()==4) return (int)(searchBarXSize*0.8);
- return searchBarXSize;
- }
-
- /**
- * Sets the activeInfoPane and sets the target of the infoPaneOffsetFactor to make the infoPane "slide" out.
- */
- public void displayInformationPane(InfoPane pane) {
- if(pane == null) {
- infoPaneOffsetFactor.setTarget(0);
- } else {
- infoPaneOffsetFactor.setTarget(1/3f);
- }
- infoPaneOffsetFactor.resetTimer();
- this.activeInfoPane = pane;
- }
-
- public InfoPane getActiveInfoPane() {
- return activeInfoPane;
- }
-
- /**
- * Finds the index of the character inside the search bar that was clicked, used to set the caret.
- */
- public int getClickedIndex(int mouseX, int mouseY) {
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
-
- int xComp = mouseX - (width/2 - getSearchBarXSize()/2 + 5);
-
- String trimmed = Minecraft.getMinecraft().fontRendererObj.trimStringToWidth(textField.getText(), xComp);
- int linePos = trimmed.length();
- if(linePos != textField.getText().length()) {
- char after = textField.getText().charAt(linePos);
- int trimmedWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(trimmed);
- int charWidth = Minecraft.getMinecraft().fontRendererObj.getCharWidth(after);
- if(trimmedWidth + charWidth/2 < xComp-5) {
- linePos++;
- }
- }
- return linePos;
- }
-
- public void setSearchBarFocus(boolean focus) {
- if(focus) {
- itemPaneOpen = true;
- }
- searchBarHasFocus = focus;
- }
-
- /**
- * Handles the keyboard input, cancelling the forge event if the search bar has focus.
- */
- public boolean keyboardInput(boolean hoverInv) {
- if(Minecraft.getMinecraft().currentScreen == null) return false;
- Keyboard.enableRepeatEvents(true);
-
- int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter()+256 : Keyboard.getEventKey();
-
- if(disabled) {
- if(Keyboard.getEventKeyState() && keyPressed == manager.keybindToggleDisplay.getKeyCode()) {
- disabled = !disabled;
- }
- return false;
- }
-
- if(Keyboard.isKeyDown(Keyboard.KEY_Y) && NotEnoughUpdates.INSTANCE.config.hidden.dev) {
- displayInformationPane(new DevInfoPane(this, manager));
- }
-
- if(Keyboard.getEventKeyState()) {
- if(!NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- searchBarHasFocus = false;
- }
- if(searchBarHasFocus) {
- if(keyPressed == 1) {
- searchBarHasFocus = false;
- } else {
- if(textField.textboxKeyTyped(Keyboard.getEventCharacter(), keyPressed)) {
- updateSearch();
- }
- }
- } else {
- if(activeInfoPane != null) {
- if(activeInfoPane.keyboardInput()) {
- return true;
- }
- }
-
- if(keyPressed == manager.keybindClosePanes.getKeyCode()) {
- itemPaneOffsetFactor.setValue(1);
- itemPaneTabOffset.setValue(20);
- itemPaneOpen = false;
- displayInformationPane(null);
- }
-
- if(keyPressed == manager.keybindToggleDisplay.getKeyCode()) {
- disabled = !disabled;
- return true;
- }
-
- AtomicReference internalname = new AtomicReference<>(null);
- AtomicReference itemstack = new AtomicReference<>(null);
- if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer &&
- Utils.getSlotUnderMouse((GuiContainer)Minecraft.getMinecraft().currentScreen) != null) {
- Slot slot = Utils.getSlotUnderMouse((GuiContainer)Minecraft.getMinecraft().currentScreen);
- ItemStack hover = slot.getStack();
- if(hover != null) {
- internalname.set(manager.getInternalNameForItem(hover));
- itemstack.set(hover);
- }
- } else if(!hoverInv) {
- Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
-
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
-
- if (selectedItemGroup != null) {
- int selectedX = Math.min(selectedItemGroupX, width - getBoxPadding() - 18 * selectedItemGroup.size());
-
- if (mouseY > selectedItemGroupY + 17 && mouseY < selectedItemGroupY + 35) {
- for (int i = 0; i < selectedItemGroup.size(); i++) {
- if (mouseX >= selectedX - 1 + 18 * i && mouseX <= selectedX + 17 + 18 * i) {
- internalname.set(selectedItemGroup.get(i).get("internalname").getAsString());
- }
- }
- }
- } else {
- iterateItemSlots(new ItemSlotConsumer() {
- public void consume(int x, int y, int id) {
- if (mouseX >= x - 1 && mouseX <= x + ITEM_SIZE + 1) {
- if (mouseY >= y - 1 && mouseY <= y + ITEM_SIZE + 1) {
- JsonObject json = getSearchedItemPage(id);
- if (json != null) internalname.set(json.get("internalname").getAsString());
- }
- }
- }
- });
- }
-
-
- Utils.pushGuiScale(-1);
- }
- if(internalname.get() != null) {
- if(itemstack.get() != null) {
- if(NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && Keyboard.getEventCharacter() == 'k') {
- Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager,
- internalname.get(), manager.getJsonForItem(itemstack.get())));
- return true;
- }
- }
- JsonObject item = manager.getItemInformation().get(internalname.get());
- if(item != null) {
- if(keyPressed == manager.keybindViewUsages.getKeyCode()) {
- manager.displayGuiItemUsages(internalname.get());
- return true;
- } else if(keyPressed == manager.keybindFavourite.getKeyCode()) {
- toggleFavourite(item.get("internalname").getAsString());
- return true;
- } else if(keyPressed == manager.keybindViewRecipe.getKeyCode()) {
- manager.showRecipe(item);
- return true;
- } else if(keyPressed == manager.keybindGive.getKeyCode()) {
- if(Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) {
- Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory(
- manager.jsonToStack(item));
- }
- } else if(NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && Keyboard.getEventCharacter() == 'k') {
- Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager,
- internalname.get(), item));
- return true;
- } else if(keyPressed == manager.keybindItemSelect.getKeyCode() && NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
- textField.setText("id:"+internalname.get());
- itemPaneOpen = true;
- updateSearch();
- }
- }
- }
- }
- }
-
- return searchBarHasFocus; //Cancels keyboard events if the search bar has focus
- }
-
- public void toggleFavourite(String internalname) {
- if(getFavourites().contains(internalname)) {
- getFavourites().remove(internalname);
- } else {
- getFavourites().add(internalname);
- }
- updateSearch();
- }
-
- String[] rarityArr = new String[] {
- EnumChatFormatting.WHITE+EnumChatFormatting.BOLD.toString()+"COMMON",
- EnumChatFormatting.GREEN+EnumChatFormatting.BOLD.toString()+"UNCOMMON",
- EnumChatFormatting.BLUE+EnumChatFormatting.BOLD.toString()+"RARE",
- EnumChatFormatting.DARK_PURPLE+EnumChatFormatting.BOLD.toString()+"EPIC",
- EnumChatFormatting.GOLD+EnumChatFormatting.BOLD.toString()+"LEGENDARY",
- EnumChatFormatting.LIGHT_PURPLE+EnumChatFormatting.BOLD.toString()+"MYTHIC",
- EnumChatFormatting.RED+EnumChatFormatting.BOLD.toString()+"SPECIAL",
- };
-
- /**
- * Finds the rarity from the lore of an item.
- * -1 = UNKNOWN
- * 0 = COMMON
- * 1 = UNCOMMON
- * 2 = RARE
- * 3 = EPIC
- * 4 = LEGENDARY
- * 5 = MYTHIC
- * 6 = SPECIAL
- */
- public int getRarity(JsonArray lore) {
- for(int i=lore.size()-1; i>=0; i--) {
- String line = lore.get(i).getAsString();
-
- for(int j=0; j getCompareAscending() {
- return NotEnoughUpdates.INSTANCE.config.hidden.compareAscending;
- }
- private List getFavourites() {
- return NotEnoughUpdates.INSTANCE.config.hidden.favourites;
- }
-
- /**
- * Creates an item comparator used to sort the list of items according to the favourite set then compare mode.
- * Defaults to alphabetical sorting if the above factors cannot distinguish between two items.
- */
- private Comparator getItemComparator() {
- return (o1, o2) -> {
- //1 (mult) if o1 should appear after o2
- //-1 (-mult) if o2 should appear after o1
- if(getFavourites().contains(o1.get("internalname").getAsString()) && !getFavourites().contains(o2.get("internalname").getAsString())) {
- return -1;
- }
- if(!getFavourites().contains(o1.get("internalname").getAsString()) && getFavourites().contains(o2.get("internalname").getAsString())) {
- return 1;
- }
-
- int mult = getCompareAscending().get(getCompareMode()) ? 1 : -1;
- if(getCompareMode() == COMPARE_MODE_RARITY) {
- int rarity1 = getRarity(o1.get("lore").getAsJsonArray());
- int rarity2 = getRarity(o2.get("lore").getAsJsonArray());
-
- if(rarity1 < rarity2) return mult;
- if(rarity1 > rarity2) return -mult;
- } else if(getCompareMode() == COMPARE_MODE_VALUE) {
- String internal1 = o1.get("internalname").getAsString();
- String internal2 = o2.get("internalname").getAsString();
-
- float cost1 = manager.auctionManager.getLowestBin(internal1);
- float cost2 = manager.auctionManager.getLowestBin(internal2);
-
-
- if(cost1 < cost2) return mult;
- if(cost1 > cost2) return -mult;
- }
-
- String i1 = o1.get("internalname").getAsString();
- String[] split1 = i1.split("_");
- String last1 = split1[split1.length-1];
- String start1 = i1.substring(0, i1.length()-last1.length());
-
- String i2 = o2.get("internalname").getAsString();
- String[] split2 = i2.split("_");
- String last2 = split2[split2.length-1];
- String start2 = i2.substring(0, i2.length()-last2.length());
-
- mult = getCompareAscending().get(COMPARE_MODE_ALPHABETICAL) ? 1 : -1;
- if(start1.equals(start2)) {
- String[] order = new String[]{"HELMET","CHESTPLATE","LEGGINGS","BOOTS"};
- int type1 = checkItemType(o1.get("lore").getAsJsonArray(), order);
- int type2 = checkItemType(o2.get("lore").getAsJsonArray(), order);
-
-
- if(type1 < type2) return -mult;
- if(type1 > type2) return mult;
- }
-
- int nameComp = mult*o1.get("displayname").getAsString().replaceAll("(?i)\\u00A7.", "")
- .compareTo(o2.get("displayname").getAsString().replaceAll("(?i)\\u00A7.", ""));
- if(nameComp != 0) {
- return nameComp;
- }
- return mult*o1.get("internalname").getAsString().compareTo(o2.get("internalname").getAsString());
- };
- }
-
- /**
- * Checks whether an item matches a certain type, i.e. whether the item lore ends in "{rarity} {item type}"
- * eg. "SHOVEL" will return >0 for "COMMON SHOVEL", "EPIC SHOVEL", etc.
- * @return the index of the type that matched, or -1 otherwise.
- */
- public int checkItemType(JsonArray lore, String... typeMatches) {
- for(int i=lore.size()-1; i>=0; i--) {
- String line = lore.get(i).getAsString();
-
- for(String rarity : rarityArr) {
- for(int j=0; j= 0;
- } else if(getSortMode() == SORT_MODE_ARMOR) {
- return checkItemType(item.get("lore").getAsJsonArray(), "HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS", "DUNGEON HELMET", "DUNGEON CHESTPLATE", "DUNGEON LEGGINGS", "DUNGEON BOOTS") >= 0;
- } else if(getSortMode() == SORT_MODE_ACCESSORY) {
- return checkItemType(item.get("lore").getAsJsonArray(), "ACCESSORY", "HATCCESSORY", "DUNGEON ACCESSORY") >= 0;
- }
- return true;
- }
-
- private HashMap parentMap = new HashMap<>();
-
- private ExecutorService searchES = Executors.newSingleThreadExecutor();
-
- /**
- * Clears the current item list, creating a new TreeSet if necessary.
- * Adds all items that match the search AND match the sort mode to the current item list.
- * Also adds some easter egg items. (Also I'm very upset if you came here to find them :'( )
- */
- public void updateSearch() {
- SunTzu.randomizeQuote();
-
- if(searchedItems == null) searchedItems = new TreeSet<>(getItemComparator());
-
- searchES.submit(() -> {
- TreeSet searchedItems = new TreeSet<>(getItemComparator());
- HashMap> searchedItemsSubgroup = new HashMap<>();
-
- Set removeChildItems = new HashSet<>();
- Set itemsMatch = manager.search(textField.getText(), true);
- for(String itemname : itemsMatch) {
- JsonObject item = manager.getItemInformation().get(itemname);
- if(checkMatchesSort(itemname, item)) {
- if(Constants.PARENTS != null) {
- if(Constants.PARENTS.has(itemname) && Constants.PARENTS.get(itemname).isJsonArray()) {
- List children = new ArrayList<>();
- for(JsonElement e : Constants.PARENTS.get(itemname).getAsJsonArray()) {
- if(e.isJsonPrimitive()) {
- children.add(e.getAsString());
- }
- }
- children.retainAll(itemsMatch);
- for(String child : children) {
- removeChildItems.add(manager.getItemInformation().get(child));
- }
- searchedItemsSubgroup.put(itemname, children);
- }
- }
- searchedItems.add(item);
- }
- }
- searchedItems.removeAll(removeChildItems);
- out:
- for(Map.Entry> entry : searchedItemsSubgroup.entrySet()) {
- if(searchedItems.contains(manager.getItemInformation().get(entry.getKey()))) {
- continue;
- }
- for(String itemname : entry.getValue()) {
- JsonObject item = manager.getItemInformation().get(itemname);
- if(item != null) searchedItems.add(item);
- }
- }
- switch(textField.getText().toLowerCase().trim()) {
- case "nullzee":
- searchedItems.add(CustomItems.NULLZEE);
- break;
- case "rune":
- searchedItems.add(CustomItems.RUNE);
- break;
- case "2b2t":
- searchedItems.add(CustomItems.TWOBEETWOTEE);
- break;
- case "ducttape":
- case "ducttapedigger":
- searchedItems.add(CustomItems.DUCTTAPE);
- break;
- case "thirtyvirus":
- searchedItems.add(manager.getItemInformation().get("SPIKED_BAIT"));
- break;
- case "leocthl":
- searchedItems.add(CustomItems.LEOCTHL);
- break;
- case "spinaxx":
- searchedItems.add(CustomItems.SPINAXX);
- break;
- case "credits":
- case "credit":
- case "who made this mod":
- searchedItems.add(CustomItems.CREDITS);
- break;
- case "ironmoon":
- case "ironm00n":
- searchedItems.add(CustomItems.IRONM00N);
- break;
- }
-
- this.searchedItems = searchedItems;
- this.searchedItemsSubgroup = searchedItemsSubgroup;
-
- synchronized(this.searchedItemsArr) {
- this.searchedItemsArr.clear();
- }
-
- redrawItems = true;
- });
- }
-
- /**
- * Returns an index-able array containing the elements in searchedItems.
- * Whenever searchedItems is updated in updateSearch(), the array is recreated here.
- */
- public List getSearchedItems() {
- if(searchedItems == null) {
- updateSearch();
- return new ArrayList<>();
- }
-
- if(searchedItems.size() > 0 && searchedItemsArr.size() == 0) {
- synchronized(searchedItemsArr) {
- searchedItemsArr.addAll(searchedItems);
- }
- }
- return searchedItemsArr;
- }
-
- /**
- * Gets the item in searchedItemArr corresponding to the certain index on the current page.
- * @return item, if the item exists. null, otherwise.
- */
- public JsonObject getSearchedItemPage(int index) {
- if(index < getSlotsXSize()*getSlotsYSize()) {
- int actualIndex = index + getSlotsXSize()*getSlotsYSize()*page;
- List searchedItems = getSearchedItems();
- if(actualIndex < searchedItems.size()) {
- return searchedItems.get(actualIndex);
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- public int getItemBoxXPadding() {
- int width = Utils.peekGuiScale().getScaledWidth();
- return (((int)(width/3*getWidthMult())-2*getBoxPadding())%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2;
- }
-
- public int getBoxPadding() {
- double panePadding = Math.max(0, Math.min(20, NotEnoughUpdates.INSTANCE.config.itemlist.panePadding));
- return (int)(panePadding*2/Utils.peekGuiScale().getScaleFactor()+5);
- }
-
- private abstract class ItemSlotConsumer {
- public abstract void consume(int x, int y, int id);
- }
-
- public void iterateItemSlots(ItemSlotConsumer itemSlotConsumer) {
- int width = Utils.peekGuiScale().getScaledWidth();
- int itemBoxXPadding = getItemBoxXPadding();
- iterateItemSlots(itemSlotConsumer, (int)(width*getItemPaneOffsetFactor())+getBoxPadding()+itemBoxXPadding);
- }
-
- /**
- * Iterates through all the item slots in the right panel and calls a ItemSlotConsumer for each slot with
- * arguments equal to the slot's x and y position respectively. This is used in order to prevent
- * code duplication issues.
- */
- public void iterateItemSlots(ItemSlotConsumer itemSlotConsumer, int xStart) {
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
-
- int paneWidth = (int)(width/3*getWidthMult());
- int itemBoxYPadding = ((height-getSearchBarYSize()-2*getBoxPadding()-ITEM_SIZE-2)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2;
-
- int yStart = getBoxPadding()+getSearchBarYSize()+itemBoxYPadding;
- int itemBoxXPadding = getItemBoxXPadding();
- int xEnd = xStart+paneWidth-getBoxPadding()*2-ITEM_SIZE-itemBoxXPadding;
- int yEnd = height-getBoxPadding()-ITEM_SIZE-2-itemBoxYPadding;
-
- //Render the items, displaying the tooltip if the cursor is over the item
- int id = 0;
- for(int y = yStart; y < yEnd; y+=ITEM_SIZE+ITEM_PADDING) {
- for(int x = xStart; x < xEnd; x+=ITEM_SIZE+ITEM_PADDING) {
- itemSlotConsumer.consume(x, y, id++);
- }
- }
- }
-
- public float getWidthMult() {
- float scaleFMult = 1;
- if(Utils.peekGuiScale().getScaleFactor()==4) scaleFMult *= 0.9f;
- if(manager.auctionManager.customAH.isRenderOverAuctionView() || Minecraft.getMinecraft().currentScreen instanceof CustomAHGui) scaleFMult *= 0.8f;
- return (float)Math.max(0.5, Math.min(1.5, NotEnoughUpdates.INSTANCE.config.itemlist.paneWidthMult))*scaleFMult;
- }
-
- /**
- * Calculates the number of horizontal item slots.
- */
- public int getSlotsXSize() {
- int width = Utils.peekGuiScale().getScaledWidth();
-
- int paneWidth = (int)(width/3*getWidthMult());
- int itemBoxXPadding = (((int)(width-width*getItemPaneOffsetFactor())-2*getBoxPadding())%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2;
- int xStart = (int)(width*getItemPaneOffsetFactor())+getBoxPadding()+itemBoxXPadding;
- int xEnd = (int)(width*getItemPaneOffsetFactor())+paneWidth-getBoxPadding()-ITEM_SIZE;
-
- return (int)Math.ceil((xEnd - xStart)/((float)(ITEM_SIZE+ITEM_PADDING)));
- }
-
- /**
- * Calculates the number of vertical item slots.
- */
- public int getSlotsYSize() {
- int height = Utils.peekGuiScale().getScaledHeight();
-
- int itemBoxYPadding = ((height-getSearchBarYSize()-2*getBoxPadding()-ITEM_SIZE-2)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2;
- int yStart = getBoxPadding()+getSearchBarYSize()+itemBoxYPadding;
- int yEnd = height-getBoxPadding()-ITEM_SIZE-2-itemBoxYPadding;
-
- return (int)Math.ceil((yEnd - yStart)/((float)(ITEM_SIZE+ITEM_PADDING)));
- }
-
- public int getMaxPages() {
- if(getSearchedItems().size() == 0) return 1;
- return (int)Math.ceil(getSearchedItems().size()/(float)getSlotsYSize()/getSlotsXSize());
- }
-
- public int getSearchBarYSize() {
- int searchBarYSize = NotEnoughUpdates.INSTANCE.config.toolbar.searchBarHeight;
- return Math.max(searchBarYSize/Utils.peekGuiScale().getScaleFactor(), ITEM_SIZE);
- }
-
- /**
- * Renders the top navigation bar, can be used by InfoPane implementations (such as SettingsInfoPane).
- * Renders "prev" button, index/maxIndex string, "next" button.
- */
- public void renderNavElement(int leftSide, int rightSide, int maxPages, int page, String name) {
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
-
- String pageText = EnumChatFormatting.BOLD+name + page + "/" + maxPages;
-
- float maxStrLen = fr.getStringWidth(EnumChatFormatting.BOLD+name + maxPages + "/" + maxPages);
- float maxButtonXSize = (rightSide-leftSide+2 - maxStrLen*0.5f - 10)/2f;
- int buttonXSize = (int)Math.min(maxButtonXSize, getSearchBarYSize()*480/160f);
- int ySize = (int)(buttonXSize/480f*160);
- int yOffset = (int)((getSearchBarYSize()-ySize)/2f);
- int top = getBoxPadding()+yOffset;
-
- int leftPressed = 0;
- int rightPressed = 0;
-
- if(Mouse.isButtonDown(0) || Mouse.isButtonDown(1)) {
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
-
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
-
- if(mouseY >= top && mouseY <= top+ySize) {
- int leftPrev = leftSide-1;
- if(mouseX > leftPrev && mouseX < leftPrev+buttonXSize) { //"Previous" button
- leftPressed = 1;
- }
- int leftNext = rightSide+1-buttonXSize;
- if(mouseX > leftNext && mouseX < leftNext+buttonXSize) { //"Next" button
- rightPressed = 1;
- }
- }
- }
-
- drawRect(leftSide-1, top, leftSide-1+buttonXSize, top+ySize, fg.getRGB());
- GlStateManager.color(1f, 1f, 1f, 1f);
- Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow);
- Utils.drawTexturedRect(leftSide-1+leftPressed,
- top+leftPressed,
- buttonXSize, ySize, 1, 0, 0, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay);
- Utils.drawTexturedRect(leftSide-1,
- top,
- buttonXSize, ySize, 1-leftPressed, leftPressed, 1-leftPressed, leftPressed);
- GlStateManager.bindTexture(0);
- Utils.drawStringCenteredScaled(EnumChatFormatting.BOLD+"Prev", fr,
- leftSide-1+buttonXSize*300/480f+leftPressed,
- top+ySize/2f+leftPressed, false,
- (int)(buttonXSize*240/480f), Color.BLACK.getRGB());
-
- drawRect(rightSide+1-buttonXSize, top, rightSide+1, top+ySize, fg.getRGB());
- GlStateManager.color(1f, 1f, 1f, 1f);
- Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow);
- Utils.drawTexturedRect(rightSide+1-buttonXSize+rightPressed,
- top+rightPressed,
- buttonXSize, ySize);
- Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay);
- Utils.drawTexturedRect(rightSide+1-buttonXSize,
- top,
- buttonXSize, ySize, 1-rightPressed, rightPressed, 1-rightPressed, rightPressed);
- GlStateManager.bindTexture(0);
- Utils.drawStringCenteredScaled(EnumChatFormatting.BOLD+"Next", fr,
- rightSide+1-buttonXSize*300/480f+rightPressed,
- top+ySize/2f+rightPressed, false,
- (int)(buttonXSize*240/480f), Color.BLACK.getRGB());
-
- int strMaxLen = rightSide-leftSide-2*buttonXSize-10;
-
- drawRect(leftSide-1+buttonXSize+3, top, rightSide+1-buttonXSize-3, top+ySize,
- new Color(177,177,177).getRGB());
- drawRect(leftSide+buttonXSize+3, top+1, rightSide+1-buttonXSize-3, top+ySize,
- new Color(50,50,50).getRGB());
- drawRect(leftSide+buttonXSize+3, top+1, rightSide-buttonXSize-3, top+ySize-1, fg.getRGB());
- Utils.drawStringCenteredScaledMaxWidth(pageText, fr,(leftSide+rightSide)/2,
- top+ySize/2f, false, strMaxLen, Color.BLACK.getRGB());
- }
-
- private int limCol(int col) {
- return Math.min(255, Math.max(0, col));
- }
-
- public boolean isUsingMobsFilter() {
- return getSortMode() == SORT_MODE_MOB;
- }
-
- public float yaw = 0;
- public float pitch = 20;
-
- /**
- * Renders an entity onto the GUI at a certain x and y position.
- */
- private void renderEntity(float posX, float posY, float scale, String name, Class extends EntityLivingBase>... classes) {
- EntityLivingBase[] entities = new EntityLivingBase[classes.length];
- try {
- EntityLivingBase last = null;
- for(int i=0; i clazz = classes[i];
- if(clazz == null) continue;
-
- EntityLivingBase newEnt = clazz.getConstructor(new Class[] {World.class}).newInstance(Minecraft.getMinecraft().theWorld);
-
- //newEnt.renderYawOffset = yaw;
- //newEnt.rotationYaw = yaw;
- newEnt.rotationPitch = pitch;
- //newEnt.rotationYawHead = yaw;
- //newEnt.prevRotationYawHead = yaw-1;
-
- newEnt.setCustomNameTag(name);
-
- if(last != null) {
- last.riddenByEntity = newEnt;
- newEnt.ridingEntity = last;
- last.updateRiderPosition();
- }
- last = newEnt;
-
- entities[i] = newEnt;
- }
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
- e.printStackTrace();
- return;
- }
-
-
- GlStateManager.enableColorMaterial();
- GlStateManager.pushMatrix();
- GlStateManager.translate(posX, posY, 50.0F);
- GlStateManager.scale(-scale, scale, scale);
- GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F);
-
- GlStateManager.rotate(135.0F, 0.0F, 1.0F, 0.0F);
- RenderHelper.enableStandardItemLighting();
- GlStateManager.rotate(-135.0F, 0.0F, 1.0F, 0.0F);
-
- GlStateManager.rotate(pitch, 1.0F, 0.0F, 0.0F);
- GlStateManager.rotate(yaw, 0.0F, 1.0F, 0.0F);
-
- RenderManager rendermanager = Minecraft.getMinecraft().getRenderManager();
- rendermanager.setPlayerViewY(180.0F);
- rendermanager.setRenderShadow(false);
- for(EntityLivingBase ent : entities) {
- GL11.glColor4f(1,1,1,1);
- if(ent != null) rendermanager.renderEntityWithPosYaw(ent, ent.posX, ent.posY, ent.posZ, 0.0F, 1.0F);
- }
- rendermanager.setRenderShadow(true);
-
- GlStateManager.popMatrix();
- RenderHelper.disableStandardItemLighting();
- GlStateManager.disableRescaleNormal();
- GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit);
- GlStateManager.disableTexture2D();
- GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
-
- GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
- }
-
- Shader blurShaderHorz = null;
- Framebuffer blurOutputHorz = null;
- Shader blurShaderVert = null;
- Framebuffer blurOutputVert = null;
-
- /**
- * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate
- * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis).
- *
- * This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to
- * apply scales and translations manually.
- */
- private Matrix4f createProjectionMatrix(int width, int height) {
- Matrix4f projMatrix = new Matrix4f();
- projMatrix.setIdentity();
- projMatrix.m00 = 2.0F / (float)width;
- projMatrix.m11 = 2.0F / (float)(-height);
- projMatrix.m22 = -0.0020001999F;
- projMatrix.m33 = 1.0F;
- projMatrix.m03 = -1.0F;
- projMatrix.m13 = 1.0F;
- projMatrix.m23 = -1.0001999F;
- return projMatrix;
- }
-
- public void updateGuiGroupSize() {
- Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
-
- if(lastScreenWidth != width || lastScreenHeight != height || Utils.peekGuiScale().getScaleFactor() != lastScale) {
- guiGroup.width = width;
- guiGroup.height = height;
-
- resetAnchors(true);
- guiGroup.recalculate();
-
- lastScreenWidth = width;
- lastScreenHeight = height;
- lastScale = Utils.peekGuiScale().getScaleFactor();
- }
-
- Utils.pushGuiScale(-1);
- }
-
- int guiScaleLast = 0;
- private boolean showVanillaLast = false;
-
- /**
- * Renders the search bar, quick commands, item selection (right) and item info (left) gui elements.
- */
- public void render(boolean hoverInv) {
- if(disabled) {
- return;
- }
- GlStateManager.enableDepth();
-
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
-
- Utils.resetGuiScale();
- Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
-
- int width = Utils.peekGuiScale().getScaledWidth();
- int height = Utils.peekGuiScale().getScaledHeight();
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
-
- if(showVanillaLast != NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems) {
- showVanillaLast = NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems;
- updateSearch();
- }
-
- if(textField.getText().toLowerCase().contains("bald")) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(SUPERGEHEIMNISVERMOGEN);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect((width-64)/2f, (height-64)/2f-114, 64, 64, GL11.GL_LINEAR);
- GlStateManager.bindTexture(0);
- }
-
- SunTzu.setEnabled(textField.getText().toLowerCase().startsWith("potato"));
-
- updateGuiGroupSize();
-
- if(guiScaleLast != Utils.peekGuiScale().getScaleFactor()) {
- guiScaleLast = Utils.peekGuiScale().getScaleFactor();
- redrawItems = true;
- }
-
- if(oldWidthMult != getWidthMult()) {
- oldWidthMult = getWidthMult();
- redrawItems = true;
- }
-
- yaw++;
- yaw %= 360;
-
- bg = new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.backgroundColour), true);
- fg = new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.foregroundColour));
- Color fgCustomOpacity = new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.foregroundColour), true);
-
- Color fgFavourite2 = new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.favouriteColour), true);
- Color fgFavourite = new Color((int)(fgFavourite2.getRed()*0.8f), (int)(fgFavourite2.getGreen()*0.8f),
- (int)(fgFavourite2.getBlue()*0.8f), fgFavourite2.getAlpha());
-
- if(itemPaneOpen) {
- if(itemPaneTabOffset.getValue() == 0) {
- if(itemPaneOffsetFactor.getTarget() != 2/3f) {
- itemPaneOffsetFactor.setTarget(2/3f);
- itemPaneOffsetFactor.resetTimer();
- }
- } else {
- if(itemPaneTabOffset.getTarget() != 0) {
- itemPaneTabOffset.setTarget(0);
- itemPaneTabOffset.resetTimer();
- }
- }
- } else {
- if(itemPaneOffsetFactor.getValue() == 1) {
- if(itemPaneTabOffset.getTarget() != 20) {
- itemPaneTabOffset.setTarget(20);
- itemPaneTabOffset.resetTimer();
- }
- } else {
- if(itemPaneOffsetFactor.getTarget() != 1f) {
- itemPaneOffsetFactor.setTarget(1f);
- itemPaneOffsetFactor.resetTimer();
- }
- }
- }
-
- itemPaneOffsetFactor.tick();
- itemPaneTabOffset.tick();
- infoPaneOffsetFactor.tick();
-
- if(page > getMaxPages()-1) setPage(getMaxPages()-1);
- if(page < 0) setPage(0);
-
- GlStateManager.disableLighting();
-
- /**
- * Item selection (right) gui element rendering
- */
- int paneWidth = (int)(width/3*getWidthMult());
- int leftSide = (int)(width*getItemPaneOffsetFactor());
- int rightSide = leftSide+paneWidth-getBoxPadding()-getItemBoxXPadding();
-
- //Tab
- if(NotEnoughUpdates.INSTANCE.config.itemlist.tabOpen) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(itemPaneTabArrow);
- GlStateManager.color(1f, 1f, 1f, 0.3f);
- Utils.drawTexturedRect(width-itemPaneTabOffset.getValue()*64/20f, height/2f - 32, 64, 64);
- GlStateManager.bindTexture(0);
-
- if(!itemPaneOpen && mouseX > width-itemPaneTabOffset.getValue() && mouseY > height/2 - 32
- && mouseY < height/2 + 32) {
- itemPaneOpen = true;
- }
- }
-
- //Atomic reference used so that below lambda doesn't complain about non-effectively-final variable
- AtomicReference tooltipToDisplay = new AtomicReference<>(null);
- //System.out.println(itemPaneOffsetFactor.getValue());
- if(itemPaneOffsetFactor.getValue() < 0.99) {
- if(NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor > 0.5) {
- BackgroundBlur.renderBlurredBackground(NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor,
- width, height,
- leftSide+getBoxPadding()-5, getBoxPadding()-5,
- paneWidth-getBoxPadding()*2+10, height-getBoxPadding()*2+10,
- itemPaneOffsetFactor.getValue() > 0.01);
- Gui.drawRect(leftSide+getBoxPadding()-5, getBoxPadding()-5,
- leftSide+getBoxPadding()-5+paneWidth-getBoxPadding()*2+10,
- getBoxPadding()-5+height-getBoxPadding()*2+10, 0xc8101010);
- }
-
- drawRect(leftSide+getBoxPadding()-5, getBoxPadding()-5,
- leftSide+paneWidth-getBoxPadding()+5, height-getBoxPadding()+5, bg.getRGB());
-
- renderNavElement(leftSide+getBoxPadding()+getItemBoxXPadding(), rightSide, getMaxPages(), page+1,
- Utils.peekGuiScale().getScaleFactor()<4?"Page: ":"");
-
- //Sort bar
- drawRect(leftSide+getBoxPadding()+getItemBoxXPadding()-1,
- height-getBoxPadding()-ITEM_SIZE-2,
- rightSide+1,
- height-getBoxPadding(), fgCustomOpacity.getRGB());
-
- float sortIconsMinX = (sortIcons.length+orderIcons.length)*(ITEM_SIZE+ITEM_PADDING)+ITEM_SIZE;
- float availableX = rightSide-(leftSide+getBoxPadding()+getItemBoxXPadding());
- float sortOrderScaleFactor = Math.min(1, availableX / sortIconsMinX);
-
- int scaledITEM_SIZE = (int)(ITEM_SIZE*sortOrderScaleFactor);
- int scaledItemPaddedSize = (int)((ITEM_SIZE+ITEM_PADDING)*sortOrderScaleFactor);
- int iconTop = height-getBoxPadding()-(ITEM_SIZE+scaledITEM_SIZE)/2-1;
-
- boolean hoveredOverControl = false;
- for(int i=0; i iconTop && mouseY < iconTop+scaledITEM_SIZE) {
- if(mouseX > orderIconX && mouseX < orderIconX+scaledITEM_SIZE) {
- hoveredOverControl = true;
- if(System.currentTimeMillis() - millisLastMouseMove > 400) {
- String text = EnumChatFormatting.GRAY+"Order ";
- if(i == COMPARE_MODE_ALPHABETICAL) text += "Alphabetically";
- else if(i == COMPARE_MODE_RARITY) text += "by Rarity";
- else if(i == COMPARE_MODE_VALUE) text += "by Item Worth";
- else text = null;
- if(text != null) textToDisplay = Utils.createList(text);
- }
- }
- }
- }
-
- for(int i=0; i iconTop && mouseY < iconTop+scaledITEM_SIZE) {
- if(mouseX > sortIconX && mouseX < sortIconX+scaledITEM_SIZE) {
- hoveredOverControl = true;
- if(System.currentTimeMillis() - millisLastMouseMove > 400) {
- String text = EnumChatFormatting.GRAY+"Filter ";
- if(i == SORT_MODE_ALL) text = EnumChatFormatting.GRAY+"No Filter";
- else if(i == SORT_MODE_MOB) text += "Mobs";
- else if(i == SORT_MODE_PET) text += "Pets";
- else if(i == SORT_MODE_TOOL) text += "Tools";
- else if(i == SORT_MODE_ARMOR) text += "Armor";
- else if(i == SORT_MODE_ACCESSORY) text += "Accessories";
- else text = null;
- if(text != null) textToDisplay = Utils.createList(text);
- }
- }
- }
- }
-
- if(!hoveredOverControl) {
- millisLastMouseMove = System.currentTimeMillis();
- }
-
- if(selectedItemGroup != null) {
- if(mouseX < selectedItemGroupX-1 || mouseX > selectedItemGroupX+17 ||
- mouseY < selectedItemGroupY-1 || mouseY > selectedItemGroupY+17) {
- int selectedX = Math.min(selectedItemGroupX, width-getBoxPadding()-18*selectedItemGroup.size());
- if(mouseX < selectedX-1 || mouseX > selectedX-1+18*selectedItemGroup.size() ||
- mouseY < selectedItemGroupY+17 || mouseY > selectedItemGroupY+35) {
- selectedItemGroup = null;
- selectedItemMillis = -1;
- }
- }
- }
-
- if(!hoverInv) {
- iterateItemSlots(new ItemSlotConsumer() {
- public void consume(int x, int y, int id) {
- JsonObject json = getSearchedItemPage(id);
- if (json == null) {
- return;
- }
- if (mouseX > x - 1 && mouseX < x + ITEM_SIZE + 1) {
- if (mouseY > y - 1 && mouseY < y + ITEM_SIZE + 1) {
- String internalname = json.get("internalname").getAsString();
- if(searchedItemsSubgroup.containsKey(internalname)) {
- if(selectedItemMillis == -1) selectedItemMillis = System.currentTimeMillis();
- if(System.currentTimeMillis() - selectedItemMillis > 200 &&
- (selectedItemGroup == null || selectedItemGroup.isEmpty())) {
-
- ArrayList children = new ArrayList<>();
- children.add(json);
- for(String itemname : searchedItemsSubgroup.get(internalname)) {
- children.add(manager.getItemInformation().get(itemname));
- }
-
- selectedItemGroup = children;
- selectedItemGroupX = x;
- selectedItemGroupY = y;
- }
- } else {
- tooltipToDisplay.set(json);
- }
- }
- }
- }
- });
- }
-
- //Iterate through all item slots and display the appropriate item
- int itemBoxXPadding = getItemBoxXPadding();
- int xStart = (int)(width*getItemPaneOffsetFactor())+getBoxPadding()+itemBoxXPadding;
-
- if(OpenGlHelper.isFramebufferEnabled()) {
- renderItemsFromImage(xStart, width, height);
- renderEnchOverlay();
-
- checkFramebufferSizes(width, height);
-
- if(redrawItems || !NotEnoughUpdates.INSTANCE.config.hidden.cacheRenderedItempane) {
- renderItemsToImage(width, height, fgFavourite2, fgFavourite, fgCustomOpacity, true, true);
- redrawItems = false;
- }
- } else {
- renderItems(xStart, true, true, true);
- }
-
- if(selectedItemGroup != null) {
- GL11.glTranslatef(0, 0, 10);
-
- int selectedX = Math.min(selectedItemGroupX, width-getBoxPadding()-18*selectedItemGroup.size());
-
- GlStateManager.enableDepth();
- GlStateManager.depthFunc(GL11.GL_LESS);
- drawRect(selectedX, selectedItemGroupY+18,
- selectedX-2+18*selectedItemGroup.size(), selectedItemGroupY+34, fgCustomOpacity.getRGB());
- drawRect(selectedX-1, selectedItemGroupY+17,
- selectedX-2+18*selectedItemGroup.size(), selectedItemGroupY+34, new Color(180, 180, 180).getRGB());
- drawRect(selectedX, selectedItemGroupY+18,
- selectedX-1+18*selectedItemGroup.size(), selectedItemGroupY+35, new Color(30, 30, 30).getRGB());
- drawRect(selectedX-1+2, selectedItemGroupY+17+2,
- selectedX-1+18*selectedItemGroup.size()+2, selectedItemGroupY+35+2, 0xa0000000);
- GlStateManager.depthFunc(GL11.GL_LEQUAL);
-
- GL11.glTranslatef(0, 0, 10);
-
- tooltipToDisplay.set(null);
- if(mouseY > selectedItemGroupY+17 && mouseY < selectedItemGroupY+35) {
- for(int i=0; i= selectedX-1+18*i && mouseX <= selectedX+17+18*i) {
- tooltipToDisplay.set(selectedItemGroup.get(i));
- }
- }
- }
- for(int i=0; i text = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
-
- String internalname = json.get("internalname").getAsString();
- if(!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoInvItem) {
- ItemPriceInformation.addToTooltip(text, internalname, stack);
- }
-
- boolean hasClick = false;
- boolean hasInfo = false;
- if(json.has("clickcommand") && !json.get("clickcommand").getAsString().isEmpty()) {
- hasClick = true;
- }
- if(json.has("info") && json.get("info").getAsJsonArray().size() > 0) {
- hasInfo = true;
- }
-
- if(hasClick || hasInfo) text.add("");
- if(hasClick) text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"LMB/R : View recipe!");
- if(hasInfo) text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"RMB : View additional information!");
-
-
- textToDisplay = text;
- }
- if(textToDisplay != null) {
- Utils.drawHoveringText(textToDisplay, mouseX, mouseY, width, height, -1, fr);
- textToDisplay = null;
- }
-
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.enableAlpha();
- GlStateManager.alphaFunc(516, 0.1F);
- GlStateManager.disableLighting();
-
- Utils.pushGuiScale(-1);
- }
-
- /**
- * Used in SettingsInfoPane to redraw the items when a setting changes.
- */
- public void redrawItems() {
- redrawItems = true;
- }
-
- /**
- * Sets the current page and marks that the itemsPane should be redrawn
- * @param page
- */
- public void setPage(int page) {
- this.page = page;
- redrawItems = true;
- }
-
- private Framebuffer[] itemFramebuffers = new Framebuffer[2];
-
- /**
- * Checks whether the screen size has changed, if so it reconstructs the itemPane framebuffer and marks that the
- * itemPane should be redrawn.
- */
- private void checkFramebufferSizes(int width, int height) {
- int sw = width*Utils.peekGuiScale().getScaleFactor();
- int sh = height*Utils.peekGuiScale().getScaleFactor();
- for(int i=0; i quads, int color) {
- if(quads == null) return;
-
- for(BakedQuad quad : quads) {
- renderer.addVertexData(quad.getVertexData());
- renderer.putColor4(color);
- }
- }
-
- /**
- * Renders all the item backgrounds, either squares or squircles.
- */
- private void renderItemBackgrounds(Color fgFavourite2, Color fgFavourite, Color fgCustomOpacity) {
- if(fgCustomOpacity.getAlpha() == 0) return;
- iterateItemSlots(new ItemSlotConsumer() {
- public void consume(int x, int y, int id) {
- JsonObject json = getSearchedItemPage(id);
- if (json == null) {
- return;
- }
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(item_mask);
- if (getFavourites().contains(json.get("internalname").getAsString())) {
- if(NotEnoughUpdates.INSTANCE.config.itemlist.itemStyle == 0) {
- GlStateManager.color(fgFavourite2.getRed() / 255f, fgFavourite2.getGreen() / 255f,
- fgFavourite2.getBlue() / 255f, fgFavourite2.getAlpha() / 255f);
- Utils.drawTexturedRect(x - 1, y - 1, ITEM_SIZE + 2, ITEM_SIZE + 2, GL11.GL_NEAREST);
-
- GlStateManager.color(fgFavourite.getRed() / 255f, fgFavourite.getGreen() / 255f,
- fgFavourite.getBlue() / 255f, fgFavourite.getAlpha() / 255f);
- Utils.drawTexturedRect(x, y, ITEM_SIZE, ITEM_SIZE, GL11.GL_NEAREST);
- } else {
- drawRect(x-1, y-1, x+ITEM_SIZE+1, y+ITEM_SIZE+1, fgFavourite2.getRGB());
- drawRect(x, y, x+ITEM_SIZE, y+ITEM_SIZE, fgFavourite.getRGB());
- }
- } else {
- if(NotEnoughUpdates.INSTANCE.config.itemlist.itemStyle == 0) {
- GlStateManager.color(fgCustomOpacity.getRed() / 255f, fgCustomOpacity.getGreen() / 255f,
- fgCustomOpacity.getBlue() / 255f, fgCustomOpacity.getAlpha() / 255f);
- Utils.drawTexturedRect(x - 1, y - 1, ITEM_SIZE + 2, ITEM_SIZE + 2, GL11.GL_NEAREST);
- } else {
- drawRect(x-1, y-1, x+ITEM_SIZE+1, y+ITEM_SIZE+1, fgCustomOpacity.getRGB());
- }
- }
- GlStateManager.bindTexture(0);
- }
- }, 10);
- }
-
- private void renderItems(int xStart, boolean items, boolean entities, boolean glint) {
- iterateItemSlots(new ItemSlotConsumer() {
- public void consume(int x, int y, int id) {
- JsonObject json = getSearchedItemPage(id);
- if (json == null) {
- return;
- }
-
- if (json.has("entityrender")) {
- if(!entities) return;
- String name = json.get("displayname").getAsString();
- String[] split = name.split(" \\(");
- name = name.substring(0, name.length() - split[split.length - 1].length() - 2);
-
- Class extends EntityLivingBase>[] entities = new Class[1];
- if (json.get("entityrender").isJsonArray()) {
- JsonArray entityrender = json.get("entityrender").getAsJsonArray();
- entities = new Class[entityrender.size()];
- for (int i = 0; i < entityrender.size(); i++) {
- Class extends Entity> clazz = EntityList.stringToClassMapping.get(entityrender.get(i).getAsString());
- if (clazz != null && EntityLivingBase.class.isAssignableFrom(clazz)) {
- entities[i] = (Class extends EntityLivingBase>) clazz;
- }
- }
- } else if (json.get("entityrender").isJsonPrimitive()) {
- Class extends Entity> clazz = EntityList.stringToClassMapping.get(json.get("entityrender").getAsString());
- if (clazz != null && EntityLivingBase.class.isAssignableFrom(clazz)) {
- entities[0] = (Class extends EntityLivingBase>) clazz;
- }
- }
-
- float scale = 8;
- if (json.has("entityscale")) {
- scale *= json.get("entityscale").getAsFloat();
- }
-
- renderEntity(x + ITEM_SIZE / 2, y + ITEM_SIZE, scale, name, entities);
- } else {
- if(!items) return;
- ItemStack stack = manager.jsonToStack(json, true, true, false);
- if(stack != null) {
- if(glint) {
- Utils.drawItemStack(stack, x, y);
- } else {
- Utils.drawItemStackWithoutGlint(stack, x, y);
- }
- }
- }
-
- GlStateManager.translate(0, 0, 50);
- if(searchedItemsSubgroup.containsKey(json.get("internalname").getAsString())) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(item_haschild);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(x-1, y-1, ITEM_SIZE+2, ITEM_SIZE+2, GL11.GL_NEAREST);
- }
- GlStateManager.translate(0, 0, -50);
- }
- }, xStart);
- }
-
- public float getItemPaneOffsetFactor() {
- return itemPaneOffsetFactor.getValue() * getWidthMult() + (1-getWidthMult());
- }
-
- public float getInfoPaneOffsetFactor() {
- return infoPaneOffsetFactor.getValue() * getWidthMult();
- }
-
-}
\ No newline at end of file
+ private static final ResourceLocation SUPERGEHEIMNISVERMOGEN =
+ new ResourceLocation("notenoughupdates:supersecretassets/bald.png");
+ private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png");
+ private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png");
+
+ private static final ResourceLocation ARMOR_DISPLAY =
+ new ResourceLocation("notenoughupdates:armordisplay/armordisplay.png");
+ private static final ResourceLocation ARMOR_DISPLAY_GREY =
+ new ResourceLocation("notenoughupdates:armordisplay/armordisplay_grey.png");
+ private static final ResourceLocation ARMOR_DISPLAY_DARK =
+ new ResourceLocation("notenoughupdates:armordisplay/armordisplay_phq_dark.png");
+ private static final ResourceLocation ARMOR_DISPLAY_FSR =
+ new ResourceLocation("notenoughupdates:armordisplay/armordisplay_fsr.png");
+ private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT =
+ new ResourceLocation("notenoughupdates:armordisplay/armordisplay_transparent.png");
+ private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT_PET =
+ new ResourceLocation("notenoughupdates:armordisplay/armordisplay_transparent_pet.png");
+
+ private static final ResourceLocation QUESTION_MARK = new ResourceLocation("notenoughupdates:pv_unknown.png");
+
+ private static final ResourceLocation PET_DISPLAY =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo.png");
+ private static final ResourceLocation PET_DISPLAY_GREY =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_dark.png");
+ private static final ResourceLocation PET_DISPLAY_DARK =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_phqdark.png");
+ private static final ResourceLocation PET_DISPLAY_FSR =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_fsr.png");
+ private static final ResourceLocation PET_DISPLAY_TRANSPARENT =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_transparent.png");
+
+ private static final ResourceLocation PET_ARMOR_DISPLAY =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor.png");
+ private static final ResourceLocation PET_ARMOR_DISPLAY_GREY =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_dark.png");
+ private static final ResourceLocation PET_ARMOR_DISPLAY_DARK =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_phqdark.png");
+ private static final ResourceLocation PET_ARMOR_DISPLAY_FSR =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_fsr.png");
+ private static final ResourceLocation PET_ARMOR_DISPLAY_TRANSPARENT =
+ new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_transparent.png");
+
+ private static boolean renderingArmorHud;
+ private static boolean renderingPetHud;
+ public static boolean shouldUseCachedPet;
+ public static long cachedPetTimer;
+
+ private final NEUManager manager;
+
+ private final String mobRegex = ".*?((_MONSTER)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$";
+ private final String petRegex = ".*?;[0-5]$";
+
+ private final ResourceLocation[] sortIcons = new ResourceLocation[]{
+ sort_all, sort_mob, sort_pet, sort_tool, sort_armor, sort_accessory
+ };
+ private final ResourceLocation[] sortIconsActive = new ResourceLocation[]{
+ sort_all_active, sort_mob_active, sort_pet_active, sort_tool_active, sort_armor_active, sort_accessory_active
+ };
+
+ private final ResourceLocation[] orderIcons = new ResourceLocation[]{
+ order_alphabetical, order_rarity, order_value
+ };
+ private final ResourceLocation[] orderIconsActive = new ResourceLocation[]{
+ order_alphabetical_active, order_rarity_active, order_value_active
+ };
+
+ //Various constants used for GUI structure
+ private final int searchBarYOffset = 10;
+ private final int searchBarPadding = 2;
+ private long lastSearchMode = 0;
+
+ private float oldWidthMult = 0;
+
+ public static final int ITEM_PADDING = 4;
+ public static final int ITEM_SIZE = 16;
+
+ private Color bg = new Color(90, 90, 140, 50);
+ private Color fg = new Color(100, 100, 100, 255);
+
+ private InfoPane activeInfoPane = null;
+
+ private TreeSet searchedItems = null;
+ private final List searchedItemsArr = new ArrayList<>();
+
+ private HashMap> searchedItemsSubgroup = new HashMap<>();
+
+ private long selectedItemMillis = 0;
+ private int selectedItemGroupX = -1;
+ private int selectedItemGroupY = -1;
+ private List selectedItemGroup = null;
+
+ private boolean itemPaneOpen = false;
+
+ private int page = 0;
+
+ private final LerpingFloat itemPaneOffsetFactor = new LerpingFloat(1);
+ private final LerpingInteger itemPaneTabOffset = new LerpingInteger(20, 50);
+ private final LerpingFloat infoPaneOffsetFactor = new LerpingFloat(0);
+
+ public boolean searchMode = false;
+ private long millisLastLeftClick = 0;
+ private long millisLastMouseMove = 0;
+ private int lastMouseX = 0;
+ private int lastMouseY = 0;
+
+ public static final int overlayColourDark = new Color(0, 0, 0, 120).getRGB();
+ public static final int overlayColourLight = new Color(255, 255, 255, 120).getRGB();
+
+ boolean mouseDown = false;
+
+ private boolean redrawItems = false;
+
+ private boolean searchBarHasFocus = false;
+ private final GuiTextField textField = new GuiTextField(0, null, 0, 0, 0, 0);
+
+ private static final int COMPARE_MODE_ALPHABETICAL = 0;
+ private static final int COMPARE_MODE_RARITY = 1;
+ private static final int COMPARE_MODE_VALUE = 2;
+
+ private static final int SORT_MODE_ALL = 0;
+ private static final int SORT_MODE_MOB = 1;
+ private static final int SORT_MODE_PET = 2;
+ private static final int SORT_MODE_TOOL = 3;
+ private static final int SORT_MODE_ARMOR = 4;
+ private static final int SORT_MODE_ACCESSORY = 5;
+
+ private boolean disabled = false;
+
+ private int lastScreenWidth;
+ private int lastScreenHeight;
+ private int lastScale;
+
+ private CompletableFuture infoPaneLoadingJob = CompletableFuture.completedFuture(null);
+
+ private List textToDisplay = null;
+
+ public MBGuiGroupFloating guiGroup = null;
+
+ public NEUOverlay(NEUManager manager) {
+ this.manager = manager;
+ textField.setFocused(true);
+ textField.setCanLoseFocus(false);
+
+ guiGroup = createGuiGroup();
+ }
+
+ private MBGuiElement createSearchBar() {
+ return new MBGuiElement() {
+ public int getWidth() {
+ int paddingUnscaled = getPaddingUnscaled();
+
+ return getSearchBarXSize() + 2 * paddingUnscaled;
+ }
+
+ public int getHeight() {
+ int paddingUnscaled = getPaddingUnscaled();
+
+ return getSearchBarYSize() + 2 * paddingUnscaled;
+ }
+
+ @Override
+ public void mouseClick(float x, float y, int mouseX, int mouseY) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ return;
+ }
+ if (Mouse.getEventButtonState()) {
+ setSearchBarFocus(true);
+ if (Mouse.getEventButton() == 1) { //Right mouse button down
+ textField.setText("");
+ updateSearch();
+ } else {
+ if (System.currentTimeMillis() - millisLastLeftClick < 300) {
+ searchMode = !searchMode;
+ lastSearchMode = System.currentTimeMillis();
+ if (searchMode && NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus) {
+ NEUEventListener.displayNotification(Lists.newArrayList(
+ "\u00a7eSearch Highlight",
+ "\u00a77In this mode NEU will gray out non matching items in",
+ "\u00a77your inventory or chests.",
+ "\u00a77This allows you easily find items as the item will stand out.",
+ "\u00a77To toggle this please double click on the search bar in your inventory.",
+ "\u00a77",
+ "\u00a77Press X on your keyboard to close this notification"
+ ), true, true);
+ NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus = false;
+
+ }
+ }
+ textField.setCursorPosition(getClickedIndex(mouseX, mouseY));
+ millisLastLeftClick = System.currentTimeMillis();
+ if (searchMode) {
+ lastSearchMode = System.currentTimeMillis();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void mouseClickOutside() {
+ setSearchBarFocus(false);
+ }
+
+ @Override
+ public void render(float x, float y) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ return;
+ }
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ int paddingUnscaled = getPaddingUnscaled();
+
+ GlStateManager.color(1, 1, 1, 1);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(searchMode ? SEARCH_BAR_GOLD : SEARCH_BAR);
+
+ int w = getWidth();
+ int h = getHeight();
+
+ for (int yIndex = 0; yIndex <= 2; yIndex++) {
+ for (int xIndex = 0; xIndex <= 2; xIndex++) {
+ float uMin = 0;
+ float uMax = 4 / 20f;
+ int partX = (int) x;
+ int partW = 4;
+ if (xIndex == 1) {
+ partX += 4;
+ uMin = 4 / 20f;
+ uMax = 16 / 20f;
+ partW = w - 8;
+ } else if (xIndex == 2) {
+ partX += w - 4;
+ uMin = 16 / 20f;
+ uMax = 20 / 20f;
+ }
+
+ float vMin = 0;
+ float vMax = 4 / 20f;
+ int partY = (int) y;
+ int partH = 4;
+ if (yIndex == 1) {
+ partY += 4;
+ vMin = 4 / 20f;
+ vMax = 16 / 20f;
+ partH = h - 8;
+ } else if (yIndex == 2) {
+ partY += h - 4;
+ vMin = 16 / 20f;
+ vMax = 20 / 20f;
+ }
+
+ Utils.drawTexturedRect(partX, partY, partW, partH, uMin, uMax, vMin, vMax, GL11.GL_NEAREST);
+ }
+ }
+
+ //Search bar text
+ fr.drawString(textField.getText(), (int) x + 5,
+ (int) y - 4 + getHeight() / 2, Color.WHITE.getRGB()
+ );
+
+ //Determines position of cursor. Cursor blinks on and off every 500ms.
+ if (searchBarHasFocus && System.currentTimeMillis() % 1000 > 500) {
+ String textBeforeCursor = textField.getText().substring(0, textField.getCursorPosition());
+ int textBeforeCursorWidth = fr.getStringWidth(textBeforeCursor);
+ drawRect((int) x + 5 + textBeforeCursorWidth,
+ (int) y - 5 + getHeight() / 2,
+ (int) x + 5 + textBeforeCursorWidth + 1,
+ (int) y - 4 + 9 + getHeight() / 2, Color.WHITE.getRGB()
+ );
+ }
+
+ String selectedText = textField.getSelectedText();
+ if (!selectedText.isEmpty()) {
+ int selectionWidth = fr.getStringWidth(selectedText);
+
+ int leftIndex = Math.min(textField.getCursorPosition(), textField.getSelectionEnd());
+ String textBeforeSelection = textField.getText().substring(0, leftIndex);
+ int textBeforeSelectionWidth = fr.getStringWidth(textBeforeSelection);
+
+ drawRect((int) x + 5 + textBeforeSelectionWidth,
+ (int) y - 5 + getHeight() / 2,
+ (int) x + 5 + textBeforeSelectionWidth + selectionWidth,
+ (int) y - 4 + 9 + getHeight() / 2, Color.LIGHT_GRAY.getRGB()
+ );
+
+ fr.drawString(selectedText,
+ (int) x + 5 + textBeforeSelectionWidth,
+ (int) y - 4 + getHeight() / 2, Color.BLACK.getRGB()
+ );
+ }
+
+ }
+
+ @Override
+ public void recalculate() {
+ }
+ };
+ }
+
+ private MBGuiElement createSettingsButton(NEUOverlay overlay) {
+ return new MBGuiElement() {
+ @Override
+ public int getWidth() {
+ return getSearchBarYSize() + getPaddingUnscaled() * 2;
+ }
+
+ @Override
+ public int getHeight() {
+ return getWidth();
+ }
+
+ @Override
+ public void recalculate() {
+ }
+
+ @Override
+ public void mouseClick(float x, float y, int mouseX, int mouseY) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.enableSettingsButton) {
+ return;
+ }
+ if (Mouse.getEventButtonState()) {
+ NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(NEUConfigEditor.editor);
+ }
+ }
+
+ @Override
+ public void mouseClickOutside() {
+ }
+
+ @Override
+ public void render(float x, float y) {
+ int paddingUnscaled = getPaddingUnscaled();
+ int searchYSize = getSearchBarYSize();
+
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.enableSettingsButton) {
+ return;
+ }
+ Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(x, y,
+ searchYSize + paddingUnscaled * 2, searchYSize + paddingUnscaled * 2, GL11.GL_NEAREST
+ );
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(settings);
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect((int) x + paddingUnscaled, (int) y + paddingUnscaled,
+ searchYSize, searchYSize
+ );
+
+ GlStateManager.bindTexture(0);
+ }
+ };
+ }
+
+ private MBGuiElement createHelpButton(NEUOverlay overlay) {
+ return new MBGuiElement() {
+ @Override
+ public int getWidth() {
+ return getSearchBarYSize() + getPaddingUnscaled() * 2;
+ }
+
+ @Override
+ public int getHeight() {
+ return getWidth();
+ }
+
+ @Override
+ public void recalculate() {
+ }
+
+ @Override
+ public void mouseClick(float x, float y, int mouseX, int mouseY) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.enableHelpButton) {
+ return;
+ }
+ if (Mouse.getEventButtonState()) {
+ //displayInformationPane(HTMLInfoPane.createFromWikiUrl(overlay, manager, "Help",
+ // "https://moulberry.github.io/files/neu_help.html"));
+ //Minecraft.getMinecraft().displayGuiScreen(new HelpGUI());
+ ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/neuhelp");
+ Utils.playPressSound();
+ }
+ }
+
+ @Override
+ public void mouseClickOutside() {
+ }
+
+ @Override
+ public void render(float x, float y) {
+ int paddingUnscaled = getPaddingUnscaled();
+ int searchYSize = getSearchBarYSize();
+
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.enableHelpButton) {
+ return;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(x, y,
+ searchYSize + paddingUnscaled * 2, searchYSize + paddingUnscaled * 2, GL11.GL_NEAREST
+ );
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(help);
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect((int) x + paddingUnscaled, (int) y + paddingUnscaled,
+ getSearchBarYSize(), getSearchBarYSize()
+ );
+ GlStateManager.bindTexture(0);
+
+ }
+ };
+ }
+
+ private MBGuiElement createQuickCommand(String quickCommandStr) {
+ return new MBGuiElement() {
+ @Override
+ public int getWidth() {
+ return getSearchBarYSize() + getPaddingUnscaled() * 2;
+ }
+
+ @Override
+ public int getHeight() {
+ return getWidth();
+ }
+
+ @Override
+ public void recalculate() {
+ }
+
+ @Override
+ public void mouseClick(float x, float y, int mouseX, int mouseY) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.quickCommands) return;
+
+ if ((NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType != 0 && Mouse.getEventButtonState()) ||
+ (NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType == 0 &&
+ !Mouse.getEventButtonState() &&
+ Mouse.getEventButton() != -1)) {
+ if (quickCommandStr.contains(":")) {
+ String command = quickCommandStr.split(":")[0].trim();
+ if (command.startsWith("/")) {
+ NotEnoughUpdates.INSTANCE.sendChatMessage(command);
+ } else {
+ ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/" + command);
+ }
+ Utils.playPressSound();
+ }
+ }
+ }
+
+ @Override
+ public void mouseClickOutside() {
+ }
+
+ @Override
+ public void render(float x, float y) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.quickCommands) return;
+
+ int paddingUnscaled = getPaddingUnscaled();
+ int bigItemSize = getSearchBarYSize();
+
+ String[] quickCommandStrSplit = quickCommandStr.split(":");
+ if (quickCommandStrSplit.length != 3) {
+ return;
+ }
+ String display = quickCommandStrSplit[2];
+ ItemStack render = null;
+ float extraScale = 1;
+ if (display.length() > 20) { //Custom head
+ render = new ItemStack(Items.skull, 1, 3);
+ NBTTagCompound nbt = new NBTTagCompound();
+ NBTTagCompound skullOwner = new NBTTagCompound();
+ NBTTagCompound properties = new NBTTagCompound();
+ NBTTagList textures = new NBTTagList();
+ NBTTagCompound textures_0 = new NBTTagCompound();
+
+ String uuid = UUID.nameUUIDFromBytes(display.getBytes()).toString();
+ skullOwner.setString("Id", uuid);
+ skullOwner.setString("Name", uuid);
+
+ textures_0.setString("Value", display);
+ textures.appendTag(textures_0);
+
+ properties.setTag("textures", textures);
+ skullOwner.setTag("Properties", properties);
+ nbt.setTag("SkullOwner", skullOwner);
+ render.setTagCompound(nbt);
+
+ extraScale = 1.3f;
+ } else if (manager.getItemInformation().containsKey(display)) {
+ render = manager.jsonToStack(manager.getItemInformation().get(display), true, true);
+ } else {
+ Item item = Item.itemRegistry.getObject(new ResourceLocation(display.toLowerCase()));
+ if (item != null) {
+ render = new ItemStack(item);
+ }
+ }
+ if (render != null) {
+ NBTTagCompound tag = render.getTagCompound() != null ? render.getTagCompound() : new NBTTagCompound();
+ tag.setString("qc_id", quickCommandStrSplit[0].toLowerCase().trim());
+ render.setTagCompound(tag);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(x, y,
+ bigItemSize + paddingUnscaled * 2, bigItemSize + paddingUnscaled * 2, GL11.GL_NEAREST
+ );
+
+ int mouseX = Mouse.getX() * Utils.peekGuiScale().getScaledWidth() / Minecraft.getMinecraft().displayWidth;
+ int mouseY = Utils.peekGuiScale().getScaledHeight() -
+ Mouse.getY() * Utils.peekGuiScale().getScaledHeight() / Minecraft.getMinecraft().displayHeight -
+ 1;
+
+ if (mouseX > x && mouseX < x + bigItemSize) {
+ if (mouseY > y && mouseY < y + bigItemSize) {
+ textToDisplay = new ArrayList<>();
+ textToDisplay.add(EnumChatFormatting.GRAY + quickCommandStrSplit[1]);
+ }
+ }
+
+ GlStateManager.enableDepth();
+ float itemScale = bigItemSize / (float) ITEM_SIZE * extraScale;
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(itemScale, itemScale, 1);
+ GlStateManager.translate((x - (extraScale - 1) * bigItemSize / 2 + paddingUnscaled) / itemScale,
+ (y - (extraScale - 1) * bigItemSize / 2 + paddingUnscaled) / itemScale, 0f
+ );
+ Utils.drawItemStack(render, 0, 0);
+ GlStateManager.popMatrix();
+ }
+ }
+ };
+ }
+
+ private MBGuiGroupAligned createQuickCommandGroup() {
+ List children = new ArrayList<>();
+ for (String quickCommand : NotEnoughUpdates.INSTANCE.config.hidden.quickCommands) {
+ children.add(createQuickCommand(quickCommand));
+ }
+ return new MBGuiGroupAligned(children, false) {
+ public int getPadding() {
+ return getPaddingUnscaled() * 4;
+ }
+ };
+ }
+
+ private MBGuiGroupAligned createSearchBarGroup() {
+ List children =
+ Lists.newArrayList(createSettingsButton(this), createSearchBar(), createHelpButton(this));
+ return new MBGuiGroupAligned(children, false) {
+ public int getPadding() {
+ return getPaddingUnscaled() * 4;
+ }
+ };
+ }
+
+ private MBGuiGroupFloating createGuiGroup() {
+ LinkedHashMap map = new LinkedHashMap<>();
+
+ MBAnchorPoint searchBarAnchor =
+ MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlaySearchBar);
+ MBAnchorPoint quickCommandAnchor =
+ MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlayQuickCommand);
+
+ searchBarAnchor = searchBarAnchor != null ? searchBarAnchor :
+ new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0, -searchBarYOffset));
+ quickCommandAnchor = quickCommandAnchor != null ? quickCommandAnchor :
+ new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(
+ 0,
+ -searchBarYOffset - getSearchBarYSize() - getPaddingUnscaled() * 4
+ ));
+
+ map.put(createSearchBarGroup(), searchBarAnchor);
+ map.put(createQuickCommandGroup(), quickCommandAnchor);
+
+ return new MBGuiGroupFloating(Utils.peekGuiScale().getScaledWidth(), Utils.peekGuiScale().getScaledHeight(), map);
+ }
+
+ public void resetAnchors(boolean onlyIfNull) {
+ MBAnchorPoint searchBarAnchor =
+ MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlaySearchBar);
+ MBAnchorPoint quickCommandAnchor =
+ MBAnchorPoint.createFromString(NotEnoughUpdates.INSTANCE.config.hidden.overlayQuickCommand);
+
+ if (onlyIfNull) {
+ searchBarAnchor = searchBarAnchor != null ? null :
+ new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0, -searchBarYOffset));
+ quickCommandAnchor = quickCommandAnchor != null ? null :
+ new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(
+ 0,
+ -searchBarYOffset - getSearchBarYSize() - getPaddingUnscaled() * 4
+ ));
+ } else {
+ searchBarAnchor = searchBarAnchor != null ? searchBarAnchor :
+ new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(0, -searchBarYOffset));
+ quickCommandAnchor = quickCommandAnchor != null ? quickCommandAnchor :
+ new MBAnchorPoint(MBAnchorPoint.AnchorPoint.BOTMID, new Vector2f(
+ 0,
+ -searchBarYOffset - getSearchBarYSize() - getPaddingUnscaled() * 4
+ ));
+ }
+
+ int index = 0;
+ Set set = new LinkedHashSet<>(guiGroup.getChildrenMap().keySet());
+ for (MBGuiElement element : set) {
+ switch (index) {
+ case 0:
+ if (searchBarAnchor == null) continue;
+ guiGroup.getChildrenMap().get(element).anchorPoint = searchBarAnchor.anchorPoint;
+ guiGroup.getChildrenMap().get(element).offset = searchBarAnchor.offset;
+ break;
+ case 1:
+ if (quickCommandAnchor == null) continue;
+ guiGroup.getChildrenMap().get(element).anchorPoint = quickCommandAnchor.anchorPoint;
+ guiGroup.getChildrenMap().get(element).offset = quickCommandAnchor.offset;
+ break;
+ }
+ index++;
+ }
+ }
+
+ /**
+ * Disables searchBarFocus and resets the item pane position. Called whenever NEUOverlay is opened.
+ */
+ public void reset() {
+ searchBarHasFocus = false;
+ if (!(searchMode || (NotEnoughUpdates.INSTANCE.config.itemlist.keepopen && itemPaneOpen))) {
+ itemPaneOpen = false;
+ displayInformationPane(null);
+ itemPaneOffsetFactor.setValue(1);
+ itemPaneTabOffset.setValue(20);
+ }
+ if (activeInfoPane != null) activeInfoPane.reset();
+ guiGroup.recalculate();
+ }
+
+ /**
+ * Calls #displayInformationPane with a HTMLInfoPane created from item.info and item.infoType.
+ */
+ public void showInfo(JsonObject item) {
+ if (item.has("info") && item.has("infoType")) {
+ JsonArray lore = item.get("info").getAsJsonArray();
+ StringBuilder loreBuilder = new StringBuilder();
+ for (int i = 0; i < lore.size(); i++) {
+ loreBuilder.append(lore.get(i).getAsString());
+ if (i != lore.size() - 1)
+ loreBuilder.append("\n");
+ }
+ String infoText = loreBuilder.toString();
+ String internalname = item.get("internalname").getAsString();
+ String name = item.get("displayname").getAsString();
+ String infoType = item.get("infoType").getAsString();
+ displayInformationPane(new TextInfoPane(this, manager, "Loading", "Loading your requested information about " +
+ name +
+ "."));
+ infoPaneLoadingJob = InfoPane.create(this, manager, infoType, name, internalname, infoText)
+ .thenAccept(this::displayInformationPane);
+ }
+ }
+
+ public void mouseInputInv() {
+ if (Minecraft.getMinecraft().currentScreen instanceof GuiContainer) {
+ if (Mouse.getEventButton() == manager.keybindItemSelect.getKeyCode() + 100 &&
+ NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ Slot slot = Utils.getSlotUnderMouse((GuiContainer) Minecraft.getMinecraft().currentScreen);
+ if (slot != null) {
+ ItemStack hover = slot.getStack();
+ if (hover != null) {
+ textField.setText("id:" + manager.getInternalNameForItem(hover));
+ itemPaneOpen = true;
+ updateSearch();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Handles the mouse input, cancelling the forge event if a NEU gui element is clicked.
+ */
+ public boolean mouseInput() {
+ if (disabled) {
+ return false;
+ }
+
+ Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
+
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+
+ //if(lastMouseX != mouseX || lastMouseY != mouseY) {
+ // millisLastMouseMove = System.currentTimeMillis();
+ //}
+
+ lastMouseX = mouseX;
+ lastMouseY = mouseY;
+
+ if (Mouse.getEventButtonState()) {
+ mouseDown = true;
+ } else if (Mouse.getEventButton() != -1) {
+ mouseDown = false;
+ }
+
+ //Unfocuses the search bar by default. Search bar is focused if the click is on the bar itself.
+ if (Mouse.getEventButtonState()) setSearchBarFocus(false);
+
+ guiGroup.mouseClick(0, 0, mouseX, mouseY);
+
+ if (selectedItemGroup != null) {
+ int selectedX = Math.min(selectedItemGroupX, width - getBoxPadding() - 18 * selectedItemGroup.size());
+ if (mouseY > selectedItemGroupY + 17 && mouseY < selectedItemGroupY + 35) {
+ for (int i = 0; i < selectedItemGroup.size(); i++) {
+ if (mouseX >= selectedX - 1 + 18 * i && mouseX <= selectedX + 17 + 18 * i) {
+ JsonObject item = selectedItemGroup.get(i);
+ if (item != null) {
+ if (Mouse.getEventButton() == 0) {
+ manager.showRecipe(item);
+ } else if (Mouse.getEventButton() == 1) {
+ showInfo(item);
+ } else if (Mouse.getEventButton() == manager.keybindItemSelect.getKeyCode() + 100 &&
+ NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ textField.setText("id:" + item.get("internalname").getAsString());
+ updateSearch();
+ searchMode = true;
+ }
+ }
+ Utils.pushGuiScale(-1);
+ return true;
+ }
+ }
+ }
+ }
+
+ //Item selection (right) gui
+ if (mouseX > width * getItemPaneOffsetFactor()) {
+ if (!Mouse.getEventButtonState()) {
+ Utils.pushGuiScale(-1);
+ return true; //End early if the mouse isn't pressed, but still cancel event.
+ }
+
+ AtomicBoolean clickedItem = new AtomicBoolean(false);
+ iterateItemSlots(new ItemSlotConsumer() {
+ public void consume(int x, int y, int id) {
+ if (mouseX >= x - 1 && mouseX <= x + ITEM_SIZE + 1) {
+ if (mouseY >= y - 1 && mouseY <= y + ITEM_SIZE + 1) {
+ clickedItem.set(true);
+
+ JsonObject item = getSearchedItemPage(id);
+ if (item != null) {
+ if (Mouse.getEventButton() == 0) {
+ manager.showRecipe(item);
+ } else if (Mouse.getEventButton() == 1) {
+ showInfo(item);
+ } else if (Mouse.getEventButton() == manager.keybindItemSelect.getKeyCode() + 100 &&
+ NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ textField.setText("id:" + item.get("internalname").getAsString());
+ updateSearch();
+ searchMode = true;
+ }
+ }
+ }
+ }
+ }
+ });
+ if (!clickedItem.get()) {
+ int paneWidth = (int) (width / 3 * getWidthMult());
+ int leftSide = (int) (width * getItemPaneOffsetFactor());
+ int rightSide = leftSide + paneWidth - getBoxPadding() - getItemBoxXPadding();
+ leftSide = leftSide + getBoxPadding() + getItemBoxXPadding();
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ int maxPages = getMaxPages();
+ String name = Utils.peekGuiScale().getScaleFactor() < 4 ? "Page: " : "";
+ float maxStrLen = fr.getStringWidth(EnumChatFormatting.BOLD + name + maxPages + "/" + maxPages);
+ float maxButtonXSize = (rightSide - leftSide + 2 - maxStrLen * 0.5f - 10) / 2f;
+ int buttonXSize = (int) Math.min(maxButtonXSize, getSearchBarYSize() * 480 / 160f);
+ int ySize = (int) (buttonXSize / 480f * 160);
+ int yOffset = (int) ((getSearchBarYSize() - ySize) / 2f);
+ int top = getBoxPadding() + yOffset;
+
+ if (mouseY >= top && mouseY <= top + ySize) {
+ int leftPrev = leftSide - 1;
+ if (mouseX > leftPrev && mouseX < leftPrev + buttonXSize) { //"Previous" button
+ setPage(page - 1);
+ Utils.playPressSound();
+ }
+ int leftNext = rightSide + 1 - buttonXSize;
+ if (mouseX > leftNext && mouseX < leftNext + buttonXSize) { //"Next" button
+ setPage(page + 1);
+ Utils.playPressSound();
+ }
+ }
+
+ float sortIconsMinX = (sortIcons.length + orderIcons.length) * (ITEM_SIZE + ITEM_PADDING) + ITEM_SIZE;
+ float availableX = rightSide - leftSide;
+ float sortOrderScaleFactor = Math.min(1, availableX / sortIconsMinX);
+
+ int scaledITEM_SIZE = (int) (ITEM_SIZE * sortOrderScaleFactor);
+ int scaledItemPaddedSize = (int) ((ITEM_SIZE + ITEM_PADDING) * sortOrderScaleFactor);
+ int iconTop = height - getBoxPadding() - (ITEM_SIZE + scaledITEM_SIZE) / 2 - 1;
+
+ if (mouseY >= iconTop && mouseY <= iconTop + scaledITEM_SIZE) {
+ for (int i = 0; i < orderIcons.length; i++) {
+ int orderIconX = leftSide + i * scaledItemPaddedSize;
+ if (mouseX >= orderIconX && mouseX <= orderIconX + scaledITEM_SIZE) {
+ if (Mouse.getEventButton() == 0) {
+ NotEnoughUpdates.INSTANCE.config.hidden.compareMode = i;
+ updateSearch();
+ Utils.playPressSound();
+ } else if (Mouse.getEventButton() == 1) {
+ NotEnoughUpdates.INSTANCE.config.hidden.compareAscending.set(
+ i,
+ !NotEnoughUpdates.INSTANCE.config.hidden.compareAscending.get(i)
+ );
+ updateSearch();
+ Utils.playPressSound();
+ }
+ }
+ }
+
+ for (int i = 0; i < sortIcons.length; i++) {
+ int sortIconX = rightSide - scaledITEM_SIZE - i * scaledItemPaddedSize;
+ if (mouseX >= sortIconX && mouseX <= sortIconX + scaledITEM_SIZE) {
+ NotEnoughUpdates.INSTANCE.config.hidden.sortMode = i;
+ updateSearch();
+ Utils.playPressSound();
+ }
+ }
+ }
+ }
+ Utils.pushGuiScale(-1);
+ return true;
+ }
+
+ //Clicking on "close info pane" button
+ if (mouseX > width * getInfoPaneOffsetFactor() - getBoxPadding() - 8 &&
+ mouseX < width * getInfoPaneOffsetFactor() - getBoxPadding() + 8) {
+ if (mouseY > getBoxPadding() - 8 && mouseY < getBoxPadding() + 8) {
+ if (Mouse.getEventButtonState() && Mouse.getEventButton() < 2) { //Left or right click up
+ displayInformationPane(null);
+ Utils.pushGuiScale(-1);
+ return true;
+ }
+ }
+ }
+
+ if (activeInfoPane != null) {
+ if (mouseX < width * getInfoPaneOffsetFactor()) {
+ activeInfoPane.mouseInput(width, height, mouseX, mouseY, mouseDown);
+ Utils.pushGuiScale(-1);
+ return true;
+ } else if (Mouse.getEventButton() <= 1 && Mouse.getEventButtonState()) { //Left or right click
+ activeInfoPane.mouseInputOutside();
+ }
+ }
+
+ Utils.pushGuiScale(-1);
+ return false;
+ }
+
+ public int getPaddingUnscaled() {
+ int paddingUnscaled = searchBarPadding / Utils.peekGuiScale().getScaleFactor();
+ if (paddingUnscaled < 1) paddingUnscaled = 1;
+
+ return paddingUnscaled;
+ }
+
+ public GuiTextField getTextField() {
+ return textField;
+ }
+
+ /**
+ * Returns searchBarXSize, scaled by 0.8 if gui scale == AUTO.
+ */
+ public int getSearchBarXSize() {
+ int searchBarXSize = NotEnoughUpdates.INSTANCE.config.toolbar.searchBarWidth;
+ if (Utils.peekGuiScale().getScaleFactor() == 4) return (int) (searchBarXSize * 0.8);
+ return searchBarXSize;
+ }
+
+ /**
+ * Sets the activeInfoPane and sets the target of the infoPaneOffsetFactor to make the infoPane "slide" out.
+ */
+ public void displayInformationPane(InfoPane pane) {
+ infoPaneLoadingJob.cancel(false);
+ if (pane == null) {
+ infoPaneOffsetFactor.setTarget(0);
+ } else {
+ infoPaneOffsetFactor.setTarget(1 / 3f);
+ }
+ infoPaneOffsetFactor.resetTimer();
+ this.activeInfoPane = pane;
+ }
+
+ public InfoPane getActiveInfoPane() {
+ return activeInfoPane;
+ }
+
+ /**
+ * Finds the index of the character inside the search bar that was clicked, used to set the caret.
+ */
+ public int getClickedIndex(int mouseX, int mouseY) {
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+
+ int xComp = mouseX - (width / 2 - getSearchBarXSize() / 2 + 5);
+
+ String trimmed = Minecraft.getMinecraft().fontRendererObj.trimStringToWidth(textField.getText(), xComp);
+ int linePos = trimmed.length();
+ if (linePos != textField.getText().length()) {
+ char after = textField.getText().charAt(linePos);
+ int trimmedWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(trimmed);
+ int charWidth = Minecraft.getMinecraft().fontRendererObj.getCharWidth(after);
+ if (trimmedWidth + charWidth / 2 < xComp - 5) {
+ linePos++;
+ }
+ }
+ return linePos;
+ }
+
+ public void setSearchBarFocus(boolean focus) {
+ if (focus) {
+ itemPaneOpen = true;
+ }
+ searchBarHasFocus = focus;
+ }
+
+ /**
+ * Handles the keyboard input, cancelling the forge event if the search bar has focus.
+ */
+ public boolean keyboardInput(boolean hoverInv) {
+ if (Minecraft.getMinecraft().currentScreen == null) return false;
+ Keyboard.enableRepeatEvents(true);
+
+ int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
+
+ if (disabled) {
+ if (Keyboard.getEventKeyState() && keyPressed == manager.keybindToggleDisplay.getKeyCode()) {
+ disabled = !disabled;
+ }
+ return false;
+ }
+
+ if (Keyboard.isKeyDown(Keyboard.KEY_Y) && NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ displayInformationPane(new DevInfoPane(this, manager));
+ }
+
+ if (Keyboard.getEventKeyState()) {
+ if (!NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ searchBarHasFocus = false;
+ }
+ if (searchBarHasFocus) {
+ if (keyPressed == 1) {
+ searchBarHasFocus = false;
+ } else {
+ if (textField.textboxKeyTyped(Keyboard.getEventCharacter(), keyPressed)) {
+ updateSearch();
+ }
+ }
+ } else {
+ if (activeInfoPane != null) {
+ if (activeInfoPane.keyboardInput()) {
+ return true;
+ }
+ }
+
+ if (keyPressed == manager.keybindClosePanes.getKeyCode()) {
+ itemPaneOffsetFactor.setValue(1);
+ itemPaneTabOffset.setValue(20);
+ itemPaneOpen = false;
+ displayInformationPane(null);
+ }
+
+ if (keyPressed == manager.keybindToggleDisplay.getKeyCode()) {
+ disabled = !disabled;
+ return true;
+ }
+
+ AtomicReference internalname = new AtomicReference<>(null);
+ AtomicReference itemstack = new AtomicReference<>(null);
+ if (Minecraft.getMinecraft().currentScreen instanceof GuiContainer &&
+ Utils.getSlotUnderMouse((GuiContainer) Minecraft.getMinecraft().currentScreen) != null) {
+ Slot slot = Utils.getSlotUnderMouse((GuiContainer) Minecraft.getMinecraft().currentScreen);
+ ItemStack hover = slot.getStack();
+ if (hover != null) {
+ internalname.set(manager.getInternalNameForItem(hover));
+ itemstack.set(hover);
+ }
+ } else if (!hoverInv) {
+ Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
+
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+
+ if (selectedItemGroup != null) {
+ int selectedX = Math.min(selectedItemGroupX, width - getBoxPadding() - 18 * selectedItemGroup.size());
+
+ if (mouseY > selectedItemGroupY + 17 && mouseY < selectedItemGroupY + 35) {
+ for (int i = 0; i < selectedItemGroup.size(); i++) {
+ if (mouseX >= selectedX - 1 + 18 * i && mouseX <= selectedX + 17 + 18 * i) {
+ internalname.set(selectedItemGroup.get(i).get("internalname").getAsString());
+ }
+ }
+ }
+ } else {
+ iterateItemSlots(new ItemSlotConsumer() {
+ public void consume(int x, int y, int id) {
+ if (mouseX >= x - 1 && mouseX <= x + ITEM_SIZE + 1) {
+ if (mouseY >= y - 1 && mouseY <= y + ITEM_SIZE + 1) {
+ JsonObject json = getSearchedItemPage(id);
+ if (json != null) internalname.set(json.get("internalname").getAsString());
+ }
+ }
+ }
+ });
+ }
+
+ Utils.pushGuiScale(-1);
+ }
+ if (internalname.get() != null) {
+ if (itemstack.get() != null) {
+ if (NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && Keyboard.getEventCharacter() == 'k') {
+ Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager,
+ internalname.get(), manager.getJsonForItem(itemstack.get())
+ ));
+ return true;
+ }
+ }
+ JsonObject item = manager.getItemInformation().get(internalname.get());
+ if (item != null) {
+ if (keyPressed == manager.keybindViewUsages.getKeyCode()) {
+ manager.displayGuiItemUsages(internalname.get());
+ return true;
+ } else if (keyPressed == manager.keybindFavourite.getKeyCode()) {
+ toggleFavourite(item.get("internalname").getAsString());
+ return true;
+ } else if (keyPressed == manager.keybindViewRecipe.getKeyCode()) {
+ manager.showRecipe(item);
+ return true;
+ } else if (keyPressed == manager.keybindGive.getKeyCode()) {
+ if (Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) {
+ Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory(
+ manager.jsonToStack(item));
+ }
+ } else if (NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing &&
+ Keyboard.getEventCharacter() == 'k') {
+ Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager,
+ internalname.get(), item
+ ));
+ return true;
+ } else if (keyPressed == manager.keybindItemSelect.getKeyCode() &&
+ NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ textField.setText("id:" + internalname.get());
+ itemPaneOpen = true;
+ updateSearch();
+ } else if (keyPressed == NotEnoughUpdates.INSTANCE.config.ahGraph.graphKey &&
+ NotEnoughUpdates.INSTANCE.config.ahGraph.graphEnabled) {
+ NotEnoughUpdates.INSTANCE.openGui = new GuiPriceGraph(internalname.get());
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return searchBarHasFocus; //Cancels keyboard events if the search bar has focus
+ }
+
+ public void toggleFavourite(String internalname) {
+ if (getFavourites().contains(internalname)) {
+ getFavourites().remove(internalname);
+ } else {
+ getFavourites().add(internalname);
+ }
+ updateSearch();
+ }
+
+ String[] rarityArr = new String[]{
+ EnumChatFormatting.WHITE + EnumChatFormatting.BOLD.toString() + "COMMON",
+ EnumChatFormatting.GREEN + EnumChatFormatting.BOLD.toString() + "UNCOMMON",
+ EnumChatFormatting.BLUE + EnumChatFormatting.BOLD.toString() + "RARE",
+ EnumChatFormatting.DARK_PURPLE + EnumChatFormatting.BOLD.toString() + "EPIC",
+ EnumChatFormatting.GOLD + EnumChatFormatting.BOLD.toString() + "LEGENDARY",
+ EnumChatFormatting.LIGHT_PURPLE + EnumChatFormatting.BOLD.toString() + "MYTHIC",
+ EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "SPECIAL",
+ };
+
+ /**
+ * Finds the rarity from the lore of an item.
+ * -1 = UNKNOWN
+ * 0 = COMMON
+ * 1 = UNCOMMON
+ * 2 = RARE
+ * 3 = EPIC
+ * 4 = LEGENDARY
+ * 5 = MYTHIC
+ * 6 = SPECIAL
+ */
+ public int getRarity(JsonArray lore) {
+ for (int i = lore.size() - 1; i >= 0; i--) {
+ String line = lore.get(i).getAsString();
+
+ for (int j = 0; j < rarityArr.length; j++) {
+ if (line.startsWith(rarityArr[j])) {
+ return j;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Convenience functions that get various compare/sort modes from the config.
+ */
+ private int getCompareMode() {
+ return NotEnoughUpdates.INSTANCE.config.hidden.compareMode;
+ }
+
+ private int getSortMode() {
+ return NotEnoughUpdates.INSTANCE.config.hidden.sortMode;
+ }
+
+ private List getCompareAscending() {
+ return NotEnoughUpdates.INSTANCE.config.hidden.compareAscending;
+ }
+
+ private List getFavourites() {
+ return NotEnoughUpdates.INSTANCE.config.hidden.favourites;
+ }
+
+ /**
+ * Creates an item comparator used to sort the list of items according to the favourite set then compare mode.
+ * Defaults to alphabetical sorting if the above factors cannot distinguish between two items.
+ */
+ private Comparator getItemComparator() {
+ return (o1, o2) -> {
+ //1 (mult) if o1 should appear after o2
+ //-1 (-mult) if o2 should appear after o1
+ if (getFavourites().contains(o1.get("internalname").getAsString()) &&
+ !getFavourites().contains(o2.get("internalname").getAsString())) {
+ return -1;
+ }
+ if (!getFavourites().contains(o1.get("internalname").getAsString()) &&
+ getFavourites().contains(o2.get("internalname").getAsString())) {
+ return 1;
+ }
+
+ int mult = getCompareAscending().get(getCompareMode()) ? 1 : -1;
+ if (getCompareMode() == COMPARE_MODE_RARITY) {
+ int rarity1 = getRarity(o1.get("lore").getAsJsonArray());
+ int rarity2 = getRarity(o2.get("lore").getAsJsonArray());
+
+ if (rarity1 < rarity2) return mult;
+ if (rarity1 > rarity2) return -mult;
+ } else if (getCompareMode() == COMPARE_MODE_VALUE) {
+ String internal1 = o1.get("internalname").getAsString();
+ String internal2 = o2.get("internalname").getAsString();
+
+ float cost1 = manager.auctionManager.getLowestBin(internal1);
+ float cost2 = manager.auctionManager.getLowestBin(internal2);
+
+ if (cost1 < cost2) return mult;
+ if (cost1 > cost2) return -mult;
+ }
+
+ String i1 = o1.get("internalname").getAsString();
+ String[] split1 = i1.split("_");
+ String last1 = split1[split1.length - 1];
+ String start1 = i1.substring(0, i1.length() - last1.length());
+
+ String i2 = o2.get("internalname").getAsString();
+ String[] split2 = i2.split("_");
+ String last2 = split2[split2.length - 1];
+ String start2 = i2.substring(0, i2.length() - last2.length());
+
+ mult = getCompareAscending().get(COMPARE_MODE_ALPHABETICAL) ? 1 : -1;
+ if (start1.equals(start2)) {
+ String[] order = new String[]{"HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS"};
+ int type1 = checkItemType(o1.get("lore").getAsJsonArray(), order);
+ int type2 = checkItemType(o2.get("lore").getAsJsonArray(), order);
+
+ if (type1 < type2) return -mult;
+ if (type1 > type2) return mult;
+ }
+
+ int nameComp = mult * o1.get("displayname").getAsString().replaceAll("(?i)\\u00A7.", "")
+ .compareTo(o2.get("displayname").getAsString().replaceAll("(?i)\\u00A7.", ""));
+ if (nameComp != 0) {
+ return nameComp;
+ }
+ return mult * o1.get("internalname").getAsString().compareTo(o2.get("internalname").getAsString());
+ };
+ }
+
+ /**
+ * Checks whether an item matches a certain type, i.e. whether the item lore ends in "{rarity} {item type}"
+ * eg. "SHOVEL" will return >0 for "COMMON SHOVEL", "EPIC SHOVEL", etc.
+ *
+ * @return the index of the type that matched, or -1 otherwise.
+ */
+ public int checkItemType(JsonArray lore, String... typeMatches) {
+ for (int i = lore.size() - 1; i >= 0; i--) {
+ String line = lore.get(i).getAsString();
+
+ for (String rarity : rarityArr) {
+ for (int j = 0; j < typeMatches.length; j++) {
+ if (line.trim().equals(rarity + " " + typeMatches[j])) {
+ return j;
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Checks whether an item matches the current sort mode.
+ */
+ public boolean checkMatchesSort(String internalname, JsonObject item) {
+ if (!NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems &&
+ item.has("vanilla") &&
+ item.get("vanilla").getAsBoolean()) {
+ return false;
+ }
+
+ if (getSortMode() == SORT_MODE_ALL) {
+ return !internalname.matches(mobRegex);
+ } else if (getSortMode() == SORT_MODE_MOB) {
+ return internalname.matches(mobRegex);
+ } else if (getSortMode() == SORT_MODE_PET) {
+ return internalname.matches(petRegex) && item.get("displayname").getAsString().contains("[");
+ } else if (getSortMode() == SORT_MODE_TOOL) {
+ return checkItemType(
+ item.get("lore").getAsJsonArray(),
+ "SWORD",
+ "BOW",
+ "AXE",
+ "PICKAXE",
+ "FISHING ROD",
+ "WAND",
+ "SHOVEL",
+ "HOE",
+ "DUNGEON SWORD",
+ "DUNGEON BOW",
+ "DRILL",
+ "GAUNTLET"
+ ) >= 0;
+ } else if (getSortMode() == SORT_MODE_ARMOR) {
+ return checkItemType(
+ item
+ .get("lore")
+ .getAsJsonArray(),
+ "HELMET",
+ "CHESTPLATE",
+ "LEGGINGS",
+ "BOOTS",
+ "DUNGEON HELMET",
+ "DUNGEON CHESTPLATE",
+ "DUNGEON LEGGINGS",
+ "DUNGEON BOOTS"
+ ) >=
+ 0;
+ } else if (getSortMode() == SORT_MODE_ACCESSORY) {
+ return checkItemType(item.get("lore").getAsJsonArray(), "ACCESSORY", "HATCCESSORY", "DUNGEON ACCESSORY") >= 0;
+ }
+ return true;
+ }
+
+ private final HashMap parentMap = new HashMap<>();
+
+ private final ExecutorService searchES = Executors.newSingleThreadExecutor();
+
+ /**
+ * Clears the current item list, creating a new TreeSet if necessary.
+ * Adds all items that match the search AND match the sort mode to the current item list.
+ * Also adds some easter egg items. (Also I'm very upset if you came here to find them :'( )
+ */
+ public void updateSearch() {
+ SunTzu.randomizeQuote();
+
+ if (searchedItems == null) searchedItems = new TreeSet<>(getItemComparator());
+
+ searchES.submit(() -> {
+ TreeSet searchedItems = new TreeSet<>(getItemComparator());
+ HashMap> searchedItemsSubgroup = new HashMap<>();
+
+ Set removeChildItems = new HashSet<>();
+ Set itemsMatch = manager.search(textField.getText(), true);
+ for (String itemname : itemsMatch) {
+ JsonObject item = manager.getItemInformation().get(itemname);
+ if (checkMatchesSort(itemname, item)) {
+ if (Constants.PARENTS != null) {
+ if (Constants.PARENTS.has(itemname) && Constants.PARENTS.get(itemname).isJsonArray()) {
+ List children = new ArrayList<>();
+ for (JsonElement e : Constants.PARENTS.get(itemname).getAsJsonArray()) {
+ if (e.isJsonPrimitive()) {
+ children.add(e.getAsString());
+ }
+ }
+ children.retainAll(itemsMatch);
+ for (String child : children) {
+ removeChildItems.add(manager.getItemInformation().get(child));
+ }
+ searchedItemsSubgroup.put(itemname, children);
+ }
+ }
+ searchedItems.add(item);
+ }
+ }
+ searchedItems.removeAll(removeChildItems);
+ out:
+ for (Map.Entry> entry : searchedItemsSubgroup.entrySet()) {
+ if (searchedItems.contains(manager.getItemInformation().get(entry.getKey()))) {
+ continue;
+ }
+ for (String itemname : entry.getValue()) {
+ JsonObject item = manager.getItemInformation().get(itemname);
+ if (item != null) searchedItems.add(item);
+ }
+ }
+ switch (textField.getText().toLowerCase().trim()) {
+ case "nullzee":
+ searchedItems.add(CustomItems.NULLZEE);
+ break;
+ case "rune":
+ searchedItems.add(CustomItems.RUNE);
+ break;
+ case "2b2t":
+ searchedItems.add(CustomItems.TWOBEETWOTEE);
+ break;
+ case "ducttape":
+ case "ducttapedigger":
+ searchedItems.add(CustomItems.DUCTTAPE);
+ break;
+ case "thirtyvirus":
+ searchedItems.add(manager.getItemInformation().get("SPIKED_BAIT"));
+ break;
+ case "leocthl":
+ searchedItems.add(CustomItems.LEOCTHL);
+ break;
+ case "spinaxx":
+ searchedItems.add(CustomItems.SPINAXX);
+ break;
+ case "credits":
+ case "credit":
+ case "who made this mod":
+ searchedItems.add(CustomItems.CREDITS);
+ break;
+ case "ironmoon":
+ case "ironm00n":
+ searchedItems.add(CustomItems.IRONM00N);
+ break;
+ case "nopo":
+ case "nopothegamer":
+ searchedItems.add(CustomItems.NOPO);
+ break;
+ }
+
+ this.searchedItems = searchedItems;
+ this.searchedItemsSubgroup = searchedItemsSubgroup;
+
+ synchronized (this.searchedItemsArr) {
+ this.searchedItemsArr.clear();
+ }
+
+ redrawItems = true;
+ });
+ }
+
+ /**
+ * Returns an index-able array containing the elements in searchedItems.
+ * Whenever searchedItems is updated in updateSearch(), the array is recreated here.
+ */
+ public List getSearchedItems() {
+ if (searchedItems == null) {
+ updateSearch();
+ return new ArrayList<>();
+ }
+
+ if (searchedItems.size() > 0 && searchedItemsArr.size() == 0) {
+ synchronized (searchedItemsArr) {
+ searchedItemsArr.addAll(searchedItems);
+ }
+ }
+ return searchedItemsArr;
+ }
+
+ /**
+ * Gets the item in searchedItemArr corresponding to the certain index on the current page.
+ *
+ * @return item, if the item exists. null, otherwise.
+ */
+ public JsonObject getSearchedItemPage(int index) {
+ if (index < getSlotsXSize() * getSlotsYSize()) {
+ int actualIndex = index + getSlotsXSize() * getSlotsYSize() * page;
+ List searchedItems = getSearchedItems();
+ if (actualIndex < searchedItems.size()) {
+ return searchedItems.get(actualIndex);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ public int getItemBoxXPadding() {
+ int width = Utils.peekGuiScale().getScaledWidth();
+ return (((int) (width / 3 * getWidthMult()) - 2 * getBoxPadding()) % (ITEM_SIZE + ITEM_PADDING) + ITEM_PADDING) / 2;
+ }
+
+ public int getBoxPadding() {
+ double panePadding = Math.max(0, Math.min(20, NotEnoughUpdates.INSTANCE.config.itemlist.panePadding));
+ return (int) (panePadding * 2 / Utils.peekGuiScale().getScaleFactor() + 5);
+ }
+
+ private abstract static class ItemSlotConsumer {
+ public abstract void consume(int x, int y, int id);
+ }
+
+ public void iterateItemSlots(ItemSlotConsumer itemSlotConsumer) {
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int itemBoxXPadding = getItemBoxXPadding();
+ iterateItemSlots(itemSlotConsumer, (int) (width * getItemPaneOffsetFactor()) + getBoxPadding() + itemBoxXPadding);
+ }
+
+ /**
+ * Iterates through all the item slots in the right panel and calls a ItemSlotConsumer for each slot with
+ * arguments equal to the slot's x and y position respectively. This is used in order to prevent
+ * code duplication issues.
+ */
+ public void iterateItemSlots(ItemSlotConsumer itemSlotConsumer, int xStart) {
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+
+ int paneWidth = (int) (width / 3 * getWidthMult());
+ int itemBoxYPadding =
+ ((height - getSearchBarYSize() - 2 * getBoxPadding() - ITEM_SIZE - 2) % (ITEM_SIZE + ITEM_PADDING) +
+ ITEM_PADDING) / 2;
+
+ int yStart = getBoxPadding() + getSearchBarYSize() + itemBoxYPadding;
+ int itemBoxXPadding = getItemBoxXPadding();
+ int xEnd = xStart + paneWidth - getBoxPadding() * 2 - ITEM_SIZE - itemBoxXPadding;
+ int yEnd = height - getBoxPadding() - ITEM_SIZE - 2 - itemBoxYPadding;
+
+ //Render the items, displaying the tooltip if the cursor is over the item
+ int id = 0;
+ for (int y = yStart; y < yEnd; y += ITEM_SIZE + ITEM_PADDING) {
+ for (int x = xStart; x < xEnd; x += ITEM_SIZE + ITEM_PADDING) {
+ itemSlotConsumer.consume(x, y, id++);
+ }
+ }
+ }
+
+ public float getWidthMult() {
+ float scaleFMult = 1;
+ if (Utils.peekGuiScale().getScaleFactor() == 4) scaleFMult *= 0.9f;
+ if (manager.auctionManager.customAH.isRenderOverAuctionView() ||
+ Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)
+ scaleFMult *= 0.8f;
+ return (float) Math.max(0.5, Math.min(1.5, NotEnoughUpdates.INSTANCE.config.itemlist.paneWidthMult)) * scaleFMult;
+ }
+
+ /**
+ * Calculates the number of horizontal item slots.
+ */
+ public int getSlotsXSize() {
+ int width = Utils.peekGuiScale().getScaledWidth();
+
+ int paneWidth = (int) (width / 3 * getWidthMult());
+ int itemBoxXPadding =
+ (((int) (width - width * getItemPaneOffsetFactor()) - 2 * getBoxPadding()) % (ITEM_SIZE + ITEM_PADDING) +
+ ITEM_PADDING) / 2;
+ int xStart = (int) (width * getItemPaneOffsetFactor()) + getBoxPadding() + itemBoxXPadding;
+ int xEnd = (int) (width * getItemPaneOffsetFactor()) + paneWidth - getBoxPadding() - ITEM_SIZE;
+
+ return (int) Math.ceil((xEnd - xStart) / ((float) (ITEM_SIZE + ITEM_PADDING)));
+ }
+
+ /**
+ * Calculates the number of vertical item slots.
+ */
+ public int getSlotsYSize() {
+ int height = Utils.peekGuiScale().getScaledHeight();
+
+ int itemBoxYPadding =
+ ((height - getSearchBarYSize() - 2 * getBoxPadding() - ITEM_SIZE - 2) % (ITEM_SIZE + ITEM_PADDING) +
+ ITEM_PADDING) / 2;
+ int yStart = getBoxPadding() + getSearchBarYSize() + itemBoxYPadding;
+ int yEnd = height - getBoxPadding() - ITEM_SIZE - 2 - itemBoxYPadding;
+
+ return (int) Math.ceil((yEnd - yStart) / ((float) (ITEM_SIZE + ITEM_PADDING)));
+ }
+
+ public int getMaxPages() {
+ if (getSearchedItems().size() == 0) return 1;
+ return (int) Math.ceil(getSearchedItems().size() / (float) getSlotsYSize() / getSlotsXSize());
+ }
+
+ public int getSearchBarYSize() {
+ int searchBarYSize = NotEnoughUpdates.INSTANCE.config.toolbar.searchBarHeight;
+ return Math.max(searchBarYSize / Utils.peekGuiScale().getScaleFactor(), ITEM_SIZE);
+ }
+
+ /**
+ * Renders the top navigation bar, can be used by InfoPane implementations (such as SettingsInfoPane).
+ * Renders "prev" button, index/maxIndex string, "next" button.
+ */
+ public void renderNavElement(int leftSide, int rightSide, int maxPages, int page, String name) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+
+ String pageText = EnumChatFormatting.BOLD + name + page + "/" + maxPages;
+
+ float maxStrLen = fr.getStringWidth(EnumChatFormatting.BOLD + name + maxPages + "/" + maxPages);
+ float maxButtonXSize = (rightSide - leftSide + 2 - maxStrLen * 0.5f - 10) / 2f;
+ int buttonXSize = (int) Math.min(maxButtonXSize, getSearchBarYSize() * 480 / 160f);
+ int ySize = (int) (buttonXSize / 480f * 160);
+ int yOffset = (int) ((getSearchBarYSize() - ySize) / 2f);
+ int top = getBoxPadding() + yOffset;
+
+ int leftPressed = 0;
+ int rightPressed = 0;
+
+ if (Mouse.isButtonDown(0) || Mouse.isButtonDown(1)) {
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+
+ if (mouseY >= top && mouseY <= top + ySize) {
+ int leftPrev = leftSide - 1;
+ if (mouseX > leftPrev && mouseX < leftPrev + buttonXSize) { //"Previous" button
+ leftPressed = 1;
+ }
+ int leftNext = rightSide + 1 - buttonXSize;
+ if (mouseX > leftNext && mouseX < leftNext + buttonXSize) { //"Next" button
+ rightPressed = 1;
+ }
+ }
+ }
+
+ drawRect(leftSide - 1, top, leftSide - 1 + buttonXSize, top + ySize, fg.getRGB());
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow);
+ Utils.drawTexturedRect(leftSide - 1 + leftPressed,
+ top + leftPressed,
+ buttonXSize, ySize, 1, 0, 0, 1
+ );
+ Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay);
+ Utils.drawTexturedRect(leftSide - 1,
+ top,
+ buttonXSize, ySize, 1 - leftPressed, leftPressed, 1 - leftPressed, leftPressed
+ );
+ GlStateManager.bindTexture(0);
+ Utils.drawStringCenteredScaled(EnumChatFormatting.BOLD + "Prev", fr,
+ leftSide - 1 + buttonXSize * 300 / 480f + leftPressed,
+ top + ySize / 2f + leftPressed, false,
+ (int) (buttonXSize * 240 / 480f), Color.BLACK.getRGB()
+ );
+
+ drawRect(rightSide + 1 - buttonXSize, top, rightSide + 1, top + ySize, fg.getRGB());
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow);
+ Utils.drawTexturedRect(rightSide + 1 - buttonXSize + rightPressed,
+ top + rightPressed,
+ buttonXSize, ySize
+ );
+ Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay);
+ Utils.drawTexturedRect(rightSide + 1 - buttonXSize,
+ top,
+ buttonXSize, ySize, 1 - rightPressed, rightPressed, 1 - rightPressed, rightPressed
+ );
+ GlStateManager.bindTexture(0);
+ Utils.drawStringCenteredScaled(EnumChatFormatting.BOLD + "Next", fr,
+ rightSide + 1 - buttonXSize * 300 / 480f + rightPressed,
+ top + ySize / 2f + rightPressed, false,
+ (int) (buttonXSize * 240 / 480f), Color.BLACK.getRGB()
+ );
+
+ int strMaxLen = rightSide - leftSide - 2 * buttonXSize - 10;
+
+ drawRect(leftSide - 1 + buttonXSize + 3, top, rightSide + 1 - buttonXSize - 3, top + ySize,
+ new Color(177, 177, 177).getRGB()
+ );
+ drawRect(leftSide + buttonXSize + 3, top + 1, rightSide + 1 - buttonXSize - 3, top + ySize,
+ new Color(50, 50, 50).getRGB()
+ );
+ drawRect(leftSide + buttonXSize + 3, top + 1, rightSide - buttonXSize - 3, top + ySize - 1, fg.getRGB());
+ Utils.drawStringCenteredScaledMaxWidth(pageText, fr, (leftSide + rightSide) / 2,
+ top + ySize / 2f, false, strMaxLen, Color.BLACK.getRGB()
+ );
+ }
+
+ private int limCol(int col) {
+ return Math.min(255, Math.max(0, col));
+ }
+
+ public boolean isUsingMobsFilter() {
+ return getSortMode() == SORT_MODE_MOB;
+ }
+
+ public float yaw = 0;
+ public float pitch = 20;
+
+ /**
+ * Renders an entity onto the GUI at a certain x and y position.
+ */
+ private void renderEntity(
+ float posX,
+ float posY,
+ float scale,
+ String name,
+ Class extends EntityLivingBase>... classes
+ ) {
+ EntityLivingBase[] entities = new EntityLivingBase[classes.length];
+ try {
+ EntityLivingBase last = null;
+ for (int i = 0; i < classes.length; i++) {
+ Class extends EntityLivingBase> clazz = classes[i];
+ if (clazz == null) continue;
+
+ EntityLivingBase newEnt =
+ clazz.getConstructor(new Class[]{World.class}).newInstance(Minecraft.getMinecraft().theWorld);
+
+ //newEnt.renderYawOffset = yaw;
+ //newEnt.rotationYaw = yaw;
+ newEnt.rotationPitch = pitch;
+ //newEnt.rotationYawHead = yaw;
+ //newEnt.prevRotationYawHead = yaw-1;
+
+ newEnt.setCustomNameTag(name);
+
+ if (last != null) {
+ last.riddenByEntity = newEnt;
+ newEnt.ridingEntity = last;
+ last.updateRiderPosition();
+ }
+ last = newEnt;
+
+ entities[i] = newEnt;
+ }
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ GlStateManager.enableColorMaterial();
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(posX, posY, 50.0F);
+ GlStateManager.scale(-scale, scale, scale);
+ GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F);
+
+ GlStateManager.rotate(135.0F, 0.0F, 1.0F, 0.0F);
+ RenderHelper.enableStandardItemLighting();
+ GlStateManager.rotate(-135.0F, 0.0F, 1.0F, 0.0F);
+
+ GlStateManager.rotate(pitch, 1.0F, 0.0F, 0.0F);
+ GlStateManager.rotate(yaw, 0.0F, 1.0F, 0.0F);
+
+ RenderManager rendermanager = Minecraft.getMinecraft().getRenderManager();
+ rendermanager.setPlayerViewY(180.0F);
+ rendermanager.setRenderShadow(false);
+ for (EntityLivingBase ent : entities) {
+ GL11.glColor4f(1, 1, 1, 1);
+ if (ent != null) rendermanager.renderEntityWithPosYaw(ent, ent.posX, ent.posY, ent.posZ, 0.0F, 1.0F);
+ }
+ rendermanager.setRenderShadow(true);
+
+ GlStateManager.popMatrix();
+ RenderHelper.disableStandardItemLighting();
+ GlStateManager.disableRescaleNormal();
+ GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit);
+ GlStateManager.disableTexture2D();
+ GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
+
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ }
+
+ Shader blurShaderHorz = null;
+ Framebuffer blurOutputHorz = null;
+ Shader blurShaderVert = null;
+ Framebuffer blurOutputVert = null;
+
+ /**
+ * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate
+ * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis).
+ *
+ * This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to
+ * apply scales and translations manually.
+ */
+ private Matrix4f createProjectionMatrix(int width, int height) {
+ Matrix4f projMatrix = new Matrix4f();
+ projMatrix.setIdentity();
+ projMatrix.m00 = 2.0F / (float) width;
+ projMatrix.m11 = 2.0F / (float) (-height);
+ projMatrix.m22 = -0.0020001999F;
+ projMatrix.m33 = 1.0F;
+ projMatrix.m03 = -1.0F;
+ projMatrix.m13 = 1.0F;
+ projMatrix.m23 = -1.0001999F;
+ return projMatrix;
+ }
+
+ public void updateGuiGroupSize() {
+ Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+
+ if (lastScreenWidth != width || lastScreenHeight != height || Utils.peekGuiScale().getScaleFactor() != lastScale) {
+ guiGroup.width = width;
+ guiGroup.height = height;
+
+ resetAnchors(true);
+ guiGroup.recalculate();
+
+ lastScreenWidth = width;
+ lastScreenHeight = height;
+ lastScale = Utils.peekGuiScale().getScaleFactor();
+ }
+
+ Utils.pushGuiScale(-1);
+ }
+
+ int guiScaleLast = 0;
+ private boolean showVanillaLast = false;
+
+ private boolean wardrobeOpen = false;
+
+ private boolean isInNamedGui(String guiName) {
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+ if (guiScreen instanceof GuiChest) {
+ GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen;
+ ContainerChest container = (ContainerChest) chest.inventorySlots;
+ IInventory lower = container.getLowerChestInventory();
+ String containerName = lower.getDisplayName().getUnformattedText();
+ wardrobeOpen = containerName.contains(guiName);
+ }
+ if (guiScreen instanceof GuiInventory) {
+ wardrobeOpen = false;
+ }
+ return wardrobeOpen;
+ }
+
+ private int wardrobePage = -1;
+
+ private int getWardrobePage() {
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+ if (guiScreen instanceof GuiChest) {
+ if (isInNamedGui("Wardrobe")) {
+ GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen;
+ ContainerChest container = (ContainerChest) chest.inventorySlots;
+ IInventory lower = container.getLowerChestInventory();
+ String containerName = lower.getDisplayName().getUnformattedText();
+ try {
+ wardrobePage = Integer.parseInt(containerName.substring(10, 11));
+ } catch (NumberFormatException e) {
+ System.out.println(containerName.charAt(10));
+ System.out.println("Did hypixel change the wardrobe string?");
+ wardrobePage = -1;
+ }
+ } else wardrobePage = -1;
+ }
+ return wardrobePage;
+ }
+
+ private ItemStack getChestSlotsAsItemStack(int slot) {
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+ if (guiScreen instanceof GuiChest) {
+ GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen;
+ return chest.inventorySlots.getSlot(slot).getStack();
+ } else {
+ return null;
+ }
+ }
+
+ private int selectedArmor = 9;
+
+ private int getEquippedArmor() {
+ if (!isInNamedGui("Wardrobe")) return selectedArmor;
+
+ ItemStack nullTest1 = getChestSlotsAsItemStack(8);
+ ItemStack nullTest2 = getChestSlotsAsItemStack(17);
+ ItemStack nullTest3 = getChestSlotsAsItemStack(26);
+ ItemStack nullTest4 = getChestSlotsAsItemStack(35);
+ ItemStack nullTest5 = getChestSlotsAsItemStack(44);
+ if (nullTest1 != null || nullTest2 != null || nullTest3 != null || nullTest4 != null || nullTest5 != null) {
+ selectedArmor = 9;
+ }
+ for (int ii = 1; ii < 5; ii++) {
+ if (ii != 1 && selectedArmor != 9) continue;
+ if (getWardrobePage() != ii) continue;
+ for (int i = 8; i < 54; i += 9) {
+ ItemStack stack1 = getChestSlotsAsItemStack(i);
+ if (stack1 == null) continue;
+ String[] lore1 = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack1.getTagCompound());
+ for (String line : lore1) {
+ if (line.contains("to unequip this armor")) {
+ selectedArmor = i;
+ break;
+ }
+ }
+ }
+ }
+ return selectedArmor;
+ }
+
+ private ItemStack getWardrobeSlot(int armourSlot) {
+ if (isInNamedGui("Wardrobe")) {
+ if (getChestSlotsAsItemStack(getEquippedArmor() - armourSlot) != null && getEquippedArmor() != 9) {
+ return getChestSlotsAsItemStack(getEquippedArmor() - armourSlot);
+ } else return null;
+ } else return null;
+ }
+
+ public boolean isWardrobeSystemOnMainServer() {
+ JsonElement alphaWardrobeElement = Utils.getElement(Constants.DISABLE, "wardrobeFeature");
+ if (alphaWardrobeElement == null || !alphaWardrobeElement.isJsonObject()) {
+ return true;
+ }
+ JsonObject isWardrobe = alphaWardrobeElement.getAsJsonObject();
+ if (isWardrobe.has("enableNewWardrob")) {
+ return isWardrobe.get("enableNewWardrob").getAsBoolean();
+ } else {
+ return true;
+ }
+ }
+
+ public ItemStack slot1 = null;
+ public ItemStack slot2 = null;
+ public ItemStack slot3 = null;
+ public ItemStack slot4 = null;
+ public ItemStack petSlot = null;
+
+ public static boolean isRenderingArmorHud() {
+ return renderingArmorHud;
+ }
+
+ public static boolean isRenderingPetHud() {
+ return renderingPetHud;
+ }
+
+ /**
+ * Renders the search bar, quick commands, item selection (right), item info (left) and armor hud gui elements.
+ */
+ public void render(boolean hoverInv) {
+ if (disabled) return;
+ renderingArmorHud = false;
+ renderingPetHud = false;
+ GlStateManager.enableDepth();
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+
+ Utils.resetGuiScale();
+ Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale);
+
+ int width = Utils.peekGuiScale().getScaledWidth();
+ int height = Utils.peekGuiScale().getScaledHeight();
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+
+ if (showVanillaLast != NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems) {
+ showVanillaLast = NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems;
+ updateSearch();
+ }
+
+ if (textField.getText().toLowerCase().contains("bald")) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(SUPERGEHEIMNISVERMOGEN);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect((width - 64) / 2f, (height - 64) / 2f - 114, 64, 64, GL11.GL_LINEAR);
+ GlStateManager.bindTexture(0);
+ }
+ GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen;
+
+ if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud &&
+ NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect
+ &&
+ NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() &&
+ isWardrobeSystemOnMainServer()) {
+ if (getWardrobeSlot(1) != null) {
+ slot1 = getWardrobeSlot(4);
+ slot2 = getWardrobeSlot(3);
+ slot3 = getWardrobeSlot(2);
+ slot4 = getWardrobeSlot(1);
+ }
+ if (guiScreen instanceof GuiInventory) {
+ renderingArmorHud = true;
+ selectedArmor = 9;
+
+ List tooltipToDisplay = null;
+ if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 0) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 1) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_GREY);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 2) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_DARK);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 3) {
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3 &&
+ NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay &&
+ petSlot != null) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT_PET);
+ } else {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT);
+ }
+ }
+ if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 4) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_FSR);
+ }
+
+ GlStateManager.color(1, 1, 1, 1);
+ GL11.glTranslatef(0, 0, 401);
+ float yNumber = (float) (height - 167) / 2f;
+ Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 86, GL11.GL_NEAREST);
+ GlStateManager.bindTexture(0);
+
+ Utils.drawItemStack(slot1, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105));
+ Utils.drawItemStack(slot2, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 18);
+ Utils.drawItemStack(slot3, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 36);
+ Utils.drawItemStack(slot4, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 54);
+ if (slot1 == null) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(QUESTION_MARK);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(((width - 208) / 2f), ((height + 60) / 2f - 105), 16, 16, GL11.GL_NEAREST);
+ GlStateManager.bindTexture(0);
+
+ tooltipToDisplay = Lists.newArrayList(
+ EnumChatFormatting.RED + "Warning",
+ EnumChatFormatting.GREEN + "You need to open /wardrobe",
+ EnumChatFormatting.GREEN + "To cache your armour"
+ );
+ if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) {
+ if (mouseY >= ((height + 60) / 2f - 105) &&
+ mouseY <= ((height + 60) / 2f - 105) + 70 &&
+ NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand) {
+ if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) {
+ if (Mouse.getEventButtonState()) {
+ if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/wardrobe") ==
+ 0) {
+ NotEnoughUpdates.INSTANCE.sendChatMessage("/wardrobe");
+ }
+ }
+ }
+ }
+ if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) {
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr);
+ GL11.glTranslatef(0, 0, -401);
+ }
+ }
+
+ }
+ if (slot1 != null && slot2 != null && slot3 != null && slot4 != null) {
+ if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) {
+ if (mouseY >= ((height + 60) / 2f - 105) &&
+ mouseY <= ((height + 60) / 2f - 105) + 70 &&
+ NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand) {
+ if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) {
+ if (Mouse.getEventButtonState()) {
+ if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/wardrobe") ==
+ 0) {
+ NotEnoughUpdates.INSTANCE.sendChatMessage("/wardrobe");
+ }
+ }
+ }
+ }
+ //top slot
+ if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) {
+ tooltipToDisplay = slot1.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr);
+ tooltipToDisplay = null;
+ GL11.glTranslatef(0, 0, -401);
+ }
+ if (mouseY >= ((height + 60) / 2f - 105) + 18 && mouseY <= ((height + 60) / 2f - 105) + 34) {
+ tooltipToDisplay = slot2.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr);
+ tooltipToDisplay = null;
+ GL11.glTranslatef(0, 0, -401);
+ }
+ if (mouseY >= ((height + 60) / 2f - 105) + 36 && mouseY <= ((height + 60) / 2f - 105) + 52) {
+ tooltipToDisplay = slot3.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr);
+ tooltipToDisplay = null;
+ GL11.glTranslatef(0, 0, -401);
+ }
+ if (mouseY >= ((height + 60) / 2f - 105) + 54 && mouseY <= ((height + 60) / 2f - 105) + 70) {
+ tooltipToDisplay = slot4.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr);
+ tooltipToDisplay = null;
+ GL11.glTranslatef(0, 0, -401);
+ }
+ }
+ GL11.glTranslatef(0, 0, -401);
+ }
+ }
+ }
+ if (PetInfoOverlay.getCurrentPet() != null) {
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay
+ &&
+ (NotEnoughUpdates.INSTANCE.manager
+ .jsonToStack(NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId))
+ .hasDisplayName()
+ ||
+ NotEnoughUpdates.INSTANCE.manager
+ .jsonToStack(NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get(PetInfoOverlay.getCurrentPet().petType + ";" + (PetInfoOverlay.getCurrentPet().rarity.petId - 1)))
+ .hasDisplayName())
+ &&
+ NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect &&
+ NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) {
+ if (!NotEnoughUpdates.INSTANCE.manager
+ .jsonToStack(
+ NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId))
+ .hasDisplayName()) {
+ petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack(
+ NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(
+ PetInfoOverlay.getCurrentPet().petType + ";" + (PetInfoOverlay.getCurrentPet().rarity.petId - 1)));
+ } else {
+ petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack(
+ NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(
+ PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId));
+ }
+ petSlot.getTagCompound().setBoolean("NEUPETINVDISPLAY", true);
+ petSlot
+ .getTagCompound()
+ .setBoolean("NEUHIDEPETTOOLTIP", NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip);
+ ItemStack petInfo = petSlot;
+
+ if (guiScreen instanceof GuiInventory) {
+ GL11.glTranslatef(0, 0, 401);
+ if (!NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud || !isWardrobeSystemOnMainServer()) {
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_GREY);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_DARK);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_TRANSPARENT);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_FSR);
+ }
+ } else {
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_GREY);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_DARK);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_TRANSPARENT);
+ }
+ if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_FSR);
+ }
+ }
+
+ GlStateManager.color(1, 1, 1, 1);
+ float yNumber = (float) (height - 23) / 2f;
+ Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 32, GL11.GL_NEAREST);
+ GlStateManager.bindTexture(0);
+
+ Utils.drawItemStack(petInfo, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 72);
+ renderingPetHud = true;
+
+ List tooltipToDisplay = null;
+ if (petInfo != null) {
+ if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) {
+ if (mouseY >= ((height + 60) / 2f - 105) + 72 &&
+ mouseY <= ((height + 60) / 2f - 105) + 88 &&
+ NotEnoughUpdates.INSTANCE.config.petOverlay.sendPetsCommand) {
+ if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) {
+ if (Mouse.getEventButtonState()) {
+ if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/pets") ==
+ 0) {
+ NotEnoughUpdates.INSTANCE.sendChatMessage("/pets");
+ }
+ }
+ }
+ tooltipToDisplay = petInfo.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr);
+ tooltipToDisplay = null;
+ GL11.glTranslatef(0, 0, -80);
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ SunTzu.setEnabled(textField.getText().toLowerCase().startsWith("potato"));
+
+ updateGuiGroupSize();
+
+ if (guiScaleLast != Utils.peekGuiScale().getScaleFactor()) {
+ guiScaleLast = Utils.peekGuiScale().getScaleFactor();
+ redrawItems = true;
+ }
+
+ if (oldWidthMult != getWidthMult()) {
+ oldWidthMult = getWidthMult();
+ redrawItems = true;
+ }
+
+ yaw++;
+ yaw %= 360;
+
+ bg = new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.backgroundColour), true);
+ fg = new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.foregroundColour));
+ Color fgCustomOpacity =
+ new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.foregroundColour), true);
+
+ Color fgFavourite2 =
+ new Color(SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.itemlist.favouriteColour), true);
+ Color fgFavourite = new Color((int) (fgFavourite2.getRed() * 0.8f), (int) (fgFavourite2.getGreen() * 0.8f),
+ (int) (fgFavourite2.getBlue() * 0.8f), fgFavourite2.getAlpha()
+ );
+
+ if (itemPaneOpen) {
+ if (itemPaneTabOffset.getValue() == 0) {
+ if (itemPaneOffsetFactor.getTarget() != 2 / 3f) {
+ itemPaneOffsetFactor.setTarget(2 / 3f);
+ itemPaneOffsetFactor.resetTimer();
+ }
+ } else {
+ if (itemPaneTabOffset.getTarget() != 0) {
+ itemPaneTabOffset.setTarget(0);
+ itemPaneTabOffset.resetTimer();
+ }
+ }
+ } else {
+ if (itemPaneOffsetFactor.getValue() == 1) {
+ if (itemPaneTabOffset.getTarget() != 20) {
+ itemPaneTabOffset.setTarget(20);
+ itemPaneTabOffset.resetTimer();
+ }
+ } else {
+ if (itemPaneOffsetFactor.getTarget() != 1f) {
+ itemPaneOffsetFactor.setTarget(1f);
+ itemPaneOffsetFactor.resetTimer();
+ }
+ }
+ }
+
+ itemPaneOffsetFactor.tick();
+ itemPaneTabOffset.tick();
+ infoPaneOffsetFactor.tick();
+
+ if (page > getMaxPages() - 1) setPage(getMaxPages() - 1);
+ if (page < 0) setPage(0);
+
+ GlStateManager.disableLighting();
+
+ /*
+ * Item selection (right) gui element rendering
+ */
+ int paneWidth = (int) (width / 3 * getWidthMult());
+ int leftSide = (int) (width * getItemPaneOffsetFactor());
+ int rightSide = leftSide + paneWidth - getBoxPadding() - getItemBoxXPadding();
+
+ //Tab
+ if (NotEnoughUpdates.INSTANCE.config.itemlist.tabOpen) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(itemPaneTabArrow);
+ GlStateManager.color(1f, 1f, 1f, 0.3f);
+ Utils.drawTexturedRect(width - itemPaneTabOffset.getValue() * 64 / 20f, height / 2f - 32, 64, 64);
+ GlStateManager.bindTexture(0);
+
+ if (!itemPaneOpen && mouseX > width - itemPaneTabOffset.getValue() && mouseY > height / 2 - 32
+ && mouseY < height / 2 + 32) {
+ itemPaneOpen = true;
+ }
+ }
+
+ //Atomic reference used so that below lambda doesn't complain about non-effectively-final variable
+ AtomicReference tooltipToDisplay = new AtomicReference<>(null);
+ //System.out.println(itemPaneOffsetFactor.getValue());
+ if (itemPaneOffsetFactor.getValue() < 0.99) {
+ if (NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor > 0.5) {
+ BackgroundBlur.renderBlurredBackground(NotEnoughUpdates.INSTANCE.config.itemlist.bgBlurFactor,
+ width, height,
+ leftSide + getBoxPadding() - 5, getBoxPadding() - 5,
+ paneWidth - getBoxPadding() * 2 + 10, height - getBoxPadding() * 2 + 10,
+ itemPaneOffsetFactor.getValue() > 0.01
+ );
+ Gui.drawRect(leftSide + getBoxPadding() - 5, getBoxPadding() - 5,
+ leftSide + getBoxPadding() - 5 + paneWidth - getBoxPadding() * 2 + 10,
+ getBoxPadding() - 5 + height - getBoxPadding() * 2 + 10, 0xc8101010
+ );
+ }
+
+ drawRect(leftSide + getBoxPadding() - 5, getBoxPadding() - 5,
+ leftSide + paneWidth - getBoxPadding() + 5, height - getBoxPadding() + 5, bg.getRGB()
+ );
+
+ renderNavElement(leftSide + getBoxPadding() + getItemBoxXPadding(), rightSide, getMaxPages(), page + 1,
+ Utils.peekGuiScale().getScaleFactor() < 4 ? "Page: " : ""
+ );
+
+ //Sort bar
+ drawRect(leftSide + getBoxPadding() + getItemBoxXPadding() - 1,
+ height - getBoxPadding() - ITEM_SIZE - 2,
+ rightSide + 1,
+ height - getBoxPadding(), fgCustomOpacity.getRGB()
+ );
+
+ float sortIconsMinX = (sortIcons.length + orderIcons.length) * (ITEM_SIZE + ITEM_PADDING) + ITEM_SIZE;
+ float availableX = rightSide - (leftSide + getBoxPadding() + getItemBoxXPadding());
+ float sortOrderScaleFactor = Math.min(1, availableX / sortIconsMinX);
+
+ int scaledITEM_SIZE = (int) (ITEM_SIZE * sortOrderScaleFactor);
+ int scaledItemPaddedSize = (int) ((ITEM_SIZE + ITEM_PADDING) * sortOrderScaleFactor);
+ int iconTop = height - getBoxPadding() - (ITEM_SIZE + scaledITEM_SIZE) / 2 - 1;
+
+ boolean hoveredOverControl = false;
+ for (int i = 0; i < orderIcons.length; i++) {
+ int orderIconX = leftSide + getBoxPadding() + getItemBoxXPadding() + i * scaledItemPaddedSize;
+ drawRect(orderIconX, iconTop, scaledITEM_SIZE + orderIconX, iconTop + scaledITEM_SIZE, fg.getRGB());
+
+ Minecraft
+ .getMinecraft()
+ .getTextureManager()
+ .bindTexture(getCompareMode() == i ? orderIconsActive[i] : orderIcons[i]);
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect(orderIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE, 0, 1, 0, 1, GL11.GL_NEAREST);
+
+ Minecraft
+ .getMinecraft()
+ .getTextureManager()
+ .bindTexture(getCompareAscending().get(i) ? ascending_overlay : descending_overlay);
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect(orderIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE, 0, 1, 0, 1, GL11.GL_NEAREST);
+ GlStateManager.bindTexture(0);
+
+ if (mouseY > iconTop && mouseY < iconTop + scaledITEM_SIZE) {
+ if (mouseX > orderIconX && mouseX < orderIconX + scaledITEM_SIZE) {
+ hoveredOverControl = true;
+ if (System.currentTimeMillis() - millisLastMouseMove > 400) {
+ String text = EnumChatFormatting.GRAY + "Order ";
+ if (i == COMPARE_MODE_ALPHABETICAL) text += "Alphabetically";
+ else if (i == COMPARE_MODE_RARITY) text += "by Rarity";
+ else if (i == COMPARE_MODE_VALUE) text += "by Item Worth";
+ else text = null;
+ if (text != null) textToDisplay = Utils.createList(text);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < sortIcons.length; i++) {
+ int sortIconX = rightSide - scaledITEM_SIZE - i * scaledItemPaddedSize;
+ drawRect(sortIconX, iconTop, scaledITEM_SIZE + sortIconX, iconTop + scaledITEM_SIZE, fg.getRGB());
+ Minecraft
+ .getMinecraft()
+ .getTextureManager()
+ .bindTexture(getSortMode() == i ? sortIconsActive[i] : sortIcons[i]);
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect(sortIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE, 0, 1, 0, 1, GL11.GL_NEAREST);
+ GlStateManager.bindTexture(0);
+
+ if (mouseY > iconTop && mouseY < iconTop + scaledITEM_SIZE) {
+ if (mouseX > sortIconX && mouseX < sortIconX + scaledITEM_SIZE) {
+ hoveredOverControl = true;
+ if (System.currentTimeMillis() - millisLastMouseMove > 400) {
+ String text = EnumChatFormatting.GRAY + "Filter ";
+ if (i == SORT_MODE_ALL) text = EnumChatFormatting.GRAY + "No Filter";
+ else if (i == SORT_MODE_MOB) text += "Mobs";
+ else if (i == SORT_MODE_PET) text += "Pets";
+ else if (i == SORT_MODE_TOOL) text += "Tools";
+ else if (i == SORT_MODE_ARMOR) text += "Armor";
+ else if (i == SORT_MODE_ACCESSORY) text += "Accessories";
+ else text = null;
+ if (text != null) textToDisplay = Utils.createList(text);
+ }
+ }
+ }
+ }
+
+ if (!hoveredOverControl) {
+ millisLastMouseMove = System.currentTimeMillis();
+ }
+
+ if (selectedItemGroup != null) {
+ if (mouseX < selectedItemGroupX - 1 || mouseX > selectedItemGroupX + 17 ||
+ mouseY < selectedItemGroupY - 1 || mouseY > selectedItemGroupY + 17) {
+ int selectedX = Math.min(selectedItemGroupX, width - getBoxPadding() - 18 * selectedItemGroup.size());
+ if (mouseX < selectedX - 1 || mouseX > selectedX - 1 + 18 * selectedItemGroup.size() ||
+ mouseY < selectedItemGroupY + 17 || mouseY > selectedItemGroupY + 35) {
+ selectedItemGroup = null;
+ selectedItemMillis = -1;
+ }
+ }
+ }
+
+ if (!hoverInv) {
+ iterateItemSlots(new ItemSlotConsumer() {
+ public void consume(int x, int y, int id) {
+ JsonObject json = getSearchedItemPage(id);
+ if (json == null) {
+ return;
+ }
+ if (mouseX > x - 1 && mouseX < x + ITEM_SIZE + 1) {
+ if (mouseY > y - 1 && mouseY < y + ITEM_SIZE + 1) {
+ String internalname = json.get("internalname").getAsString();
+ if (searchedItemsSubgroup.containsKey(internalname)) {
+ if (selectedItemMillis == -1) selectedItemMillis = System.currentTimeMillis();
+ if (System.currentTimeMillis() - selectedItemMillis > 200 &&
+ (selectedItemGroup == null || selectedItemGroup.isEmpty())) {
+
+ ArrayList children = new ArrayList<>();
+ children.add(json);
+ for (String itemname : searchedItemsSubgroup.get(internalname)) {
+ children.add(manager.getItemInformation().get(itemname));
+ }
+
+ selectedItemGroup = children;
+ selectedItemGroupX = x;
+ selectedItemGroupY = y;
+ }
+ } else {
+ tooltipToDisplay.set(json);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ //Iterate through all item slots and display the appropriate item
+ int itemBoxXPadding = getItemBoxXPadding();
+ int xStart = (int) (width * getItemPaneOffsetFactor()) + getBoxPadding() + itemBoxXPadding;
+
+ if (OpenGlHelper.isFramebufferEnabled()) {
+ renderItemsFromImage(xStart, width, height);
+ renderEnchOverlay();
+
+ checkFramebufferSizes(width, height);
+
+ if (redrawItems || !NotEnoughUpdates.INSTANCE.config.hidden.cacheRenderedItempane) {
+ renderItemsToImage(width, height, fgFavourite2, fgFavourite, fgCustomOpacity, true, true);
+ redrawItems = false;
+ }
+ } else {
+ renderItems(xStart, true, true, true);
+ }
+
+ if (selectedItemGroup != null) {
+ GL11.glTranslatef(0, 0, 10);
+
+ int selectedX = Math.min(selectedItemGroupX, width - getBoxPadding() - 18 * selectedItemGroup.size());
+
+ GlStateManager.enableDepth();
+ GlStateManager.depthFunc(GL11.GL_LESS);
+ drawRect(selectedX, selectedItemGroupY + 18,
+ selectedX - 2 + 18 * selectedItemGroup.size(), selectedItemGroupY + 34, fgCustomOpacity.getRGB()
+ );
+ drawRect(selectedX - 1, selectedItemGroupY + 17,
+ selectedX - 2 + 18 * selectedItemGroup.size(), selectedItemGroupY + 34, new Color(180, 180, 180).getRGB()
+ );
+ drawRect(selectedX, selectedItemGroupY + 18,
+ selectedX - 1 + 18 * selectedItemGroup.size(), selectedItemGroupY + 35, new Color(30, 30, 30).getRGB()
+ );
+ drawRect(selectedX - 1 + 2, selectedItemGroupY + 17 + 2,
+ selectedX - 1 + 18 * selectedItemGroup.size() + 2, selectedItemGroupY + 35 + 2, 0xa0000000
+ );
+ GlStateManager.depthFunc(GL11.GL_LEQUAL);
+
+ GL11.glTranslatef(0, 0, 10);
+
+ tooltipToDisplay.set(null);
+ if (mouseY > selectedItemGroupY + 17 && mouseY < selectedItemGroupY + 35) {
+ for (int i = 0; i < selectedItemGroup.size(); i++) {
+ if (mouseX >= selectedX - 1 + 18 * i && mouseX <= selectedX + 17 + 18 * i) {
+ tooltipToDisplay.set(selectedItemGroup.get(i));
+ }
+ }
+ }
+ for (int i = 0; i < selectedItemGroup.size(); i++) {
+ JsonObject item = selectedItemGroup.get(i);
+ Utils.drawItemStack(manager.jsonToStack(item), selectedX + 18 * i, selectedItemGroupY + 18);
+ }
+
+ GL11.glTranslatef(0, 0, -20);
+ }
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(
+ GL11.GL_SRC_ALPHA,
+ GL11.GL_ONE_MINUS_SRC_ALPHA,
+ GL11.GL_ONE,
+ GL11.GL_ONE_MINUS_SRC_ALPHA
+ );
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+ GlStateManager.disableLighting();
+ }
+
+ /*
+ * Search bar & quickcommand elements
+ */
+ guiGroup.render(0, 0);
+ resetAnchors(true);
+
+ /*
+ * Item info (left) gui element rendering
+ */
+
+ rightSide = (int) (width * getInfoPaneOffsetFactor());
+ leftSide = rightSide - paneWidth;
+
+ if (activeInfoPane != null) {
+ activeInfoPane.tick();
+ activeInfoPane.render(width, height, bg, fg, Utils.peekGuiScale(), mouseX, mouseY);
+
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(close);
+ Utils.drawTexturedRect(rightSide - getBoxPadding() - 8, getBoxPadding() - 8, 16, 16);
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
+ }
+
+ //Render tooltip
+ JsonObject json = tooltipToDisplay.get();
+ if (json != null) {
+
+ ItemStack stack = manager.jsonToStack(json);
+ {
+ NBTTagCompound tag = stack.getTagCompound();
+ tag.setBoolean("DisablePetExp", true);
+ stack.setTagCompound(tag);
+ }
+
+ List text = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+
+ String internalname = json.get("internalname").getAsString();
+ if (!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoInvItem) {
+ ItemPriceInformation.addToTooltip(text, internalname, stack);
+ }
+
+ boolean hasClick =
+ (json.has("clickcommand") && !json.get("clickcommand").getAsString().isEmpty())
+ || !manager.getAvailableRecipesFor(internalname).isEmpty();
+ boolean hasInfo = json.has("info") && json.get("info").getAsJsonArray().size() > 0;
+
+ if (hasClick || hasInfo) text.add("");
+ if (hasClick)
+ text.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "LMB/R : View recipe!");
+ if (hasInfo)
+ text.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "RMB : View additional information!");
+
+ textToDisplay = text;
+ }
+ if (textToDisplay != null) {
+ Utils.drawHoveringText(textToDisplay, mouseX, mouseY, width, height, -1, fr);
+ textToDisplay = null;
+ }
+
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+ GlStateManager.disableLighting();
+
+ Utils.pushGuiScale(-1);
+
+ if (System.currentTimeMillis() - lastSearchMode > 120000 &&
+ NotEnoughUpdates.INSTANCE.config.toolbar.autoTurnOffSearchMode
+ || !NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) {
+ searchMode = false;
+ }
+ }
+
+ /**
+ * Used in SettingsInfoPane to redraw the items when a setting changes.
+ */
+ public void redrawItems() {
+ redrawItems = true;
+ }
+
+ /**
+ * Sets the current page and marks that the itemsPane should be redrawn
+ */
+ public void setPage(int page) {
+ this.page = page;
+ redrawItems = true;
+ }
+
+ private final Framebuffer[] itemFramebuffers = new Framebuffer[2];
+
+ /**
+ * Checks whether the screen size has changed, if so it reconstructs the itemPane framebuffer and marks that the
+ * itemPane should be redrawn.
+ */
+ private void checkFramebufferSizes(int width, int height) {
+ int sw = width * Utils.peekGuiScale().getScaleFactor();
+ int sh = height * Utils.peekGuiScale().getScaleFactor();
+ for (int i = 0; i < itemFramebuffers.length; i++) {
+ if (itemFramebuffers[i] == null ||
+ itemFramebuffers[i].framebufferWidth != sw ||
+ itemFramebuffers[i].framebufferHeight != sh) {
+ if (itemFramebuffers[i] == null) {
+ itemFramebuffers[i] = new Framebuffer(sw, sh, true);
+ } else {
+ itemFramebuffers[i].createBindFramebuffer(sw, sh);
+ }
+ itemFramebuffers[i].setFramebufferFilter(GL11.GL_NEAREST);
+ redrawItems = true;
+ }
+ }
+ }
+
+ private void prepareFramebuffer(Framebuffer buffer, int sw, int sh) {
+ buffer.framebufferClear();
+ buffer.bindFramebuffer(false);
+ GL11.glViewport(0, 0, sw, sh);
+ }
+
+ private void cleanupFramebuffer(Framebuffer buffer, int sw, int sh) {
+ buffer.unbindFramebuffer();
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true);
+ }
+
+ /**
+ * Renders all items to a framebuffer so that it can be reused later, drastically improving performance.
+ * Unfortunately using this feature will mean that animated textures will not work, but oh well.
+ * Mojang please optimize item rendering thanks.
+ */
+ private void renderItemsToImage(
+ int width, int height, Color fgFavourite2,
+ Color fgFavourite, Color fgCustomOpacity, boolean items, boolean entities
+ ) {
+ int sw = width * Utils.peekGuiScale().getScaleFactor();
+ int sh = height * Utils.peekGuiScale().getScaleFactor();
+
+ GL11.glPushMatrix();
+ prepareFramebuffer(itemFramebuffers[0], sw, sh);
+ renderItems(10, items, entities, false);
+ cleanupFramebuffer(itemFramebuffers[0], sw, sh);
+ GL11.glPopMatrix();
+
+ GL11.glPushMatrix();
+ prepareFramebuffer(itemFramebuffers[1], sw, sh);
+ renderItemBackgrounds(fgFavourite2, fgFavourite, fgCustomOpacity);
+ cleanupFramebuffer(itemFramebuffers[1], sw, sh);
+ GL11.glPopMatrix();
+ }
+
+ private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
+
+ /**
+ * Renders the framebuffer created by #renderItemsToImage to the screen.
+ * itemRenderOffset is a magic number that makes the z-level of the rendered items equal to the z-level of
+ * the item glint overlay model, meaning that a depthFunc of GL_EQUAL can correctly render on to the item.
+ */
+ float itemRenderOffset = 7.5001f;
+
+ private void renderItemsFromImage(int xOffset, int width, int height) {
+ if (itemFramebuffers[0] != null && itemFramebuffers[1] != null) {
+ itemFramebuffers[1].bindFramebufferTexture();
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect(xOffset - 10, 0, width, height, 0, 1, 1, 0);
+ itemFramebuffers[1].unbindFramebufferTexture();
+
+ GL11.glTranslatef(0, 0, itemRenderOffset);
+ itemFramebuffers[0].bindFramebufferTexture();
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect(xOffset - 10, 0, width, height, 0, 1, 1, 0);
+ itemFramebuffers[0].unbindFramebufferTexture();
+ GL11.glTranslatef(0, 0, -itemRenderOffset);
+ }
+ }
+
+ /**
+ * Renders the enchant overlay, since only the items have the specific z-offset of 7.5001, this will only apply
+ * the enchant overlay to the actual items and not anything else.
+ *
+ * (I tried very hard to replicate the enchant rendering overlay code from vanilla, but I couldn't get it to
+ * work without rendering with the "ITEM" vertex model like in vanilla, so I choose to render an arbitrary 2D
+ * item. If a texture pack sets a custom 3D model for an apple, this will probably break.)
+ */
+ private void renderEnchOverlay() {
+ ItemStack stack = new ItemStack(Items.apple);
+ IBakedModel model = Minecraft.getMinecraft().getRenderItem().getItemModelMesher()
+ .getItemModel(stack);
+ float f = (float) (Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F;
+ float f1 = (float) (Minecraft.getSystemTime() % 4873L) / 4873.0F / 8.0F;
+ Minecraft.getMinecraft().getTextureManager().bindTexture(RES_ITEM_GLINT);
+
+ GL11.glPushMatrix();
+ GL11.glTranslatef(0, 0, -7.5001f + itemRenderOffset);
+ iterateItemSlots(new ItemSlotConsumer() {
+ public void consume(int x, int y, int id) {
+ JsonObject json = getSearchedItemPage(id);
+ if (json == null) {
+ return;
+ }
+ ItemStack stack = manager.jsonToStack(json, true, true, false);
+ if (stack == null || !stack.hasEffect()) {
+ return;
+ }
+
+ GlStateManager.pushMatrix();
+ GlStateManager.enableRescaleNormal();
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+ GlStateManager.enableBlend();
+
+ GlStateManager.disableLighting();
+
+ GlStateManager.translate(x, y, 0);
+ GlStateManager.scale(16f, 16f, 16f);
+
+ GlStateManager.depthMask(false);
+ GlStateManager.depthFunc(GL11.GL_EQUAL);
+ GlStateManager.blendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE);
+ GlStateManager.matrixMode(5890);
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(8.0F, 8.0F, 8.0F);
+ GlStateManager.translate(f, 0.0F, 0.0F);
+ GlStateManager.rotate(-50.0F, 0.0F, 0.0F, 1.0F);
+
+ renderModel(model, -8372020, null);
+
+ GlStateManager.popMatrix();
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(8.0F, 8.0F, 8.0F);
+ GlStateManager.translate(-f1, 0.0F, 0.0F);
+ GlStateManager.rotate(10.0F, 0.0F, 0.0F, 1.0F);
+
+ renderModel(model, -8372020, null);
+
+ GlStateManager.popMatrix();
+ GlStateManager.matrixMode(5888);
+ GlStateManager.blendFunc(770, 771);
+ GlStateManager.depthFunc(515);
+ GlStateManager.depthMask(true);
+
+ GlStateManager.popMatrix();
+ }
+ });
+ GlStateManager.disableBlend();
+ GlStateManager.disableAlpha();
+ GlStateManager.disableRescaleNormal();
+ GL11.glTranslatef(0, 0, 7.5001f - itemRenderOffset);
+ GL11.glPopMatrix();
+
+ GlStateManager.bindTexture(0);
+ }
+
+ private void renderModel(IBakedModel model, int color, ItemStack stack) {
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldrenderer = tessellator.getWorldRenderer();
+ worldrenderer.begin(7, DefaultVertexFormats.ITEM);
+
+ for (EnumFacing enumfacing : EnumFacing.values()) {
+ this.renderQuads(worldrenderer, model.getFaceQuads(enumfacing), color);
+ }
+
+ this.renderQuads(worldrenderer, model.getGeneralQuads(), color);
+
+ tessellator.draw();
+ }
+
+ private void renderQuads(WorldRenderer renderer, List quads, int color) {
+ if (quads == null) return;
+
+ for (BakedQuad quad : quads) {
+ renderer.addVertexData(quad.getVertexData());
+ renderer.putColor4(color);
+ }
+ }
+
+ /**
+ * Renders all the item backgrounds, either squares or squircles.
+ */
+ private void renderItemBackgrounds(Color fgFavourite2, Color fgFavourite, Color fgCustomOpacity) {
+ if (fgCustomOpacity.getAlpha() == 0) return;
+ iterateItemSlots(new ItemSlotConsumer() {
+ public void consume(int x, int y, int id) {
+ JsonObject json = getSearchedItemPage(id);
+ if (json == null) {
+ return;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(item_mask);
+ if (getFavourites().contains(json.get("internalname").getAsString())) {
+ if (NotEnoughUpdates.INSTANCE.config.itemlist.itemStyle == 0) {
+ GlStateManager.color(fgFavourite2.getRed() / 255f, fgFavourite2.getGreen() / 255f,
+ fgFavourite2.getBlue() / 255f, fgFavourite2.getAlpha() / 255f
+ );
+ Utils.drawTexturedRect(x - 1, y - 1, ITEM_SIZE + 2, ITEM_SIZE + 2, GL11.GL_NEAREST);
+
+ GlStateManager.color(fgFavourite.getRed() / 255f, fgFavourite.getGreen() / 255f,
+ fgFavourite.getBlue() / 255f, fgFavourite.getAlpha() / 255f
+ );
+ Utils.drawTexturedRect(x, y, ITEM_SIZE, ITEM_SIZE, GL11.GL_NEAREST);
+ } else {
+ drawRect(x - 1, y - 1, x + ITEM_SIZE + 1, y + ITEM_SIZE + 1, fgFavourite2.getRGB());
+ drawRect(x, y, x + ITEM_SIZE, y + ITEM_SIZE, fgFavourite.getRGB());
+ }
+ } else {
+ if (NotEnoughUpdates.INSTANCE.config.itemlist.itemStyle == 0) {
+ GlStateManager.color(fgCustomOpacity.getRed() / 255f, fgCustomOpacity.getGreen() / 255f,
+ fgCustomOpacity.getBlue() / 255f, fgCustomOpacity.getAlpha() / 255f
+ );
+ Utils.drawTexturedRect(x - 1, y - 1, ITEM_SIZE + 2, ITEM_SIZE + 2, GL11.GL_NEAREST);
+ } else {
+ drawRect(x - 1, y - 1, x + ITEM_SIZE + 1, y + ITEM_SIZE + 1, fgCustomOpacity.getRGB());
+ }
+ }
+ GlStateManager.bindTexture(0);
+ }
+ }, 10);
+ }
+
+ private void renderItems(int xStart, boolean items, boolean entities, boolean glint) {
+ iterateItemSlots(new ItemSlotConsumer() {
+ public void consume(int x, int y, int id) {
+ JsonObject json = getSearchedItemPage(id);
+ if (json == null) {
+ return;
+ }
+
+ if (json.has("entityrender")) {
+ if (!entities) return;
+ String name = json.get("displayname").getAsString();
+ String[] split = name.split(" \\(");
+ name = name.substring(0, name.length() - split[split.length - 1].length() - 2);
+
+ Class extends EntityLivingBase>[] entities = new Class[1];
+ if (json.get("entityrender").isJsonArray()) {
+ JsonArray entityrender = json.get("entityrender").getAsJsonArray();
+ entities = new Class[entityrender.size()];
+ for (int i = 0; i < entityrender.size(); i++) {
+ Class extends Entity> clazz = EntityList.stringToClassMapping.get(entityrender.get(i).getAsString());
+ if (clazz != null && EntityLivingBase.class.isAssignableFrom(clazz)) {
+ entities[i] = (Class extends EntityLivingBase>) clazz;
+ }
+ }
+ } else if (json.get("entityrender").isJsonPrimitive()) {
+ Class extends Entity> clazz = EntityList.stringToClassMapping.get(json.get("entityrender").getAsString());
+ if (clazz != null && EntityLivingBase.class.isAssignableFrom(clazz)) {
+ entities[0] = (Class extends EntityLivingBase>) clazz;
+ }
+ }
+
+ float scale = 8;
+ if (json.has("entityscale")) {
+ scale *= json.get("entityscale").getAsFloat();
+ }
+
+ renderEntity(x + ITEM_SIZE / 2, y + ITEM_SIZE, scale, name, entities);
+ } else {
+ if (!items) return;
+ ItemStack stack = manager.jsonToStack(json, true, true, false);
+ if (stack != null) {
+ if (glint) {
+ Utils.drawItemStack(stack, x, y);
+ } else {
+ Utils.drawItemStackWithoutGlint(stack, x, y);
+ }
+ }
+ }
+
+ GlStateManager.translate(0, 0, 50);
+ if (searchedItemsSubgroup.containsKey(json.get("internalname").getAsString())) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(item_haschild);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(x - 1, y - 1, ITEM_SIZE + 2, ITEM_SIZE + 2, GL11.GL_NEAREST);
+ }
+ GlStateManager.translate(0, 0, -50);
+ }
+ }, xStart);
+ }
+
+ public float getItemPaneOffsetFactor() {
+ return itemPaneOffsetFactor.getValue() * getWidthMult() + (1 - getWidthMult());
+ }
+
+ public float getInfoPaneOffsetFactor() {
+ return infoPaneOffsetFactor.getValue() * getWidthMult();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 6a0d3ab4a5..b6ac71a42c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -1,372 +1,408 @@
package io.github.moulberry.notenoughupdates;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
-import io.github.moulberry.notenoughupdates.auction.CustomAHGui;
-import io.github.moulberry.notenoughupdates.collectionlog.GuiCollectionLog;
import io.github.moulberry.notenoughupdates.commands.Commands;
-import io.github.moulberry.notenoughupdates.commands.SimpleCommand;
import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
-import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper;
-import io.github.moulberry.notenoughupdates.core.config.GuiPositionEditor;
-import io.github.moulberry.notenoughupdates.core.util.MiscUtils;
import io.github.moulberry.notenoughupdates.cosmetics.CapeManager;
-import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics;
import io.github.moulberry.notenoughupdates.dungeons.DungeonMap;
-import io.github.moulberry.notenoughupdates.dungeons.DungeonWin;
-import io.github.moulberry.notenoughupdates.dungeons.GuiDungeonMapEditor;
-import io.github.moulberry.notenoughupdates.gamemodes.GuiGamemodes;
import io.github.moulberry.notenoughupdates.miscfeatures.*;
-import io.github.moulberry.notenoughupdates.miscgui.*;
-import io.github.moulberry.notenoughupdates.miscgui.tutorials.NeuTutorial;
+import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes;
+import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBlockSounds;
+import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures;
+import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay;
+import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
-import io.github.moulberry.notenoughupdates.options.NEUConfigEditor;
import io.github.moulberry.notenoughupdates.overlays.FuelBar;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
-import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
-import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.recipes.RecipeGenerator;
import io.github.moulberry.notenoughupdates.util.SBInfo;
-import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
import io.github.moulberry.notenoughupdates.util.XPInformation;
-import net.minecraft.block.material.MapColor;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.entity.AbstractClientPlayer;
-import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.settings.KeyBinding;
-import net.minecraft.command.ICommandSender;
-import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.event.ClickEvent;
-import net.minecraft.item.ItemMap;
-import net.minecraft.item.ItemStack;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.Scoreboard;
-import net.minecraft.util.*;
-import net.minecraft.world.storage.MapData;
-import net.minecraftforge.client.ClientCommandHandler;
-import net.minecraftforge.common.ForgeVersion;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.biome.*;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
-import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
-import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.text.WordUtils;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.GL11;
import java.awt.*;
-import java.awt.datatransfer.StringSelection;
import java.io.*;
-import java.lang.management.ManagementFactory;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.HashMap;
+import java.util.Set;
@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true)
public class NotEnoughUpdates {
- public static final String MODID = "notenoughupdates";
- public static final String VERSION = "2.0.0-REL";
- public static final String PRE_VERSION = "30.2";
- public static final int VERSION_ID = 20000;
- public static final int PRE_VERSION_ID = 3002;
-
- public static NotEnoughUpdates INSTANCE = null;
-
- public NEUManager manager;
- public NEUOverlay overlay;
- public NEUConfig config;
-
- private File configFile;
-
- public File getConfigFile(){
- return this.configFile;
- }
- public void newConfigFile(){
- this.configFile = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), "configNew.json");
- }
-
- private static final long CHAT_MSG_COOLDOWN = 200;
- private long lastChatMessage = 0;
- private long secondLastChatMessage = 0;
- private String currChatMessage = null;
-
- //Stolen from Biscut and used for detecting whether in skyblock
- private static final Set SKYBLOCK_IN_ALL_LANGUAGES = Sets.newHashSet("SKYBLOCK","\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58");
-
- public GuiScreen openGui = null;
- public long lastOpenedGui = 0;
-
- public Commands commands;
-
-
-
- public static HashMap petRarityToColourMap = new HashMap<>();
- static {
- petRarityToColourMap.put("UNKNOWN", EnumChatFormatting.RED.toString());
-
- petRarityToColourMap.put("COMMON", EnumChatFormatting.WHITE.toString());
- petRarityToColourMap.put("UNCOMMON", EnumChatFormatting.GREEN.toString());
- petRarityToColourMap.put("RARE", EnumChatFormatting.BLUE.toString());
- petRarityToColourMap.put("EPIC", EnumChatFormatting.DARK_PURPLE.toString());
- petRarityToColourMap.put("LEGENDARY", EnumChatFormatting.GOLD.toString());
- petRarityToColourMap.put("MYTHIC", EnumChatFormatting.LIGHT_PURPLE.toString());
- }
-
- public static ProfileViewer profileViewer;
-
- public boolean packDevEnabled = false;
-
- private Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
- private File neuDir;
-
- public File getNeuDir(){ return this.neuDir;}
-
- public Color[][] colourMap = null;
-
- /**
- * Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder.
- * @param event
- */
- @EventHandler
- public void preinit(FMLPreInitializationEvent event) {
- INSTANCE = this;
-
- neuDir = new File(event.getModConfigurationDirectory(), "notenoughupdates");
- neuDir.mkdirs();
-
- configFile = new File(neuDir, "configNew.json");
-
- if(configFile.exists()) {
- try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8))) {
- config = gson.fromJson(reader, NEUConfig.class);
- } catch(Exception e) { }
- }
-
- ItemCustomizeManager.loadCustomization(new File(neuDir, "itemCustomization.json"));
- StorageManager.getInstance().loadConfig(new File(neuDir, "storageItems.json"));
- FairySouls.load(new File(neuDir, "collected_fairy_souls.json"), gson);
- PetInfoOverlay.loadConfig(new File(neuDir, "petCache.json"));
- SlotLocking.getInstance().loadConfig(new File(neuDir, "slotLocking.json"));
-
- if(config == null) {
- config = new NEUConfig();
- saveConfig();
- }
-
- MinecraftForge.EVENT_BUS.register(this);
- MinecraftForge.EVENT_BUS.register(new NEUEventListener(this));
- MinecraftForge.EVENT_BUS.register(CapeManager.getInstance());
- //MinecraftForge.EVENT_BUS.register(new SBGamemodes());
- MinecraftForge.EVENT_BUS.register(new EnchantingSolvers());
- MinecraftForge.EVENT_BUS.register(new CalendarOverlay());
- MinecraftForge.EVENT_BUS.register(SBInfo.getInstance());
- MinecraftForge.EVENT_BUS.register(CustomItemEffects.INSTANCE);
- MinecraftForge.EVENT_BUS.register(new DungeonMap());
- MinecraftForge.EVENT_BUS.register(new SunTzu());
- MinecraftForge.EVENT_BUS.register(new MiningStuff());
- MinecraftForge.EVENT_BUS.register(new FairySouls());
- MinecraftForge.EVENT_BUS.register(new CrystalOverlay());
- MinecraftForge.EVENT_BUS.register(new ItemCooldowns());
- MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures());
- MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints());
- MinecraftForge.EVENT_BUS.register(new FuelBar());
- //MinecraftForge.EVENT_BUS.register(new FancyPortals());
- MinecraftForge.EVENT_BUS.register(XPInformation.getInstance());
- MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay);
- MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay);
- MinecraftForge.EVENT_BUS.register(new NullzeeSphere());
- MinecraftForge.EVENT_BUS.register(InventoryStorageSelector.getInstance());
- MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance());
- MinecraftForge.EVENT_BUS.register(FishingHelper.getInstance());
-
- if(Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) {
- ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(CustomSkulls.getInstance());
- ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(NPCRetexturing.getInstance());
- ((IReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).registerReloadListener(new ItemCustomizeManager.ReloadListener());
- }
-
- this.commands = new Commands();
-
- BackgroundBlur.registerListener();
-
- manager = new NEUManager(this, neuDir);
- manager.loadItemInformation();
- overlay = new NEUOverlay(manager);
- profileViewer = new ProfileViewer(manager);
-
- for(KeyBinding kb : manager.keybinds) {
- ClientRegistry.registerKeyBinding(kb);
- }
-
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- File tmp = new File(neuDir, "tmp");
- if(tmp.exists()) {
- for(File tmpFile : tmp.listFiles()) {
- tmpFile.delete();
- }
- tmp.delete();
- }
- //saveConfig();
- }));
- }
-
- public void saveConfig() {
- try {
- configFile.createNewFile();
-
- try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8))) {
- writer.write(gson.toJson(config));
- }
- } catch(Exception ignored) {}
-
- try { ItemCustomizeManager.saveCustomization(new File(neuDir, "itemCustomization.json")); } catch(Exception ignored) {}
- try { StorageManager.getInstance().saveConfig(new File(neuDir, "storageItems.json")); } catch(Exception ignored) {}
- try { FairySouls.save(new File(neuDir, "collected_fairy_souls.json"), gson); } catch(Exception ignored) {}
- try { PetInfoOverlay.saveConfig(new File(neuDir, "petCache.json")); } catch(Exception ignored) {}
- try { SlotLocking.getInstance().saveConfig(new File(neuDir, "slotLocking.json")); } catch(Exception ignored) {}
- }
-
- /**
- * If the last chat messages was sent >200ms ago, sends the message.
- * If the last chat message was sent <200 ago, will cache the message for #onTick to handle.
- */
- public void sendChatMessage(String message) {
- if(System.currentTimeMillis() - lastChatMessage > CHAT_MSG_COOLDOWN) {
- secondLastChatMessage = lastChatMessage;
- lastChatMessage = System.currentTimeMillis();
- Minecraft.getMinecraft().thePlayer.sendChatMessage(message);
- currChatMessage = null;
- } else {
- currChatMessage = message;
- }
- }
-
- public void displayLinks(JsonObject update) {
- String discord_link = update.get("discord_link").getAsString();
- String youtube_link = update.get("youtube_link").getAsString();
- String twitch_link = update.get("twitch_link").getAsString();
- String update_link = update.get("update_link").getAsString();
- String github_link = update.get("github_link").getAsString();
- String other_text = update.get("other_text").getAsString();
- String other_link = update.get("other_link").getAsString();
-
- ChatComponentText other = null;
- if(other_text.length() > 0) {
- other = new ChatComponentText(EnumChatFormatting.GRAY+"["+EnumChatFormatting.BLUE+other_text+EnumChatFormatting.GRAY+"]");
- other.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, other_link));
- }
- ChatComponentText links = new ChatComponentText("");
- ChatComponentText separator = new ChatComponentText(
- EnumChatFormatting.GRAY+EnumChatFormatting.BOLD.toString()+EnumChatFormatting.STRIKETHROUGH+(other==null?"--":"-"));
- ChatComponentText discord = new ChatComponentText(EnumChatFormatting.GRAY+"["+EnumChatFormatting.BLUE+"Discord"+EnumChatFormatting.GRAY+"]");
- discord.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, discord_link));
- ChatComponentText youtube = new ChatComponentText(EnumChatFormatting.GRAY+"["+EnumChatFormatting.RED+"YouTube"+EnumChatFormatting.GRAY+"]");
- youtube.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, youtube_link));
- ChatComponentText twitch = new ChatComponentText(EnumChatFormatting.GRAY+"["+EnumChatFormatting.DARK_PURPLE+"Twitch"+EnumChatFormatting.GRAY+"]");
- twitch.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, twitch_link));
- ChatComponentText release = new ChatComponentText(EnumChatFormatting.GRAY+"["+EnumChatFormatting.GREEN+"Release"+EnumChatFormatting.GRAY+"]");
- release.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, update_link));
- ChatComponentText github = new ChatComponentText(EnumChatFormatting.GRAY+"["+EnumChatFormatting.DARK_PURPLE+"GitHub"+EnumChatFormatting.GRAY+"]");
- github.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, github_link));
-
- links.appendSibling(separator);
- links.appendSibling(discord);
- links.appendSibling(separator);
- links.appendSibling(youtube);
- links.appendSibling(separator);
- links.appendSibling(twitch);
- links.appendSibling(separator);
- links.appendSibling(release);
- links.appendSibling(separator);
- links.appendSibling(github);
- links.appendSibling(separator);
- if(other != null) {
- links.appendSibling(other);
- links.appendSibling(separator);
- }
-
- Minecraft.getMinecraft().thePlayer.addChatMessage(links);
- }
-
- @SubscribeEvent
- public void onTick(TickEvent.ClientTickEvent event) {
- if (event.phase != TickEvent.Phase.START) return;
- if(Minecraft.getMinecraft().thePlayer == null) {
- openGui = null;
- currChatMessage = null;
- return;
- }
- long currentTime = System.currentTimeMillis();
-
- if (openGui != null) {
- if(Minecraft.getMinecraft().thePlayer.openContainer != null) {
- Minecraft.getMinecraft().thePlayer.closeScreen();
- }
- Minecraft.getMinecraft().displayGuiScreen(openGui);
- openGui = null;
- lastOpenedGui = System.currentTimeMillis();
- }
- if(currChatMessage != null && currentTime - lastChatMessage > CHAT_MSG_COOLDOWN) {
- lastChatMessage = currentTime;
- Minecraft.getMinecraft().thePlayer.sendChatMessage(currChatMessage);
- currChatMessage = null;
- }
- }
-
- public boolean isOnSkyblock() {
- if(!config.misc.onlyShowOnSkyblock) return true;
- return hasSkyblockScoreboard();
- }
-
- private boolean hasSkyblockScoreboard;
-
- public boolean hasSkyblockScoreboard() {
- return hasSkyblockScoreboard;
- }
-
- public void updateSkyblockScoreboard() {
- Minecraft mc = Minecraft.getMinecraft();
-
- if (mc != null && mc.theWorld != null && mc.thePlayer != null) {
- if (mc.isSingleplayer() || mc.thePlayer.getClientBrand() == null ||
- !mc.thePlayer.getClientBrand().toLowerCase().contains("hypixel")) {
- hasSkyblockScoreboard = false;
- return;
- }
-
- Scoreboard scoreboard = mc.theWorld.getScoreboard();
- ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1);
- if (sidebarObjective != null) {
- String objectiveName = sidebarObjective.getDisplayName().replaceAll("(?i)\\u00A7.", "");
- for (String skyblock : SKYBLOCK_IN_ALL_LANGUAGES) {
- if (objectiveName.startsWith(skyblock)) {
- hasSkyblockScoreboard = true;
- return;
- }
- }
- }
-
- hasSkyblockScoreboard = false;
- }
-
- }
+ public static final String MODID = "notenoughupdates";
+ public static final String VERSION = "2.1.0-REL";
+ public static final String PRE_VERSION = "0.0";
+ public static final int VERSION_ID = 20100;
+ public static final int PRE_VERSION_ID = 0;
+
+ public static NotEnoughUpdates INSTANCE = null;
+
+ public NEUManager manager;
+ public NEUOverlay overlay;
+ public NEUConfig config;
+
+ private File configFile;
+
+ public File getConfigFile() {
+ return this.configFile;
+ }
+
+ public void newConfigFile() {
+ this.configFile = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), "configNew.json");
+ }
+
+ private static final long CHAT_MSG_COOLDOWN = 200;
+ private long lastChatMessage = 0;
+ private long secondLastChatMessage = 0;
+ private String currChatMessage = null;
+
+ //Stolen from Biscut and used for detecting whether in skyblock
+ private static final Set SKYBLOCK_IN_ALL_LANGUAGES =
+ Sets.newHashSet("SKYBLOCK", "\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58");
+
+ public GuiScreen openGui = null;
+ public long lastOpenedGui = 0;
+
+ public Commands commands;
+
+ public static HashMap petRarityToColourMap = new HashMap() {{
+ put("UNKNOWN", EnumChatFormatting.RED.toString());
+ put("COMMON", EnumChatFormatting.WHITE.toString());
+ put("UNCOMMON", EnumChatFormatting.GREEN.toString());
+ put("RARE", EnumChatFormatting.BLUE.toString());
+ put("EPIC", EnumChatFormatting.DARK_PURPLE.toString());
+ put("LEGENDARY", EnumChatFormatting.GOLD.toString());
+ put("MYTHIC", EnumChatFormatting.LIGHT_PURPLE.toString());
+ }};
+
+ public static ProfileViewer profileViewer;
+
+ public boolean packDevEnabled = false;
+
+ private final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
+ private File neuDir;
+
+ public File getNeuDir() {
+ return this.neuDir;
+ }
+
+ public Color[][] colourMap = null;
+
+ /**
+ * Registers the biomes for the crystal hollows here so optifine knows they exists
+ */
+ public static final BiomeGenBase crystalHollowsJungle =
+ (new BiomeGenJungle(101, true))
+ .setColor(5470985)
+ .setBiomeName("NeuCrystalHollowsJungle")
+ .setFillerBlockMetadata(5470985)
+ .setTemperatureRainfall(0.95F, 0.9F);
+ public static final BiomeGenBase crystalHollowsMagmaFields =
+ (new BiomeGenHell(102))
+ .setColor(16711680)
+ .setBiomeName("NeuCrystalHollowsMagmaFields")
+ .setDisableRain()
+ .setTemperatureRainfall(2.0F, 0.0F);
+ public static final BiomeGenBase crystalHollowsGoblinHoldout =
+ (new BiomeGenMesa(103, false, false))
+ .setColor(13274213)
+ .setBiomeName("NeuCrystalHollowsGoblinHoldout");
+ public static final BiomeGenBase crystalHollowsPrecursorRemnants =
+ (new BiomeGenMesa(104, false, true))
+ .setColor(11573093)
+ .setBiomeName("NeuCrystalHollowsPrecursorRemnants");
+ public static final BiomeGenBase crystalHollowsMithrilDeposit =
+ (new BiomeGenSnow(105, false))
+ .setColor(16777215)
+ .setBiomeName("NeuCrystalHollowsMithrilDeposits");
+ public static final BiomeGenBase crystalHollowsCrystalNucleus =
+ (new BiomeGenJungle(106, true))
+ .setColor(5470985)
+ .setBiomeName("NeuCrystalHollowsCrystalNucleus")
+ .setFillerBlockMetadata(5470985)
+ .setTemperatureRainfall(0.95F, 0.9F);
+
+ /**
+ * Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder.
+ */
+ @EventHandler
+ public void preinit(FMLPreInitializationEvent event) {
+ INSTANCE = this;
+
+ neuDir = new File(event.getModConfigurationDirectory(), "notenoughupdates");
+ neuDir.mkdirs();
+
+ configFile = new File(neuDir, "configNew.json");
+
+ if (configFile.exists()) {
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(configFile),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ config = gson.fromJson(reader, NEUConfig.class);
+ } catch (Exception ignored) {
+ }
+ }
+
+ ItemCustomizeManager.loadCustomization(new File(neuDir, "itemCustomization.json"));
+ StorageManager.getInstance().loadConfig(new File(neuDir, "storageItems.json"));
+ FairySouls.load(new File(neuDir, "collected_fairy_souls.json"), gson);
+ PetInfoOverlay.loadConfig(new File(neuDir, "petCache.json"));
+ SlotLocking.getInstance().loadConfig(new File(neuDir, "slotLocking.json"));
+ ItemPriceInformation.init(new File(neuDir, "auctionable_items.json"), gson);
+
+ if (config == null) {
+ config = new NEUConfig();
+ saveConfig();
+ }
+
+ MinecraftForge.EVENT_BUS.register(this);
+ MinecraftForge.EVENT_BUS.register(new NEUEventListener(this));
+ MinecraftForge.EVENT_BUS.register(new RecipeGenerator(this));
+ MinecraftForge.EVENT_BUS.register(CapeManager.getInstance());
+ //MinecraftForge.EVENT_BUS.register(new SBGamemodes());
+ MinecraftForge.EVENT_BUS.register(new EnchantingSolvers());
+ MinecraftForge.EVENT_BUS.register(new CalendarOverlay());
+ MinecraftForge.EVENT_BUS.register(SBInfo.getInstance());
+ MinecraftForge.EVENT_BUS.register(CustomItemEffects.INSTANCE);
+ MinecraftForge.EVENT_BUS.register(new DungeonMap());
+ MinecraftForge.EVENT_BUS.register(new SunTzu());
+ MinecraftForge.EVENT_BUS.register(new MiningStuff());
+ MinecraftForge.EVENT_BUS.register(new FairySouls());
+ MinecraftForge.EVENT_BUS.register(new CrystalOverlay());
+ MinecraftForge.EVENT_BUS.register(new ItemCooldowns());
+ MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints());
+ MinecraftForge.EVENT_BUS.register(new FuelBar());
+ //MinecraftForge.EVENT_BUS.register(new FancyPortals());
+ MinecraftForge.EVENT_BUS.register(XPInformation.getInstance());
+ MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay);
+ MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay);
+ MinecraftForge.EVENT_BUS.register(new NullzeeSphere());
+ MinecraftForge.EVENT_BUS.register(InventoryStorageSelector.getInstance());
+ MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance());
+ MinecraftForge.EVENT_BUS.register(FishingHelper.getInstance());
+ MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures());
+ MinecraftForge.EVENT_BUS.register(CustomBiomes.INSTANCE);
+
+ if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) {
+ IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
+ manager.registerReloadListener(CustomSkulls.getInstance());
+ manager.registerReloadListener(NPCRetexturing.getInstance());
+ manager.registerReloadListener(new ItemCustomizeManager.ReloadListener());
+ manager.registerReloadListener(new CustomBlockSounds.ReloaderListener());
+ }
+
+ this.commands = new Commands();
+
+ BackgroundBlur.registerListener();
+
+ manager = new NEUManager(this, neuDir);
+ manager.loadItemInformation();
+ overlay = new NEUOverlay(manager);
+ profileViewer = new ProfileViewer(manager);
+
+ for (KeyBinding kb : manager.keybinds) {
+ ClientRegistry.registerKeyBinding(kb);
+ }
+
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ File tmp = new File(neuDir, "tmp");
+ if (tmp.exists()) {
+ for (File tmpFile : tmp.listFiles()) {
+ tmpFile.delete();
+ }
+ tmp.delete();
+ }
+ //saveConfig();
+ }));
+ }
+
+ public void saveConfig() {
+ try {
+ configFile.createNewFile();
+
+ try (
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(configFile),
+ StandardCharsets.UTF_8
+ ))
+ ) {
+ writer.write(gson.toJson(config));
+ }
+ } catch (Exception ignored) {
+ }
+
+ try {
+ ItemCustomizeManager.saveCustomization(new File(neuDir, "itemCustomization.json"));
+ } catch (Exception ignored) {
+ }
+ try {
+ StorageManager.getInstance().saveConfig(new File(neuDir, "storageItems.json"));
+ } catch (Exception ignored) {
+ }
+ try {
+ FairySouls.save(new File(neuDir, "collected_fairy_souls.json"), gson);
+ } catch (Exception ignored) {
+ }
+ try {
+ PetInfoOverlay.saveConfig(new File(neuDir, "petCache.json"));
+ } catch (Exception ignored) {
+ }
+ try {
+ SlotLocking.getInstance().saveConfig(new File(neuDir, "slotLocking.json"));
+ } catch (Exception ignored) {
+ }
+ }
+
+ /**
+ * If the last chat messages was sent >200ms ago, sends the message.
+ * If the last chat message was sent <200 ago, will cache the message for #onTick to handle.
+ */
+ public void sendChatMessage(String message) {
+ if (System.currentTimeMillis() - lastChatMessage > CHAT_MSG_COOLDOWN) {
+ secondLastChatMessage = lastChatMessage;
+ lastChatMessage = System.currentTimeMillis();
+ Minecraft.getMinecraft().thePlayer.sendChatMessage(message);
+ currChatMessage = null;
+ } else {
+ currChatMessage = message;
+ }
+ }
+
+ public void displayLinks(JsonObject update) {
+ String discord_link = update.get("discord_link").getAsString();
+ String youtube_link = update.get("youtube_link").getAsString();
+ String twitch_link = update.get("twitch_link").getAsString();
+ String update_link = update.get("update_link").getAsString();
+ String github_link = update.get("github_link").getAsString();
+ String other_text = update.get("other_text").getAsString();
+ String other_link = update.get("other_link").getAsString();
+
+ ChatComponentText other = null;
+ if (other_text.length() > 0) {
+ other = new ChatComponentText(
+ EnumChatFormatting.GRAY + "[" + EnumChatFormatting.BLUE + other_text + EnumChatFormatting.GRAY + "]");
+ other.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, other_link));
+ }
+ ChatComponentText links = new ChatComponentText("");
+ ChatComponentText separator = new ChatComponentText(
+ EnumChatFormatting.GRAY + EnumChatFormatting.BOLD.toString() + EnumChatFormatting.STRIKETHROUGH +
+ (other == null ? "--" : "-"));
+ ChatComponentText discord = new ChatComponentText(
+ EnumChatFormatting.GRAY + "[" + EnumChatFormatting.BLUE + "Discord" + EnumChatFormatting.GRAY + "]");
+ discord.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, discord_link));
+ ChatComponentText youtube = new ChatComponentText(
+ EnumChatFormatting.GRAY + "[" + EnumChatFormatting.RED + "YouTube" + EnumChatFormatting.GRAY + "]");
+ youtube.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, youtube_link));
+ ChatComponentText twitch = new ChatComponentText(
+ EnumChatFormatting.GRAY + "[" + EnumChatFormatting.DARK_PURPLE + "Twitch" + EnumChatFormatting.GRAY + "]");
+ twitch.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, twitch_link));
+ ChatComponentText release = new ChatComponentText(
+ EnumChatFormatting.GRAY + "[" + EnumChatFormatting.GREEN + "Release" + EnumChatFormatting.GRAY + "]");
+ release.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, update_link));
+ ChatComponentText github = new ChatComponentText(
+ EnumChatFormatting.GRAY + "[" + EnumChatFormatting.DARK_PURPLE + "GitHub" + EnumChatFormatting.GRAY + "]");
+ github.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, github_link));
+
+ links.appendSibling(separator);
+ links.appendSibling(discord);
+ links.appendSibling(separator);
+ links.appendSibling(youtube);
+ links.appendSibling(separator);
+ links.appendSibling(twitch);
+ links.appendSibling(separator);
+ links.appendSibling(release);
+ links.appendSibling(separator);
+ links.appendSibling(github);
+ links.appendSibling(separator);
+ if (other != null) {
+ links.appendSibling(other);
+ links.appendSibling(separator);
+ }
+
+ Minecraft.getMinecraft().thePlayer.addChatMessage(links);
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (event.phase != TickEvent.Phase.START) return;
+ if (Minecraft.getMinecraft().thePlayer == null) {
+ openGui = null;
+ currChatMessage = null;
+ return;
+ }
+ long currentTime = System.currentTimeMillis();
+
+ if (openGui != null) {
+ if (Minecraft.getMinecraft().thePlayer.openContainer != null) {
+ Minecraft.getMinecraft().thePlayer.closeScreen();
+ }
+ Minecraft.getMinecraft().displayGuiScreen(openGui);
+ openGui = null;
+ lastOpenedGui = System.currentTimeMillis();
+ }
+ if (currChatMessage != null && currentTime - lastChatMessage > CHAT_MSG_COOLDOWN) {
+ lastChatMessage = currentTime;
+ Minecraft.getMinecraft().thePlayer.sendChatMessage(currChatMessage);
+ currChatMessage = null;
+ }
+ }
+
+ public boolean isOnSkyblock() {
+ if (!config.misc.onlyShowOnSkyblock) return true;
+ return hasSkyblockScoreboard();
+ }
+
+ private boolean hasSkyblockScoreboard;
+
+ public boolean hasSkyblockScoreboard() {
+ return hasSkyblockScoreboard;
+ }
+
+ public void updateSkyblockScoreboard() {
+ Minecraft mc = Minecraft.getMinecraft();
+
+ if (mc != null && mc.theWorld != null && mc.thePlayer != null) {
+ if (mc.isSingleplayer() || mc.thePlayer.getClientBrand() == null ||
+ !mc.thePlayer.getClientBrand().toLowerCase().contains("hypixel")) {
+ hasSkyblockScoreboard = false;
+ return;
+ }
+
+ Scoreboard scoreboard = mc.theWorld.getScoreboard();
+ ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1);
+ if (sidebarObjective != null) {
+ String objectiveName = sidebarObjective.getDisplayName().replaceAll("(?i)\\u00A7.", "");
+ for (String skyblock : SKYBLOCK_IN_ALL_LANGUAGES) {
+ if (objectiveName.startsWith(skyblock)) {
+ hasSkyblockScoreboard = true;
+ return;
+ }
+ }
+ }
+
+ hasSkyblockScoreboard = false;
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
index 9351b2081b..c47e0844ac 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
@@ -3,8 +3,12 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.ItemPriceInformation;
import io.github.moulberry.notenoughupdates.NEUManager;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph;
+import io.github.moulberry.notenoughupdates.recipes.Ingredient;
+import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -26,885 +30,920 @@
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
public class APIManager {
-
- private NEUManager manager;
- public final CustomAH customAH;
-
- private TreeMap auctionMap = new TreeMap<>();
- public HashMap> internalnameToAucIdMap = new HashMap<>();
- private HashSet playerBids = new HashSet<>();
- private HashSet playerBidsNotified = new HashSet<>();
- private HashSet playerBidsFinishedNotified = new HashSet<>();
-
- private JsonObject lowestBins = null;
- private JsonObject auctionPricesAvgLowestBinJson = null;
-
- private LinkedList pagesToDownload = null;
-
- private JsonObject bazaarJson = null;
- private JsonObject auctionPricesJson = null;
- private HashMap craftCost = new HashMap<>();
-
- public TreeMap>> extrasToAucIdMap = new TreeMap<>();
-
- private long lastAuctionUpdate = 0;
- private long lastShortAuctionUpdate = 0;
- private long lastCustomAHSearch = 0;
- private long lastCleanup = 0;
- private long lastAuctionAvgUpdate = 0;
- private long lastBazaarUpdate = 0;
- private long lastLowestBinUpdate = 0;
-
- private long lastApiUpdate = 0;
- private long firstHypixelApiUpdate = 0;
-
- public int activeAuctions = 0;
- public int uniqueItems = 0;
- public int totalTags = 0;
- public int internalnameTaggedAuctions = 0;
- public int taggedAuctions = 0;
- public int processMillis = 0;
-
- public APIManager(NEUManager manager) {
- this.manager = manager;
- customAH = new CustomAH(manager);
- }
-
- public TreeMap getAuctionItems() {
- return auctionMap;
- }
-
- public HashSet getPlayerBids() {
- return playerBids;
- }
-
- public HashSet getAuctionsForInternalname(String internalname) {
- return internalnameToAucIdMap.computeIfAbsent(internalname, k -> new HashSet<>());
- }
-
- public class Auction {
- public String auctioneerUuid;
- public long end;
- public int starting_bid;
- public int highest_bid_amount;
- public int bid_count;
- public boolean bin;
- public String category;
- public String rarity;
- public int dungeonTier;
- public String item_tag_str;
- public NBTTagCompound item_tag = null;
- private ItemStack stack;
-
- public int enchLevel = 0; //0 = clean, 1 = ench, 2 = ench/hpb
-
- public Auction(String auctioneerUuid, long end, int starting_bid, int highest_bid_amount, int bid_count,
- boolean bin, String category, String rarity, int dungeonTier, String item_tag_str) {
- this.auctioneerUuid = auctioneerUuid;
- this.end = end;
- this.starting_bid = starting_bid;
- this.highest_bid_amount = highest_bid_amount;
- this.bid_count = bid_count;
- this.bin = bin;
- this.category = category;
- this.dungeonTier = dungeonTier;
- this.rarity = rarity;
- this.item_tag_str = item_tag_str;
- }
-
- public ItemStack getStack() {
- if(item_tag == null && item_tag_str != null) {
- try {
- item_tag = CompressedStreamTools.readCompressed(
- new ByteArrayInputStream(Base64.getDecoder().decode(item_tag_str)));
- item_tag_str = null;
- } catch(IOException e) {
- return null;
- }
- }
- if(stack != null) {
- return stack;
- } else {
- JsonObject item = manager.getJsonFromNBT(item_tag);
- ItemStack stack = manager.jsonToStack(item, false);
-
- JsonObject itemDefault = manager.getItemInformation().get(item.get("internalname").getAsString());
-
- if(stack != null && itemDefault != null) {
- ItemStack stackDefault = manager.jsonToStack(itemDefault, true);
- if(stack.isItemEqual(stackDefault)) {
- //Item types are the same, compare lore
-
- String[] stackLore = manager.getLoreFromNBT(stack.getTagCompound());
- String[] defaultLore = manager.getLoreFromNBT(stackDefault.getTagCompound());
-
- boolean loreMatches = stackLore != null && defaultLore != null && stackLore.length == defaultLore.length;
- if(loreMatches) {
- for(int i=0; i 60*1000) {
- lastAuctionUpdate = currentTime;
- updatePageTick();
- }
- if(currentTime - lastShortAuctionUpdate > 10*1000) {
- lastShortAuctionUpdate = currentTime;
- updatePageTickShort();
- ahNotification();
- }
- if(currentTime - lastCleanup > 60*1000) {
- lastCleanup = currentTime;
- cleanup();
- }
- if(currentTime - lastCustomAHSearch > 60*1000) {
- lastCustomAHSearch = currentTime;
- if(Minecraft.getMinecraft().currentScreen instanceof CustomAHGui || customAH.isRenderOverAuctionView()) {
- customAH.updateSearch();
- calculateStats();
- }
- }
- }
- if(currentTime - lastAuctionAvgUpdate > 5*60*1000) { //5 minutes
- lastAuctionAvgUpdate = currentTime - 4*60*1000; //Try again in 1 minute if updateAvgPrices doesn't succeed
- updateAvgPrices();
- }
- if(currentTime - lastBazaarUpdate > 5*60*1000) { //5 minutes
- lastBazaarUpdate = currentTime;
- updateBazaar();
- }
- if(currentTime - lastLowestBinUpdate > 2*60*1000) {
- lastLowestBinUpdate = currentTime;
- updateLowestBin();
- }
- }
-
- private String niceAucId(String aucId) {
- if(aucId.length()!=32) return aucId;
-
- StringBuilder niceAucId = new StringBuilder();
- niceAucId.append(aucId, 0, 8);
- niceAucId.append("-");
- niceAucId.append(aucId, 8, 12);
- niceAucId.append("-");
- niceAucId.append(aucId, 12, 16);
- niceAucId.append("-");
- niceAucId.append(aucId, 16, 20);
- niceAucId.append("-");
- niceAucId.append(aucId, 20, 32);
- return niceAucId.toString();
- }
-
- public Set getLowestBinKeySet() {
- if(lowestBins == null) return new HashSet<>();
- HashSet keys = new HashSet<>();
- for(Map.Entry entry : lowestBins.entrySet()) {
- keys.add(entry.getKey());
- }
- return keys;
- }
-
- public int getLowestBin(String internalname) {
- if(lowestBins != null && lowestBins.has(internalname)) {
- JsonElement e = lowestBins.get(internalname);
- if(e.isJsonPrimitive() && e.getAsJsonPrimitive().isNumber()) {
- return e.getAsInt();
- }
- }
- return -1;
- }
-
- public void updateLowestBin() {
- manager.hypixelApi.getMyApiGZIPAsync("lowestbin.json.gz", (jsonObject) -> {
- if(lowestBins == null) {
- lowestBins = new JsonObject();
- }
- for(Map.Entry entry : jsonObject.entrySet()) {
- lowestBins.add(entry.getKey(), entry.getValue());
- }
- }, () -> {});
- }
-
- private void ahNotification() {
- playerBidsNotified.retainAll(playerBids);
- playerBidsFinishedNotified.retainAll(playerBids);
- if(NotEnoughUpdates.INSTANCE.config.neuAuctionHouse.ahNotification <= 0) {
- return;
- }
- for(String aucid : playerBids) {
- Auction auc = auctionMap.get(aucid);
- if(!playerBidsNotified.contains(aucid)) {
- if(auc != null && auc.end - System.currentTimeMillis() < 1000*60*NotEnoughUpdates.INSTANCE.config.neuAuctionHouse.ahNotification) {
- ChatComponentText message = new ChatComponentText(
- EnumChatFormatting.YELLOW+"The " + auc.getStack().getDisplayName() + EnumChatFormatting.YELLOW + " you have bid on is ending soon! Click here to view.");
- ChatStyle clickEvent = new ChatStyle().setChatClickEvent(
- new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/viewauction " + niceAucId(aucid)));
- clickEvent.setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW+"View auction")));
- message.setChatStyle(clickEvent);
- Minecraft.getMinecraft().thePlayer.addChatMessage(message);
-
- playerBidsNotified.add(aucid);
- }
- }
- if(!playerBidsFinishedNotified.contains(aucid)) {
- if(auc != null && auc.end < System.currentTimeMillis()) {
- ChatComponentText message = new ChatComponentText(
- EnumChatFormatting.YELLOW+"The " + auc.getStack().getDisplayName() + EnumChatFormatting.YELLOW + " you have bid on (might) have ended! Click here to view.");
- ChatStyle clickEvent = new ChatStyle().setChatClickEvent(
- new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/viewauction " + niceAucId(aucid)));
- clickEvent.setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW+"View auction")));
- message.setChatStyle(clickEvent);
- Minecraft.getMinecraft().thePlayer.addChatMessage(message);
-
- playerBidsFinishedNotified.add(aucid);
- }
- }
- }
- }
-
- private ExecutorService es = Executors.newSingleThreadExecutor();
- private void cleanup() {
- es.submit(() -> {
- try {
- long currTime = System.currentTimeMillis();
- Set toRemove = new HashSet<>();
- for(Map.Entry entry : auctionMap.entrySet()) {
- long timeToEnd = entry.getValue().end - currTime;
- if(timeToEnd < -120*1000) { //2 minutes
- toRemove.add(entry.getKey());
- }
- }
- toRemove.removeAll(playerBids);
- remove(toRemove);
- } catch(ConcurrentModificationException e) {
- lastCleanup = System.currentTimeMillis() - 110*1000;
- }
- });
- }
-
- private void remove(Set toRemove) {
- for(String aucid : toRemove) {
- auctionMap.remove(aucid);
- }
- for(HashMap> extrasMap : extrasToAucIdMap.values()) {
- for(HashSet aucids : extrasMap.values()) {
- for(String aucid : toRemove) {
- aucids.remove(aucid);
- }
- }
- }
- for(HashSet aucids : internalnameToAucIdMap.values()) {
- aucids.removeAll(toRemove);
- }
- }
-
- private void updatePageTickShort() {
- if(pagesToDownload == null || pagesToDownload.isEmpty()) return;
-
- if(firstHypixelApiUpdate == 0 || (System.currentTimeMillis() - firstHypixelApiUpdate)%(60*1000) > 15*1000) return;
-
- JsonObject disable = Constants.DISABLE;
- if(disable != null && disable.has("auctions_new") && disable.get("auctions_new").getAsBoolean()) return;
-
- while(!pagesToDownload.isEmpty()) {
- try {
- int page = pagesToDownload.pop();
- getPageFromAPI(page);
- } catch(NoSuchElementException ignored) {} //Weird race condition?
- }
- }
-
- private void updatePageTick() {
- JsonObject disable = Constants.DISABLE;
- if(disable != null && disable.has("auctions_new") && disable.get("auctions_new").getAsBoolean()) return;
-
- if(pagesToDownload == null) {
- getPageFromAPI(0);
- }
-
- Consumer process = jsonObject -> {
- if(jsonObject.get("success").getAsBoolean()) {
- JsonArray new_auctions = jsonObject.get("new_auctions").getAsJsonArray();
- for(JsonElement auctionElement : new_auctions) {
- JsonObject auction = auctionElement.getAsJsonObject();
- //System.out.println("New auction " + auction);
- processAuction(auction);
- }
- JsonArray new_bids = jsonObject.get("new_bids").getAsJsonArray();
- for(JsonElement newBidElement : new_bids) {
- JsonObject newBid = newBidElement.getAsJsonObject();
- String newBidUUID = newBid.get("uuid").getAsString();
- //System.out.println("new bid" + newBidUUID);
- int newBidAmount = newBid.get("highest_bid_amount").getAsInt();
- int end = newBid.get("end").getAsInt();
- int bid_count = newBid.get("bid_count").getAsInt();
-
- Auction auc = auctionMap.get(newBidUUID);
- if(auc != null) {
- //System.out.println("Setting auction " + newBidUUID + " price to " + newBidAmount);
- auc.highest_bid_amount = newBidAmount;
- auc.end = end;
- auc.bid_count = bid_count;
- }
- }
- Set toRemove = new HashSet<>();
- JsonArray removed_auctions = jsonObject.get("removed_auctions").getAsJsonArray();
- for(JsonElement removedAuctionsElement : removed_auctions) {
- String removed = removedAuctionsElement.getAsString();
- toRemove.add(removed);
- }
- remove(toRemove);
- }
- };
-
- manager.hypixelApi.getMyApiGZIPAsync("auctionLast.json.gz", process, () -> {
- System.out.println("Error downloading auction from Moulberry's jank API. :(");
- });
-
- manager.hypixelApi.getMyApiGZIPAsync("auction.json.gz", jsonObject -> {
- if(jsonObject.get("success").getAsBoolean()) {
- long apiUpdate = (long) jsonObject.get("time").getAsFloat();
- if (lastApiUpdate == apiUpdate) {
- lastAuctionUpdate -= 30 * 1000;
- }
- lastApiUpdate = apiUpdate;
-
- process.accept(jsonObject);
- }
- }, () -> {
- System.out.println("Error downloading auction from Moulberry's jank API. :(");
- });
-
- }
-
- public void calculateStats() {
- try {
- uniqueItems = internalnameToAucIdMap.size();
- Set