diff options
Diffstat (limited to 'src/main/java/io')
24 files changed, 872 insertions, 154 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index 4682a744..9e31c19e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -3,20 +3,23 @@ package io.github.moulberry.notenoughupdates; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; import io.github.moulberry.notenoughupdates.auction.CustomAHGui; +import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; import io.github.moulberry.notenoughupdates.dungeons.DungeonBlocks; import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; import io.github.moulberry.notenoughupdates.gamemodes.SBGamemodes; import io.github.moulberry.notenoughupdates.miscfeatures.*; import io.github.moulberry.notenoughupdates.miscgui.*; +import io.github.moulberry.notenoughupdates.mixins.MinecraftAccessor; +import io.github.moulberry.notenoughupdates.overlays.CommissionOverlay; +import io.github.moulberry.notenoughupdates.overlays.FarmingOverlay; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; import io.github.moulberry.notenoughupdates.overlays.TextOverlayStyle; -import io.github.moulberry.notenoughupdates.util.Constants; -import io.github.moulberry.notenoughupdates.util.RequestFocusListener; -import io.github.moulberry.notenoughupdates.util.SBInfo; -import io.github.moulberry.notenoughupdates.util.Utils; +import io.github.moulberry.notenoughupdates.util.*; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; @@ -27,17 +30,21 @@ import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiEditSign; import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.event.ClickEvent; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; 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.nbt.NBTUtil; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.*; import net.minecraftforge.event.entity.player.EntityInteractEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; @@ -46,6 +53,7 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; @@ -56,9 +64,12 @@ import java.awt.*; import java.awt.datatransfer.StringSelection; import java.io.File; import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; import java.text.NumberFormat; import java.util.List; import java.util.*; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -146,6 +157,7 @@ public class NEUEventListener { } return TextOverlayStyle.BACKGROUND; })); + textOverlays.add(new FarmingOverlay(new Position(20, 300), () -> TextOverlayStyle.BACKGROUND)); } /** @@ -153,14 +165,37 @@ public class NEUEventListener { * This is used in order to prevent the mod spamming messages. * 2)Adds unique items to the collection log */ + private boolean preloadedItems = false; private long lastLongUpdate = 0; private long lastSkyblockScoreboard = 0; + + private final ExecutorService itemPreloader = Executors.newFixedThreadPool(10); + private final List<ItemStack> toPreload = new ArrayList<>(); + @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { if(event.phase != TickEvent.Phase.START) return; if(Minecraft.getMinecraft().theWorld == null) return; if(Minecraft.getMinecraft().thePlayer == null) return; + if(neu.hasSkyblockScoreboard()) { + if(!preloadedItems) { + preloadedItems = true; + for(JsonObject json : neu.manager.getItemInformation().values()) { + itemPreloader.submit(() -> { + ItemStack stack = neu.manager.jsonToStack(json, true, true); + if(stack.getItem() == Items.skull) toPreload.add(stack); + }); + } + } else if(!toPreload.isEmpty()) { + System.out.println("Preload size:"+toPreload.size()); + Utils.drawItemStack(toPreload.get(0), -100, -100); + toPreload.remove(0); + } else { + itemPreloader.shutdown(); + } + } + boolean longUpdate = false; long currentTime = System.currentTimeMillis(); if(currentTime - lastLongUpdate > 1000) { @@ -176,6 +211,8 @@ public class NEUEventListener { DwarvenMinesTextures.tick(); FairySouls.tick(); MiningStuff.tick(); + ProfileApiSyncer.getInstance().tick(); + DamageCommas.tick(); for(TextOverlay overlay : textOverlays) { overlay.tick(); } @@ -285,6 +322,9 @@ public class NEUEventListener { neu.manager.auctionManager.markNeedsUpdate(); } } + + + /*if(longUpdate && neu.hasSkyblockScoreboard()) { if(neu.manager.getCurrentProfile() == null || neu.manager.getCurrentProfile().length() == 0) { ProfileViewer.Profile profile = NotEnoughUpdates.profileViewer.getProfile(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""), @@ -777,6 +817,8 @@ public class NEUEventListener { } private void renderDungeonChestOverlay(GuiScreen gui) { + if(neu.config.dungeonProfit.profitDisplayLoc == 3) return; + if(gui instanceof GuiChest && neu.config.dungeonProfit.profitDisplayLoc != 2) { try { int xSize = (int) Utils.getField(GuiContainer.class, gui, "xSize", "field_146999_f"); @@ -815,9 +857,10 @@ public class NEUEventListener { internal = internal.replace("\u00CD", "I").replace("\u0130", "I"); float bazaarPrice = -1; JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal); - if(bazaarInfo != null && bazaarInfo.has("avg_sell")) { - bazaarPrice = bazaarInfo.get("avg_sell").getAsFloat(); + if(bazaarInfo != null && bazaarInfo.has("curr_sell")) { + bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat(); } + if(bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000; float worth = -1; if(bazaarPrice > 0) { @@ -918,8 +961,10 @@ public class NEUEventListener { if(neu.config.dungeonProfit.profitDisplayLoc == 1 && !valueStringBIN2.equals(missingItem)) { int w = Minecraft.getMinecraft().fontRendererObj.getStringWidth(plStringBIN); GlStateManager.disableLighting(); + GlStateManager.translate(0, 0, 200); Minecraft.getMinecraft().fontRendererObj.drawString(plStringBIN, guiLeft+xSize-5-w, guiTop+5, 0xffffffff, true); + GlStateManager.translate(0, 0, -200); return; } @@ -1440,9 +1485,10 @@ public class NEUEventListener { internal = internal.replace("\u00CD", "I").replace("\u0130", "I"); float bazaarPrice = -1; JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal); - if(bazaarInfo != null && bazaarInfo.has("avg_sell")) { - bazaarPrice = bazaarInfo.get("avg_sell").getAsFloat(); + if(bazaarInfo != null && bazaarInfo.has("curr_sell")) { + bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat(); } + if(bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000; float worth = -1; if(bazaarPrice > 0) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 668ac1fe..0381a70a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -172,8 +173,6 @@ public class NEUManager { }*/ - - Thread thread = new Thread(() -> { JDialog dialog = null; try { @@ -277,7 +276,6 @@ public class NEUManager { } }); - System.out.println("finished thread create"); File items = new File(repoLocation, "items"); if(items.exists()) { File[] itemFiles = new File(repoLocation, "items").listFiles(); @@ -652,6 +650,8 @@ public class NEUManager { if(ea.hasKey("id", 8)) { internalname = ea.getString("id").replaceAll(":", "-"); + } else { + return null; } if("PET".equals(internalname)) { @@ -1313,28 +1313,25 @@ public class NEUManager { } public ItemStack jsonToStack(JsonObject json, boolean useCache) { - return jsonToStack(json, useCache, true, false); + return jsonToStack(json, useCache, true); } - private static ExecutorService asyncItemES = Executors.newFixedThreadPool(10); - public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean multithread) { + public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements) { + return jsonToStack(json, useCache, useReplacements, true); + } + + public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean copyStack) { if(json == null) return new ItemStack(Items.painting, 1, 10); String internalname = json.get("internalname").getAsString(); if(useCache) { - if(itemstackCache.containsKey(internalname)) { - ItemStack stack = itemstackCache.get(internalname); - if(stack == null) { - if(multithread) { - return null; - } - } else { + ItemStack stack = itemstackCache.get(internalname); + if(stack != null) { + if(copyStack) { return stack.copy(); + } else { + return stack; } - } else if(multithread) { - asyncItemES.submit(() -> jsonToStack(json, true, useReplacements, false)); - itemstackCache.put(internalname, null); - return null; } } @@ -1385,7 +1382,11 @@ public class NEUManager { } if(useCache) itemstackCache.put(internalname, stack); - return stack; + if(copyStack) { + return stack.copy(); + } else { + return stack; + } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 9012e67e..cd81da0b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -54,6 +54,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -264,8 +266,7 @@ public class NEUOverlay extends Gui { @Override public void mouseClick(float x, float y, int mouseX, int mouseY) { if(Mouse.getEventButtonState()) { - Minecraft.getMinecraft().thePlayer.closeScreen(); - Minecraft.getMinecraft().displayGuiScreen(new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config))); + NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config)); } } @@ -415,7 +416,7 @@ public class NEUOverlay extends Gui { extraScale = 1.3f; } else if(manager.getItemInformation().containsKey(display)) { - render = manager.jsonToStack(manager.getItemInformation().get(display)); + render = manager.jsonToStack(manager.getItemInformation().get(display), true, true); } else { Item item = Item.itemRegistry.getObject(new ResourceLocation(display.toLowerCase())); if(item != null) { @@ -1148,6 +1149,8 @@ public class NEUOverlay extends Gui { private HashMap<String, JsonObject> parentMap = new HashMap<>(); + private ExecutorService searchES = Executors.newSingleThreadExecutor(); + /** * Clears the current item list, creating a new TreeSet if necessary. * Adds all items that match the search AND match the sort mode to the current item list. @@ -1156,69 +1159,77 @@ public class NEUOverlay extends Gui { public void updateSearch() { SunTzu.randomizeQuote(); - if(searchedItems==null) searchedItems = new TreeSet<>(getItemComparator()); - searchedItems.clear(); - searchedItemsSubgroup.clear(); - searchedItemsArr = null; - redrawItems = true; - Set<JsonObject> removeChildItems = new HashSet<>(); - Set<String> itemsMatch = manager.search(textField.getText(), true); - for(String itemname : itemsMatch) { - JsonObject item = manager.getItemInformation().get(itemname); - if(checkMatchesSort(itemname, item)) { - if(Constants.PARENTS != null) { - if(Constants.PARENTS.has(itemname) && Constants.PARENTS.get(itemname).isJsonArray()) { - List<String> children = new ArrayList<>(); - for(JsonElement e : Constants.PARENTS.get(itemname).getAsJsonArray()) { - if(e.isJsonPrimitive()) { - children.add(e.getAsString()); + if(searchedItems == null) searchedItems = new TreeSet<>(getItemComparator()); + + searchES.submit(() -> { + TreeSet<JsonObject> searchedItems = new TreeSet<>(getItemComparator()); + HashMap<String, List<String>> searchedItemsSubgroup = new HashMap<>(); + + Set<JsonObject> removeChildItems = new HashSet<>(); + Set<String> itemsMatch = manager.search(textField.getText(), true); + for(String itemname : itemsMatch) { + JsonObject item = manager.getItemInformation().get(itemname); + if(checkMatchesSort(itemname, item)) { + if(Constants.PARENTS != null) { + if(Constants.PARENTS.has(itemname) && Constants.PARENTS.get(itemname).isJsonArray()) { + List<String> children = new ArrayList<>(); + for(JsonElement e : Constants.PARENTS.get(itemname).getAsJsonArray()) { + if(e.isJsonPrimitive()) { + children.add(e.getAsString()); + } } + children.retainAll(itemsMatch); + for(String child : children) { + removeChildItems.add(manager.getItemInformation().get(child)); + } + searchedItemsSubgroup.put(itemname, children); } - children.retainAll(itemsMatch); - for(String child : children) { - removeChildItems.add(manager.getItemInformation().get(child)); - } - searchedItemsSubgroup.put(itemname, children); } + searchedItems.add(item); } - searchedItems.add(item); } - } - searchedItems.removeAll(removeChildItems); - out: - for(Map.Entry<String, List<String>> entry : searchedItemsSubgroup.entrySet()) { - if(searchedItems.contains(manager.getItemInformation().get(entry.getKey()))) { - continue; + searchedItems.removeAll(removeChildItems); + out: + for(Map.Entry<String, List<String>> entry : searchedItemsSubgroup.entrySet()) { + if(searchedItems.contains(manager.getItemInformation().get(entry.getKey()))) { + continue; + } + for(String itemname : entry.getValue()) { + JsonObject item = manager.getItemInformation().get(itemname); + if(item != null) searchedItems.add(item); + } } - for(String itemname : entry.getValue()) { - JsonObject item = manager.getItemInformation().get(itemname); - if(item != null) searchedItems.add(item); + switch(textField.getText().toLowerCase().trim()) { + case "nullzee": + searchedItems.add(CustomItems.NULLZEE); + break; + case "rune": + searchedItems.add(CustomItems.RUNE); + break; + case "2b2t": + searchedItems.add(CustomItems.TWOBEETWOTEE); + break; + case "ducttape": + case "ducttapedigger": + searchedItems.add(CustomItems.DUCTTAPE); + break; + case "thirtyvirus": + searchedItems.add(manager.getItemInformation().get("SPIKED_BAIT")); + break; + case "leocthl": + searchedItems.add(CustomItems.LEOCTHL); + break; + case "spinaxx": + searchedItems.add(CustomItems.SPINAXX); + break; } - } - switch(textField.getText().toLowerCase().trim()) { - case "nullzee": - searchedItems.add(CustomItems.NULLZEE); - break; - case "rune": - searchedItems.add(CustomItems.RUNE); - break; - case "2b2t": - searchedItems.add(CustomItems.TWOBEETWOTEE); - break; - case "ducttape": - case "ducttapedigger": - searchedItems.add(CustomItems.DUCTTAPE); - break; - case "thirtyvirus": - searchedItems.add(manager.getItemInformation().get("SPIKED_BAIT")); - break; - case "leocthl": - searchedItems.add(CustomItems.LEOCTHL); - break; - case "spinaxx": - searchedItems.add(CustomItems.SPINAXX); - break; - } + + this.searchedItems = searchedItems; + this.searchedItemsSubgroup = searchedItemsSubgroup; + + searchedItemsArr = null; + redrawItems = true; + }); } /** @@ -1512,8 +1523,6 @@ public class NEUOverlay extends Gui { * is enabled) */ public void renderOverlay() { - GlStateManager.enableDepth(); - int width = Utils.peekGuiScale().getScaledWidth(); int height = Utils.peekGuiScale().getScaledHeight(); int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; @@ -1610,6 +1619,8 @@ public class NEUOverlay extends Gui { if(disabled) { return; } + GlStateManager.enableDepth(); + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; Utils.resetGuiScale(); @@ -2086,8 +2097,11 @@ public class NEUOverlay extends Gui { iterateItemSlots(new ItemSlotConsumer() { public void consume(int x, int y, int id) { JsonObject json = getSearchedItemPage(id); - ItemStack stack = manager.jsonToStack(json, true, true, true); - if (json == null || stack == null || !stack.hasEffect()) { + if(json == null) { + return; + } + ItemStack stack = manager.jsonToStack(json, true, true, false); + if (stack == null || !stack.hasEffect()) { return; } @@ -2241,7 +2255,7 @@ public class NEUOverlay extends Gui { renderEntity(x + ITEM_SIZE / 2, y + ITEM_SIZE, scale, name, entities); } else { if(!items) return; - ItemStack stack = manager.jsonToStack(json, true, true, true); + ItemStack stack = manager.jsonToStack(json, true, true, false); if(stack != null) { if(glint) { Utils.drawItemStack(stack, x, y); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index f2f41b17..b70dcc24 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -31,6 +31,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; +import io.github.moulberry.notenoughupdates.util.XPInformation; import net.minecraft.block.material.MapColor; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -909,6 +910,7 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures()); MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints()); MinecraftForge.EVENT_BUS.register(new FuelBar()); + MinecraftForge.EVENT_BUS.register(XPInformation.getInstance()); ClientCommandHandler.instance.registerCommand(collectionLogCommand); ClientCommandHandler.instance.registerCommand(cosmeticsCommand); @@ -920,7 +922,7 @@ public class NotEnoughUpdates { ClientCommandHandler.instance.registerCommand(joinDungeonCommand); ClientCommandHandler.instance.registerCommand(viewProfileCommand); ClientCommandHandler.instance.registerCommand(viewProfileShortCommand); - ClientCommandHandler.instance.registerCommand(viewCataCommand); + if(!Loader.isModLoaded("skyblockextras")) ClientCommandHandler.instance.registerCommand(viewCataCommand); ClientCommandHandler.instance.registerCommand(peekCommand); ClientCommandHandler.instance.registerCommand(tutorialCommand); ClientCommandHandler.instance.registerCommand(overlayPlacementsCommand); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index 993eb78b..fa51cdca 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -23,7 +23,10 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; +import net.minecraft.scoreboard.Score; +import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.*; import net.minecraft.world.storage.MapData; import net.minecraftforge.client.event.RenderGameOverlayEvent; @@ -83,6 +86,7 @@ public class DungeonMap { private Map<String, MapPosition> playerEntityMapPositions = new HashMap<>(); private Map<String, MapPosition> playerMarkerMapPositions = new HashMap<>(); + private Set<MapPosition> rawPlayerMarkerMapPositions = new HashSet<>(); private Map<String, MapPosition> playerMarkerMapPositionsLast = new HashMap<>(); private Map<String, ResourceLocation> playerSkinMap = new HashMap<>(); @@ -586,7 +590,7 @@ public class DungeonMap { float angle = pos.rotation; boolean doInterp = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerInterp; - if(playerEntityMapPositions.containsKey(name)) { + if(!isFloorOne && playerEntityMapPositions.containsKey(name)) { MapPosition entityPos = playerEntityMapPositions.get(name); angle = entityPos.rotation; @@ -994,6 +998,7 @@ public class DungeonMap { } } + private boolean isFloorOne = false; private boolean failMap = false; private long lastClearCache = 0; public void renderMap(int centerX, int centerY, Color[][] colourMap, Map<String, Vec4b> mapDecorations, @@ -1014,6 +1019,25 @@ public class DungeonMap { failMap = false; lastClearCache = System.currentTimeMillis(); + + isFloorOne = false; + Scoreboard scoreboard = Minecraft.getMinecraft().thePlayer.getWorldScoreboard(); + + ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1); + + List<Score> scores = new ArrayList<>(scoreboard.getSortedScores(sidebarObjective)); + + for(int i=scores.size()-1; i>=0; i--) { + Score score = scores.get(i); + ScorePlayerTeam scoreplayerteam1 = scoreboard.getPlayersTeam(score.getPlayerName()); + String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName()); + line = Utils.cleanDuplicateColourCodes(line); + + if(line.contains("(F1)")) { + isFloorOne = true; + break; + } + } } if(failMap) { @@ -1192,8 +1216,6 @@ public class DungeonMap { continue; } - if(decorations++ >= 6) break; - float deltaX = x - startRoomX; float deltaY = y - startRoomY; @@ -1229,10 +1251,13 @@ public class DungeonMap { MapPosition pos = new MapPosition(roomsOffsetX, connOffsetX, roomsOffsetY, connOffsetY); pos.rotation = angle % 360; if(pos.rotation < 0) pos.rotation += 360; - positions.add(pos); + + if(decorations++ <= 6) { + positions.add(pos); + } + rawPlayerMarkerMapPositions.add(pos); } - //System.out.println(playerMarkerMapPositions.size() + ":" + positions.size()); boolean different = playerMarkerMapPositions.size() != positions.size(); if (!different) { @@ -1275,9 +1300,6 @@ public class DungeonMap { List<String> playerList = new ArrayList<>(playerMarkerMapPositionsLast.keySet()); List<List<String>> playerPermutations = permutations(playerList); - //if(playerPermutations.size() > 0 || playerMarkerMapPositionsLast.size() > 0) - // System.out.println("Perm Size: " + playerPermutations.size() + " from " + playerMarkerMapPositionsLast.size()); - List<Integer> finalUsedIndexes = new ArrayList<>(); if (playerPermutations.size() > 0) { HashMap<String, Integer> smallestPermutation = null; @@ -1455,13 +1477,15 @@ public class DungeonMap { for(ScorePlayerTeam team : Minecraft.getMinecraft().thePlayer.getWorldScoreboard().getTeams()) { if(team.getTeamName().startsWith("a") && team.getMembershipCollection().size() == 1) { String playerName = Iterables.get(team.getMembershipCollection(), 0); + boolean foundPlayer = false; for(EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) { - if(player.getName().equals(playerName) && (player == Minecraft.getMinecraft().thePlayer || - (!player.isPlayerSleeping() && !player.isInvisible()))) { + if(player.getName().equals(playerName) && (player == Minecraft.getMinecraft().thePlayer || !player.isPlayerSleeping())) { actualPlayers.add(playerName); + foundPlayer = true; break; } } + if(!foundPlayer) actualPlayers.add(playerName); if(++players >= 6) break; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java b/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java index 0c645255..827f9498 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/gamemodes/SBGamemodes.java @@ -247,8 +247,7 @@ public class SBGamemodes { boolean inDungeons = SBInfo.getInstance().getLocation() != null && SBInfo.getInstance().getLocation().equals("dungeon"); - if("Your Island".equals(SBInfo.getInstance().location) && - (EnumChatFormatting.YELLOW+"Break a log").equals(SBInfo.getInstance().objective)) { + if((EnumChatFormatting.YELLOW+"Break a log").equals(SBInfo.getInstance().objective)) { getGamemode().locked = false; } else { getGamemode().locked = true; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java index 2c1d1fab..9e97cfc0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java @@ -108,6 +108,10 @@ public class CrystalOverlay { int radius; } + private static double posLastUpdateX; + private static double posLastUpdateY; + private static double posLastUpdateZ; + private static HashMap<String, CrystalType> skullId = new HashMap<>(); static { skullId.put("d9c3168a-8654-3dd8-b297-4d3b7e55b95a", CrystalType.FARMING_MINION); @@ -118,6 +122,8 @@ public class CrystalOverlay { public static long displayMillis = 0; + public static long lastMiningUpdate = 0; + public static HashMap<CrystalType, BlockPos> crystals = new HashMap<>(); private static ExecutorService es = Executors.newSingleThreadExecutor(); @@ -131,6 +137,7 @@ public class CrystalOverlay { long currentTime = System.currentTimeMillis(); if(currentTime - displayMillis > 10*1000) { + crystals.clear(); displayMillis = -1; } @@ -191,11 +198,35 @@ public class CrystalOverlay { @SubscribeEvent public void onTick(TickEvent.ClientTickEvent event) { + if(displayMillis < 0) { + return; + } + EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; if(p == null) return; if(event.phase == TickEvent.Phase.START) { + double dX = p.posX - posLastUpdateX; + double dY = p.posY - posLastUpdateY; + double dZ = p.posZ - posLastUpdateZ; + + if(dX*dX + dY*dY + dZ*dZ < 1) { + return; + } + + posLastUpdateX = p.posX; + posLastUpdateY = p.posY; + posLastUpdateZ = p.posZ; + for(CrystalType type : crystals.keySet()) { + if(type == CrystalType.MINING_MINION) { + long currentTime = System.currentTimeMillis(); + if(currentTime - lastMiningUpdate < 1000) { + continue; + } + lastMiningUpdate = currentTime; + } + ReverseWorldRenderer worldRenderer = type.getOverlayVBO(); if(worldRenderer != null) { BlockPos crystal = crystals.get(type); @@ -205,6 +236,11 @@ public class CrystalOverlay { (float)p.posX-crystal.getX(), (float)p.posY-crystal.getY(), (float)p.posZ-crystal.getZ()); + /*es.submit(() -> worldRenderer.sortVertexData( + (float)p.posX-crystal.getX(), + (float)p.posY-crystal.getY(), + (float)p.posZ-crystal.getZ()));*/ + } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java new file mode 100644 index 00000000..c011ac9b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java @@ -0,0 +1,94 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; + +import java.text.NumberFormat; +import java.util.HashMap; + +public class DamageCommas { + + private static final HashMap<Integer, ChatComponentText> replacementMap = new HashMap<>(); + + public static void tick() { + replacementMap.clear(); + } + + public static IChatComponent replaceName(IChatComponent name) { + if(!NotEnoughUpdates.INSTANCE.config.misc.damageCommas) return name; + + String formatted = name.getFormattedText(); + int hashCode = formatted.hashCode(); + + if(replacementMap.containsKey(hashCode)) { + ChatComponentText component = replacementMap.get(hashCode); + if(component == null) return name; + return component; + } + + if(formatted.length() >= 7 && formatted.startsWith("\u00A7f\u2727") && + formatted.endsWith("\u2727\u00a7r")) { + StringBuilder builder = new StringBuilder(); + boolean numLast = false; + boolean colLast = false; + int numCount = 0; + for(int i=formatted.length()-4; i>=3; i--) { + char c = formatted.charAt(i); + if(c == '\u00a7') { + if(numLast) numCount--; + numLast = false; + colLast = true; + } else if(c >= '0' && c <= '9') { + numLast = true; + colLast = false; + numCount++; + } else { + if(colLast) { + replacementMap.put(hashCode, null); + return name; + } + numLast = false; + } + + builder.append(c); + if(numLast && numCount % 3 == 0) builder.append(','); + } + + ChatComponentText ret = new ChatComponentText("\u00A7f\u2727"+builder.reverse().toString()+"\u2727\u00a7r"); + replacementMap.put(hashCode, ret); + return ret; + } + + if(formatted.length() >= 5 && formatted.startsWith(EnumChatFormatting.GRAY.toString()) && + formatted.endsWith(EnumChatFormatting.RESET.toString())) { + String damageS = formatted.substring(2, formatted.length()-2); + + for(int i=0; i<damageS.length(); i++) { + char c = damageS.charAt(i); + if(c < '0' || c > '9') { + replacementMap.put(hashCode, null); + return name; + } + } + + try { + int damage = Integer.parseInt(damageS); + + String damageFormatted = NumberFormat.getIntegerInstance().format(damage); + + ChatComponentText ret = new ChatComponentText(EnumChatFormatting.GRAY+damageFormatted+EnumChatFormatting.RESET); + replacementMap.put(hashCode, ret); + return ret; + } catch(Exception e) { + replacementMap.put(hashCode, null); + return name; + } + } + replacementMap.put(hashCode, null); + return name; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java index 58cf4d20..1502cf4a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java @@ -1,7 +1,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.overlays.CommissionOverlay; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -194,7 +194,11 @@ public class DwarvenMinesWaypoints { } else { for(String commissionName : CommissionOverlay.commissionProgress.keySet()) { if(commissionName.toLowerCase().contains(entry.getKey().toLowerCase())) { - renderWayPoint(EnumChatFormatting.AQUA+entry.getKey(), entry.getValue(), event.partialTicks); + if(commissionName.contains("Titanium")) { + renderWayPoint(EnumChatFormatting.WHITE+entry.getKey(), entry.getValue(), event.partialTicks); + } else { + renderWayPoint(EnumChatFormatting.AQUA+entry.getKey(), entry.getValue(), event.partialTicks); + } } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java index b5a98704..5fe5938b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java @@ -73,6 +73,8 @@ public class FairySouls { @SubscribeEvent public void onChatReceived(ClientChatReceivedEvent event) { + if(currentSoulList == null) return; + if(event.message.getFormattedText().equals("\u00A7r\u00A7dYou have already found that Fairy Soul!\u00A7r") || event.message.getFormattedText().equals("\u00A7d\u00A7lSOUL! \u00A7fYou found a \u00A7r\u00A7dFairy Soul\u00A7r\u00A7f!\u00A7r")) { String location = SBInfo.getInstance().getLocation(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java index 3e4649be..8b130d24 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java @@ -2,7 +2,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; -import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.overlays.CommissionOverlay; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.SpecialColour; import io.github.moulberry.notenoughupdates.util.Utils; @@ -19,13 +19,9 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import org.lwjgl.util.vector.Vector3f; -import org.lwjgl.util.vector.Vector4f; public class MiningStuff { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MinecraftAccessor.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MinecraftAccessor.java new file mode 100644 index 00000000..b40d418b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MinecraftAccessor.java @@ -0,0 +1,15 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.io.File; + +@Mixin(Minecraft.class) +public interface MinecraftAccessor { + + @Accessor + public File getFileAssets(); + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRendererLivingEntity.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRendererLivingEntity.java new file mode 100644 index 00000000..39e42152 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRendererLivingEntity.java @@ -0,0 +1,26 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.miscfeatures.DamageCommas; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.util.IChatComponent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(RendererLivingEntity.class) +public class MixinRendererLivingEntity { + + @Redirect(method = "renderName", at=@At(value = "INVOKE", target = + "Lnet/minecraft/entity/EntityLivingBase;getDisplayName()Lnet/minecraft/util/IChatComponent;")) + public IChatComponent renderName_getDisplayName(EntityLivingBase entity) { + if(entity instanceof EntityArmorStand) { + return DamageCommas.replaceName(entity.getDisplayName()); + } else { + return entity.getDisplayName(); + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 44d2faa1..ca0ebb2e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -10,7 +10,7 @@ import io.github.moulberry.notenoughupdates.core.config.Config; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.config.annotations.*; import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor; -import io.github.moulberry.notenoughupdates.miscfeatures.CommissionOverlay; +import io.github.moulberry.notenoughupdates.overlays.CommissionOverlay; import io.github.moulberry.notenoughupdates.overlays.TextOverlayStyle; import net.minecraft.client.Minecraft; import net.minecraftforge.client.ClientCommandHandler; @@ -256,7 +256,7 @@ public class NEUConfig extends Config { @Expose @ConfigOption( name = "Hide Potion Effects", - desc = "Hides the potion effects inside your inventory while on skyblock" + desc = "Hide the potion effects inside your inventory while on skyblock" ) @ConfigEditorBoolean public boolean hidePotionEffect = true; @@ -264,7 +264,7 @@ public class NEUConfig extends Config { @Expose @ConfigOption( name = "Streamer Mode", - desc = "Randomizes lobby names in the scoreboard and chat messages to help prevent stream sniping" + desc = "Randomize lobby names in the scoreboard and chat messages to help prevent stream sniping" ) @ConfigEditorBoolean public boolean streamerMode = false; @@ -272,10 +272,18 @@ public class NEUConfig extends Config { @Expose @ConfigOption( name = "Gui Click Sounds", - desc = "Plays click sounds in various NEU-related GUIs when pressing buttons" + desc = "Play click sounds in various NEU-related GUIs when pressing buttons" ) @ConfigEditorBoolean public boolean guiButtonClicks = true; + + @Expose + @ConfigOption( + name = "Commas in Damage Numbers", + desc = "Add a comma to damage number indicators to make it more readable" + ) + @ConfigEditorBoolean + public boolean damageCommas = true; } public static class Notifications { @@ -636,7 +644,7 @@ public class NEUConfig extends Config { "Lore = Inside the \"Open Reward Chest\" item" ) @ConfigEditorDropdown( - values = {"Overlay", "GUI Title", "Lore"} + values = {"Overlay", "GUI Title", "Lore", "Off"} ) public int profitDisplayLoc = 0; } @@ -1287,7 +1295,7 @@ public class NEUConfig extends Config { arr.add("/enderchest:Ender Chest:ENDER_CHEST"); arr.add("/wardrobe:Wardrobe:LEATHER_CHESTPLATE"); arr.add("/pets:Pets:BONE"); - arr.add("/ah:Auction House:GOLD_BLOCK"); + arr.add("/neuah:NEU Auction House:GOLD_BLOCK"); arr.add("/bz:Bazaar:GOLD_BARDING"); return arr; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CommissionOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CommissionOverlay.java index decfbf3f..1920c49a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CommissionOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CommissionOverlay.java @@ -1,4 +1,4 @@ -package io.github.moulberry.notenoughupdates.miscfeatures; +package io.github.moulberry.notenoughupdates.overlays; import com.google.common.collect.ComparisonChain; import com.google.common.collect.Ordering; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java new file mode 100644 index 00000000..e32e2c87 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java @@ -0,0 +1,199 @@ +package io.github.moulberry.notenoughupdates.overlays; + +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.util.XPInformation; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.function.Supplier; + +public class FarmingOverlay extends TextOverlay { + + private long lastUpdate = -1; + private int counterLast = -1; + private int counter = -1; + private float cropsPerSecondLast = 0; + private float cropsPerSecond = 0; + private LinkedList<Integer> counterQueue = new LinkedList<>(); + + private float lastTotalXp = -1; + private boolean isFarming = false; + private LinkedList<Float> xpGainQueue = new LinkedList<>(); + private float xpGainHourLast = -1; + private float xpGainHour = -1; + + public FarmingOverlay(Position position, Supplier<TextOverlayStyle> styleSupplier) { + super(position, styleSupplier); + } + + @Override + public void update() { + lastUpdate = System.currentTimeMillis(); + counterLast = counter; + xpGainHourLast = xpGainHour; + counter = -1; + + XPInformation.SkillInfo skillInfo = XPInformation.getInstance().getSkillInfo("Farming"); + if(skillInfo != null) { + float totalXp = skillInfo.totalXp; + + if(lastTotalXp > 0) { + float delta = totalXp - lastTotalXp; + + if(delta > 0 && delta < 1000) { + xpGainQueue.add(delta); + while (xpGainQueue.size() > 120) { + xpGainQueue.removeLast(); + } + + float totalGain = 0; + for(float f : xpGainQueue) totalGain += f; + + xpGainHour = totalGain*(60*60)/xpGainQueue.size(); + + isFarming = true; + } else if(delta <= 0) { + isFarming = false; + } + } + + lastTotalXp = totalXp; + } + + if(Minecraft.getMinecraft().thePlayer == null) return; + + ItemStack stack = Minecraft.getMinecraft().thePlayer.getHeldItem(); + if(stack != null && stack.hasTagCompound()) { + NBTTagCompound tag = stack.getTagCompound(); + + if(tag.hasKey("ExtraAttributes", 10)) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + + if(ea.hasKey("mined_crops", 99)) { + counter = ea.getInteger("mined_crops"); + counterQueue.add(0, counter); + } + } + } + + while(counterQueue.size() >= 4) { + counterQueue.removeLast(); + } + + if(counterQueue.isEmpty()) { + cropsPerSecond = -1; + cropsPerSecondLast = 0; + } else { + cropsPerSecondLast = cropsPerSecond; + int last = counterQueue.getLast(); + int first = counterQueue.getFirst(); + + cropsPerSecond = (first - last)/3f; + } + + if(counter != -1) { + overlayStrings = new ArrayList<>(); + } else { + overlayStrings = null; + } + + } + + @Override + public void updateFrequent() { + if(counter < 0) { + overlayStrings = null; + } else { + overlayStrings = new ArrayList<>(); + + int counterInterp = counter; + if(counterLast > 0 && counterLast != counter) { + float factor = (System.currentTimeMillis()-lastUpdate)/1000f; + factor = LerpUtils.clampZeroOne(factor); + counterInterp = (int)(counterLast + (counter - counterLast) * factor); + } + + NumberFormat format = NumberFormat.getIntegerInstance(); + overlayStrings.add(EnumChatFormatting.AQUA+"Counter: "+EnumChatFormatting.YELLOW+format.format(counterInterp)); + + if(cropsPerSecondLast == cropsPerSecond && cropsPerSecond <= 0) { + overlayStrings.add(EnumChatFormatting.AQUA+"Crops/m: "+EnumChatFormatting.YELLOW+"N/A"); + } else { + float cpsInterp = cropsPerSecond; + if(cropsPerSecondLast >= 0 && cropsPerSecondLast != cropsPerSecond) { + float factor = (System.currentTimeMillis()-lastUpdate)/1000f; + factor = LerpUtils.clampZeroOne(factor); + cpsInterp = cropsPerSecondLast + (cropsPerSecond - cropsPerSecondLast) * factor; + } + + overlayStrings.add(EnumChatFormatting.AQUA+"Crops/m: "+EnumChatFormatting.YELLOW+ + String.format("%.2f", cpsInterp*60)); + } + + XPInformation.SkillInfo skillInfo = XPInformation.getInstance().getSkillInfo("Farming"); + if(skillInfo != null) { + StringBuilder levelStr = new StringBuilder(EnumChatFormatting.AQUA + "Level: "); + + levelStr.append(EnumChatFormatting.YELLOW) + .append(skillInfo.level) + .append(EnumChatFormatting.GRAY) + .append(" ["); + + float progress = skillInfo.currentXp / skillInfo.currentXpMax; + + float lines = 25; + for(int i=0; i<lines; i++) { + if(i/lines < progress) { + levelStr.append(EnumChatFormatting.YELLOW); + } else { + levelStr.append(EnumChatFormatting.DARK_GRAY); + } + levelStr.append('|'); + } + + levelStr.append(EnumChatFormatting.GRAY) + .append("] ") + .append(EnumChatFormatting.YELLOW) + .append((int)(progress*100)) + .append("%"); + + overlayStrings.add(levelStr.toString()); + overlayStrings.add(EnumChatFormatting.AQUA+"Current XP: " + EnumChatFormatting.YELLOW+ + format.format((int)skillInfo.currentXp)); + overlayStrings.add(EnumChatFormatting.AQUA+"Remaining XP: " + EnumChatFormatting.YELLOW+ + format.format((int)(skillInfo.currentXpMax - skillInfo.currentXp))); + } + + if(xpGainHourLast == xpGainHour && xpGainHour <= 0) { + overlayStrings.add(EnumChatFormatting.AQUA+"XP/h: "+EnumChatFormatting.YELLOW+"N/A"); + } else { + float xpInterp = xpGainHour; + if(xpGainHourLast >= 0 && cropsPerSecondLast != xpGainHour) { + float factor = (System.currentTimeMillis()-lastUpdate)/1000f; + factor = LerpUtils.clampZeroOne(factor); + xpInterp = xpGainHourLast + (xpGainHour - xpGainHourLast) * factor; + } + + overlayStrings.add(EnumChatFormatting.AQUA+"XP/h: "+EnumChatFormatting.YELLOW+ + format.format(xpInterp)+(isFarming ? "" : EnumChatFormatting.RED + " (PAUSED)")); + } + + float yaw = Minecraft.getMinecraft().thePlayer.rotationYawHead; + yaw %= 360; + if(yaw < 0) yaw += 360; + if(yaw > 180) yaw -= 360; + + overlayStrings.add(EnumChatFormatting.AQUA+"Yaw: "+EnumChatFormatting.YELLOW+ + String.format("%.2f", yaw)+EnumChatFormatting.BOLD+"\u1D52"); + } + } + + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java index 256026e3..a2071065 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java @@ -40,7 +40,7 @@ public class FuelBar { ItemStack held = Minecraft.getMinecraft().thePlayer.getHeldItem(); if(held != null) { String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); - if(internalname.contains("_DRILL_")) { + if(internalname != null && internalname.contains("_DRILL_")) { String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(held.getTagCompound()); for(String line : lore) { try { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextOverlay.java index ed1b6b21..c73c3b8d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextOverlay.java @@ -50,10 +50,30 @@ public abstract class TextOverlay { } } + public void updateFrequent() {}; public abstract void update(); public void render() { + if(overlayStrings == null) return; + + updateFrequent(); + if(overlayStrings != null) { + overlayHeight = 0; + overlayWidth = 0; + for(String s : overlayStrings) { + if(s == null) { + overlayHeight += 3; + continue; + } + int sWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(s); + if(sWidth > overlayWidth) { + overlayWidth = sWidth; + } + overlayHeight += 10; + } + overlayHeight -= 2; + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); int x = position.getAbsX(scaledResolution); 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 e52bcc2d..0ee6e2ff 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -48,6 +48,7 @@ import java.util.*; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -89,6 +90,7 @@ public class GuiProfileViewer extends GuiScreen { public enum ProfileViewerPage { LOADING(null), INVALID_NAME(null), + NO_SKYBLOCK(null), BASIC(new ItemStack(Items.paper)), DUNG(new ItemStack(Item.getItemFromBlock(Blocks.deadbush))), EXTRA(new ItemStack(Items.book)), @@ -112,6 +114,10 @@ public class GuiProfileViewer extends GuiScreen { playerNameTextField = new GuiElementTextField(name, GuiElementTextField.SCALE_TEXT); playerNameTextField.setSize(100, 20); + + if(currentPage == ProfileViewerPage.LOADING) { + currentPage = ProfileViewerPage.BASIC; + } } private GuiElementTextField playerNameTextField; @@ -121,9 +127,15 @@ public class GuiProfileViewer extends GuiScreen { currentTime = System.currentTimeMillis(); if(startTime == 0) startTime = currentTime; + ProfileViewerPage page = currentPage; if(profile == null) { - currentPage = ProfileViewerPage.INVALID_NAME; + page = ProfileViewerPage.INVALID_NAME; + } else if(profile.getPlayerInformation(null) == null) { + page = ProfileViewerPage.LOADING; + } else if(profile.getLatestProfile() == null) { + page = ProfileViewerPage.NO_SKYBLOCK; } + if(profileId == null && profile != null && profile.getLatestProfile() != null) { profileId = profile.getLatestProfile(); } @@ -159,7 +171,7 @@ public class GuiProfileViewer extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_bg); Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY, GL11.GL_NEAREST); - if(!(currentPage == ProfileViewerPage.LOADING) && profileId != null) { + if(!(page == ProfileViewerPage.LOADING)) { playerNameTextField.render(guiLeft+sizeX-100, guiTop+sizeY+5); ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); @@ -196,7 +208,7 @@ public class GuiProfileViewer extends GuiScreen { } GlStateManager.color(1, 1, 1, 1); - switch (currentPage) { + switch (page) { case BASIC: drawBasicPage(mouseX, mouseY, partialTicks); break; @@ -216,13 +228,27 @@ public class GuiProfileViewer extends GuiScreen { drawPetsPage(mouseX, mouseY, partialTicks); break; case LOADING: - Utils.drawStringCentered(EnumChatFormatting.YELLOW+"Loading player profiles...", Minecraft.getMinecraft().fontRendererObj, + String str = EnumChatFormatting.YELLOW+"Loading player profiles."; + long currentTimeMod = System.currentTimeMillis() % 1000; + if(currentTimeMod > 333) { + if(currentTimeMod < 666) { + str += "."; + } else { + str += ".."; + } + } + + Utils.drawStringCentered(str, Minecraft.getMinecraft().fontRendererObj, guiLeft+sizeX/2f, guiTop+101, true, 0); break; case INVALID_NAME: Utils.drawStringCentered(EnumChatFormatting.RED+"Invalid name or API is down!", Minecraft.getMinecraft().fontRendererObj, guiLeft+sizeX/2f, guiTop+101, true, 0); break; + case NO_SKYBLOCK: + Utils.drawStringCentered(EnumChatFormatting.RED+"No skyblock data found!", Minecraft.getMinecraft().fontRendererObj, + guiLeft+sizeX/2f, guiTop+101, true, 0); + break; } lastTime = currentTime; @@ -619,8 +645,8 @@ public class GuiProfileViewer extends GuiScreen { private static final ItemStack DEADBUSH = new ItemStack(Item.getItemFromBlock(Blocks.deadbush)); private static final ItemStack[] BOSS_HEADS = new ItemStack[7]; - private ProfileViewer.Level levelObjCata = null; - private HashMap<String, ProfileViewer.Level> levelObjClasses = new HashMap<>(); + private HashMap<String, ProfileViewer.Level> levelObjCatas = new HashMap<>(); + private HashMap<String, HashMap<String, ProfileViewer.Level>> levelObjClasseses = new HashMap<>(); private GuiElementTextField dungeonLevelTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); @@ -644,6 +670,7 @@ public class GuiProfileViewer extends GuiScreen { private void calculateFloorLevelXP() { JsonObject leveling = Constants.LEVELING; if(leveling == null) return; + ProfileViewer.Level levelObjCata = levelObjCatas.get(profileId); if(levelObjCata == null) return; try { @@ -684,6 +711,7 @@ public class GuiProfileViewer extends GuiScreen { int sectionWidth = 110; + ProfileViewer.Level levelObjCata = levelObjCatas.get(profileId); //Catacombs level thingy { if(levelObjCata == null) { @@ -691,6 +719,7 @@ public class GuiProfileViewer extends GuiScreen { "dungeons.dungeon_types.catacombs.experience"), 0); levelObjCata = ProfileViewer.getLevel(Utils.getElement(leveling, "catacombs").getAsJsonArray(), cataXp, 50, false); + levelObjCatas.put(profileId, levelObjCata); } String skillName = EnumChatFormatting.RED+"Catacombs"; @@ -925,6 +954,8 @@ public class GuiProfileViewer extends GuiScreen { for(int i=0; i<dungSkillsName.length; i++) { String skillName = dungSkillsName[i]; + + HashMap<String, ProfileViewer.Level> levelObjClasses = levelObjClasseses.computeIfAbsent(profileId, k->new HashMap<>()); if(!levelObjClasses.containsKey(skillName)) { float cataXp = Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.player_classes."+skillName.toLowerCase()+".experience"), 0); @@ -934,7 +965,7 @@ public class GuiProfileViewer extends GuiScreen { } String colour = EnumChatFormatting.WHITE.toString(); - if(activeClass != null && skillName.toLowerCase().equals(activeClass)) { + if(skillName.toLowerCase().equals(activeClass)) { colour = EnumChatFormatting.GREEN.toString(); } @@ -951,6 +982,8 @@ public class GuiProfileViewer extends GuiScreen { private void renderXpBar(String skillName, ItemStack stack, int x, int y, int xSize, int levelFloored, float level, int mouseX, int mouseY) { Utils.renderAlignedString(skillName, EnumChatFormatting.WHITE.toString()+levelFloored, x+14, y-4, xSize-20); + ProfileViewer.Level levelObjCata = levelObjCatas.get(profileId); + if(levelObjCata.maxed) { renderGoldBar(x, y+6, xSize); } else { @@ -1138,7 +1171,7 @@ public class GuiProfileViewer extends GuiScreen { JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(petname+";"+tierNum); if(petItem == null) continue; - ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem, false, false, false); + ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem, false, false); HashMap<String, String> replacements = NotEnoughUpdates.INSTANCE.manager.getLoreReplacements(petname, tier, (int)Math.floor(level)); if(heldItem != null) { @@ -2269,7 +2302,7 @@ public class GuiProfileViewer extends GuiScreen { } private boolean loadingProfile = false; - private static final ExecutorService profileLoader = Executors.newSingleThreadExecutor(); + private static final ExecutorService profileLoader = Executors.newFixedThreadPool(1); private void drawBasicPage(int mouseX, int mouseY, float partialTicks) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -2435,7 +2468,7 @@ public class GuiProfileViewer extends GuiScreen { } if(entityPlayer == null) { - if(!loadingProfile) { + if(!loadingProfile || ((ThreadPoolExecutor)profileLoader).getActiveCount() == 0) { loadingProfile = true; UUID playerUUID = UUID.fromString(niceUuid(profile.getUuid())); @@ -2475,9 +2508,7 @@ public class GuiProfileViewer extends GuiScreen { if(entityPlayer != null) { if(backgroundClickedX != -1 && Mouse.isButtonDown(1)) { - for(int i=0; i<entityPlayer.inventory.armorInventory.length; i++) { - entityPlayer.inventory.armorInventory[i] = null; - } + Arrays.fill(entityPlayer.inventory.armorInventory, null); } else { if(inventoryInfo != null && inventoryInfo.has("inv_armor")) { JsonArray items = inventoryInfo.get("inv_armor").getAsJsonArray(); @@ -2489,6 +2520,8 @@ public class GuiProfileViewer extends GuiScreen { } } } + } else { + Arrays.fill(entityPlayer.inventory.armorInventory, null); } } } @@ -2621,15 +2654,18 @@ public class GuiProfileViewer extends GuiScreen { if(mouseX > x && mouseX < x+80) { if(mouseY > y-4 && mouseY < y+13) { - String levelStr; + tooltipToDisplay = new ArrayList<>(); + tooltipToDisplay.add(skillName); if(skillInfo.get("maxed_"+entry.getKey()).getAsBoolean()) { - levelStr = EnumChatFormatting.GOLD+"MAXED!"; + tooltipToDisplay.add(EnumChatFormatting.GRAY+"Progress: "+EnumChatFormatting.GOLD+"MAXED!"); } else { int maxXp = (int)skillInfo.get("maxxp_"+entry.getKey()).getAsFloat(); - levelStr = EnumChatFormatting.DARK_PURPLE.toString() + shortNumberFormat(Math.round((level%1)*maxXp), 0) + "/" + shortNumberFormat(maxXp, 0); + tooltipToDisplay.add(EnumChatFormatting.GRAY+"Progress: "+EnumChatFormatting.DARK_PURPLE.toString() + + shortNumberFormat(Math.round((level%1)*maxXp), 0) + "/" + shortNumberFormat(maxXp, 0)); } - - tooltipToDisplay = Utils.createList(levelStr); + String totalXpS = NumberFormat.getIntegerInstance().format((int)skillInfo.get("experience_"+entry.getKey()).getAsFloat()); + tooltipToDisplay.add(EnumChatFormatting.GRAY+"Total XP: " + + EnumChatFormatting.DARK_PURPLE+totalXpS); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index b9f9b03d..227d94bd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -314,13 +314,14 @@ public class ProfileViewer { private JsonObject playerStatus = null; private HashMap<String, PlayerStats.Stats> stats = new HashMap<>(); private HashMap<String, PlayerStats.Stats> passiveStats = new HashMap<>(); - private long networth = -1; + private HashMap<String, Long> networth = new HashMap<>(); public Profile(String uuid) { this.uuid = uuid; } private AtomicBoolean updatingPlayerInfoState = new AtomicBoolean(false); + private long lastPlayerInfoState = 0; private AtomicBoolean updatingPlayerStatusState = new AtomicBoolean(false); public JsonObject getPlayerStatus() { @@ -346,7 +347,8 @@ public class ProfileViewer { } public long getNetWorth(String profileId) { - if(networth != -1) return networth; + if(profileId == null) profileId = latestProfile; + if(networth.get(profileId) != null) return networth.get(profileId); if(getProfileInformation(profileId) == null) return -1; if(getInventoryInfo(profileId) == null) return -1; @@ -363,9 +365,16 @@ public class ProfileViewer { if(manager.auctionManager.isVanillaItem(internalname)) continue; - int auctionPrice = (int)manager.auctionManager.getItemAvgBin(internalname); - if(auctionPrice <= 0) { - auctionPrice = (int)manager.auctionManager.getLowestBin(internalname); + JsonObject bzInfo = manager.auctionManager.getBazaarInfo(internalname); + + int auctionPrice; + if(bzInfo != null) { + auctionPrice = (int)bzInfo.get("curr_sell").getAsFloat(); + } else { + auctionPrice = (int)manager.auctionManager.getItemAvgBin(internalname); + if(auctionPrice <= 0) { + auctionPrice = manager.auctionManager.getLowestBin(internalname); + } } try { @@ -384,9 +393,16 @@ public class ProfileViewer { if(internalname2 != null) { if(manager.auctionManager.isVanillaItem(internalname2)) continue; - int auctionPrice2 = (int)manager.auctionManager.getItemAvgBin(internalname2); - if(auctionPrice2 <= 0) { - auctionPrice2 = (int)manager.auctionManager.getLowestBin(internalname2); + JsonObject bzInfo2 = manager.auctionManager.getBazaarInfo(internalname); + + int auctionPrice2; + if(bzInfo2 != null) { + auctionPrice2 = (int)bzInfo2.get("curr_sell").getAsFloat(); + } else { + auctionPrice2 = (int)manager.auctionManager.getItemAvgBin(internalname2); + if(auctionPrice2 <= 0) { + auctionPrice2 = manager.auctionManager.getLowestBin(internalname2); + } } int count2 = items.getCompoundTagAt(j).getByte("Count"); @@ -401,7 +417,6 @@ public class ProfileViewer { if(element.getAsJsonObject().has("count")) { count = element.getAsJsonObject().get("count").getAsInt(); } - networth += auctionPrice * count; } } @@ -440,7 +455,7 @@ public class ProfileViewer { networth += bankBalance+purseBalance; - this.networth = networth; + this.networth.put(profileId, networth); return networth; } @@ -450,17 +465,21 @@ public class ProfileViewer { public JsonArray getPlayerInformation(Runnable runnable) { if (playerInformation != null) return playerInformation; - if (updatingPlayerInfoState.get()) return null; + long currentTime = System.currentTimeMillis(); + + if (currentTime - lastPlayerInfoState < 15*1000 && updatingPlayerInfoState.get()) return null; + + lastPlayerInfoState = currentTime; updatingPlayerInfoState.set(true); HashMap<String, String> args = new HashMap<>(); args.put("uuid", "" + uuid); manager.hypixelApi.getHypixelApiAsync(NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, "skyblock/profiles", args, jsonObject -> { - if (jsonObject == null) return; - updatingPlayerInfoState.set(false); + + if (jsonObject == null) return; if (jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { playerInformation = jsonObject.get("profiles").getAsJsonArray(); if (playerInformation == null) return; @@ -498,8 +517,8 @@ public class ProfileViewer { } } - if (runnable != null) runnable.run(); latestProfile = backup; + if (runnable != null) runnable.run(); } }, () -> { updatingPlayerInfoState.set(false); @@ -585,7 +604,7 @@ public class ProfileViewer { skillInfoMap.clear(); inventoryInfoMap.clear(); collectionInfoMap.clear(); - networth = -1; + networth.clear(); } public int getCap(JsonObject leveling, String skillName) { @@ -1018,11 +1037,19 @@ public class ProfileViewer { public void getProfileByName(String name, Consumer<Profile> callback) { String nameF = name.toLowerCase(); + if(nameToUuid.containsKey(nameF) && nameToUuid.get(nameF) == null) { + callback.accept(null); + return; + } + getPlayerUUID(nameF, (uuid) -> { if(uuid == null) { getHypixelProfile(nameF, jsonObject -> { if(jsonObject != null) { callback.accept(getProfileReset(nameToUuid.get(nameF), ignored -> {})); + } else { + callback.accept(null); + nameToUuid.put(nameF, null); } }); } else { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java index c237959a..9c9cba53 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java @@ -8,6 +8,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.ConnectException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; @@ -117,6 +118,7 @@ public class HypixelApi { String response = IOUtils.toString(connection.getInputStream(), StandardCharsets.UTF_8); JsonObject json = gson.fromJson(response, JsonObject.class); + if(json == null) throw new ConnectException("Invalid JSON"); return json; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ProfileApiSyncer.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ProfileApiSyncer.java new file mode 100644 index 00000000..15482d0a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ProfileApiSyncer.java @@ -0,0 +1,75 @@ +package io.github.moulberry.notenoughupdates.util; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; +import net.minecraft.client.Minecraft; + +import java.util.HashMap; +import java.util.function.Consumer; + +public class ProfileApiSyncer { + + private static ProfileApiSyncer INSTANCE = new ProfileApiSyncer(); + + private HashMap<String, Long> resyncTimes = new HashMap<>(); + private HashMap<String, Runnable> syncingCallbacks = new HashMap<>(); + private HashMap<String, Consumer<ProfileViewer.Profile>> finishSyncCallbacks = new HashMap<>(); + private long lastResync; + + public static ProfileApiSyncer getInstance() { + return INSTANCE; + } + + public void requestResync(String id, long timeBetween) { + requestResync(id, timeBetween, null); + } + + public void requestResync(String id, long timeBetween, Runnable syncingCallback) { + requestResync(id, timeBetween, null, null); + } + + public void requestResync(String id, long timeBetween, Runnable syncingCallback, Consumer<ProfileViewer.Profile> finishSyncCallback) { + resyncTimes.put(id, timeBetween); + syncingCallbacks.put(id, syncingCallback); + finishSyncCallbacks.put(id, finishSyncCallback); + } + + public long getCurrentResyncTime() { + long time = -1; + for(long l : resyncTimes.values()) { + if(l > 0 && (l < time || time == -1)) time = l; + } + return time; + } + + public void tick() { + if(Minecraft.getMinecraft().thePlayer == null) return; + + long resyncTime = getCurrentResyncTime(); + + if(resyncTime < 0) return; + + long currentTime = System.currentTimeMillis(); + + if(currentTime - lastResync > resyncTime) { + lastResync = currentTime; + resyncTimes.clear(); + + for(Runnable r : syncingCallbacks.values()) r.run(); + syncingCallbacks.clear(); + + forceResync(); + } + } + + private void forceResync() { + if(Minecraft.getMinecraft().thePlayer == null) return; + + String uuid = Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""); + NotEnoughUpdates.profileViewer.getProfileReset(uuid, (profile) -> { + for(Consumer<ProfileViewer.Profile> c : finishSyncCallbacks.values()) c.accept(profile); + finishSyncCallbacks.clear(); + }); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 3e44dbda..1e29fb5e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -45,6 +45,7 @@ public class SBInfo { public void onWorldChange(WorldEvent.Load event) { lastLocRaw = -1; locraw = null; + mode = null; } @SubscribeEvent @@ -53,9 +54,10 @@ public class SBInfo { try { JsonObject obj = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(event.message.getUnformattedText(), JsonObject.class); if(obj.has("server")) { - if(System.currentTimeMillis() - lastLocRaw < 5000) event.setCanceled(true); + if(true || System.currentTimeMillis() - lastLocRaw < 5000) event.setCanceled(true); if(obj.has("gametype") && obj.has("mode") && obj.has("map")) { locraw = obj; + mode = locraw.get("mode").getAsString(); } } } catch(Exception e) { @@ -65,10 +67,10 @@ public class SBInfo { } public String getLocation() { - if(locraw == null) { + if(mode == null) { return null; } - return locraw.get("mode").getAsString(); + return mode; } public void tick() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java new file mode 100644 index 00000000..c88d09f9 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java @@ -0,0 +1,90 @@ +package io.github.moulberry.notenoughupdates.util; + +import com.google.common.base.Splitter; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class XPInformation { + + private static XPInformation INSTANCE = new XPInformation(); + + public static XPInformation getInstance() { + return INSTANCE; + } + + public static class SkillInfo { + public int level; + public float totalXp; + public float currentXp; + public float currentXpMax; + } + + private HashMap<String, SkillInfo> skillInfoMap = new HashMap<>(); + + private static Splitter SPACE_SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults(); + private static Pattern SKILL_PATTERN = Pattern.compile("\\+(\\d+(?:\\.\\d+)?) (.+) \\((\\d+(?:,\\d+)*(?:\\.\\d+)?)/(\\d+(?:,\\d+)*(?:\\.\\d+)?)\\)"); + + public SkillInfo getSkillInfo(String skillName) { + return skillInfoMap.get(skillName); + } + + @SubscribeEvent + public void onChatReceived(ClientChatReceivedEvent event) { + if(event.type == 2) { + JsonObject leveling = Constants.LEVELING; + if(leveling == null) return; + + List<String> components = SPACE_SPLITTER.splitToList(StringUtils.cleanColour(event.message.getUnformattedText())); + + for(String component : components) { + Matcher matcher = SKILL_PATTERN.matcher(component); + if(matcher.matches()) { + String skillS = matcher.group(2); + String currentXpS = matcher.group(3).replace(",",""); + String maxXpS = matcher.group(4).replace(",","");; + + float currentXp = Float.parseFloat(currentXpS); + float maxXp = Float.parseFloat(maxXpS); + + SkillInfo skillInfo = new SkillInfo(); + skillInfo.currentXp = currentXp; + skillInfo.currentXpMax = maxXp; + skillInfo.totalXp = currentXp; + + JsonArray levelingArray = leveling.getAsJsonArray("leveling_xp"); + for(int i=0; i<levelingArray.size(); i++) { + float cap = levelingArray.get(i).getAsFloat(); + if(maxXp <= cap) { + break; + } + + skillInfo.totalXp += cap; + skillInfo.level++; + } + + skillInfoMap.put(skillS, skillInfo); + } + } + } + } + + public void tick() { + ProfileApiSyncer.getInstance().requestResync("xpinformation", 5*60*1000, + () -> {}, this::onApiUpdated); + } + + private void onApiUpdated(ProfileViewer.Profile profile) { + JsonObject skillInfo = profile.getSkillInfo(null); + + } + +} |