diff options
Diffstat (limited to 'src/main/java')
16 files changed, 1897 insertions, 1022 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java index 1f87018b..9fcb218f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java @@ -24,6 +24,12 @@ public class GuiTextures { public static final ResourceLocation item_mask = new ResourceLocation("notenoughupdates:item_mask.png"); public static final ResourceLocation button_tex = new ResourceLocation("notenoughupdates:button.png"); + public static final ResourceLocation gamemodes = new ResourceLocation("notenoughupdates:gamemodes.png"); + public static final ResourceLocation radial_square_off = new ResourceLocation("notenoughupdates:radial_square_off.png"); + public static final ResourceLocation radial_square_on = new ResourceLocation("notenoughupdates:radial_square_on.png"); + public static final ResourceLocation radial_circle_off = new ResourceLocation("notenoughupdates:radial_circle_off.png"); + public static final ResourceLocation radial_circle_on = new ResourceLocation("notenoughupdates:radial_circle_on.png"); + public static final ResourceLocation dungeon_chest_worth = new ResourceLocation("notenoughupdates:dungeon_chest_worth.png"); public static final ResourceLocation auction_view = new ResourceLocation("notenoughupdates:auction_view.png"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java new file mode 100644 index 00000000..fc7db07b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -0,0 +1,1006 @@ +package io.github.moulberry.notenoughupdates; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.auction.CustomAHGui; +import io.github.moulberry.notenoughupdates.gamemodes.SBGamemodes; +import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; +import io.github.moulberry.notenoughupdates.questing.SBScoreboardData; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.gui.inventory.GuiCrafting; +import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.event.ClickEvent; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.client.event.*; +import net.minecraftforge.event.entity.player.ItemTooltipEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.io.File; +import java.io.IOException; +import java.text.NumberFormat; +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.AtomicBoolean; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static io.github.moulberry.notenoughupdates.GuiTextures.dungeon_chest_worth; + +public class NEUEventListener { + + private NotEnoughUpdates neu; + + private boolean hoverInv = false; + private boolean focusInv = false; + + private boolean joinedSB = false; + + public NEUEventListener(NotEnoughUpdates neu) { + this.neu = neu; + } + + private void displayUpdateMessageIfOutOfDate() { + File repo = neu.manager.repoLocation; + if(repo.exists()) { + File updateJson = new File(repo, "update.json"); + try { + JsonObject o = neu.manager.getJsonFromFile(updateJson); + + String version = o.get("version").getAsString(); + + if(!neu.VERSION.equalsIgnoreCase(version)) { + String update_msg = o.get("update_msg").getAsString(); + String discord_link = o.get("discord_link").getAsString(); + String youtube_link = o.get("youtube_link").getAsString(); + String update_link = o.get("update_link").getAsString(); + String github_link = o.get("github_link").getAsString(); + String other_text = o.get("other_text").getAsString(); + String other_link = o.get("other_link").getAsString(); + + int first_len = -1; + for(String line : update_msg.split("\n")) { + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + int len = fr.getStringWidth(line); + if(first_len == -1) { + first_len = len; + } + int missing_len = first_len-len; + if(missing_len > 0) { + StringBuilder sb = new StringBuilder(line); + for(int i=0; i<missing_len/8; i++) { + sb.insert(0, " "); + } + line = sb.toString(); + } + line = line.replaceAll("\\{version}", version); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(line)); + } + + neu.displayLinks(o); + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + + } + } catch(Exception ignored) {} + } + } + + /** + * 1)Will send the cached message from #sendChatMessage when at least 200ms has passed since the last message. + * This is used in order to prevent the mod spamming messages. + * 2)Adds unique items to the collection log + */ + private HashMap<String, Long> newItemAddMap = new HashMap<>(); + private long lastLongUpdate = 0; + private long lastSkyblockScoreboard = 0; + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if(event.phase != TickEvent.Phase.START) return; + + boolean longUpdate = false; + long currentTime = System.currentTimeMillis(); + if(currentTime - lastLongUpdate > 1000) { + longUpdate = true; + lastLongUpdate = currentTime; + } + if(longUpdate) { + neu.updateSkyblockScoreboard(); + if(neu.hasSkyblockScoreboard()) { + lastSkyblockScoreboard = currentTime; + if(!joinedSB) { + joinedSB = true; + + SBGamemodes.loadFromFile(); + + if(neu.manager.config.showUpdateMsg.value) { + displayUpdateMessageIfOutOfDate(); + } + + if(!neu.manager.config.loadedModBefore.value) { + neu.manager.config.loadedModBefore.value = true; + try { neu.manager.saveConfig(); } catch(IOException e) {} + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.BLUE+"It seems this is your first time using NotEnoughUpdates.")); + ChatComponentText clickText = new ChatComponentText( + EnumChatFormatting.YELLOW+"Click this message if you would like to view a short tutorial."); + clickText.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/neututorial")); + Minecraft.getMinecraft().thePlayer.addChatMessage(clickText); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + } + } + SBScoreboardData.getInstance().tick(); + //GuiQuestLine.questLine.tick(); + } + if(currentTime - lastSkyblockScoreboard < 5*60*1000) { //5 minutes + neu.manager.auctionManager.tick(); + } else { + neu.manager.auctionManager.markNeedsUpdate(); + } + //ItemRarityHalo.resetItemHaloCache(); + } + if(longUpdate && neu.hasSkyblockScoreboard()) { + if(neu.manager.getCurrentProfile() == null || neu.manager.getCurrentProfile().length() == 0) { + ProfileViewer.Profile profile = neu.profileViewer.getProfile( + Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""), (json) -> {}); + if(profile != null) { + String latest = profile.getLatestProfile(); + if(latest != null) { + neu.manager.setCurrentProfileBackup(profile.getLatestProfile()); + } + } + } + if(neu.manager.getCurrentProfile() != null && neu.manager.getCurrentProfile().length() > 0) { + HashSet<String> newItem = new HashSet<>(); + if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer && + !(Minecraft.getMinecraft().currentScreen instanceof GuiCrafting)) { + boolean usableContainer = true; + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { + if(stack == null) { + continue; + } + if(stack.hasTagCompound()) { + NBTTagCompound tag = stack.getTagCompound(); + if(tag.hasKey("ExtraAttributes", 10)) { + continue; + } + } + usableContainer = false; + break; + } + if(!usableContainer) { + if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); + + if(containerName.equals("Accessory Bag") || containerName.startsWith("Wardrobe")) { + usableContainer = true; + } + } + } + if(usableContainer) { + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { + processUniqueStack(stack, newItem); + } + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { + processUniqueStack(stack, newItem); + } + } + } else { + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { + processUniqueStack(stack, newItem); + } + } + newItemAddMap.keySet().retainAll(newItem); + } + } + } + + private void processUniqueStack(ItemStack stack, HashSet<String> newItem) { + if(stack != null && stack.hasTagCompound()) { + String internalname = neu.manager.getInternalNameForItem(stack); + if(internalname != null) { + ArrayList<String> log = neu.manager.config.collectionLog.value.computeIfAbsent( + neu.manager.getCurrentProfile(), k -> new ArrayList<>()); + if(!log.contains(internalname)) { + newItem.add(internalname); + if(newItemAddMap.containsKey(internalname)) { + if(System.currentTimeMillis() - newItemAddMap.get(internalname) > 1000) { + log.add(internalname); + try { neu.manager.saveConfig(); } catch(IOException ignored) {} + } + } else { + newItemAddMap.put(internalname, System.currentTimeMillis()); + } + } + } + } + } + + @SubscribeEvent(priority= EventPriority.HIGHEST) + public void onRenderEntitySpecials(RenderLivingEvent.Specials.Pre event) { + if(Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer) { + if(((GuiProfileViewer)Minecraft.getMinecraft().currentScreen).getEntityPlayer() == event.entity) { + event.setCanceled(true); + } + } + } + + @SubscribeEvent + public void onRenderGameOverlay(RenderGameOverlayEvent event) { + if(event.type != null && event.type.equals(RenderGameOverlayEvent.ElementType.BOSSHEALTH) && + Minecraft.getMinecraft().currentScreen instanceof GuiContainer && neu.overlay.isUsingMobsFilter()) { + event.setCanceled(true); + } + } + + /** + * When opening a GuiContainer, will reset the overlay and load the config. + * When closing a GuiContainer, will save the config. + * Also includes a dev feature used for automatically acquiring crafting information from the "Crafting Table" GUI. + */ + AtomicBoolean missingRecipe = new AtomicBoolean(false); + @SubscribeEvent + public void onGuiOpen(GuiOpenEvent event) { + neu.manager.auctionManager.customAH.lastGuiScreenSwitch = System.currentTimeMillis(); + + if(event.gui == null && neu.manager.auctionManager.customAH.isRenderOverAuctionView() && + !(Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)) { + event.gui = new CustomAHGui(); + } + + if(!(event.gui instanceof GuiChest || event.gui instanceof GuiEditSign)) { + neu.manager.auctionManager.customAH.setRenderOverAuctionView(false); + } else if(event.gui instanceof GuiChest && (neu.manager.auctionManager.customAH.isRenderOverAuctionView() || + Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)){ + GuiChest chest = (GuiChest) event.gui; + ContainerChest container = (ContainerChest) chest.inventorySlots; + String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); + + neu.manager.auctionManager.customAH.setRenderOverAuctionView(containerName.trim().equals("Auction View") || + containerName.trim().equals("BIN Auction View") || containerName.trim().equals("Confirm Bid") || + containerName.trim().equals("Confirm Purchase")); + } + + //OPEN + if(Minecraft.getMinecraft().currentScreen == null + && event.gui instanceof GuiContainer) { + neu.overlay.reset(); + neu.manager.loadConfig(); + } + //CLOSE + if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer + && event.gui == null) { + try { + neu.manager.saveConfig(); + } catch(IOException e) {} + } + if(event.gui != null && neu.manager.config.dev.value) { + if(event.gui instanceof GuiChest) { + GuiChest eventGui = (GuiChest) event.gui; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + IInventory lower = cc.getLowerChestInventory(); + ses.schedule(() -> { + if(Minecraft.getMinecraft().currentScreen != event.gui) { + return; + } + if(lower.getStackInSlot(23).getDisplayName().endsWith("Crafting Table")) { + try { + ItemStack res = lower.getStackInSlot(25); + String resInternalname = neu.manager.getInternalNameForItem(res); + + if(lower.getStackInSlot(48) != null) { + String backName = null; + NBTTagCompound tag = lower.getStackInSlot(48).getTagCompound(); + if(tag.hasKey("display", 10)) { + NBTTagCompound nbttagcompound = tag.getCompoundTag("display"); + if(nbttagcompound.getTagId("Lore") == 9){ + NBTTagList nbttaglist1 = nbttagcompound.getTagList("Lore", 8); + backName = nbttaglist1.getStringTagAt(0); + } + } + + if(backName != null) { + String[] split = backName.split(" "); + if(split[split.length-1].contains("Rewards")) { + String col = backName.substring(split[0].length()+1, + backName.length()-split[split.length-1].length()-1); + + JsonObject json = neu.manager.getItemInformation().get(resInternalname); + json.addProperty("crafttext", "Requires: " + col); + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); + neu.manager.writeJsonDefaultDir(json, resInternalname+".json"); + neu.manager.loadItem(resInternalname); + } + } + } + + /*JsonArray arr = null; + File f = new File(neu.manager.configLocation, "missing.json"); + try(InputStream instream = new FileInputStream(f)) { + BufferedReader reader = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8)); + JsonObject json = neu.manager.gson.fromJson(reader, JsonObject.class); + arr = json.getAsJsonArray("missing"); + } catch(IOException e) {} + try { + JsonObject json = new JsonObject(); + JsonArray newArr = new JsonArray(); + for(JsonElement e : arr) { + if(!e.getAsString().equals(resInternalname)) { + newArr.add(e); + } + } + json.add("missing", newArr); + neu.manager.writeJson(json, f); + } catch(IOException e) {}*/ + + + + /*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); + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); + neu.manager.writeJsonDefaultDir(json, resInternalname+".json"); + neu.manager.loadItem(resInternalname);*/ + } catch(Exception e) { + e.printStackTrace(); + } + } + }, 200, TimeUnit.MILLISECONDS); + return; + } + } + } + + /** + * 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) + public void onGuiChat(ClientChatReceivedEvent e) { + String r = null; + String unformatted = Utils.cleanColour(e.message.getUnformattedText()); + 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 ")) { + neu.manager.config.apiKey.value = unformatted.substring("Your new API key is ".length()); + try { neu.manager.saveConfig(); } catch(IOException ioe) {} + } + 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 = ""; + } + 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() && neu.manager.config.streamerMode.value && 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); + } + } + } + + /** + * 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. + * @param event + */ + @SubscribeEvent + public void onGuiBackgroundDraw(GuiScreenEvent.BackgroundDrawnEvent event) { + 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 = (int) Utils.getField(GuiContainer.class, event.gui, "xSize", "field_146999_f"); + int ySize = (int) Utils.getField(GuiContainer.class, event.gui, "ySize", "field_147000_g"); + int guiLeft = (int) Utils.getField(GuiContainer.class, event.gui, "guiLeft", "field_147003_i"); + int guiTop = (int) Utils.getField(GuiContainer.class, event.gui, "guiTop", "field_147009_r"); + + 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) { + npe.printStackTrace(); + 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(event.getMouseX(), event.getMouseY(), hoverInv && focusInv); + } catch(ConcurrentModificationException e) {e.printStackTrace();} + GL11.glTranslatef(0, 0, 10); + } + } + + if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { + renderDungeonChestOverlay(event.gui); + } + } + + @SubscribeEvent + public void onGuiScreenDrawPre(GuiScreenEvent.DrawScreenEvent.Pre event) { + if(event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + 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) { + neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); + neu.overlay.render(event.mouseX, event.mouseY, false); + } else { + neu.overlay.render(event.mouseX, event.mouseY, false); + neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); + } + } + } + + 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; + } + + /** + * 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)) + * @param event + */ + @SubscribeEvent + public void onGuiScreenDrawPost(GuiScreenEvent.DrawScreenEvent.Post event) { + if(!(event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView())) { + if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { + if(!focusInv) { + GL11.glTranslatef(0, 0, 300); + neu.overlay.render(event.mouseX, event.mouseY, hoverInv && focusInv); + GL11.glTranslatef(0, 0, -300); + } + neu.overlay.renderOverlay(event.mouseX, event.mouseY); + } + } + } + + private void renderDungeonChestOverlay(GuiScreen gui) { + if(gui instanceof GuiChest && neu.manager.auctionManager.activeAuctions > 0) { + try { + int xSize = (int) Utils.getField(GuiContainer.class, gui, "xSize", "field_146999_f"); + int ySize = (int) Utils.getField(GuiContainer.class, gui, "ySize", "field_147000_g"); + int guiLeft = (int) Utils.getField(GuiContainer.class, gui, "guiLeft", "field_147003_i"); + int guiTop = (int) Utils.getField(GuiContainer.class, gui, "guiTop", "field_147009_r"); + + 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")) { + Minecraft.getMinecraft().getTextureManager().bindTexture(dungeon_chest_worth); + GL11.glColor4f(1, 1, 1, 1); + GlStateManager.disableLighting(); + Utils.drawTexturedRect(guiLeft+xSize+4, guiTop, 180, 45, 0, 180/256f, 0, 45/256f, GL11.GL_NEAREST); + + int chestCost = 0; + 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()); + } + + boolean missing = false; + int totalValue = 0; + for(int i=0; i<5; i++) { + ItemStack item = lower.getStackInSlot(11+i); + String internal = neu.manager.getInternalNameForItem(item); + if(internal != null) { + float worth = neu.manager.auctionManager.getLowestBin(internal); + + if(worth == -1) worth = neu.manager.getCraftCost(internal).craftCost; + + if(worth > 0) { + totalValue += worth; + } else { + missing = true; + break; + } + } + } + int profitLoss = totalValue - chestCost; + + NumberFormat format = NumberFormat.getInstance(Locale.US); + String valueString; + if(!missing) { + valueString = EnumChatFormatting.BLUE+"Chest value: " + EnumChatFormatting.GOLD + + EnumChatFormatting.BOLD + format.format(totalValue) + " coins"; + } else { + valueString = EnumChatFormatting.BLUE+"Couldn't find item on AH. Item is very rare!"; + } + String plString; + if(missing) { + plString = ""; + } else if(profitLoss >= 0) { + plString = EnumChatFormatting.BLUE+"Profit/loss: " + EnumChatFormatting.DARK_GREEN + + EnumChatFormatting.BOLD + "+" + format.format(profitLoss) + " coins"; + } else { + plString = EnumChatFormatting.BLUE+"Profit/loss: " + EnumChatFormatting.RED + + EnumChatFormatting.BOLD + "-" + format.format(-profitLoss) + " coins"; + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(dungeon_chest_worth); + GL11.glColor4f(1, 1, 1, 1); + GlStateManager.disableLighting(); + Utils.drawTexturedRect(guiLeft+xSize+4, guiTop, 180, 45, 0, 180/256f, 0, 45/256f, GL11.GL_NEAREST); + + Utils.drawStringCenteredScaledMaxWidth(valueString, Minecraft.getMinecraft().fontRendererObj, guiLeft+xSize+4+90, + guiTop+14, true, 170, Color.BLACK.getRGB()); + Utils.drawStringCenteredScaledMaxWidth(plString, Minecraft.getMinecraft().fontRendererObj, guiLeft+xSize+4+90, + guiTop+28, true, 170, Color.BLACK.getRGB()); + } + } catch(Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 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. + * @param event + */ + @SubscribeEvent + public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) { + if(event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + event.setCanceled(true); + neu.manager.auctionManager.customAH.handleMouseInput(); + neu.overlay.mouseInput(); + return; + } + if(shouldRenderOverlay(event.gui) && !(hoverInv && focusInv) && neu.isOnSkyblock()) { + if(neu.overlay.mouseInput()) { + event.setCanceled(true); + } + } + } + + ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); + + /** + * 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(event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView()) { + if(neu.manager.auctionManager.customAH.keyboardInput()) { + event.setCanceled(true); + Minecraft.getMinecraft().dispatchKeypresses(); + } else if(neu.overlay.keyboardInput(focusInv)) { + event.setCanceled(true); + } + return; + } + + if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { + if(neu.overlay.keyboardInput(focusInv)) { + event.setCanceled(true); + } + } + if(neu.manager.config.dev.value && neu.manager.config.enableItemEditing.value && 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 e) {} + } + } + } + /*if(Minecraft.getMinecraft().theWorld != null && Keyboard.getEventKey() == Keyboard.KEY_RBRACKET && Keyboard.getEventKeyState()) { + Minecraft.getMinecraft().displayGuiScreen(null); + started = true; + final Object[] items = neu.manager.getItemInformation().values().toArray(); + AtomicInteger i = new AtomicInteger(0); + + Runnable checker = new Runnable() { + @Override + public void run() { + int in = i.getAndIncrement(); + /*if(missingRecipe.get()) { + String internalname = ((JsonObject)items[in]).get("internalname").getAsString(); + + JsonArray arr = null; + File f = new File(neu.manager.configLocation, "missing.json"); + try(InputStream instream = new FileInputStream(f)) { + BufferedReader reader = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8)); + JsonObject json = neu.manager.gson.fromJson(reader, JsonObject.class); + arr = json.getAsJsonArray("missing"); + } catch(IOException e) {} + + try { + JsonObject json = new JsonObject(); + if(arr == null) arr = new JsonArray(); + arr.add(new JsonPrimitive(internalname)); + json.add("missing", arr); + neu.manager.writeJson(json, f); + } catch(IOException e) {} + } + missingRecipe.set(false); + + ses.schedule(() -> { + int index = i.get(); + JsonObject o = (JsonObject)items[index]; + if(Minecraft.getMinecraft().currentScreen != null) { + Minecraft.getMinecraft().displayGuiScreen(null); + } + Minecraft.getMinecraft().thePlayer.sendChatMessage("/viewrecipe " + o.get("internalname").getAsString()); + + ses.schedule(this, 1000, TimeUnit.MILLISECONDS); + }, 100, TimeUnit.MILLISECONDS); + } + }; + + int index = i.get(); + JsonObject o = (JsonObject)items[index]; + if(Minecraft.getMinecraft().currentScreen != null) { + Minecraft.getMinecraft().displayGuiScreen(null); + } + Minecraft.getMinecraft().thePlayer.sendChatMessage("/viewrecipe " + o.get("internalname").getAsString()); + + ses.schedule(checker, 1000, TimeUnit.MILLISECONDS); + }*/ + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void onItemTooltipLow(ItemTooltipEvent event) { + //NotEnoughUpdates.INSTANCE.neu.manager.config.enchantColours.value + int index = 0; + List<String> newTooltip = new ArrayList<>(); + for(String line : event.toolTip) { + for(String op : neu.manager.config.enchantColours.value) { + List<String> 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); + + if(enchantName.length() == 0) continue; + if(comparator.length() == 0) continue; + if(comparison.length() == 0) continue; + if(colourCode.length() == 0) continue; + + if(enchantName.contains("(") || enchantName.contains(")")) continue; + + int comparatorI = ">=<".indexOf(comparator.charAt(0)); + + int levelToFind = -1; + try { + levelToFind = Integer.parseInt(comparison); + } catch(Exception e) { continue; } + + if(comparatorI < 0) continue; + if("0123456789abcdefz".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 { + String prefix = "\u00A79"; + if(enchantName.startsWith("ULT_")) prefix = "\u00A7l\u00A7d"; + pattern = Pattern.compile(prefix+"("+enchantName+") ([0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X))(,|$)"); + } catch(Exception e) {continue;} //malformed regex + Matcher matcher = pattern.matcher(line); + int matchCount = 0; + while(matcher.find() && matchCount < 5) { + matchCount++; + int level = -1; + String levelStr = matcher.group(2); + 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; + } + } + 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) { + if(!colourCode.equals("z")) { + line = line.replaceAll("\\u00A79"+matcher.group(1), "\u00A7"+colourCode+matcher.group(1)); + } else { + line = line.replaceAll("\\u00A79"+matcher.group(1), Utils.chromaString(matcher.group(1))); + } + } + } + } + newTooltip.add(line); + } + event.toolTip.clear(); + event.toolTip.addAll(newTooltip); + } + + /** + * This makes it so that holding LCONTROL while hovering over an item with NBT will show the NBT of the item. + * @param event + */ + @SubscribeEvent + public void onItemTooltip(ItemTooltipEvent event) { + if(!neu.isOnSkyblock()) return; + if(neu.manager.config.hideEmptyPanes.value && + event.itemStack.getItem().equals(Item.getItemFromBlock(Blocks.stained_glass_pane))) { + String first = Utils.cleanColour(event.toolTip.get(0)); + first = first.replaceAll("\\(.*\\)", "").trim(); + if(first.length() == 0) { + event.toolTip.clear(); + } + } + //AH prices + /*if(Minecraft.getMinecraft().currentScreen != null) { + if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); + if(containerName.trim().equals("Auctions Browser")) { + String internalname = neu.manager.getInternalNameForItem(event.itemStack); + if(internalname != null) { + for(int i=0; i<event.toolTip.size(); i++) { + String line = event.toolTip.get(i); + if(line.contains(EnumChatFormatting.GRAY + "Bidder: ") || + line.contains(EnumChatFormatting.GRAY + "Starting bid: ") || + line.contains(EnumChatFormatting.GRAY + "Buy it now: ")) { + neu.manager.updatePrices(); + JsonObject auctionInfo = neu.manager.getItemAuctionInfo(internalname); + + if(auctionInfo != null) { + NumberFormat format = NumberFormat.getInstance(Locale.US); + int auctionPrice = (int)(auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); + float costOfEnchants = neu.manager.getCostOfEnchants(internalname, + event.itemStack.getTagCompound()); + int priceWithEnchants = auctionPrice+(int)costOfEnchants; + + event.toolTip.add(++i, EnumChatFormatting.GRAY + "Average price: " + + EnumChatFormatting.GOLD + format.format(auctionPrice) + " coins"); + if(costOfEnchants > 0) { + event.toolTip.add(++i, EnumChatFormatting.GRAY + "Average price (w/ enchants): " + + EnumChatFormatting.GOLD + + format.format(priceWithEnchants) + " coins"); + } + + if(neu.manager.config.advancedPriceInfo.value) { + int salesVolume = (int) auctionInfo.get("sales").getAsFloat(); + int flipPrice = (int)(0.93*priceWithEnchants); + + event.toolTip.add(++i, EnumChatFormatting.GRAY + "Flip Price (93%): " + + EnumChatFormatting.GOLD + format.format(flipPrice) + " coins"); + event.toolTip.add(++i, EnumChatFormatting.GRAY + "Volume: " + + EnumChatFormatting.GOLD + format.format(salesVolume) + " sales/day"); + } + break; + } + } + } + } + } + } + }*/ + if(!Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || !neu.manager.config.dev.value) return; + if(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)) { + StringSelection selection = new StringSelection(sb.toString()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); + } + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java index f272ee29..ac828606 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java @@ -67,6 +67,7 @@ public class NEUIO { try { GitHub github = new GitHubBuilder().withOAuthToken(accessToken).build(); GHRepository repo = github.getRepositoryById("247692460"); + for(GHCommit commit : repo.listCommits()) { return commit.getSHA1(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 3a84dc5c..2cfe9d91 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -24,6 +24,8 @@ import java.io.*; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -361,12 +363,51 @@ public class NEUManager { } catch(Exception e) { e.printStackTrace(); 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) {} + try { itemShaLocation.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() { + /*File repoFile = new File(configLocation, "repo2"); + repoFile.mkdirs(); + + try(Git git = Git.init().setDirectory(repoFile).call()) { + StoredConfig config = git.getRepository().getConfig(); + config.setString("branch", "master", "merge", "refs/heads/master"); + config.setString("branch", "master", "remote", "origin"); + config.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*"); + config.setString("remote", "origin", "url", "https://github.com/Moulberry/NotEnoughUpdates-REPO.git"); + config.save(); + + git.remoteAdd().setName("origin").setUri(new URIish("https://github.com/Moulberry/NotEnoughUpdates-REPO.git")).call(); + PullResult result = git.pull().setRemote("origin").setTimeout(30000).call(); + System.out.println("successful pull: " + result.isSuccessful()); + } catch(Exception e) { + e.printStackTrace(); + }*/ + + /*if(repoFile.mkdirs()) { + try { + Git.cloneRepository() + .setURI("https://github.com/Moulberry/NotEnoughUpdates-REPO.git") + .setDirectory(repoFile) + .call(); + } catch(Exception e) { + e.printStackTrace(); + } + } else { + + }*/ + + + Thread thread = new Thread(() -> { JDialog dialog = null; try { @@ -378,29 +419,27 @@ public class NEUManager { if (Display.isActive()) dialog.toFront(); + JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json")); + String latestCommit = neuio.getLatestCommit(); if(latestCommit == null || latestCommit.isEmpty()) return; - JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json")); - if(currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestCommit)) { - JsonObject newCurrentCommitJSON = new JsonObject(); - newCurrentCommitJSON.addProperty("sha", latestCommit); - try { - writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json")); - } catch (IOException e) { + Map<String, String> changedFiles = null; + if(new File(configLocation, "repo").exists() && new File(configLocation, "repo/items").exists()) { + + if(currentCommitJSON != null && currentCommitJSON.get("sha").getAsString().equals(latestCommit)) { + dialog.setVisible(false); + return; } - } else { - dialog.setVisible(false); - return; - } - HashMap<String, String> oldShas = new HashMap<>(); - for (Map.Entry<String, JsonElement> entry : itemShaConfig.entrySet()) { - if (new File(repoLocation, entry.getKey() + ".json").exists()) { - oldShas.put(entry.getKey() + ".json", entry.getValue().getAsString()); + HashMap<String, String> oldShas = new HashMap<>(); + for (Map.Entry<String, JsonElement> entry : itemShaConfig.entrySet()) { + if (new File(repoLocation, entry.getKey() + ".json").exists()) { + oldShas.put(entry.getKey() + ".json", entry.getValue().getAsString()); + } } + changedFiles = neuio.getChangedItems(oldShas); } - Map<String, String> changedFiles = neuio.getChangedItems(oldShas); if (Display.isActive()) dialog.toFront(); @@ -496,6 +535,15 @@ public class NEUManager { } } } + + if(currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestCommit)) { + JsonObject newCurrentCommitJSON = new JsonObject(); + newCurrentCommitJSON.addProperty("sha", latestCommit); + try { + writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json")); + } catch (IOException e) { + } + } } } catch(Exception e) { e.printStackTrace(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index fbcd3de3..6e01e409 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -9,73 +9,53 @@ import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication; import io.github.moulberry.notenoughupdates.auction.CustomAHGui; import io.github.moulberry.notenoughupdates.commands.SimpleCommand; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; +import io.github.moulberry.notenoughupdates.gamemodes.GuiGamemodes; +import io.github.moulberry.notenoughupdates.gamemodes.SBGamemodes; import io.github.moulberry.notenoughupdates.infopanes.CollectionLogInfoPane; import io.github.moulberry.notenoughupdates.infopanes.CosmeticsInfoPane; -import io.github.moulberry.notenoughupdates.mixins.MixinRenderItem; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.questing.GuiQuestLine; -import io.github.moulberry.notenoughupdates.questing.SBScoreboardData; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.gui.inventory.*; -import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.gui.inventory.GuiInventory; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.settings.KeyBinding; -import net.minecraft.client.shader.Framebuffer; -import net.minecraft.client.shader.Shader; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.event.ClickEvent; -import net.minecraft.init.Blocks; -import net.minecraft.inventory.ContainerChest; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.Scoreboard; -import net.minecraft.util.*; +import net.minecraft.util.BlockPos; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.Session; import net.minecraftforge.client.ClientCommandHandler; -import net.minecraftforge.client.event.*; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.lang3.StringUtils; -import org.lwjgl.input.Keyboard; -import org.lwjgl.opengl.GL11; import javax.swing.*; -import java.awt.*; -import java.awt.datatransfer.StringSelection; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.net.Proxy; -import java.text.NumberFormat; -import java.util.*; +import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Set; +import java.util.UUID; -import static io.github.moulberry.notenoughupdates.GuiTextures.*; - -@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION) +@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true) public class NotEnoughUpdates { public static final String MODID = "notenoughupdates"; public static final String VERSION = "1.1-REL"; @@ -91,11 +71,6 @@ public class NotEnoughUpdates { private long secondLastChatMessage = 0; private String currChatMessage = null; - private boolean hoverInv = false; - private boolean focusInv = false; - - private boolean joinedSB = false; - //Stolen from Biscut and used for detecting whether in skyblock private static final Set<String> SKYBLOCK_IN_ALL_LANGUAGES = Sets.newHashSet("SKYBLOCK","\u7A7A\u5C9B\u751F\u5B58"); @@ -134,12 +109,25 @@ public class NotEnoughUpdates { } }); + SimpleCommand gamemodesCommand = new SimpleCommand("neugamemodes", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + boolean upgradeOverride = args.length == 1 && args[0].equals("upgradeOverride"); + openGui = new GuiGamemodes(upgradeOverride); + } + }); + SimpleCommand enchantColourCommand = new SimpleCommand("neuec", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { openGui = new GuiEnchantColour(); } }); + SimpleCommand resetRepoCommand = new SimpleCommand("neuresetrepo", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + manager.resetRepo(); + } + }); + public static ProfileViewer profileViewer; SimpleCommand.ProcessCommandRunnable viewProfileRunnable = new SimpleCommand.ProcessCommandRunnable() { @@ -295,14 +283,19 @@ public class NotEnoughUpdates { @EventHandler public void preinit(FMLPreInitializationEvent event) { INSTANCE = this; + MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.EVENT_BUS.register(new NEUEventListener(this)); MinecraftForge.EVENT_BUS.register(CapeManager.getInstance()); + MinecraftForge.EVENT_BUS.register(new SBGamemodes()); File f = new File(event.getModConfigurationDirectory(), "notenoughupdates"); f.mkdirs(); ClientCommandHandler.instance.registerCommand(collectionLogCommand); ClientCommandHandler.instance.registerCommand(cosmeticsCommand); ClientCommandHandler.instance.registerCommand(linksCommand); + ClientCommandHandler.instance.registerCommand(gamemodesCommand); + ClientCommandHandler.instance.registerCommand(resetRepoCommand); ClientCommandHandler.instance.registerCommand(viewProfileCommand); ClientCommandHandler.instance.registerCommand(viewProfileShortCommand); ClientCommandHandler.instance.registerCommand(viewProfileShort2Command); @@ -383,7 +376,7 @@ public class NotEnoughUpdates { } } - private void displayLinks(JsonObject update) { + public void displayLinks(JsonObject update) { String discord_link = update.get("discord_link").getAsString(); String youtube_link = update.get("youtube_link").getAsString(); String update_link = update.get("update_link").getAsString(); @@ -426,940 +419,20 @@ public class NotEnoughUpdates { Minecraft.getMinecraft().thePlayer.addChatMessage(links); } - private void displayUpdateMessageIfOutOfDate() { - File repo = manager.repoLocation; - if(repo.exists()) { - File updateJson = new File(repo, "update.json"); - try { - JsonObject o = manager.getJsonFromFile(updateJson); - - String version = o.get("version").getAsString(); - - if(!VERSION.equalsIgnoreCase(version)) { - String update_msg = o.get("update_msg").getAsString(); - String discord_link = o.get("discord_link").getAsString(); - String youtube_link = o.get("youtube_link").getAsString(); - String update_link = o.get("update_link").getAsString(); - String github_link = o.get("github_link").getAsString(); - String other_text = o.get("other_text").getAsString(); - String other_link = o.get("other_link").getAsString(); - - int first_len = -1; - for(String line : update_msg.split("\n")) { - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - int len = fr.getStringWidth(line); - if(first_len == -1) { - first_len = len; - } - int missing_len = first_len-len; - if(missing_len > 0) { - StringBuilder sb = new StringBuilder(line); - for(int i=0; i<missing_len/8; i++) { - sb.insert(0, " "); - } - line = sb.toString(); - } - line = line.replaceAll("\\{version}", version); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(line)); - } - - displayLinks(o); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - - } - } catch(Exception ignored) {} - } - } - - /** - * 1)Will send the cached message from #sendChatMessage when at least 200ms has passed since the last message. - * This is used in order to prevent the mod spamming messages. - * 2)Adds unique items to the collection log - */ - private HashMap<String, Long> newItemAddMap = new HashMap<>(); - private long lastLongUpdate = 0; - private long lastSkyblockScoreboard = 0; @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { - if(event.phase != TickEvent.Phase.START) return; - - boolean longUpdate = false; + if (event.phase != TickEvent.Phase.START) return; long currentTime = System.currentTimeMillis(); - if(currentTime - lastLongUpdate > 1000) { - longUpdate = true; - lastLongUpdate = currentTime; - } - if(openGui != null) { + + if (openGui != null) { Minecraft.getMinecraft().displayGuiScreen(openGui); openGui = null; } - if(longUpdate) { - updateSkyblockScoreboard(); - if(hasSkyblockScoreboard()) { - lastSkyblockScoreboard = currentTime; - if(!joinedSB && manager.config.showUpdateMsg.value) { - joinedSB = true; - displayUpdateMessageIfOutOfDate(); - if(!manager.config.loadedModBefore.value) { - manager.config.loadedModBefore.value = true; - try { manager.saveConfig(); } catch(IOException e) {} - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.BLUE+"It seems this is your first time using NotEnoughUpdates.")); - ChatComponentText clickText = new ChatComponentText( - EnumChatFormatting.YELLOW+"Click this message if you would like to view a short tutorial."); - clickText.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/neututorial")); - Minecraft.getMinecraft().thePlayer.addChatMessage(clickText); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - } - } - SBScoreboardData.getInstance().tick(); - //GuiQuestLine.questLine.tick(); - } - if(currentTime - lastSkyblockScoreboard < 5*60*1000) { //5 minutes - manager.auctionManager.tick(); - } else { - manager.auctionManager.markNeedsUpdate(); - } - //ItemRarityHalo.resetItemHaloCache(); - } if(currChatMessage != null && currentTime - lastChatMessage > CHAT_MSG_COOLDOWN) { lastChatMessage = currentTime; Minecraft.getMinecraft().thePlayer.sendChatMessage(currChatMessage); currChatMessage = null; } - if(longUpdate && hasSkyblockScoreboard()) { - if(manager.getCurrentProfile() == null || manager.getCurrentProfile().length() == 0) { - ProfileViewer.Profile profile = profileViewer.getProfile( - Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""), (json) -> {}); - if(profile != null) { - String latest = profile.getLatestProfile(); - if(latest != null) { - manager.setCurrentProfileBackup(profile.getLatestProfile()); - } - } - } - if(manager.getCurrentProfile() != null && manager.getCurrentProfile().length() > 0) { - HashSet<String> newItem = new HashSet<>(); - if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer && - !(Minecraft.getMinecraft().currentScreen instanceof GuiCrafting)) { - boolean usableContainer = true; - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { - if(stack == null) { - continue; - } - if(stack.hasTagCompound()) { - NBTTagCompound tag = stack.getTagCompound(); - if(tag.hasKey("ExtraAttributes", 10)) { - continue; - } - } - usableContainer = false; - break; - } - if(!usableContainer) { - if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); - - if(containerName.equals("Accessory Bag") || containerName.startsWith("Wardrobe")) { - usableContainer = true; - } - } - } - if(usableContainer) { - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { - processUniqueStack(stack, newItem); - } - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { - processUniqueStack(stack, newItem); - } - } - } else { - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { - processUniqueStack(stack, newItem); - } - } - newItemAddMap.keySet().retainAll(newItem); - } - } - } - - private void processUniqueStack(ItemStack stack, HashSet<String> newItem) { - if(stack != null && stack.hasTagCompound()) { - String internalname = manager.getInternalNameForItem(stack); - if(internalname != null) { - ArrayList<String> log = manager.config.collectionLog.value.computeIfAbsent( - manager.getCurrentProfile(), k -> new ArrayList<>()); - if(!log.contains(internalname)) { - newItem.add(internalname); - if(newItemAddMap.containsKey(internalname)) { - if(System.currentTimeMillis() - newItemAddMap.get(internalname) > 1000) { - log.add(internalname); - try { manager.saveConfig(); } catch(IOException ignored) {} - } - } else { - newItemAddMap.put(internalname, System.currentTimeMillis()); - } - } - } - } - } - - @SubscribeEvent(priority=EventPriority.HIGHEST) - public void onRenderEntitySpecials(RenderLivingEvent.Specials.Pre event) { - if(Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer) { - if(((GuiProfileViewer)Minecraft.getMinecraft().currentScreen).getEntityPlayer() == event.entity) { - event.setCanceled(true); - } - } - } - - @SubscribeEvent - public void onRenderGameOverlay(RenderGameOverlayEvent event) { - if(event.type != null && event.type.equals(RenderGameOverlayEvent.ElementType.BOSSHEALTH) && - Minecraft.getMinecraft().currentScreen instanceof GuiContainer && overlay.isUsingMobsFilter()) { - event.setCanceled(true); - } - } - - /** - * When opening a GuiContainer, will reset the overlay and load the config. - * When closing a GuiContainer, will save the config. - * Also includes a dev feature used for automatically acquiring crafting information from the "Crafting Table" GUI. - */ - AtomicBoolean missingRecipe = new AtomicBoolean(false); - @SubscribeEvent - public void onGuiOpen(GuiOpenEvent event) { - manager.auctionManager.customAH.lastGuiScreenSwitch = System.currentTimeMillis(); - - if(event.gui == null && manager.auctionManager.customAH.isRenderOverAuctionView() && - !(Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)) { - event.gui = new CustomAHGui(); - } - - if(!(event.gui instanceof GuiChest || event.gui instanceof GuiEditSign)) { - manager.auctionManager.customAH.setRenderOverAuctionView(false); - } else if(event.gui instanceof GuiChest && (manager.auctionManager.customAH.isRenderOverAuctionView() || - Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)){ - GuiChest chest = (GuiChest) event.gui; - ContainerChest container = (ContainerChest) chest.inventorySlots; - String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); - - manager.auctionManager.customAH.setRenderOverAuctionView(containerName.trim().equals("Auction View") || - containerName.trim().equals("BIN Auction View") || containerName.trim().equals("Confirm Bid") || - containerName.trim().equals("Confirm Purchase")); - } - - //OPEN - if(Minecraft.getMinecraft().currentScreen == null - && event.gui instanceof GuiContainer) { - overlay.reset(); - manager.loadConfig(); - } - //CLOSE - if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer - && event.gui == null) { - try { - manager.saveConfig(); - } catch(IOException e) {} - } - if(event.gui != null && manager.config.dev.value) { - if(event.gui instanceof GuiChest) { - GuiChest eventGui = (GuiChest) event.gui; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - IInventory lower = cc.getLowerChestInventory(); - ses.schedule(() -> { - if(Minecraft.getMinecraft().currentScreen != event.gui) { - return; - } - if(lower.getStackInSlot(23).getDisplayName().endsWith("Crafting Table")) { - try { - ItemStack res = lower.getStackInSlot(25); - String resInternalname = manager.getInternalNameForItem(res); - - if(lower.getStackInSlot(48) != null) { - String backName = null; - NBTTagCompound tag = lower.getStackInSlot(48).getTagCompound(); - if(tag.hasKey("display", 10)) { - NBTTagCompound nbttagcompound = tag.getCompoundTag("display"); - if(nbttagcompound.getTagId("Lore") == 9){ - NBTTagList nbttaglist1 = nbttagcompound.getTagList("Lore", 8); - backName = nbttaglist1.getStringTagAt(0); - } - } - - if(backName != null) { - String[] split = backName.split(" "); - if(split[split.length-1].contains("Rewards")) { - String col = backName.substring(split[0].length()+1, - backName.length()-split[split.length-1].length()-1); - - JsonObject json = manager.getItemInformation().get(resInternalname); - json.addProperty("crafttext", "Requires: " + col); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); - manager.writeJsonDefaultDir(json, resInternalname+".json"); - manager.loadItem(resInternalname); - } - } - } - - /*JsonArray arr = null; - File f = new File(manager.configLocation, "missing.json"); - try(InputStream instream = new FileInputStream(f)) { - BufferedReader reader = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8)); - JsonObject json = manager.gson.fromJson(reader, JsonObject.class); - arr = json.getAsJsonArray("missing"); - } catch(IOException e) {} - try { - JsonObject json = new JsonObject(); - JsonArray newArr = new JsonArray(); - for(JsonElement e : arr) { - if(!e.getAsString().equals(resInternalname)) { - newArr.add(e); - } - } - json.add("missing", newArr); - manager.writeJson(json, f); - } catch(IOException e) {}*/ - - - - /*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 = manager.getInternalNameForItem(stack); - if(!manager.getItemInformation().containsKey(internalname)) { - manager.writeItemToFile(stack); - } - internalname += ":"+stack.stackSize; - } - recipe.addProperty(y[i/9]+x[j], internalname); - } - } - - JsonObject json = manager.getJsonForItem(res); - json.add("recipe", recipe); - json.addProperty("internalname", resInternalname); - json.addProperty("clickcommand", "viewrecipe"); - json.addProperty("modver", NotEnoughUpdates.VERSION); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); - manager.writeJsonDefaultDir(json, resInternalname+".json"); - manager.loadItem(resInternalname);*/ - } catch(Exception e) { - e.printStackTrace(); - } - } - }, 200, TimeUnit.MILLISECONDS); - return; - } - } - } - - /** - * 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) - public void onGuiChat(ClientChatReceivedEvent e) { - String r = null; - String unformatted = Utils.cleanColour(e.message.getUnformattedText()); - if(unformatted.startsWith("You are playing on profile: ")) { - 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: - manager.setCurrentProfile(unformatted.substring("Your profile was changed to: ".length()).split(" ")[0].trim()); - } else if(unformatted.startsWith("Your new API key is ")) { - manager.config.apiKey.value = unformatted.substring("Your new API key is ".length()); - try { manager.saveConfig(); } catch(IOException ioe) {} - } - 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 = ""; - } - if(r != null) { - if(manager.failViewItem(r)) { - e.setCanceled(true); - } - missingRecipe.set(true); - } - //System.out.println(e.message); - if(unformatted.startsWith("Sending to server") && - isOnSkyblock() && manager.config.streamerMode.value && 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); - } - } - } - - /** - * 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. - * @param event - */ - @SubscribeEvent - public void onGuiBackgroundDraw(GuiScreenEvent.BackgroundDrawnEvent event) { - if((shouldRenderOverlay(event.gui) || event.gui instanceof CustomAHGui) && isOnSkyblock()) { - ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); - int width = scaledresolution.getScaledWidth(); - - boolean hoverPane = event.getMouseX() < width*overlay.getInfoPaneOffsetFactor() || - event.getMouseX() > width*overlay.getItemPaneOffsetFactor(); - - if(event.gui instanceof GuiContainer) { - try { - int xSize = (int) Utils.getField(GuiContainer.class, event.gui, "xSize", "field_146999_f"); - int ySize = (int) Utils.getField(GuiContainer.class, event.gui, "ySize", "field_147000_g"); - int guiLeft = (int) Utils.getField(GuiContainer.class, event.gui, "guiLeft", "field_147003_i"); - int guiTop = (int) Utils.getField(GuiContainer.class, event.gui, "guiTop", "field_147009_r"); - - 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) { - npe.printStackTrace(); - 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 { - overlay.render(event.getMouseX(), event.getMouseY(), hoverInv && focusInv); - } catch(ConcurrentModificationException e) {e.printStackTrace();} - GL11.glTranslatef(0, 0, 10); - } - } - } - - @SubscribeEvent - public void onGuiScreenDrawPre(GuiScreenEvent.DrawScreenEvent.Pre event) { - if(event.gui instanceof CustomAHGui || manager.auctionManager.customAH.isRenderOverAuctionView()) { - 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*overlay.getWidthMult()/3 || event.mouseX > width-width*overlay.getWidthMult()/3) { - manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); - overlay.render(event.mouseX, event.mouseY, false); - } else { - overlay.render(event.mouseX, event.mouseY, false); - manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); - } - - } - } - - 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; - } - - /** - * 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)) - * @param event - */ - @SubscribeEvent - public void onGuiScreenDrawPost(GuiScreenEvent.DrawScreenEvent.Post event) { - if(!(event.gui instanceof CustomAHGui || manager.auctionManager.customAH.isRenderOverAuctionView())) { - if(shouldRenderOverlay(event.gui) && isOnSkyblock()) { - renderDungeonChestOverlay(event.gui); - - if(!focusInv) { - GL11.glTranslatef(0, 0, 300); - overlay.render(event.mouseX, event.mouseY, hoverInv && focusInv); - GL11.glTranslatef(0, 0, -300); - } - overlay.renderOverlay(event.mouseX, event.mouseY); - } - } - } - - private void renderDungeonChestOverlay(GuiScreen gui) { - if(gui instanceof GuiChest && manager.auctionManager.activeAuctions > 0) { - try { - int xSize = (int) Utils.getField(GuiContainer.class, gui, "xSize", "field_146999_f"); - int ySize = (int) Utils.getField(GuiContainer.class, gui, "ySize", "field_147000_g"); - int guiLeft = (int) Utils.getField(GuiContainer.class, gui, "guiLeft", "field_147003_i"); - int guiTop = (int) Utils.getField(GuiContainer.class, gui, "guiTop", "field_147009_r"); - - 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; - String line6 = Utils.cleanColour(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()); - } - - boolean missing = false; - int totalValue = 0; - for(int i=0; i<5; i++) { - ItemStack item = lower.getStackInSlot(11+i); - String internal = manager.getInternalNameForItem(item); - if(internal != null) { - float worth = manager.auctionManager.getLowestBin(internal); - - if(worth == -1) worth = manager.getCraftCost(internal).craftCost; - - if(worth > 0) { - totalValue += worth; - } else { - missing = true; - break; - } - } - } - int profitLoss = totalValue - chestCost; - - NumberFormat format = NumberFormat.getInstance(Locale.US); - String valueString; - if(!missing) { - valueString = EnumChatFormatting.BLUE+"Chest value: " + EnumChatFormatting.GOLD - + EnumChatFormatting.BOLD + format.format(totalValue) + " coins"; - } else { - valueString = EnumChatFormatting.BLUE+"Couldn't find item on AH. Item is very rare!"; - } - String plString; - if(missing) { - plString = ""; - } else if(profitLoss >= 0) { - plString = EnumChatFormatting.BLUE+"Profit/loss: " + EnumChatFormatting.DARK_GREEN - + EnumChatFormatting.BOLD + "+" + format.format(profitLoss) + " coins"; - } else { - plString = EnumChatFormatting.BLUE+"Profit/loss: " + EnumChatFormatting.RED - + EnumChatFormatting.BOLD + "-" + format.format(-profitLoss) + " coins"; - } - - Minecraft.getMinecraft().getTextureManager().bindTexture(dungeon_chest_worth); - GL11.glColor4f(1, 1, 1, 1); - GlStateManager.disableLighting(); - Utils.drawTexturedRect(guiLeft+xSize+4, guiTop, 180, 45, 0, 180/256f, 0, 45/256f, GL11.GL_NEAREST); - - Utils.drawStringCenteredScaledMaxWidth(valueString, Minecraft.getMinecraft().fontRendererObj, guiLeft+xSize+4+90, - guiTop+14, true, 170, Color.BLACK.getRGB()); - Utils.drawStringCenteredScaledMaxWidth(plString, Minecraft.getMinecraft().fontRendererObj, guiLeft+xSize+4+90, - guiTop+28, true, 170, Color.BLACK.getRGB()); - } - } catch(Exception e) { - e.printStackTrace(); - } - } - } - - /** - * 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. - * @param event - */ - @SubscribeEvent - public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) { - if(event.gui instanceof CustomAHGui || manager.auctionManager.customAH.isRenderOverAuctionView()) { - event.setCanceled(true); - manager.auctionManager.customAH.handleMouseInput(); - overlay.mouseInput(); - return; - } - if(shouldRenderOverlay(event.gui) && !(hoverInv && focusInv) && isOnSkyblock()) { - if(overlay.mouseInput()) { - event.setCanceled(true); - } - } - } - - ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); - - /** - * 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(event.gui instanceof CustomAHGui || manager.auctionManager.customAH.isRenderOverAuctionView()) { - if(manager.auctionManager.customAH.keyboardInput()) { - event.setCanceled(true); - Minecraft.getMinecraft().dispatchKeypresses(); - } else if(overlay.keyboardInput(focusInv)) { - event.setCanceled(true); - } - return; - } - - if(shouldRenderOverlay(event.gui) && isOnSkyblock()) { - if(overlay.keyboardInput(focusInv)) { - event.setCanceled(true); - } - } - if(manager.config.dev.value && manager.config.enableItemEditing.value && 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 = 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 = manager.getInternalNameForItem(stack); - if(!manager.getItemInformation().containsKey(internalname)) { - manager.writeItemToFile(stack); - } - internalname += ":"+stack.stackSize; - } - recipe.addProperty(y[i/9]+x[j], internalname); - } - } - - JsonObject json = 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)); - manager.writeJsonDefaultDir(json, resInternalname+".json"); - manager.loadItem(resInternalname); - } catch(IOException e) {} - } - } - } - /*if(Minecraft.getMinecraft().theWorld != null && Keyboard.getEventKey() == Keyboard.KEY_RBRACKET && Keyboard.getEventKeyState()) { - Minecraft.getMinecraft().displayGuiScreen(null); - started = true; - final Object[] items = manager.getItemInformation().values().toArray(); - AtomicInteger i = new AtomicInteger(0); - - Runnable checker = new Runnable() { - @Override - public void run() { - int in = i.getAndIncrement(); - /*if(missingRecipe.get()) { - String internalname = ((JsonObject)items[in]).get("internalname").getAsString(); - - JsonArray arr = null; - File f = new File(manager.configLocation, "missing.json"); - try(InputStream instream = new FileInputStream(f)) { - BufferedReader reader = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8)); - JsonObject json = manager.gson.fromJson(reader, JsonObject.class); - arr = json.getAsJsonArray("missing"); - } catch(IOException e) {} - - try { - JsonObject json = new JsonObject(); - if(arr == null) arr = new JsonArray(); - arr.add(new JsonPrimitive(internalname)); - json.add("missing", arr); - manager.writeJson(json, f); - } catch(IOException e) {} - } - missingRecipe.set(false); - - ses.schedule(() -> { - int index = i.get(); - JsonObject o = (JsonObject)items[index]; - if(Minecraft.getMinecraft().currentScreen != null) { - Minecraft.getMinecraft().displayGuiScreen(null); - } - Minecraft.getMinecraft().thePlayer.sendChatMessage("/viewrecipe " + o.get("internalname").getAsString()); - - ses.schedule(this, 1000, TimeUnit.MILLISECONDS); - }, 100, TimeUnit.MILLISECONDS); - } - }; - - int index = i.get(); - JsonObject o = (JsonObject)items[index]; - if(Minecraft.getMinecraft().currentScreen != null) { - Minecraft.getMinecraft().displayGuiScreen(null); - } - Minecraft.getMinecraft().thePlayer.sendChatMessage("/viewrecipe " + o.get("internalname").getAsString()); - - ses.schedule(checker, 1000, TimeUnit.MILLISECONDS); - }*/ - } - - @SubscribeEvent(priority = EventPriority.LOW) - public void onItemTooltipLow(ItemTooltipEvent event) { - //NotEnoughUpdates.INSTANCE.manager.config.enchantColours.value - int index = 0; - List<String> newTooltip = new ArrayList<>(); - for(String line : event.toolTip) { - for(String op : NotEnoughUpdates.INSTANCE.manager.config.enchantColours.value) { - List<String> 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); - - if(enchantName.length() == 0) continue; - if(comparator.length() == 0) continue; - if(comparison.length() == 0) continue; - if(colourCode.length() == 0) continue; - - if(enchantName.contains("(") || enchantName.contains(")")) continue; - - int comparatorI = ">=<".indexOf(comparator.charAt(0)); - - int levelToFind = -1; - try { - levelToFind = Integer.parseInt(comparison); - } catch(Exception e) { continue; } - - if(comparatorI < 0) continue; - if("0123456789abcdefz".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 { - String prefix = "\u00A79"; - if(enchantName.startsWith("ULT_")) prefix = "\u00A7l\u00A7d"; - pattern = Pattern.compile(prefix+"("+enchantName+") ([0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X))(,|$)"); - } catch(Exception e) {continue;} //malformed regex - Matcher matcher = pattern.matcher(line); - int matchCount = 0; - while(matcher.find() && matchCount < 5) { - matchCount++; - int level = -1; - String levelStr = matcher.group(2); - 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; - } - } - 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) { - if(!colourCode.equals("z")) { - line = line.replaceAll("\\u00A79"+matcher.group(1), "\u00A7"+colourCode+matcher.group(1)); - } else { - line = line.replaceAll("\\u00A79"+matcher.group(1), Utils.chromaString(matcher.group(1))); - } - } - } - } - newTooltip.add(line); - } - event.toolTip.clear(); - event.toolTip.addAll(newTooltip); - } - - /** - * This makes it so that holding LCONTROL while hovering over an item with NBT will show the NBT of the item. - * @param event - */ - @SubscribeEvent - public void onItemTooltip(ItemTooltipEvent event) { - if(!isOnSkyblock()) return; - if(manager.config.hideEmptyPanes.value && - event.itemStack.getItem().equals(Item.getItemFromBlock(Blocks.stained_glass_pane))) { - String first = Utils.cleanColour(event.toolTip.get(0)); - first = first.replaceAll("\\(.*\\)", "").trim(); - if(first.length() == 0) { - event.toolTip.clear(); - } - } - //AH prices - /*if(Minecraft.getMinecraft().currentScreen != null) { - if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); - if(containerName.trim().equals("Auctions Browser")) { - String internalname = manager.getInternalNameForItem(event.itemStack); - if(internalname != null) { - for(int i=0; i<event.toolTip.size(); i++) { - String line = event.toolTip.get(i); - if(line.contains(EnumChatFormatting.GRAY + "Bidder: ") || - line.contains(EnumChatFormatting.GRAY + "Starting bid: ") || - line.contains(EnumChatFormatting.GRAY + "Buy it now: ")) { - manager.updatePrices(); - JsonObject auctionInfo = manager.getItemAuctionInfo(internalname); - - if(auctionInfo != null) { - NumberFormat format = NumberFormat.getInstance(Locale.US); - int auctionPrice = (int)(auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); - float costOfEnchants = manager.getCostOfEnchants(internalname, - event.itemStack.getTagCompound()); - int priceWithEnchants = auctionPrice+(int)costOfEnchants; - - event.toolTip.add(++i, EnumChatFormatting.GRAY + "Average price: " + - EnumChatFormatting.GOLD + format.format(auctionPrice) + " coins"); - if(costOfEnchants > 0) { - event.toolTip.add(++i, EnumChatFormatting.GRAY + "Average price (w/ enchants): " + - EnumChatFormatting.GOLD + - format.format(priceWithEnchants) + " coins"); - } - - if(manager.config.advancedPriceInfo.value) { - int salesVolume = (int) auctionInfo.get("sales").getAsFloat(); - int flipPrice = (int)(0.93*priceWithEnchants); - - event.toolTip.add(++i, EnumChatFormatting.GRAY + "Flip Price (93%): " + - EnumChatFormatting.GOLD + format.format(flipPrice) + " coins"); - event.toolTip.add(++i, EnumChatFormatting.GRAY + "Volume: " + - EnumChatFormatting.GOLD + format.format(salesVolume) + " sales/day"); - } - break; - } - } - } - } - } - } - }*/ - if(!Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || !manager.config.dev.value) return; - if(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)) { - StringSelection selection = new StringSelection(sb.toString()); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); - } - } } public boolean isOnSkyblock() { @@ -1374,7 +447,7 @@ public class NotEnoughUpdates { } //Stolen from Biscut's SkyblockAddons - private void updateSkyblockScoreboard() { + public void updateSkyblockScoreboard() { Minecraft mc = Minecraft.getMinecraft(); if (mc != null && mc.theWorld != null) { 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 33012194..de03baa9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -82,15 +82,14 @@ public class APIManager { public boolean bin; public String category; public String rarity; - public NBTTagCompound item_tag; + public String item_tag_str; + public NBTTagCompound item_tag = null; private ItemStack stack; - public long lastUpdate = 0; - 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, NBTTagCompound item_tag) { + boolean bin, String category, String rarity, String item_tag_str) { this.auctioneerUuid = auctioneerUuid; this.end = end; this.starting_bid = starting_bid; @@ -99,15 +98,49 @@ public class APIManager { this.bin = bin; this.category = category; this.rarity = rarity; - this.item_tag = item_tag; + 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<stackLore.length; i++) { + if(!stackLore[i].equals(defaultLore[i])) { + loreMatches = false; + break; + } + } + } + if(loreMatches) { + stack = stackDefault; + } + } + } this.stack = stack; return stack; } @@ -117,6 +150,11 @@ public class APIManager { public void markNeedsUpdate() { firstHypixelApiUpdate = 0; pagesToDownload = null; + + auctionMap.clear(); + internalnameToAucIdMap.clear(); + internalnameToLowestBIN.clear(); + extrasToAucIdMap.clear(); } public void tick() { @@ -419,7 +457,7 @@ public class APIManager { if(ea.hasKey("enchantments", 10)) { NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); for(String key : enchantments.getKeySet()) { - String enchantname = key.toLowerCase().replace("_", " "); + String enchantname = key.toLowerCase().replace("ultimate_", "").replace("_", " "); int enchantlevel = enchantments.getInteger(key); String enchantLevelStr; if(enchantlevel >= 1 && enchantlevel <= 20) { @@ -480,7 +518,7 @@ public class APIManager { item_lore.split("\n")[0].endsWith("Mount")) category = "pet"; Auction auction1 = new Auction(auctioneerUuid, end, starting_bid, highest_bid_amount, - bid_count, bin, category, rarity, item_tag); + bid_count, bin, category, rarity, item_bytes); if(tag.hasKey("ench")) { auction1.enchLevel = 1; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java index 6fdb2924..3780db3d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java @@ -85,8 +85,8 @@ public class CustomAH extends Gui { private float scrollAmount; - private int guiLeft = 0; - private int guiTop = 0; + public int guiLeft = 0; + public int guiTop = 0; private Category CATEGORY_SWORD = new Category("sword", "Swords", "diamond_sword"); private Category CATEGORY_ARMOR = new Category("armor", "Armor", "diamond_chestplate"); @@ -250,11 +250,11 @@ public class CustomAH extends Gui { this.renderOverAuctionView = renderOverAuctionView; } - private int getXSize() { + public int getXSize() { return 195; } - private int getYSize() { + public int getYSize() { return 136 + ySplitSize*splits; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index 9b42f5a6..e78d078c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -63,14 +63,16 @@ public class CapeManager { @SubscribeEvent public void onRenderPlayer(RenderPlayerEvent.Post e) { - if(e.partialRenderTick == 1.0F) return; //rendering in inventory - if(e.entityPlayer == Minecraft.getMinecraft().thePlayer) { + //if(e.partialRenderTick == 1.0F) return; //rendering in inventory + if(Minecraft.getMinecraft().thePlayer != null && + e.entityPlayer.getName().equals(Minecraft.getMinecraft().thePlayer.getName())) { if(NotEnoughUpdates.INSTANCE.manager.config.selectedCape.value != null && !NotEnoughUpdates.INSTANCE.manager.config.selectedCape.value.isEmpty()) { setCape(Minecraft.getMinecraft().thePlayer.getName(), NotEnoughUpdates.INSTANCE.manager.config.selectedCape.value); } } + if(e.entityPlayer.getName().equals("Moulberry")) setCape(e.entityPlayer.getName(), "fade"); if(capeMap.containsKey(e.entityPlayer.getName())) { capeMap.get(e.entityPlayer.getName()).getLeft().onRenderPlayer(e); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java index 9fc2a5ee..9848f495 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java @@ -229,7 +229,10 @@ public class NEUCape { if(currentPlayer != null && currentPlayer != player) return; + if(e.partialRenderTick == 1) return; + if(player.getActivePotionEffect(Potion.invisibility) != null) return; + if(player.isSpectator() || player.isInvisible()) return; ensureCapeNodesCreated(player); @@ -487,7 +490,7 @@ public class NEUCape { nodes.get(y).get(x).update(); } } - int updates = player == Minecraft.getMinecraft().thePlayer ? 50 : 25; + int updates = player == Minecraft.getMinecraft().thePlayer ? 50 : 50; for(int i=0; i<updates; i++) { for(int y=0; y<nodes.size(); y++) { for(int x=0; x<nodes.get(y).size(); x++) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/GuiGamemodes.java b/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/GuiGamemodes.java new file mode 100644 index 00000000..0f479f53 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/GuiGamemodes.java @@ -0,0 +1,303 @@ +package io.github.moulberry.notenoughupdates.gamemodes; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; + +import java.awt.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static io.github.moulberry.notenoughupdates.GuiTextures.*; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +public class GuiGamemodes extends GuiScreen { + + private String currentProfile; + private SBGamemodes.Gamemode currentGamemode = null; + private boolean upgradeOverride; + + private int guiLeft = 100; + private int guiTop = 100; + private int xSize = 200; + private int ySize = 232; + + public GuiGamemodes(boolean upgradeOverride) { + this.currentProfile = NotEnoughUpdates.INSTANCE.manager.getCurrentProfile(); + this.upgradeOverride = upgradeOverride; + } + + private boolean canChange(int from, int to) { + if(from >= to) { + return true; + } else { + return !currentGamemode.locked || upgradeOverride; + } + } + + @Override + public void updateScreen() { + if(currentGamemode == null) { + currentGamemode = SBGamemodes.getGamemode(); + if(currentGamemode == null) { + Minecraft.getMinecraft().displayGuiScreen(null); + Minecraft.getMinecraft().thePlayer.addChatMessage( + new ChatComponentText(EnumChatFormatting.RED+"Couldn't automatically detect current profile." + + "If you have only 1 profile, try using /api new so that NEU can detect your profile.")); + } + } + + String currentProfile = NotEnoughUpdates.INSTANCE.manager.getCurrentProfile(); + if(!this.currentProfile.equals(currentProfile)) { + Minecraft.getMinecraft().displayGuiScreen(null); + Minecraft.getMinecraft().thePlayer.addChatMessage( + new ChatComponentText(EnumChatFormatting.RED+"Profile change detected. Closing gamemodes menu.")); + } + } + + @Override + public void handleKeyboardInput() throws IOException { + if(Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + SBGamemodes.saveToFile(); + } + + super.handleKeyboardInput(); + } + + 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.drawStringScaledMaxWidth(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.drawStringScaledMaxWidth(str, + Minecraft.getMinecraft().fontRendererObj, + x, y, false, len, + new Color(64, 64, 64, 255).getRGB()); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + if(mouseButton == 0) { + SBGamemodes.HardcoreMode setHC = SBGamemodes.HardcoreMode.NORMAL; + SBGamemodes.IronmanMode setIM = SBGamemodes.IronmanMode.NORMAL; + int setMod = 0; + + if(mouseX > guiLeft+xSize-27 && mouseX < guiLeft+xSize-9) { + if(mouseY > guiTop+30 && mouseY < guiTop+30+16) { + setHC = SBGamemodes.HardcoreMode.SOFTCORE; + } else if(mouseY > guiTop+50 && mouseY < guiTop+50+16) { + setHC = SBGamemodes.HardcoreMode.HARDCORE; + } else if(mouseY > guiTop+80 && mouseY < guiTop+80+16) { + setIM = SBGamemodes.IronmanMode.IRONMAN; + } else if(mouseY > guiTop+100 && mouseY < guiTop+100+16) { + setIM = SBGamemodes.IronmanMode.IRONMANPLUS; + } else if(mouseY > guiTop+120 && mouseY < guiTop+120+16) { + setIM = SBGamemodes.IronmanMode.ULTIMATE_IRONMAN; + } else if(mouseY > guiTop+140 && mouseY < guiTop+140+16) { + setIM = SBGamemodes.IronmanMode.ULTIMATE_IRONMANPLUS; + } else if(mouseY > guiTop+170 && mouseY < guiTop+170+16) { + setMod = SBGamemodes.MODIFIER_DEVILISH; + } else if(mouseY > guiTop+190 && mouseY < guiTop+190+16) { + setMod = SBGamemodes.MODIFIER_NOBANK; + } else if(mouseY > guiTop+210 && mouseY < guiTop+210+16) { + setMod = SBGamemodes.MODIFIER_SMALLISLAND; + } + } + + if(setHC != SBGamemodes.HardcoreMode.NORMAL) { + if(currentGamemode.hardcoreMode == setHC) { + currentGamemode.hardcoreMode = SBGamemodes.HardcoreMode.NORMAL; + } else { + if(canChange(currentGamemode.hardcoreMode.ordinal(), setHC.ordinal())) { + currentGamemode.hardcoreMode = setHC; + } + } + } else if(setIM != SBGamemodes.IronmanMode.NORMAL) { + if(currentGamemode.ironmanMode == setIM) { + currentGamemode.ironmanMode = SBGamemodes.IronmanMode.NORMAL; + } else { + if(canChange(currentGamemode.ironmanMode.ordinal(), setIM.ordinal())) { + currentGamemode.ironmanMode = setIM; + } + } + } else if(setMod != 0) { + if(canChange(currentGamemode.gamemodeModifiers, currentGamemode.gamemodeModifiers^setMod)) { + currentGamemode.gamemodeModifiers ^= setMod; + } + } + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + super.drawDefaultBackground(); + + guiLeft = (width-xSize)/2; + guiTop = (height-ySize)/2; + + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(gamemodes); + Utils.drawTexturedRect(guiLeft, guiTop, xSize, ySize, GL11.GL_NEAREST); + + if(currentGamemode == null) return; + + Utils.drawStringCentered("NEU Skyblock Gamemodes", Minecraft.getMinecraft().fontRendererObj, + guiLeft+xSize/2f, guiTop+14, false, new Color(64, 64, 64).getRGB()); + + drawStringShadow(SBGamemodes.HardcoreMode.SOFTCORE.display, guiLeft+10, guiTop+30, xSize-47); + drawStringShadow(SBGamemodes.HardcoreMode.HARDCORE.display, guiLeft+10, guiTop+50, xSize-47); + + drawStringShadow(SBGamemodes.IronmanMode.IRONMAN.display,guiLeft+10, guiTop+80, xSize-47); + drawStringShadow(SBGamemodes.IronmanMode.IRONMANPLUS.display,guiLeft+10, guiTop+100, xSize-47); + drawStringShadow(SBGamemodes.IronmanMode.ULTIMATE_IRONMAN.display,guiLeft+10, guiTop+120, xSize-47); + drawStringShadow(SBGamemodes.IronmanMode.ULTIMATE_IRONMANPLUS.display,guiLeft+10, guiTop+140, xSize-47); + + drawStringShadow(SBGamemodes.MODIFIER_DEVILISH_DISPLAY,guiLeft+10, guiTop+170, xSize-47); + drawStringShadow(SBGamemodes.MODIFIER_NOBANK_DISPLAY,guiLeft+10, guiTop+190, xSize-47); + drawStringShadow(SBGamemodes.MODIFIER_SMALLISLAND_DISPLAY,guiLeft+10, guiTop+210, xSize-47); + + String tooltipToDisplay = null; + + GlStateManager.color(1, 1, 1, 1); + if(canChange(currentGamemode.hardcoreMode.ordinal(), SBGamemodes.HardcoreMode.SOFTCORE.ordinal())) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + currentGamemode.hardcoreMode == SBGamemodes.HardcoreMode.SOFTCORE ? radial_circle_on : radial_circle_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+30-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+30-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+30-4 && mouseY < guiTop+30+12) { + tooltipToDisplay = SBGamemodes.HardcoreMode.SOFTCORE.desc; + } + } + } + if(canChange(currentGamemode.hardcoreMode.ordinal(), SBGamemodes.HardcoreMode.HARDCORE.ordinal())) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + currentGamemode.hardcoreMode == SBGamemodes.HardcoreMode.HARDCORE ? radial_circle_on : radial_circle_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+50-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+50-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+50-4 && mouseY < guiTop+50+12) { + tooltipToDisplay = SBGamemodes.HardcoreMode.HARDCORE.desc; + } + } + } + + if(canChange(currentGamemode.ironmanMode.ordinal(), SBGamemodes.IronmanMode.IRONMAN.ordinal())) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + currentGamemode.ironmanMode == SBGamemodes.IronmanMode.IRONMAN ? radial_circle_on : radial_circle_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+80-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+80-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+80-4 && mouseY < guiTop+80+12) { + tooltipToDisplay = SBGamemodes.IronmanMode.IRONMAN.desc; + } + } + } + if(canChange(currentGamemode.ironmanMode.ordinal(), SBGamemodes.IronmanMode.IRONMANPLUS.ordinal())) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + currentGamemode.ironmanMode == SBGamemodes.IronmanMode.IRONMANPLUS ? radial_circle_on : radial_circle_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+100-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+100-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+100-4 && mouseY < guiTop+100+12) { + tooltipToDisplay = SBGamemodes.IronmanMode.IRONMANPLUS.desc; + } + } + } + if(canChange(currentGamemode.ironmanMode.ordinal(), SBGamemodes.IronmanMode.ULTIMATE_IRONMAN.ordinal())) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + currentGamemode.ironmanMode == SBGamemodes.IronmanMode.ULTIMATE_IRONMAN ? radial_circle_on : radial_circle_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+120-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+120-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+120-4 && mouseY < guiTop+120+12) { + tooltipToDisplay = SBGamemodes.IronmanMode.ULTIMATE_IRONMAN.desc; + } + } + } + if(canChange(currentGamemode.ironmanMode.ordinal(), SBGamemodes.IronmanMode.ULTIMATE_IRONMANPLUS.ordinal())) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + currentGamemode.ironmanMode == SBGamemodes.IronmanMode.ULTIMATE_IRONMANPLUS ? radial_circle_on : radial_circle_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+140-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+140-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+140-4 && mouseY < guiTop+140+12) { + tooltipToDisplay = SBGamemodes.IronmanMode.ULTIMATE_IRONMANPLUS.desc; + } + } + } + + if(canChange(currentGamemode.gamemodeModifiers, currentGamemode.gamemodeModifiers^SBGamemodes.MODIFIER_DEVILISH)) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + (currentGamemode.gamemodeModifiers & SBGamemodes.MODIFIER_DEVILISH) != 0 ? radial_square_on : radial_square_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+170-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+170-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+170-4 && mouseY < guiTop+170+12) { + tooltipToDisplay = SBGamemodes.MODIFIER_DEVILISH_DESC; + } + } + } + if(canChange(currentGamemode.gamemodeModifiers, currentGamemode.gamemodeModifiers^SBGamemodes.MODIFIER_NOBANK)) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + (currentGamemode.gamemodeModifiers & SBGamemodes.MODIFIER_NOBANK) != 0 ? radial_square_on : radial_square_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+190-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+190-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+190-4 && mouseY < guiTop+190+12) { + tooltipToDisplay = SBGamemodes.MODIFIER_NOBANK_DESC; + } + } + } + if(canChange(currentGamemode.gamemodeModifiers, currentGamemode.gamemodeModifiers^SBGamemodes.MODIFIER_SMALLISLAND)) { + Minecraft.getMinecraft().getTextureManager().bindTexture( + (currentGamemode.gamemodeModifiers & SBGamemodes.MODIFIER_SMALLISLAND) != 0 ? radial_square_on : radial_square_off); + Utils.drawTexturedRect(guiLeft+xSize-26, guiTop+210-4, 16, 16, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-47, guiTop+210-4, 16, 16, GL11.GL_NEAREST); + if(mouseX > guiLeft+xSize-47 && mouseX < guiLeft+xSize-31) { + if(mouseY > guiTop+210-4 && mouseY < guiTop+210+12) { + tooltipToDisplay = SBGamemodes.MODIFIER_SMALLISLAND_DESC; + } + } + } + + if(tooltipToDisplay != null) { + List<String> lines = new ArrayList<>(); + for(String line : tooltipToDisplay.split("\n")) { + lines.add(EnumChatFormatting.GRAY+line); + } + Utils.drawHoveringText(lines, mouseX, mouseY, width, height, -1, Minecraft.getMinecraft().fontRendererObj); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java b/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java new file mode 100644 index 00000000..cdda9957 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java @@ -0,0 +1,348 @@ +package io.github.moulberry.notenoughupdates.gamemodes; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.options.Options; +import io.github.moulberry.notenoughupdates.questing.SBScoreboardData; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.input.Keyboard; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.util.Base64; +import java.util.HashMap; + +public class SBGamemodes { + + private static final Gson gson = new Gson(); + + public static final int MODIFIER_DEVILISH = 0b1; + public static final int MODIFIER_NOBANK = 0b10; + public static final int MODIFIER_SMALLISLAND = 0b100; + + public static final String MODIFIER_DEVILISH_DISPLAY = EnumChatFormatting.DARK_PURPLE+"Devilish"; + public static final String MODIFIER_NOBANK_DISPLAY = EnumChatFormatting.RED+"No"+EnumChatFormatting.GOLD+"Bank"; + public static final String MODIFIER_SMALLISLAND_DISPLAY = EnumChatFormatting.GREEN+"SmallIsland"; + + public static final String MODIFIER_DEVILISH_DESC = EnumChatFormatting.DARK_PURPLE+"Devilish\n" + + "You are NOT allowed to use fairy souls."; + public static final String MODIFIER_NOBANK_DESC = EnumChatFormatting.RED+"No"+EnumChatFormatting.GOLD+"Bank\n" + + "You are NOT allowed to use the bank."; + public static final String MODIFIER_SMALLISLAND_DESC = EnumChatFormatting.GREEN+"SmallIsland\n" + + "Your private island is 1/4 the normal size."; + + private static HashMap<String, Gamemode> currentGamemode = new HashMap<>(); + private static long lastDeathExemption = 0; + + public static class Gamemode { + public HardcoreMode hardcoreMode = HardcoreMode.NORMAL; + public IronmanMode ironmanMode = IronmanMode.NORMAL; + public int gamemodeModifiers = 0; + + public boolean locked = true; + } + + public enum HardcoreMode { + NORMAL("Normal", "Normal"), + SOFTCORE(EnumChatFormatting.RED+"Soft"+EnumChatFormatting.DARK_RED+"core\n" + + "You only have 1 life.\nDying will remove your hardcore status.\nDeaths to the void or \'unknown\' are exempted.", + "You died.", "You fell into the void"), + HARDCORE(EnumChatFormatting.DARK_RED+"Hardcore\n" + + "You only have 1 life.\nDying will remove your hardcore status."); + + public final String display; + public final String desc; + private String[] exemptions; + + HardcoreMode(String display, String... exemptions) { + this.display = display.split("\n")[0]; + this.desc = display; + this.exemptions = exemptions; + } + + public boolean isExemption(String line) { + for(String exemption : exemptions) { + if(line.contains(exemption)) return true; + } + return false; + } + } + + public enum IronmanMode { + NORMAL("Normal", "Normal"), + IRONMAN(EnumChatFormatting.WHITE+"Ironman\n" + + "You are NOT allowed to trade or use the auction house.", + "You ", "Auction House", "Auctions Browser", "Auction View"), + IRONMANPLUS(EnumChatFormatting.WHITE+"Ironman"+EnumChatFormatting.GOLD+"+\n" + + "You are NOT allowed to trade, use the auction house or bazaar.", + "You ", "Auction House", "Auctions Browser", "Auction View", "Bazaar"), + ULTIMATE_IRONMAN(EnumChatFormatting.DARK_AQUA+"Ultimate "+EnumChatFormatting.WHITE+"Ironman\n" + + "You are NOT allowed to trade or use the auction house.\n" + + "You are restricted to 1 inventory. (No containers, no echest, no wardrobe).", + "You ", "Auction House", "Auctions Browser", "Auction View", "Chest", + "Wardrobe", "Weapon Rack", "Shelves"), + ULTIMATE_IRONMANPLUS(EnumChatFormatting.DARK_AQUA+"Ultimate "+EnumChatFormatting.WHITE+"Ironman"+EnumChatFormatting.GOLD+"+\n" + + "You are NOT allowed to trade, use the auction house or bazaar.\n" + + "You are restricted to 1 inventory. (No containers, no echest, no wardrobe).", + "You ", "Auction House", "Auctions Browser", "Auction View", "Bazaar", + "Chest", "Wardrobe", "Weapon Rack", "Shelves"); + + public final String display; + public final String desc; + private final String[] bannedInventories; + + IronmanMode(String display, String... bannedInventories) { + this.display = display.split("\n")[0]; + this.desc = display; + this.bannedInventories = bannedInventories; + } + + public boolean isBanned(String inventoryName) { + for(String banned : bannedInventories) { + if(inventoryName.contains(banned)) return true; + } + return false; + } + } + + public static Gamemode getGamemode() { + String currentProfile = NotEnoughUpdates.INSTANCE.manager.getCurrentProfile(); + + if(currentProfile == null || currentProfile.isEmpty()) return null; + + return currentGamemode.computeIfAbsent(currentProfile, k -> new Gamemode()); + } + + public static void loadFromFile() { + File configDir = NotEnoughUpdates.INSTANCE.manager.configLocation; + File gamemodeFile = new File(configDir, + "gamemodes/gamemodes-"+Minecraft.getMinecraft().thePlayer.getUniqueID().toString()+".json"); + gamemodeFile.getParentFile().mkdirs(); + + if(!gamemodeFile.exists()) { + return; + } + + try { + InputStream in = new FileInputStream(gamemodeFile); + BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); + + String line = reader.readLine(); + String decoded = decrypt(line); + currentGamemode = gson.fromJson(decoded, GamemodeWrapper.class).currentGamemode; + } catch(Exception e) { + e.printStackTrace(); + } + } + + public static class GamemodeWrapper { + private HashMap<String, Gamemode> currentGamemode; + + public GamemodeWrapper(HashMap<String, Gamemode> currentGamemode) { + this.currentGamemode = currentGamemode; + } + } + + public static void saveToFile() { + File configDir = NotEnoughUpdates.INSTANCE.manager.configLocation; + File gamemodeFile = new File(configDir, + "gamemodes/gamemodes-"+Minecraft.getMinecraft().thePlayer.getUniqueID().toString()+".json"); + gamemodeFile.getParentFile().mkdirs(); + + try { + gamemodeFile.createNewFile(); + + try(BufferedWriter writer = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(gamemodeFile), StandardCharsets.UTF_8))) { + JsonObject obj = new JsonObject(); + writer.write(encrypt(gson.toJson(new GamemodeWrapper(currentGamemode), GamemodeWrapper.class))); + } + } catch(Exception e) { + e.printStackTrace(); + } + } + + public static Key getKeyFromPlayerUUID() { + byte[] bytes = ByteBuffer.allocate(2 * Long.SIZE / Byte.SIZE) + .putLong(Minecraft.getMinecraft().thePlayer.getUniqueID().getLeastSignificantBits()) + .putLong(Minecraft.getMinecraft().thePlayer.getUniqueID().getMostSignificantBits()) + .array(); + SecretKeySpec key = new SecretKeySpec(bytes, "AES"); + + return key; + } + + + public static String encrypt(String value) { + try { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, getKeyFromPlayerUUID()); + String encrypt = Base64.getEncoder().encodeToString(cipher.doFinal(value.getBytes())); + return encrypt; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static String decrypt(String encrypted) { + try { + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE, getKeyFromPlayerUUID()); + byte[] b64Decoded = Base64.getDecoder().decode(encrypted); + byte[] bytes = cipher.doFinal(b64Decoded); + + return new String(bytes); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static void setGamemode(Gamemode gamemode) { + String currentProfile = NotEnoughUpdates.INSTANCE.manager.getCurrentProfile(); + + if(currentProfile == null || currentProfile.isEmpty()) return; + + currentGamemode.put(currentProfile, gamemode); + } + + @SubscribeEvent + public void onPlayerInteract(PlayerInteractEvent event) { + if(getGamemode() == null || !NotEnoughUpdates.INSTANCE.isOnSkyblock()) return; + + if(!"Your Island".equals(SBScoreboardData.getInstance().location)) return; + + if(event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { + if(Math.abs(event.pos.getX()) > 40 || Math.abs(event.pos.getZ()) > 40) { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW+"[NPC] Builder"+ + EnumChatFormatting.WHITE+": Sorry, "+Minecraft.getMinecraft().thePlayer.getName()+ + ", due to budget cuts your skyblock island is now only 80 blocks wide.")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.AQUA+"(Use "+EnumChatFormatting.YELLOW+"/neugamemodes"+ + EnumChatFormatting.AQUA+" if you would like to build further out)")); + + event.setCanceled(true); + } + } + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if(getGamemode() == null || !NotEnoughUpdates.INSTANCE.isOnSkyblock()) return; + + if("Your Island".equals(SBScoreboardData.getInstance().location) && + (EnumChatFormatting.YELLOW+"Break a log").equals(SBScoreboardData.getInstance().objective)) { + getGamemode().locked = false; + } else { + getGamemode().locked = true; + } + + IronmanMode ironmanMode = getGamemode().ironmanMode; + GuiScreen gui = Minecraft.getMinecraft().currentScreen; + if(gui instanceof GuiChest) { + GuiChest eventGui = (GuiChest) gui; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + + if(containerName.equals("Bank") && (getGamemode().gamemodeModifiers & MODIFIER_NOBANK) != 0) { + Minecraft.getMinecraft().thePlayer.closeScreen(); + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW+"[NPC] Banker"+ + EnumChatFormatting.WHITE+": Hi, "+Minecraft.getMinecraft().thePlayer.getName()+ + ", you would like to create an account and make a deposit?")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW+"[NPC] Banker"+ + EnumChatFormatting.WHITE+": Alright, I've invested your money into ...")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED+"["+ + EnumChatFormatting.WHITE+"YouTube"+EnumChatFormatting.RED+"] Nullzee"+ + EnumChatFormatting.WHITE+": Hows it going everyone, welcome to my ultimate bazaar flipping guide ...")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW+"[NPC] Banker"+ + EnumChatFormatting.WHITE+": Hmm, it seems as though the economy has crashed. All your money is gone. Poof. Vanished.")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW+"[IDIOT] You"+ + EnumChatFormatting.WHITE+": ... never again ...")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.AQUA+"(Use "+EnumChatFormatting.YELLOW+"/neugamemodes"+ + EnumChatFormatting.AQUA+" if you would like to use the bank)")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + } else if(containerName.equals("Fairy") && (getGamemode().gamemodeModifiers & MODIFIER_DEVILISH) != 0) { + Minecraft.getMinecraft().thePlayer.closeScreen(); + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW+"[NPC] "+EnumChatFormatting.LIGHT_PURPLE+"Tia the Fairy"+ + EnumChatFormatting.WHITE+": Oh no, "+Minecraft.getMinecraft().thePlayer.getName()+ + ", you have sold your soul to the devil... please go away!")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.AQUA+"(Use "+EnumChatFormatting.YELLOW+"/neugamemodes"+ + EnumChatFormatting.AQUA+" if you would like to use fairy souls)")); + } else if(ironmanMode.isBanned(containerName)) { + Minecraft.getMinecraft().thePlayer.closeScreen(); + + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.AQUA+"You cannot access this inventory/menu because of your")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + " "+ironmanMode.display + EnumChatFormatting.AQUA+" status!")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.AQUA+"(Use "+EnumChatFormatting.YELLOW+"/neugamemodes"+ + EnumChatFormatting.AQUA+" if you would like to downgrade the status)")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); + } + } + } + + @SubscribeEvent + public void onChatMessage(ClientChatReceivedEvent event) { + /*if(Keyboard.isKeyDown(Keyboard.KEY_K)) { + System.out.println("-----START"); + for(char c : event.message.getFormattedText().toCharArray()) { + System.out.println((int)c); + } + System.out.println("-----END"); + }*/ + if(getGamemode() == null || !NotEnoughUpdates.INSTANCE.isOnSkyblock()) return; + + String message = event.message.getFormattedText(); + if(message.contains("\u2620")) { //Death symbol ( ☠ ) + HardcoreMode hardcoreMode = getGamemode().hardcoreMode; + if(hardcoreMode != HardcoreMode.NORMAL) { + if(hardcoreMode.isExemption(message)) { + lastDeathExemption = System.currentTimeMillis(); + } + } + } + + if(System.currentTimeMillis() - lastDeathExemption > 1000 && + message.contains("!") && message.startsWith(EnumChatFormatting.RESET.toString()+EnumChatFormatting.RED+"You died")) { + if(getGamemode().hardcoreMode != HardcoreMode.NORMAL) { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.RED.toString()+EnumChatFormatting.OBFUSCATED+"AAA"+ + EnumChatFormatting.RED+" You have lost your "+ + getGamemode().hardcoreMode.display+EnumChatFormatting.RED+" status! "+ + EnumChatFormatting.RED+EnumChatFormatting.OBFUSCATED+"AAA")); + getGamemode().hardcoreMode = HardcoreMode.NORMAL; + } + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroup.java b/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroup.java index aba1d743..86ff7278 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroup.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroup.java @@ -35,8 +35,10 @@ public abstract class MBGuiGroup extends MBGuiElement { @Override public void mouseClick(float x, float y, int mouseX, int mouseY) { + Map<MBGuiElement, Vector2f> childrenPos = getChildrenPosition(); + for(MBGuiElement child : getChildren()) { - Vector2f childPos = childrenPosition.get(child); + Vector2f childPos = childrenPos.get(child); if(mouseX > x+childPos.x && mouseX < x+childPos.x+child.getWidth()) { if(mouseY > y+childPos.y && mouseY < y+childPos.y+child.getHeight()) { child.mouseClick(x+childPos.x, y+childPos.y, mouseX, mouseY); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroupFloating.java b/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroupFloating.java index 6bdd25fd..0c44932a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroupFloating.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mbgui/MBGuiGroupFloating.java @@ -1,5 +1,9 @@ package io.github.moulberry.notenoughupdates.mbgui; +import io.github.moulberry.notenoughupdates.GuiItemRecipe; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.auction.CustomAH; +import io.github.moulberry.notenoughupdates.auction.CustomAHGui; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -11,7 +15,7 @@ import java.util.*; public class MBGuiGroupFloating extends MBGuiGroup { private LinkedHashMap<MBGuiElement, MBAnchorPoint> children; - private GuiContainer lastContainer = null; + private GuiScreen lastScreen = null; private HashMap<MBGuiElement, Vector2f> childrenPositionOffset = new HashMap<>(); public MBGuiGroupFloating(int width, int height, LinkedHashMap<MBGuiElement, MBAnchorPoint> children) { @@ -29,10 +33,45 @@ public class MBGuiGroupFloating extends MBGuiGroup { public Map<MBGuiElement, Vector2f> getChildrenPosition() { GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen; - if(currentScreen instanceof GuiContainer) { - GuiContainer currentContainer = (GuiContainer) currentScreen; - if(lastContainer != currentContainer) { - lastContainer = currentContainer; + if(currentScreen instanceof GuiContainer || currentScreen instanceof GuiItemRecipe + || currentScreen instanceof CustomAHGui || NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.isRenderOverAuctionView()) { + + if(lastScreen != currentScreen) { + lastScreen = currentScreen; + + int xSize = -1; + int ySize = -1; + int guiLeft = -1; + int guiTop = -1; + + if(currentScreen instanceof GuiContainer) { + GuiContainer currentContainer = (GuiContainer) currentScreen; + + try { + xSize = (int) Utils.getField(GuiContainer.class, currentContainer, "xSize", "field_146999_f"); + ySize = (int) Utils.getField(GuiContainer.class, currentContainer, "ySize", "field_147000_g"); + guiLeft = (int) Utils.getField(GuiContainer.class, currentContainer, "guiLeft", "field_147003_i"); + guiTop = (int) Utils.getField(GuiContainer.class, currentContainer, "guiTop", "field_147009_r"); + } catch(Exception ignored) { + } + } else if(currentScreen instanceof GuiItemRecipe) { + xSize = ((GuiItemRecipe)currentScreen).xSize; + ySize = ((GuiItemRecipe)currentScreen).ySize; + guiLeft = ((GuiItemRecipe)currentScreen).guiLeft; + guiTop = ((GuiItemRecipe)currentScreen).guiTop; + } else if(currentScreen instanceof CustomAHGui || + NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.isRenderOverAuctionView()) { + xSize = NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.getXSize(); + ySize = NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.getYSize(); + guiLeft = NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.guiLeft; + guiTop = NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.guiTop; + } + + if(xSize <= 0 && ySize <= 0 && guiLeft <= 0 && guiTop <= 0) { + lastScreen = null; + return Collections.unmodifiableMap(childrenPosition); + } + for(Map.Entry<MBGuiElement, MBAnchorPoint> entry : children.entrySet()) { MBGuiElement child = entry.getKey(); MBAnchorPoint anchorPoint = entry.getValue(); @@ -44,20 +83,13 @@ public class MBGuiGroupFloating extends MBGuiGroup { childPos = new Vector2f(); } + if(anchorPoint.anchorPoint == MBAnchorPoint.AnchorPoint.INV_BOTMID) { - try { - int xSize = (int) Utils.getField(GuiContainer.class, currentContainer, "xSize", "field_146999_f"); - int ySize = (int) Utils.getField(GuiContainer.class, currentContainer, "ySize", "field_147000_g"); - int guiLeft = (int) Utils.getField(GuiContainer.class, currentContainer, "guiLeft", "field_147003_i"); - int guiTop = (int) Utils.getField(GuiContainer.class, currentContainer, "guiTop", "field_147009_r"); - - int defGuiLeft = (this.width - xSize) / 2; - int defGuiTop = (this.height - ySize) / 2; - - childPos.x += guiLeft-defGuiLeft + (anchorPoint.anchorPoint.x-0.5f)*xSize; - childPos.y += guiTop-defGuiTop + (anchorPoint.anchorPoint.y-0.5f)*ySize; - } catch(Exception ignored) { - } + int defGuiLeft = (this.width - xSize) / 2; + int defGuiTop = (this.height - ySize) / 2; + + childPos.x += guiLeft-defGuiLeft + (anchorPoint.anchorPoint.x-0.5f)*xSize; + childPos.y += guiTop-defGuiTop + (anchorPoint.anchorPoint.y-0.5f)*ySize; } childrenPositionOffset.put(child, childPos); @@ -71,7 +103,7 @@ public class MBGuiGroupFloating extends MBGuiGroup { @Override public void recalculate() { - lastContainer = null; + lastScreen = null; for(MBGuiElement child : children.keySet()) { child.recalculate(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 76da035a..e8432d63 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -44,6 +44,8 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; import net.minecraft.util.*; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.Charsets; import org.apache.commons.lang3.StringUtils; @@ -77,8 +79,7 @@ public class GuiProfileViewer extends GuiScreen { public static final ResourceLocation pv_bg = new ResourceLocation("notenoughupdates:pv_bg.png"); public static final ResourceLocation pv_elements = new ResourceLocation("notenoughupdates:pv_elements.png"); public static final ResourceLocation resource_packs = new ResourceLocation("minecraft:textures/gui/resource_packs.png"); - private static final ResourceLocation creativeInventoryTabs = - new ResourceLocation("textures/gui/container/creative_inventory/tabs.png"); + public static final ResourceLocation icons = new ResourceLocation("textures/gui/icons.png"); private static final NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); @@ -734,7 +735,7 @@ public class GuiProfileViewer extends GuiScreen { float exp = pet.get("exp").getAsFloat(); if(tierNum == null) continue; - if(pet.has("heldItem") && pet.get("heldItem").getAsString().equals("PET_ITEM_TIER_BOOST")) { + if(pet.has("heldItem") && !pet.get("heldItem").isJsonNull() && pet.get("heldItem").getAsString().equals("PET_ITEM_TIER_BOOST")) { tierNum = ""+(Integer.parseInt(tierNum)+1); } @@ -2226,8 +2227,7 @@ public class GuiProfileViewer extends GuiScreen { } private void renderGoldBar(float x, float y, float xSize) { - - Minecraft.getMinecraft().getTextureManager().bindTexture(Gui.icons); + Minecraft.getMinecraft().getTextureManager().bindTexture(icons); ShaderManager shaderManager = ShaderManager.getInstance(); shaderManager.loadShader("make_gold"); shaderManager.loadData("make_gold", "amount", (startTime-System.currentTimeMillis())/10000f); @@ -2239,7 +2239,7 @@ public class GuiProfileViewer extends GuiScreen { } private void renderBar(float x, float y, float xSize, float completed) { - Minecraft.getMinecraft().getTextureManager().bindTexture(Gui.icons); + Minecraft.getMinecraft().getTextureManager().bindTexture(icons); completed = Math.round(completed/0.05f)*0.05f; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/questing/SBScoreboardData.java b/src/main/java/io/github/moulberry/notenoughupdates/questing/SBScoreboardData.java index 4c19dd39..9735f917 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/questing/SBScoreboardData.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/questing/SBScoreboardData.java @@ -6,6 +6,7 @@ import net.minecraft.scoreboard.Score; import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.scoreboard.Scoreboard; +import net.minecraft.util.EnumChatFormatting; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -25,6 +26,7 @@ public class SBScoreboardData { public String location = ""; public String date = ""; public String time = ""; + public String objective = ""; public Date currentTimeDate = null; @@ -67,6 +69,16 @@ public class SBScoreboardData { location = Utils.cleanColour(matcher.group()).trim(); } } + objective = null; + + boolean objTextLast = false; + for(String line : lines) { + if(objTextLast) { + objective = line; + } + + objTextLast = line.equals("Objective"); + } } catch(Exception e) { e.printStackTrace(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index 144db9da..73c15a7b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -619,6 +619,7 @@ public class Utils { return new Color(colourInt).darker(); } + //private static List<String> public static void drawHoveringText(List<String> textLines, final int mouseX, final int mouseY, final int screenWidth, final int screenHeight, final int maxTextWidth, FontRenderer font, boolean coloured) { if (!textLines.isEmpty()) { |