From bd6f658c6c53d160c40bc3b5fdead7b7b3dd20c4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Jul 2020 00:53:17 +1000 Subject: 1.8 --- .../moulberry/notenoughupdates/CustomAH.java | 208 +++++++++ .../moulberry/notenoughupdates/CustomItems.java | 6 +- .../moulberry/notenoughupdates/GuiTextures.java | 9 + .../github/moulberry/notenoughupdates/NEUIO.java | 7 - .../moulberry/notenoughupdates/NEUManager.java | 79 +++- .../moulberry/notenoughupdates/NEUOverlay.java | 77 +++- .../notenoughupdates/NEUResourceManager.java | 38 ++ .../notenoughupdates/NotEnoughUpdates.java | 115 ++++- .../moulberry/notenoughupdates/StreamerMode.java | 63 +++ .../github/moulberry/notenoughupdates/Utils.java | 57 +-- .../notenoughupdates/commands/SimpleCommand.java | 36 ++ .../infopanes/CollectionLogInfoPane.java | 492 +++++++++++++++++++++ .../notenoughupdates/infopanes/InfoPane.java | 1 + .../infopanes/SettingsInfoPane.java | 138 +++++- .../itemeditor/GuiElementTextField.java | 34 +- .../notenoughupdates/mixins/MixinGuiIngame.java | 24 + .../notenoughupdates/options/Options.java | 95 +++- .../moulberry/notenoughupdates/util/TexLoc.java | 10 +- .../assets/notenoughupdates/ah_item_holder.png | Bin 0 -> 642 bytes .../assets/notenoughupdates/ah_item_tab.png | Bin 0 -> 627 bytes .../assets/notenoughupdates/item_mask.png | Bin 856 -> 2800 bytes src/main/resources/assets/notenoughupdates/off.png | Bin 1302 -> 3331 bytes .../assets/notenoughupdates/order_value.png | Bin 0 -> 1818 bytes .../assets/notenoughupdates/order_value_active.png | Bin 0 -> 1804 bytes .../notenoughupdates/shaders/program/blit.vsh | 16 + .../notenoughupdates/shaders/program/grayscale.fsh | 15 + .../shaders/program/grayscale.json | 17 + .../assets/notenoughupdates/slider_button.png | Bin 0 -> 666 bytes .../assets/notenoughupdates/slider_off.png | Bin 0 -> 765 bytes .../assets/notenoughupdates/slider_on.png | Bin 0 -> 767 bytes src/main/resources/mixins.notenoughupdates.json | 3 +- 31 files changed, 1412 insertions(+), 128 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/CustomAH.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/NEUResourceManager.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/StreamerMode.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/commands/SimpleCommand.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/infopanes/CollectionLogInfoPane.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java create mode 100644 src/main/resources/assets/notenoughupdates/ah_item_holder.png create mode 100644 src/main/resources/assets/notenoughupdates/ah_item_tab.png create mode 100644 src/main/resources/assets/notenoughupdates/order_value.png create mode 100644 src/main/resources/assets/notenoughupdates/order_value_active.png create mode 100644 src/main/resources/assets/notenoughupdates/shaders/program/blit.vsh create mode 100644 src/main/resources/assets/notenoughupdates/shaders/program/grayscale.fsh create mode 100644 src/main/resources/assets/notenoughupdates/shaders/program/grayscale.json create mode 100644 src/main/resources/assets/notenoughupdates/slider_button.png create mode 100644 src/main/resources/assets/notenoughupdates/slider_off.png create mode 100644 src/main/resources/assets/notenoughupdates/slider_on.png diff --git a/src/main/java/io/github/moulberry/notenoughupdates/CustomAH.java b/src/main/java/io/github/moulberry/notenoughupdates/CustomAH.java new file mode 100644 index 00000000..d74d0e5c --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/CustomAH.java @@ -0,0 +1,208 @@ +package io.github.moulberry.notenoughupdates; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.util.TexLoc; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.Item; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static io.github.moulberry.notenoughupdates.GuiTextures.*; + +public class CustomAH extends GuiScreen { + + private static final ResourceLocation inventoryBackground = new ResourceLocation("textures/gui/container/inventory.png"); + private static final ResourceLocation creativeTabSearch = new ResourceLocation("textures/gui/container/creative_inventory/tab_item_search.png"); + private static final ResourceLocation creativeInventoryTabs = new ResourceLocation("textures/gui/container/creative_inventory/tabs.png"); + + private int yScrollInitial = 0; + private boolean scrollClicked = false; + + + private int splits = 2; + + private int ySplit = 35; + private int ySplitSize = 18; + private int ySize = 136 + ySplitSize*splits; + private int xSize = 195; + + private float scrollAmount; + + private int guiLeft = 0; + private int guiTop = 0; + + private NEUManager manager; + private HashMap auctionItems = new HashMap<>(); + + private TexLoc tl = new TexLoc(0, 0, Keyboard.KEY_M); + + public CustomAH(NEUManager manager) { + this.manager = manager; + updateAuctions(); + } + + private void updateAuctions() { + HashMap pages = new HashMap<>(); + + HashMap args = new HashMap<>(); + args.put("page", "0"); + AtomicInteger totalPages = new AtomicInteger(1); + AtomicInteger currentPages = new AtomicInteger(0); + manager.hypixelApi.getHypixelApiAsync(manager.config.apiKey.value, "skyblock/profiles", + args, jsonObject -> { + if(jsonObject.get("success").getAsBoolean()) { + pages.put(0, jsonObject); + totalPages.set(jsonObject.get("totalPages").getAsInt()); + currentPages.incrementAndGet(); + + for(int i=1; i args2 = new HashMap<>(); + args2.put("page", ""+i); + manager.hypixelApi.getHypixelApiAsync(manager.config.apiKey.value, "skyblock/profiles", + args2, jsonObject2 -> { + if (jsonObject2.get("success").getAsBoolean()) { + pages.put(j, jsonObject2); + currentPages.incrementAndGet(); + } + } + ); + } + } + } + ); + + ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();//1593549115 () 1593631661919 + long startTime = System.currentTimeMillis(); + ses.schedule(new Runnable() { + public void run() { + if(System.currentTimeMillis() - startTime > 20000) return; + + if(currentPages.get() == totalPages.get()) { + auctionItems.clear(); + for(int pageNum : pages.keySet()) { + JsonObject page = pages.get(pageNum); + JsonArray auctions = page.get("auctions").getAsJsonArray(); + for(int i=0; i guiLeft+175 && mouseX < guiLeft+175+12) { + if(mouseY > y && mouseY < y+15) { + scrollClicked = true; + return; + } + } + scrollClicked = false; + } + + @Override + protected void mouseReleased(int mouseX, int mouseY, int state) { + scrollClicked = false; + } + + @Override + protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + if(scrollClicked) { + int yMin = guiTop+18 + 8; + int yMax = guiTop+18+(95+ySplitSize*2) + 8; + + scrollAmount = (mouseY-yMin)/(float)yMax; + scrollAmount = Math.max(0, Math.min(1, scrollAmount)); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java b/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java index 148f1bc5..4328eaf4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java @@ -8,8 +8,8 @@ import net.minecraft.util.EnumChatFormatting; public class CustomItems { /** - * So it has come to this, huh? Snooping through the source to find all my carefully crafted easter eggs. Well - * guess what, you cheated not only the game, but yourself. You didn't grow. You didn't improve. You took a + * So it has come to this, huh? Snooping through the source to find all my carefully crafted easter eggs. You + * cheated not only the game, but yourself. You didn't grow. You didn't improve. You took a * shortcut and gained nothing. You experienced a hollow victory. Nothing was risked and nothing was gained. * It's sad that you don't know the difference. */ @@ -22,7 +22,7 @@ public class CustomItems { "Dirt, AOTD. Dirt, AOTD.", "Ooh, Dirt to Midas! Let's shake it up a little.", "", - "Also, Did you know that only 10% of the people watching are subscribed?", + "Also, did you know that only 8.7% of the people watching are subscribed?", "It's OK, everyone makes mistakes", "Also follow -> twitch.tv/nullzeelive", "Also -> discord.gg/nullzee"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java index 48db19a5..965a7e48 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java @@ -14,12 +14,19 @@ public class GuiTextures { public static final ResourceLocation item_edit = new ResourceLocation("notenoughupdates:item_edit.png"); public static final ResourceLocation close = new ResourceLocation("notenoughupdates:close.png"); public static final ResourceLocation settings = new ResourceLocation("notenoughupdates:settings.png"); + public static final ResourceLocation off = new ResourceLocation("notenoughupdates:off.png"); public static final ResourceLocation on = new ResourceLocation("notenoughupdates:on.png"); public static final ResourceLocation help = new ResourceLocation("notenoughupdates:help.png"); + public static final ResourceLocation slider_off = new ResourceLocation("notenoughupdates:slider_off.png"); + public static final ResourceLocation slider_on = new ResourceLocation("notenoughupdates:slider_on.png"); + public static final ResourceLocation slider_button = new ResourceLocation("notenoughupdates:slider_button.png"); public static final ResourceLocation item_mask = new ResourceLocation("notenoughupdates:item_mask.png"); + public static final ResourceLocation ah_item_holder = new ResourceLocation("notenoughupdates:ah_item_holder.png"); + public static final ResourceLocation ah_item_tab = new ResourceLocation("notenoughupdates:ah_item_tab.png"); + public static final ResourceLocation logo = new ResourceLocation("notenoughupdates:logo.png"); public static final ResourceLocation logo_fg = new ResourceLocation("notenoughupdates:logo_fg.png"); public static final ResourceLocation logo_bg = new ResourceLocation("notenoughupdates:logo_bg.png"); @@ -39,8 +46,10 @@ public class GuiTextures { public static final ResourceLocation order_alphabetical = new ResourceLocation("notenoughupdates:order_alphabetical.png"); public static final ResourceLocation order_rarity = new ResourceLocation("notenoughupdates:order_rarity.png"); + public static final ResourceLocation order_value = new ResourceLocation("notenoughupdates:order_value.png"); public static final ResourceLocation order_alphabetical_active = new ResourceLocation("notenoughupdates:order_alphabetical_active.png"); public static final ResourceLocation order_rarity_active = new ResourceLocation("notenoughupdates:order_rarity_active.png"); + public static final ResourceLocation order_value_active = new ResourceLocation("notenoughupdates:order_value_active.png"); public static final ResourceLocation ascending_overlay = new ResourceLocation("notenoughupdates:ascending_overlay.png"); public static final ResourceLocation descending_overlay = new ResourceLocation("notenoughupdates:descending_overlay.png"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java index a7c7a1e4..d2190425 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUIO.java @@ -84,13 +84,6 @@ public class NEUIO { } } } - - /*for(GHContent content : repo.getDirectoryContent("items")) { - String oldSha = oldShas.get(content.getName()); - if(!content.getSha().equals(oldSha)) { - changedFiles.put(content.getName(), content.getSha()); - } - }*/ } catch(IOException e) { return null; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index bebd090c..e2c8d928 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -54,7 +54,7 @@ public class NEUManager { public String viewItemAttemptID = null; public long viewItemAttemptTime = 0; - public String currentProfile = ""; + public String currentProfile = "Papaya"; public final HypixelApi hypixelApi = new HypixelApi(); private ResourceLocation wkZip = new ResourceLocation("notenoughupdates:wkhtmltox.zip"); @@ -180,6 +180,25 @@ public class NEUManager { public float craftCost = -1; } + public boolean isVanillaItem(String internalname) { + //Removes trailing numbers and underscores, eg. LEAVES_2-3 -> LEAVES + String vanillaName = internalname.split("-")[0]; + int sub = 0; + for(int i=vanillaName.length()-1; i>1; i--) { + char c = vanillaName.charAt(i); + if((int)c >= 48 && (int)c <= 57) { //0-9 + sub++; + } else if(c == '_') { + sub++; + break; + } else { + break; + } + } + vanillaName = vanillaName.substring(0, vanillaName.length()-sub).toLowerCase(); + return Item.itemRegistry.getObject(new ResourceLocation(vanillaName)) != null; + } + /** * Recursively calculates the cost of crafting an item from raw materials. */ @@ -189,24 +208,7 @@ public class NEUManager { } else { CraftInfo ci = new CraftInfo(); - //Removes trailing numbers and underscores, eg. LEAVES_2-3 -> LEAVES - String vanillaName = internalname.split("-")[0]; - int sub = 0; - for(int i=vanillaName.length()-1; i>1; i--) { - char c = vanillaName.charAt(i); - if((int)c >= 48 && (int)c <= 57) { //0-9 - sub++; - } else if(c == '_') { - sub++; - break; - } else { - break; - } - } - vanillaName = vanillaName.substring(0, vanillaName.length()-sub); - if(Item.itemRegistry.getObject(new ResourceLocation(vanillaName)) != null) { - ci.vanillaItem = true; - } + ci.vanillaItem = isVanillaItem(internalname); JsonObject auctionInfo = getItemAuctionInfo(internalname); JsonObject bazaarInfo = getBazaarInfo(internalname); @@ -657,9 +659,29 @@ public class NEUManager { public Set search(String query, boolean multi) { if(multi) { Set result = new HashSet<>(); - for(String query2 : query.split("\\|")) { - result.addAll(search(query2)); + + StringBuilder query2 = new StringBuilder(); + char lastOp = '|'; + for(char c : query.toCharArray()) { + if(c == '|' || c == '&') { + if(lastOp == '|') { + result.addAll(search(query2.toString())); + } else if(lastOp == '&') { + result.retainAll(search(query2.toString())); + } + + query2 = new StringBuilder(); + lastOp = c; + } else { + query2.append(c); + } + } + if(lastOp == '|') { + result.addAll(search(query2.toString())); + } else if(lastOp == '&') { + result.retainAll(search(query2.toString())); } + return result; } else { return search(query); @@ -670,6 +692,10 @@ public class NEUManager { * Returns the name of items which match a certain search query. */ public Set search(String query) { + query = query.trim(); + boolean negate = query.startsWith("!"); + if(negate) query = query.substring(1); + LinkedHashSet results = new LinkedHashSet<>(); if(query.startsWith("title:")) { query = query.substring(6); @@ -691,7 +717,16 @@ public class NEUManager { results.addAll(new TreeSet<>(search(query, titleWordMap))); results.addAll(new TreeSet<>(search(query, loreWordMap))); } - return results; + if(!negate) { + return results; + } else { + Set negatedResults = new HashSet<>(); + for(String internalname : itemMap.keySet()) { + negatedResults.add(internalname); + } + negatedResults.removeAll(results); + return negatedResults; + } } /** diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 59233882..d96be893 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -30,6 +30,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.Matrix4f; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.client.ClientCommandHandler; import org.apache.commons.lang3.StringUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; @@ -62,10 +63,10 @@ public class NEUOverlay extends Gui { }; private ResourceLocation[] orderIcons = new ResourceLocation[] { - order_alphabetical, order_rarity + order_alphabetical, order_rarity, order_value }; private ResourceLocation[] orderIconsActive = new ResourceLocation[] { - order_alphabetical_active, order_rarity_active + order_alphabetical_active, order_rarity_active, order_value_active }; //Various constants used for GUI structure @@ -74,9 +75,8 @@ public class NEUOverlay extends Gui { private final int searchBarYSize = 40; private final int searchBarPadding = 2; - private static final int BOX_PADDING = 15; - public static final int ITEM_PADDING = 4; - public static final int ITEM_SIZE = 16; + public static final int ITEM_PADDING = 4; + public static final int ITEM_SIZE = 16; private Color bg = new Color(90, 90, 140, 50); private Color fg = new Color(100,100,100, 255); @@ -97,6 +97,9 @@ public class NEUOverlay extends Gui { private boolean searchMode = false; private long millisLastLeftClick = 0; + private long millisLastMouseMove = 0; + private int lastMouseX = 0; + private int lastMouseY = 0; boolean mouseDown = false; @@ -107,6 +110,7 @@ public class NEUOverlay extends Gui { private static final int COMPARE_MODE_ALPHABETICAL = 0; private static final int COMPARE_MODE_RARITY = 1; + private static final int COMPARE_MODE_VALUE = 2; private static final int SORT_MODE_ALL = 0; private static final int SORT_MODE_MOB = 1; @@ -177,6 +181,13 @@ public class NEUOverlay extends Gui { int mouseX = Mouse.getX() / scaledresolution.getScaleFactor(); int mouseY = height - Mouse.getY() / scaledresolution.getScaleFactor(); + if(lastMouseX != mouseX || lastMouseY != mouseY) { + millisLastMouseMove = System.currentTimeMillis(); + } + + lastMouseX = mouseX; + lastMouseY = mouseY; + if(Mouse.getEventButtonState()) { mouseDown = true; } else if(Mouse.getEventButton() != -1) { @@ -288,8 +299,8 @@ public class NEUOverlay extends Gui { } //Clicking on "close info pane" button - if(mouseX > width*getInfoPaneOffsetFactor()-22 && mouseX < width*getInfoPaneOffsetFactor()-6) { - if(mouseY > 7 && mouseY < 23) { + if(mouseX > width*getInfoPaneOffsetFactor()-getBoxPadding()-8 && mouseX < width*getInfoPaneOffsetFactor()-getBoxPadding()+8) { + if(mouseY > getBoxPadding()-8 && mouseY < getBoxPadding()+8) { if(Mouse.getEventButtonState() && Mouse.getEventButton() < 2) { //Left or right click up displayInformationPane(null); return true; @@ -322,6 +333,9 @@ public class NEUOverlay extends Gui { if(command.startsWith("/")) { NotEnoughUpdates.INSTANCE.sendChatMessage(command); return true; + } else { + ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, command); + return true; } } } @@ -376,6 +390,8 @@ public class NEUOverlay extends Gui { if(mouseX < width*getInfoPaneOffsetFactor()) { activeInfoPane.mouseInput(width, height, mouseX, mouseY, mouseDown); return true; + } else if(Mouse.getEventButton() <= 1 && Mouse.getEventButtonState()) { //Left or right click + activeInfoPane.mouseInputOutside(); } } @@ -627,6 +643,12 @@ public class NEUOverlay extends Gui { if(rarity1 < rarity2) return mult; if(rarity1 > rarity2) return -mult; + } else if(getCompareMode() == COMPARE_MODE_VALUE) { + float cost1 = manager.getCraftCost(o1.get("internalname").getAsString()).craftCost; + float cost2 = manager.getCraftCost(o2.get("internalname").getAsString()).craftCost; + + if(cost1 < cost2) return mult; + if(cost1 > cost2) return -mult; } String i1 = o1.get("internalname").getAsString(); @@ -776,7 +798,8 @@ public class NEUOverlay extends Gui { } public int getBoxPadding() { - return (BOX_PADDING-5)*2/scaledresolution.getScaleFactor()+5; + double panePadding = Math.max(0, Math.min(20, manager.config.panePadding.value)); + return (int)(panePadding*2/scaledresolution.getScaleFactor()+5); } private abstract class ItemSlotConsumer { @@ -1252,7 +1275,7 @@ public class NEUOverlay extends Gui { //Atomic reference used so that below lambda doesn't complain about non-effectively-final variable AtomicReference tooltipToDisplay = new AtomicReference<>(null); - + List textToDisplay = null; if(itemPaneOffsetFactor.getValue() < 1) { renderBlurredBackground(width, height, leftSide+getBoxPadding()-5, getBoxPadding()-5, @@ -1290,6 +1313,19 @@ public class NEUOverlay extends Gui { GlStateManager.color(1f, 1f, 1f, 1f); Utils.drawTexturedRect(orderIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE,0, 1, 0, 1, GL11.GL_NEAREST); GlStateManager.bindTexture(0); + + if(mouseY > iconTop && mouseY < iconTop+scaledITEM_SIZE) { + if(mouseX > orderIconX && mouseX < orderIconX+scaledITEM_SIZE) { + if(System.currentTimeMillis() - millisLastMouseMove > 400) { + String text = EnumChatFormatting.GRAY+"Order "; + if(i == COMPARE_MODE_ALPHABETICAL) text += "Alphabetically"; + else if(i == COMPARE_MODE_RARITY) text += "by Rarity"; + else if(i == COMPARE_MODE_VALUE) text += "by Item Worth"; + else text = null; + if(text != null) textToDisplay = Utils.createList(text); + } + } + } } for(int i=0; i iconTop && mouseY < iconTop+scaledITEM_SIZE) { + if(mouseX > sortIconX && mouseX < sortIconX+scaledITEM_SIZE) { + if(System.currentTimeMillis() - millisLastMouseMove > 400) { + String text = EnumChatFormatting.GRAY+"Filter "; + if(i == SORT_MODE_ALL) text = EnumChatFormatting.GRAY+"No Filter"; + else if(i == SORT_MODE_MOB) text += "Mobs"; + else if(i == SORT_MODE_PET) text += "Pets"; + else if(i == SORT_MODE_TOOL) text += "Tools"; + else if(i == SORT_MODE_ARMOR) text += "Armor"; + else if(i == SORT_MODE_ACCESSORY) text += "Accessories"; + else text = null; + if(text != null) textToDisplay = Utils.createList(text); + } + } + } } if(!hoverInv) { @@ -1355,7 +1407,7 @@ public class NEUOverlay extends Gui { GlStateManager.color(1f, 1f, 1f, 1f); Minecraft.getMinecraft().getTextureManager().bindTexture(close); - Utils.drawTexturedRect(rightSide-22, 7, 16, 16); + Utils.drawTexturedRect(rightSide-getBoxPadding()-8, getBoxPadding()-8, 16, 16); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); } @@ -1567,7 +1619,10 @@ public class NEUOverlay extends Gui { if(hasClick) text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"LMB/R : View recipe!"); if(hasInfo) text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"RMB : View additional information!"); - Utils.drawHoveringText(text, mouseX, mouseY, width, height, -1, fr); + textToDisplay = text; + } + if(textToDisplay != null) { + Utils.drawHoveringText(textToDisplay, mouseX, mouseY, width, height, -1, fr); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUResourceManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUResourceManager.java new file mode 100644 index 00000000..41737eda --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUResourceManager.java @@ -0,0 +1,38 @@ +package io.github.moulberry.notenoughupdates; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +public class NEUResourceManager implements IResourceManager { + + private IResourceManager parentResourceManager; + + public NEUResourceManager(IResourceManager parentResourceManager) { + this.parentResourceManager = parentResourceManager; + } + + @Override + public Set getResourceDomains() { + return parentResourceManager.getResourceDomains(); + } + + @Override + public IResource getResource(ResourceLocation location) throws IOException { + return parentResourceManager.getResource(forceNeuRL(location)); + } + + @Override + public List getAllResources(ResourceLocation location) throws IOException { + return parentResourceManager.getAllResources(forceNeuRL(location)); + } + + private ResourceLocation forceNeuRL(ResourceLocation location) { + return new ResourceLocation("notenoughupdates", location.getResourcePath()); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index b4b48db5..ab903227 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -6,14 +6,20 @@ import com.mojang.authlib.Agent; import com.mojang.authlib.exceptions.AuthenticationException; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication; +import io.github.moulberry.notenoughupdates.commands.SimpleCommand; +import io.github.moulberry.notenoughupdates.infopanes.CollectionLogInfoPane; import net.minecraft.client.Minecraft; 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.GuiInventory; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.command.ICommandSender; +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; @@ -23,6 +29,7 @@ import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.Session; import net.minecraft.util.StatCollector; +import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.client.event.GuiScreenEvent; @@ -32,6 +39,7 @@ 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 org.lwjgl.input.Keyboard; @@ -83,6 +91,29 @@ public class NotEnoughUpdates { return s; } + ScheduledExecutorService guiDelaySES = Executors.newScheduledThreadPool(1); + SimpleCommand collectionLogCommand = new SimpleCommand("neucl", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + guiDelaySES.schedule(()->{ + Minecraft.getMinecraft().displayGuiScreen(new GuiInventory(Minecraft.getMinecraft().thePlayer)); + }, 10L, TimeUnit.MILLISECONDS); + } + manager.updatePrices(); + overlay.displayInformationPane(new CollectionLogInfoPane(overlay, manager)); + } + }); + + SimpleCommand neuAhCommand = new SimpleCommand("neuah", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + guiDelaySES.schedule(()->{ + Minecraft.getMinecraft().displayGuiScreen(new CustomAH(manager)); + }, 10L, TimeUnit.MILLISECONDS); + } + } + }); + /** * Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder. * @param event @@ -94,6 +125,9 @@ public class NotEnoughUpdates { File f = new File(event.getModConfigurationDirectory(), "notenoughupdates"); f.mkdirs(); + ClientCommandHandler.instance.registerCommand(collectionLogCommand); + ClientCommandHandler.instance.registerCommand(neuAhCommand); + neuio = new NEUIO(getAccessToken()); manager = new NEUManager(this, neuio, f); manager.loadItemInformation(); @@ -165,16 +199,64 @@ public class NotEnoughUpdates { } /** - * Will send the cached message from #sendChatMessage when at least 200ms has passed since the last message. + * 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 */ - @EventHandler + private HashMap newItemAddMap = new HashMap<>(); + @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { if(currChatMessage != null && System.currentTimeMillis() - lastChatMessage > CHAT_MSG_COOLDOWN) { lastChatMessage = System.currentTimeMillis(); Minecraft.getMinecraft().thePlayer.sendChatMessage(currChatMessage); currChatMessage = null; } + if(hasSkyblockScoreboard() && manager.currentProfile != null && manager.currentProfile.length() > 0) { + HashSet newItem = new HashSet<>(); + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { + processUniqueStack(stack, newItem); + } + 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) { + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { + processUniqueStack(stack, newItem); + } + } + newItemAddMap.keySet().retainAll(newItem); + } + } + + private void processUniqueStack(ItemStack stack, HashSet newItem) { + if(stack != null && stack.hasTagCompound()) { + String internalname = manager.getInternalNameForItem(stack); + if(internalname != null) { + ArrayList log = manager.config.collectionLog.value.computeIfAbsent( + manager.currentProfile, k -> new ArrayList<>()); + if(!log.contains(internalname)) { + newItem.add(internalname); + if(newItemAddMap.containsKey(internalname)) { + if(System.currentTimeMillis() - newItemAddMap.get(internalname) > 1000) { + log.add(internalname); + } + } else { + newItemAddMap.put(internalname, System.currentTimeMillis()); + } + } + } + } } /** @@ -302,8 +384,9 @@ public class NotEnoughUpdates { /** * 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 + @SubscribeEvent(priority = EventPriority.LOW) public void onGuiChat(ClientChatReceivedEvent e) { String r = null; String unformatted = e.message.getUnformattedText().replaceAll("(?i)\\u00A7.", ""); @@ -319,12 +402,20 @@ public class NotEnoughUpdates { EnumChatFormatting.RED+"Invalid recipe ")) { r = ""; } - if(r != null) { + if(r != null) { if(manager.failViewItem(r)) { e.setCanceled(true); } missingRecipe.set(true); } + //System.out.println(e.message); + if(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); + } + } } /** @@ -441,6 +532,9 @@ public class NotEnoughUpdates { JOptionPane.PLAIN_MESSAGE, null, new String[]{"Enter"}, "Enter"); resInternalname = tf.getText(); + if(resInternalname.trim().length() == 0) { + return; + } JsonObject recipe = new JsonObject(); @@ -536,6 +630,16 @@ public class NotEnoughUpdates { */ @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; @@ -623,7 +727,10 @@ public class NotEnoughUpdates { //Stolen from Biscut's SkyblockAddons public boolean isOnSkyblock() { if(!manager.config.onlyShowOnSkyblock.value) return true; + return hasSkyblockScoreboard(); + } + public boolean hasSkyblockScoreboard() { Minecraft mc = Minecraft.getMinecraft(); if (mc != null && mc.theWorld != null) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/StreamerMode.java b/src/main/java/io/github/moulberry/notenoughupdates/StreamerMode.java new file mode 100644 index 00000000..c7d5e8ae --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/StreamerMode.java @@ -0,0 +1,63 @@ +package io.github.moulberry.notenoughupdates; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StreamerMode { + + private static final Pattern lobbyPattern = Pattern.compile("(mini|mega)([0-9]{1,3}[A-Z])"); + + public static String filterLobbyNames(String line) { + Matcher matcher = lobbyPattern.matcher(line); + if(matcher.find() && matcher.groupCount() == 2) { + String lobbyType = matcher.group(1); + String lobbyId = matcher.group(2); + long lobbyNum = Long.parseLong(lobbyId.substring(0, lobbyId.length()-1)); + + long obfLobbyNum = (lobbyNum*9182739 + 11) % 500; + char obfLobbyLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt((int)(obfLobbyNum%26)); + + line = line.replaceAll("(mini|mega)([0-9]{1,3}[A-Z])", lobbyType+obfLobbyNum+obfLobbyLetter); + } + return line; + } + + public static String filterScoreboard(String line) { + line = filterLobbyNames(cleanDuplicateColourCodes(line)); + return line; + } + + public static String filterChat(String line) { + line = filterLobbyNames(line); + return line; + } + + private static String cleanDuplicateColourCodes(String line) { + StringBuilder sb = new StringBuilder(); + char currentColourCode = 'r'; + boolean sectionSymbolLast = false; + for(char c : line.toCharArray()) { + if((int)c > 50000) continue; + + if(c == '\u00a7') { + sectionSymbolLast = true; + } else { + if(sectionSymbolLast) { + if(currentColourCode != c) { + sb.append('\u00a7'); + sb.append(c); + currentColourCode = c; + } + sectionSymbolLast = false; + } else { + sb.append(c); + } + } + } + return sb.toString(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/Utils.java index c08adc94..f850b49d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/Utils.java @@ -112,6 +112,10 @@ public class Utils { drawTexturedRect(x, y, width, height, uMin, uMax, vMin , vMax, GL11.GL_LINEAR); } + public static String cleanColour(String in) { + return in.replaceAll("(?i)\\u00A7.", ""); + } + public static void drawTexturedRect(float x, float y, float width, float height, float uMin, float uMax, float vMin, float vMax, int filter) { GlStateManager.enableTexture2D(); GlStateManager.enableBlend(); @@ -137,34 +141,6 @@ public class Utils { .tex(uMin, vMin).endVertex(); tessellator.draw(); - /*Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer worldrenderer = tessellator.getWorldRenderer(); - worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX); - worldrenderer - .pos(x, y + height, 0) - .tex(uMin, vMax).endVertex(); - worldrenderer - .pos(x + width, y + height, 0) - .tex(uMax, vMax).endVertex(); - worldrenderer - .pos(x + width, y, 0) - .tex(uMax, vMin).endVertex(); - worldrenderer - .pos(x, y, 0) - .tex(uMin, vMin).endVertex(); - tessellator.draw();*/ - - /*GL11.glBegin(GL11.GL_TRIANGLE_STRIP); - GL11.glTexCoord2f(uMin, vMin); - GL11.glVertex3f(x, y, 0.0F); - GL11.glTexCoord2f(uMin, vMax); - GL11.glVertex3f(x, y+height, 0.0F); - GL11.glTexCoord2f(uMax, vMin); - GL11.glVertex3f(x+width, y, 0.0F); - GL11.glTexCoord2f(uMax, vMax); - GL11.glVertex3f(x+width, y+height, 0.0F); - GL11.glEnd();*/ - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); @@ -204,7 +180,21 @@ public class Utils { drawStringScaled(str, fr, x-len/2, y-fontHeight/2, shadow, colour, factor); } + public static void drawStringCenteredYScaled(String str, FontRenderer fr, float x, float y, boolean shadow, int len, int colour) { + int strLen = fr.getStringWidth(str); + float factor = len/(float)strLen; + float fontHeight = 8*factor; + + drawStringScaled(str, fr, x, y-fontHeight/2, shadow, colour, factor); + } + public static int renderStringTrimWidth(String str, FontRenderer fr, boolean shadow, int x, int y, int len, int colour, int maxLines) { + return renderStringTrimWidth(str, fr, shadow, x, y, len, colour, maxLines, 1); + } + + public static int renderStringTrimWidth(String str, FontRenderer fr, boolean shadow, int x, int y, int len, int colour, int maxLines, float scale) { + len = (int)(len/scale); + int yOff = 0; String excess; String trimmed = trimToWidth(str, len); @@ -221,26 +211,27 @@ public class Utils { int lines = 0; while((lines++ items = new TreeSet<>(getItemComparator()); + + private int buttonHover = -1; + + private static final int FILTER_ALL = 0; + private static final int FILTER_WEAPON = 1; + private static final int FILTER_ARMOR = 2; + private static final int FILTER_ACCESSORY = 3; + private static final int FILTER_PET = 4; + private static final int FILTER_TOOL = 5; + private static final int FILTER_SLAYER_ZOMBIE = 6; + private static final int FILTER_SLAYER_WOLF = 7; + private static final int FILTER_SLAYER_SPIDER = 8; + private int filterMode = FILTER_ALL; + private String[] filterPrettyNames = new String[]{"ALL","WEAPON","ARMOR", + "ACCESSORY","PET","TOOL","ZOMBIE SLAYER","WOLF SLAYER","SPIDER SLAYER"}; + + private Framebuffer itemFramebuffer = null; + private Framebuffer itemBGFramebuffer = null; + private Framebuffer itemFramebufferGrayscale = null; + private Shader grayscaleShader = null; + + public CollectionLogInfoPane(NEUOverlay overlay, NEUManager manager) { + super(overlay, manager); + refreshItems(); + } + + private boolean loreContains(JsonArray lore, String str) { + for(int i=0; i> getAcquiredItems() { + return manager.config.collectionLog.value; + } + + private Comparator getItemComparator() { + return (o1, o2) -> { + float cost1 = manager.getCraftCost(o1).craftCost; + float cost2 = manager.getCraftCost(o2).craftCost; + + if(cost1 < cost2) return 1; + if(cost1 > cost2) return -1; + + return o1.compareTo(o2); + }; + } + + public void mouseInput(int width, int height, int mouseX, int mouseY, boolean mouseDown) { + super.mouseInput(width, height, mouseX, mouseY, mouseDown); + if(mouseDown) { + if(buttonHover == 0) { + if(Mouse.getEventButton() == 0) { + filterMode++; + if(filterMode >= filterPrettyNames.length) { + filterMode = 0; + } + } else if(Mouse.getEventButton() == 1) { + filterMode--; + if(filterMode < 0) { + filterMode = filterPrettyNames.length-1; + } + } + } + refreshItems(); + } + } + + public void render(int width, int height, Color bg, Color fg, ScaledResolution scaledresolution, int mouseX, int mouseY) { + int paneWidth = (int)(width/3*overlay.getWidthMult()); + int rightSide = (int)(width*overlay.getInfoPaneOffsetFactor()); + int leftSide = rightSide - paneWidth; + int padding = overlay.getBoxPadding(); + + renderDefaultBackground(width, height, bg); + + renderControls(height, padding, leftSide+padding, rightSide-padding, 20, fg); + renderCollectionLog(fg, width, height, leftSide+padding, rightSide-padding, padding+25, height-padding); + } + + private float getCompletedness() { + int total = items.size(); + int own = 0; + for(String item : items) { + if(getAcquiredItems() != null && + getAcquiredItems().containsKey(manager.currentProfile) && + getAcquiredItems().get(manager.currentProfile).contains(item)) { + own++; + } + + } + return own/(float)total; + } + + private EnumChatFormatting[] rainbow = new EnumChatFormatting[]{ + EnumChatFormatting.RED, + EnumChatFormatting.GOLD, + EnumChatFormatting.YELLOW, + EnumChatFormatting.GREEN, + EnumChatFormatting.AQUA, + EnumChatFormatting.LIGHT_PURPLE, + EnumChatFormatting.DARK_PURPLE + }; + + private String getCompletednessString() { + float completedness = getCompletedness(); + String text = (int)(completedness*100)+"% Complete"; + if(completedness >= 1) { + StringBuilder rainbowText = new StringBuilder(); + for(int i=0; i x && mouseX < x+controlSize) { + if(mouseY > top && mouseY < top+ySize) { + buttonHover = i; + } + } + + drawRect(x, top, x+controlSize, top+ySize, + new Color(177,177,177).getRGB()); + drawRect(x+1, top+1, x+controlSize, top+ySize, + new Color(50,50,50).getRGB()); + drawRect(x+1, top+1, x+controlSize-1, top+ySize-1, fg.getRGB()); + Utils.drawStringCenteredScaledMaxWidth(controls[i], Minecraft.getMinecraft().fontRendererObj, + x+width/2f, top+ySize/2f, true, controlSize-4, Color.WHITE.getRGB()); + } + } + + private Matrix4f createProjectionMatrix(int width, int height) { + Matrix4f projMatrix = new Matrix4f(); + projMatrix.setIdentity(); + projMatrix.m00 = 2.0F / (float)width; + projMatrix.m11 = 2.0F / (float)(-height); + projMatrix.m22 = -0.0020001999F; + projMatrix.m33 = 1.0F; + projMatrix.m03 = -1.0F; + projMatrix.m13 = 1.0F; + projMatrix.m23 = -1.0001999F; + return projMatrix; + } + + private void renderCollectionLog(Color fg, int width, int height, int left, int right, int top, int bottom) { + ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + + int mouseX = Mouse.getX() / scaledresolution.getScaleFactor(); + int mouseY = height - Mouse.getY() / scaledresolution.getScaleFactor(); + + if(itemFramebuffer != null && grayscaleShader != null && + (itemFramebuffer.framebufferWidth != width || itemFramebuffer.framebufferHeight != height)) { + grayscaleShader.setProjectionMatrix(createProjectionMatrix( + width*scaledresolution.getScaleFactor(), height*scaledresolution.getScaleFactor())); + } + + itemFramebuffer = checkFramebufferSizes(itemFramebuffer, width, height, + scaledresolution.getScaleFactor()); + itemBGFramebuffer = checkFramebufferSizes(itemBGFramebuffer, width, height, + scaledresolution.getScaleFactor()); + itemFramebufferGrayscale = checkFramebufferSizes(itemFramebufferGrayscale, width, height, + scaledresolution.getScaleFactor()); + renderItemsToImage(itemFramebuffer, fg, left+5, right, top+1, bottom); + renderItemBGToImage(itemBGFramebuffer, fg, left+5, right, top+1, bottom); + + Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true); + renderFromImage(itemBGFramebuffer, width, height, left, right, top, bottom); + renderFromImage(itemFramebuffer, width, height, left, right, top, bottom); + + if(grayscaleShader == null) { + try { + grayscaleShader = new Shader(new NEUResourceManager(Minecraft.getMinecraft().getResourceManager()), + "grayscale", + itemFramebuffer, itemFramebufferGrayscale); + grayscaleShader.setProjectionMatrix(createProjectionMatrix( + width*scaledresolution.getScaleFactor(), height*scaledresolution.getScaleFactor())); + } catch(Exception e) { + return; + } + } + + GL11.glPushMatrix(); + grayscaleShader.loadShader(0); + GlStateManager.enableDepth(); + GL11.glPopMatrix(); + + Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true); + + itemFramebufferGrayscale.bindFramebufferTexture(); + + AtomicReference tooltipToDisplay = new AtomicReference<>(null); + + AtomicBoolean isTop = new AtomicBoolean(false); + AtomicInteger lowestY = new AtomicInteger(-1); + + String[] items = getItemList(); + GlStateManager.color(1f, 1f, 1f, 1f); + iterateItemSlots(new ItemSlotConsumer() { + @Override + public void consume(int x, int y, int id) { + String internalname = items[id]; + if(id == 0) isTop.set(true); + + int leftI = x-1; + int rightI = x+17; + int topI = y-1; + int bottomI = y+17; + + lowestY.set(Math.max(bottomI, lowestY.get())); + + if(mouseX > leftI && mouseX < rightI) { + if(mouseY > topI && mouseY < bottomI) { + tooltipToDisplay.set(manager.getItemInformation().get(internalname)); + } + } + + if(getAcquiredItems() != null && + getAcquiredItems().containsKey(manager.currentProfile) && + getAcquiredItems().get(manager.currentProfile).contains(internalname)) { + return; + } + + + topI = Math.max(topI, top); + bottomI = Math.min(bottomI, bottom); + + Utils.drawTexturedRect(leftI, topI, rightI-leftI, bottomI-topI, + leftI/(float)width, rightI/(float)width, + (height-topI)/(float)height, (height-bottomI)/(float)height); + } + }, left+5, right, top+1, bottom); + + if(!isTop.get()) { + if(lowestY.get() == -1) { + scrollHeight.setValue(0); + } else { + int dist = bottom - lowestY.get() - 10; + if(dist > 0) { + scrollHeight.setValue(scrollHeight.getValue() - dist); + } + } + } + + itemFramebufferGrayscale.unbindFramebufferTexture(); + + JsonObject json = tooltipToDisplay.get(); + if(json != null) { + List text = new ArrayList<>(); + text.add(json.get("displayname").getAsString()); + JsonArray lore = json.get("lore").getAsJsonArray(); + + for(int i=0; i top-extraSize) { + itemSlotConsumer.consume(x, y, id); + } + if(++id >= items.size()) { + return; + } + } + } + } + + public boolean keyboardInput() { + return false; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/InfoPane.java b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/InfoPane.java index 2b87fdbc..60f8ca72 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/InfoPane.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/InfoPane.java @@ -23,6 +23,7 @@ public abstract class InfoPane extends Gui { int mouseY); public abstract void mouseInput(int width, int height, int mouseX, int mouseY, boolean mouseDown); + public void mouseInputOutside(){}; public abstract boolean keyboardInput(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/SettingsInfoPane.java b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/SettingsInfoPane.java index 2fccbf9e..090410dd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/SettingsInfoPane.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/SettingsInfoPane.java @@ -30,6 +30,10 @@ public class SettingsInfoPane extends InfoPane { private int page = 0; private int maxPages = 1; + private Options.Option clickedSlider = null; + private int clickedSliderX = 0; + private float clickedSliderMult = 0; + public SettingsInfoPane(NEUOverlay overlay, NEUManager manager) { super(overlay, manager); } @@ -59,33 +63,65 @@ public class SettingsInfoPane extends InfoPane { float mult = tileWidth/90f; drawRect(x, y, x+tileWidth, y+tileHeight, fg.getRGB()); - if(scaledresolution.getScaleFactor()==4) { - GL11.glScalef(0.5f,0.5f,1); - Utils.renderStringTrimWidth(option.displayName, fr, true, (x+(int)(8*mult))*2, (y+(int)(8*mult))*2, - (tileWidth-(int)(16*mult))*2, new Color(100,255,150).getRGB(), 3); - GL11.glScalef(2,2,1); - } else { - Utils.renderStringTrimWidth(option.displayName, fr, true, x+(int)(8*mult), y+(int)(8*mult), - tileWidth-(int)(16*mult), new Color(100,255,150).getRGB(), 3); - } + + if(manager.config.hideApiKey.value && option==manager.config.apiKey) return; + + Utils.renderStringTrimWidth(option.displayName, fr, true, x+(int)(8*mult), y+(int)(8*mult), + tileWidth-(int)(16*mult), new Color(100,255,150).getRGB(), 3, + 2f/scaledresolution.getScaleFactor()); if(option.value instanceof Boolean) { GlStateManager.color(1f, 1f, 1f, 1f); - Minecraft.getMinecraft().getTextureManager().bindTexture(((Boolean)option.value) ? on : off); - Utils.drawTexturedRect(x+tileWidth/2-(int)(32*mult), y+tileHeight-(int)(20*mult), (int)(48*mult), (int)(16*mult)); + Minecraft.getMinecraft().getTextureManager().bindTexture(((Boolean) option.value) ? on : off); + Utils.drawTexturedRect(x + tileWidth/2f - (int) (32 * mult), y + tileHeight - (int) (20 * mult), (int) (48 * mult), (int) (16 * mult)); Minecraft.getMinecraft().getTextureManager().bindTexture(help); - Utils.drawTexturedRect(x+tileWidth/2+(int)(19*mult), y+tileHeight-(int)(19*mult), (int)(14*mult), (int)(14*mult)); + Utils.drawTexturedRect(x + tileWidth/2f + (int) (19 * mult), y + tileHeight - (int) (19 * mult), (int) (14 * mult), (int) (14 * mult)); GlStateManager.bindTexture(0); - if(mouseX > x+tileWidth/2+(int)(19*mult) && mouseX < x+tileWidth/2+(int)(19*mult)+(int)(14*mult)) { - if(mouseY > y+tileHeight-(int)(19*mult) && mouseY < y+tileHeight-(int)(19*mult)+(int)(14*mult)) { + if (mouseX > x + tileWidth / 2 + (int) (19 * mult) && mouseX < x + tileWidth / 2 + (int) (19 * mult) + (int) (14 * mult)) { + if (mouseY > y + tileHeight - (int) (19 * mult) && mouseY < y + tileHeight - (int) (19 * mult) + (int) (14 * mult)) { List textLines = new ArrayList<>(); textLines.add(option.displayName); - textLines.add(EnumChatFormatting.GRAY+option.desc); + textLines.add(EnumChatFormatting.GRAY + option.desc); textToDisplay.set(textLines); } } + } else if(option.value instanceof Double) { + if(!textConfigMap.containsKey(option)) { + textConfigMap.put(option, new GuiElementTextField(String.valueOf(option.value), + GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE | GuiElementTextField.SCALE_TEXT)); + } + GuiElementTextField tf = textConfigMap.get(option); + if(tf.getText().trim().endsWith(".0")) { + tf.setText(tf.getText().trim().substring(0, tf.getText().trim().length()-2)); + } + if(tf.getFocus()) { + tf.setSize(Math.max((int)(20*mult), fr.getStringWidth(tf.getText())+10), (int)(16*mult)); + tfTop.set(tf); + tfTopX.set(x+(int)(65*mult)); + tfTopY.set(y+tileHeight-(int)(20*mult)); + } else { + tf.setSize((int)(20*mult), (int)(16*mult)); + tf.render(x+(int)(65*mult), y+tileHeight-(int)(20*mult)); + } + + double sliderAmount = (((Options.Option)option).value-option.minValue)/(option.maxValue-option.minValue); + sliderAmount = Math.max(0, Math.min(1, sliderAmount)); + + GlStateManager.color(1f, 1f, 1f, 1f); + Minecraft.getMinecraft().getTextureManager().bindTexture(slider_on); + Utils.drawTexturedRect(x+5*mult, y + tileHeight-20*mult, (float)(54*mult*sliderAmount), 16*mult, + 0, (float)sliderAmount, 0, 1); + + Minecraft.getMinecraft().getTextureManager().bindTexture(slider_off); + Utils.drawTexturedRect((float)(x+5*mult+54*mult*sliderAmount), y + tileHeight - 20*mult, + (float)(54*mult*(1-sliderAmount)), 16*mult, + (float)(sliderAmount), 1, 0, 1); + + Minecraft.getMinecraft().getTextureManager().bindTexture(slider_button); + Utils.drawTexturedRect(x+1*mult+(float)(54*sliderAmount*mult), y + tileHeight - 20*mult, + 8*mult, 16*mult); } else { if(!textConfigMap.containsKey(option)) { textConfigMap.put(option, new GuiElementTextField(String.valueOf(option.value), 0)); @@ -121,6 +157,13 @@ public class SettingsInfoPane extends InfoPane { } } + @Override + public void mouseInputOutside() { + for(GuiElementTextField tf : textConfigMap.values()) { + tf.otherComponentClick(); + } + } + public void mouseInput(int width, int height, int mouseX, int mouseY, boolean mouseDown) { iterateSettingTile(new SettingsTileConsumer() { @Override @@ -136,13 +179,74 @@ public class SettingsInfoPane extends InfoPane { } } } + } else if(option.value instanceof Double) { + if(!textConfigMap.containsKey(option)) { + textConfigMap.put(option, new GuiElementTextField(String.valueOf(option.value), + GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE | GuiElementTextField.SCALE_TEXT)); + } + + GuiElementTextField tf = textConfigMap.get(option); + int tfX = x+(int)(65*mult); + int tfY = y+tileHeight-(int)(20*mult); + int tfWidth = tf.getWidth(); + int tfHeight = tf.getHeight(); + if(mouseY > tfY && mouseY < tfY+tfHeight) { + if(mouseX > tfX && mouseX < tfX+tfWidth) { + if(Mouse.getEventButtonState()) { + tf.mouseClicked(mouseX, mouseY, Mouse.getEventButton()); + onTextfieldChange(tf, option); + return; + } else if(Mouse.getEventButton() == -1 && mouseDown) { + tf.mouseClickMove(mouseX, mouseY, 0, 0); //last 2 values are unused + return; + } + } else if(clickedSlider != option && Mouse.getEventButtonState() && mouseX > x+1*mult && mouseX < x+63*mult) { + clickedSlider = option; + clickedSliderX = x; + clickedSliderMult = mult; + } + } + + if(clickedSlider == option) { + float xMin = clickedSliderX+5*clickedSliderMult; + float xMax = clickedSliderX+59*clickedSliderMult; + + float sliderAmount = (mouseX - xMin)/(xMax - xMin); + sliderAmount = Math.max(0, Math.min(1, sliderAmount)); + + double range = option.maxValue - option.minValue; + double value = option.minValue + sliderAmount*range; + + if(range >= 10) { + value = Math.round(value); + } else if(range >= 1) { + value = Math.round(value*10)/10.0; + } else { + value = Math.round(value*100)/100.0; + } + + value = Math.max(option.minValue, Math.min(option.maxValue, value)); + + tf.setText(String.valueOf(value)); + onTextfieldChange(tf, option); + + if(Mouse.getEventButton() == 0 && !Mouse.getEventButtonState()) { + clickedSlider = null; + } + } + + if(Mouse.getEventButtonState()) tf.otherComponentClick(); } else { if(!textConfigMap.containsKey(option)) { textConfigMap.put(option, new GuiElementTextField(String.valueOf(option.value), 0)); } GuiElementTextField tf = textConfigMap.get(option); - if(mouseX > x+(int)(10*mult) && mouseX < x+(int)(10*mult)+tileWidth-(int)(20*mult)) { - if(mouseY > y+tileHeight-(int)(20*mult) && mouseY < y+tileHeight-(int)(20*mult)+(int)(16*mult)) { + int tfX = x+(int)(10*mult); + int tfY = y+tileHeight-(int)(20*mult); + int tfWidth = tf.getWidth(); + int tfHeight = tf.getHeight(); + if(mouseX > tfX && mouseX < tfX+tfWidth) { + if(mouseY > tfY && mouseY < tfY+tfHeight) { if(Mouse.getEventButtonState()) { tf.mouseClicked(mouseX, mouseY, Mouse.getEventButton()); onTextfieldChange(tf, option); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java b/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java index 1112a882..9bcc2891 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java @@ -17,6 +17,7 @@ import java.util.regex.Pattern; public class GuiElementTextField extends GuiElement { + public static final int SCALE_TEXT = 0b100000; public static final int NUM_ONLY = 0b10000; public static final int NO_SPACE = 0b01000; public static final int FORCE_CAPS = 0b00100; @@ -55,6 +56,10 @@ public class GuiElementTextField extends GuiElement { return textField.getText(); } + public void setText(String text) { + textField.setText(text); + } + public void setSize(int searchBarXSize, int searchBarYSize) { this.searchBarXSize = searchBarXSize; this.searchBarYSize = searchBarYSize; @@ -89,6 +94,22 @@ public class GuiElementTextField extends GuiElement { return searchBarXSize + paddingUnscaled*2; } + private float getScaleFactor(String str) { + return Math.min(1, (searchBarXSize-2)/(float)Minecraft.getMinecraft().fontRendererObj.getStringWidth(str)); + } + + private boolean isScaling() { + return (options & SCALE_TEXT) != 0; + } + + private float getStringWidth(String str) { + if(isScaling()) { + return Minecraft.getMinecraft().fontRendererObj.getStringWidth(str)*getScaleFactor(str); + } else { + return Minecraft.getMinecraft().fontRendererObj.getStringWidth(str); + } + } + public int getCursorPos(int mouseX, int mouseY) { int xComp = mouseX - x; int yComp = mouseY - y; @@ -302,7 +323,7 @@ public class GuiElementTextField extends GuiElement { } } - if((options & NUM_ONLY) != 0 && textField.getText().matches("[^0-9]")) textField.setText(old); + if((options & NUM_ONLY) != 0 && textField.getText().matches("[^0-9.]")) textField.setText(old); } } @@ -364,8 +385,15 @@ public class GuiElementTextField extends GuiElement { for(int yOffI = 0; yOffI < texts.length; yOffI++) { int yOff = yOffI*extraSize; - Minecraft.getMinecraft().fontRendererObj.drawString(Utils.trimToWidth(texts[yOffI], searchBarXSize-10), x + 5, - y+(searchBarYSize-8)/2+yOff, Color.WHITE.getRGB()); + if(isScaling() && Minecraft.getMinecraft().fontRendererObj.getStringWidth(texts[yOffI])>searchBarXSize-10) { + Utils.drawStringCenteredScaledMaxWidth(texts[yOffI], Minecraft.getMinecraft().fontRendererObj, x+searchBarXSize/2f, + y+searchBarYSize/2f+yOff, false, + searchBarXSize-2, Color.WHITE.getRGB()); + } else { + Minecraft.getMinecraft().fontRendererObj.drawString(Utils.trimToWidth(texts[yOffI], searchBarXSize-10), x + 5, + y+(searchBarYSize-8)/2+yOff, Color.WHITE.getRGB()); + } + } if(focus && System.currentTimeMillis()%1000>500) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java new file mode 100644 index 00000000..60361306 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java @@ -0,0 +1,24 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.StreamerMode; +import net.minecraft.client.gui.GuiIngame; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.scoreboard.Team; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin({GuiIngame.class}) +public class MixinGuiIngame { + + private static final String TARGET = "Lnet/minecraft/scoreboard/ScorePlayerTeam;" + + "formatPlayerName(Lnet/minecraft/scoreboard/Team;Ljava/lang/String;)Ljava/lang/String;"; + @Redirect(method="renderScoreboard", at=@At(value="INVOKE", target=TARGET)) + public String renderScoreboard_formatPlayerName(Team team, String name) { + if(NotEnoughUpdates.INSTANCE.isOnSkyblock() && NotEnoughUpdates.INSTANCE.manager.config.streamerMode.value) { + return StreamerMode.filterScoreboard(ScorePlayerTeam.formatPlayerName(team, name)); + } + return ScorePlayerTeam.formatPlayerName(team, name); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java b/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java index 5eae3886..fdda8c66 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java @@ -10,7 +10,9 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class Options { @@ -23,40 +25,50 @@ public class Options { false, "Enable Item Editing", true, - "Dev Feature. Please don't use."); + "Dev Feature."); public Option onlyShowOnSkyblock = new Option( true, "Only Show On Skyblock", false, - "GUI Overlay only appears when you are playing Skyblock."); + "NEU Overlay only appears when you are playing Skyblock."); public Option hidePotionEffect = new Option( true, - "Hide Potion Effect", + "Hide Potion Effects", false, - "If true, the potion effects will not show in the inventory GUI."); + "Potion effects are hidden in the inventory GUI. Contrib: All the gamers that play on GUI AUTO"); public Option showQuickCommands = new Option( true, "Quick Commands", false, - "If true, shows quick commands above search bar."); + "Shows QuickCommands™ above search bar."); public Option advancedPriceInfo = new Option( false, - "Advanced Price Information", + "Adv. Item Price Info", false, - "Shows some extra information about item sales."); + "Shows some extra information about item prices."); public Option cacheRenderedItempane = new Option( true, - "Cache Rendered Itempane", + "Cache Itempane", + false, + "Caches the drawn itempane, drastically improving performance. Animated textures will not work."); + public Option streamerMode = new Option( + false, + "Streamer Mode", + false, + "Hides or randomises some stuff on your screen to prevent sniping."); + public Option hideApiKey = new Option( false, - "Caches the drawn itempane, drastically improving performance. However, animated textures will not work."); + "Hide Apikey Setting", + false, + "Hides the Apikey setting (please try not to leak Apikey if you're recording)"); public Option bgBlurFactor = new Option( - 10.0, - "Background Blur Factor", + 5.0, + "Background Blur", false, - "Changes the strength of pane background blur. 0-50."); + "Changes the strength of pane background blur. 0-50.", 0, 50); public Option apiKey = new Option( "", - "Api key used for certain features.", + "Api Key", false, "Type /api new to receive key and put it here."); public Option autoupdate = new Option( @@ -71,24 +83,34 @@ public class Options { "If true, the itempane will stay open after the gui is closed."); public Option itemStyle = new Option( true, - "Circular Item BG Style", + "Circular Item Style", + false, + "Uses the circular item background style instead of the square style. Contrib: Calyps0"); + public Option hideEmptyPanes = new Option( + true, + "Hide GUI Filler Tooltips", false, - "If true, uses the circular item background style instead of the square style."); + "Hides the tooltip of glass panes in skyblock GUIs. Contrib: ThatGravyBoat"); public Option paneWidthMult = new Option( 1.0, - "Pane Width Multiplier", + "Pane Width", false, - "Changes how wide the item and info panes are. Value between 0.5-1.5."); + "Changes how wide the item and info panes are. Value between 0.5-1.5.", 0.5, 1.5); public Option bgOpacity = new Option( - 50.0, + 30.0, "Pane Background Opacity", false, - "Changes the background colour opacity of item and info panes. Value between 0-255."); + "Changes the background colour opacity of item and info panes. Value between 0-255.", 0, 255); public Option fgOpacity = new Option( 255.0, "Item Background Opacity", false, - "Changes the opacity of item background. Value between 0-255."); + "Changes the opacity of item background. Value between 0-255.", 0, 255); + public Option panePadding = new Option( + 10.0, + "Pane Padding", + false, + "Changes the padding of the panes. Value between 0-20.", 0, 20); /** * OPTIONS THAT DON'T SHOW IN GUI @@ -109,7 +131,7 @@ public class Options { false, "Sort Mode"); public Option> compareAscending = new Option( - Utils.createList(true, true), + Utils.createList(true, true, true), "Compare Ascending", false, "Compare Ascending"); @@ -118,6 +140,11 @@ public class Options { "Favourites", false, "Favourites"); + public Option>> collectionLog = new Option( + new HashMap>(), + "CollectionLog", + false, + "CollectionLog"); public Option> quickCommands = new Option( createDefaultQuickCommands(), "Quick Commands", @@ -131,31 +158,39 @@ public class Options { arr.add("/craft:CRAFTING_TABLE"); arr.add("/enderchest:ENDER_CHEST"); arr.add("/wardrobe:LEATHER_CHESTPLATE"); + arr.add("/collectionlog:MAP"); return arr; } public List