diff options
Diffstat (limited to 'src/main/java/de')
43 files changed, 574 insertions, 420 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 08b0915a..58b1b48d 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -54,7 +54,7 @@ import de.hysky.skyblocker.utils.chat.ChatMessageListener; import de.hysky.skyblocker.utils.discord.DiscordRPCManager; import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.render.culling.OcclusionCulling; -import de.hysky.skyblocker.utils.render.gui.ContainerSolverManager; +import de.hysky.skyblocker.utils.container.ContainerSolverManager; import de.hysky.skyblocker.utils.render.title.TitleContainer; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.scheduler.Scheduler; diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index 709b8697..ca1cddf8 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -22,7 +22,7 @@ import de.hysky.skyblocker.skyblock.quicknav.QuickNav; import de.hysky.skyblocker.skyblock.quicknav.QuickNavButton; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.AbstractContainerSolver; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; @@ -203,7 +203,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen */ @Unique private ItemStack skyblocker$experimentSolvers$getStack(Slot slot, @NotNull ItemStack stack) { - ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); + AbstractContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); if ((currentSolver instanceof SuperpairsSolver || currentSolver instanceof UltrasequencerSolver) && ((ExperimentSolver) currentSolver).getState() == ExperimentSolver.State.SHOW && slot.inventory instanceof SimpleInventory) { ItemStack itemStack = ((ExperimentSolver) currentSolver).getSlots().get(slot.getIndex()); return itemStack == null ? stack : itemStack; @@ -231,12 +231,12 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen if (slot == null) return; String title = getTitle().getString(); ItemStack stack = skyblocker$experimentSolvers$getStack(slot, slot.getStack()); - ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); + AbstractContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); // Prevent clicks on filler items if (SkyblockerConfigManager.get().uiAndVisuals.hideEmptyTooltips && FILLER_ITEMS.contains(stack.getName().getString()) && // Allow clicks in Ultrasequencer and Superpairs - (!UltrasequencerSolver.INSTANCE.getName().matcher(title).matches() || SkyblockerConfigManager.get().helpers.experiments.enableUltrasequencerSolver)) { + (!UltrasequencerSolver.INSTANCE.getTitlePattern().matcher(title).matches() || SkyblockerConfigManager.get().helpers.experiments.enableUltrasequencerSolver)) { ci.cancel(); return; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakeBagHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakeBagHelper.java index 747ce9b4..aa5d1cd4 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakeBagHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakeBagHelper.java @@ -2,7 +2,7 @@ package de.hysky.skyblocker.skyblock.accessories.newyearcakes; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.MinecraftClient; import net.minecraft.item.ItemStack; @@ -16,12 +16,12 @@ public class NewYearCakeBagHelper extends ContainerSolver { } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return SkyblockerConfigManager.get().helpers.enableNewYearCakesHelper; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { MinecraftClient client = MinecraftClient.getInstance(); if (client.player != null) { for (Slot slot : client.player.currentScreenHandler.slots) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakesHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakesHelper.java index c403a81b..e31d4238 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakesHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/accessories/newyearcakes/NewYearCakesHelper.java @@ -3,7 +3,7 @@ package de.hysky.skyblocker.skyblock.accessories.newyearcakes; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; @@ -20,7 +20,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class NewYearCakesHelper extends ContainerSolver { - private static final Logger LOGGER = LoggerFactory.getLogger(NewYearCakeBagHelper.class); + private static final Logger LOGGER = LoggerFactory.getLogger(NewYearCakesHelper.class); private static final Pattern NEW_YEAR_CAKE = Pattern.compile("New Year Cake \\(Year (?<year>\\d+)\\)"); private static final Pattern NEW_YEAR_CAKE_PURCHASE = Pattern.compile("You purchased New Year Cake \\(Year (?<year>\\d+)\\) for .+ coins!"); private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); @@ -49,7 +49,7 @@ public class NewYearCakesHelper extends ContainerSolver { } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return SkyblockerConfigManager.get().helpers.enableNewYearCakesHelper; } @@ -65,7 +65,7 @@ public class NewYearCakesHelper extends ContainerSolver { } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { String profile = Utils.getProfile(); if (cakes.isEmpty() || !cakes.containsKey(profile) || cakes.containsKey(profile) && cakes.get(profile).isEmpty()) return List.of(); List<ColorHighlight> highlights = new ArrayList<>(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java index 04f6536d..e1d2c59e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java @@ -6,7 +6,7 @@ import de.hysky.skyblocker.skyblock.item.tooltip.adders.LineSmoothener; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.RegexUtils; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; @@ -89,12 +89,12 @@ public class ChocolateFactorySolver extends ContainerSolver { } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return SkyblockerConfigManager.get().helpers.chocolateFactory.enableChocolateFactoryHelper; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { updateFactoryInfo(slots); List<ColorHighlight> highlights = new ArrayList<>(); @@ -240,7 +240,7 @@ public class ChocolateFactorySolver extends ContainerSolver { } @Override - protected void reset() { + public void reset() { cpsIncreaseFactors.clear(); totalChocolate = -1L; totalCps = -1.0; @@ -264,6 +264,7 @@ public class ChocolateFactorySolver extends ContainerSolver { private record Rabbit(double cpsIncrease, long cost, int slot) {} + //Todo: Merge this into the outer class once #786 is merged public static final class Tooltip extends TooltipAdder { public Tooltip() { super("^Chocolate Factory$", 0); //The priority doesn't really matter here as this is the only tooltip adder for the Chocolate Factory. @@ -394,5 +395,10 @@ public class ChocolateFactorySolver extends ContainerSolver { } return Text.literal(builder.toString()).formatted(Formatting.GOLD); } + + @Override + public boolean isEnabled() { + return SkyblockerConfigManager.get().helpers.chocolateFactory.enableChocolateFactoryHelper; + } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusHelper.java index d317a2e8..de9bd048 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusHelper.java @@ -3,7 +3,7 @@ package de.hysky.skyblocker.skyblock.dungeon; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.item.ItemStack; @@ -12,18 +12,17 @@ import java.util.ArrayList; import java.util.List; public class CroesusHelper extends ContainerSolver { - public CroesusHelper() { super("^Croesus$"); } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return SkyblockerConfigManager.get().dungeons.croesusHelper; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { List<ColorHighlight> highlights = new ArrayList<>(); for (Int2ObjectMap.Entry<ItemStack> entry : slots.int2ObjectEntrySet()) { ItemStack stack = entry.getValue(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java index 0f459c9d..e0bb2748 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java @@ -1,16 +1,13 @@ package de.hysky.skyblocker.skyblock.dungeon; -import com.google.gson.JsonObject; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.item.tooltip.TooltipInfoType; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Util; - import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -21,18 +18,18 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class CroesusProfit extends ContainerSolver { - private static final Pattern ESSENCE_PATTERN = Pattern.compile("(?<type>[A-Za-z]+) Essence x(?<amount>[0-9]+)"); + private static final Pattern ESSENCE_PATTERN = Pattern.compile("(?<type>[A-Za-z]+) Essence x(?<amount>\\d+)"); public CroesusProfit() { super(".*Catacombs - Floor.*"); } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return SkyblockerConfigManager.get().dungeons.dungeonChestProfit.croesusProfit; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { List<ColorHighlight> highlights = new ArrayList<>(); ItemStack bestChest = null, secondBestChest = null; double bestValue = 0, secondBestValue = 0; // If negative value of chest - it is out of the question @@ -82,7 +79,7 @@ public class CroesusProfit extends ContainerSolver { } else if (lineString.isEmpty()) { processingContents = false; } else if (lineString.contains("Coins") && !processingContents) { - chestPrice = Integer.parseInt(lineString.replaceAll(",", "").replaceAll("\\D", "")); + chestPrice = Integer.parseInt(lineString.replace(",", "").replaceAll("\\D", "")); } if (processingContents) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java index 7a966b48..4ee81256 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java @@ -1,8 +1,9 @@ package de.hysky.skyblocker.skyblock.dungeon.terminal; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.container.AbstractContainerSolver; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -27,20 +28,20 @@ public final class ColorTerminal extends ContainerSolver implements TerminalSolv } @Override - protected boolean isEnabled() { + public boolean isEnabled() { targetColor = null; return SkyblockerConfigManager.get().dungeons.terminals.solveColor; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { - trimEdges(slots, 6); + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { + AbstractContainerSolver.trimEdges(slots, 6); List<ColorHighlight> highlights = new ArrayList<>(); String colorString = groups[0]; if (targetColor == null) { targetColor = colorFromName.get(colorString); if (targetColor == null) { - LOGGER.error("[Skyblocker] Couldn't find dye color corresponding to \"" + colorString + "\""); + LOGGER.error("[Skyblocker] Couldn't find dye color corresponding to \"{}\"", colorString); return Collections.emptyList(); } } @@ -54,7 +55,7 @@ public final class ColorTerminal extends ContainerSolver implements TerminalSolv } @Override - protected boolean onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) { + public boolean onClickSlot(int slot, ItemStack stack, int screenId) { if (stack.hasGlint() || !targetColor.equals(itemColor.get(stack.getItem()))) { return shouldBlockIncorrectClicks(); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/LightsOnTerminal.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/LightsOnTerminal.java index 4975b90b..2c024633 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/LightsOnTerminal.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/LightsOnTerminal.java @@ -1,13 +1,13 @@ package de.hysky.skyblocker.skyblock.dungeon.terminal; -import java.util.List; - +import de.hysky.skyblocker.utils.container.ContainerSolver; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import java.util.List; + /** * The terminal where you change all the panes that are red to green. * @@ -21,17 +21,17 @@ public final class LightsOnTerminal extends ContainerSolver implements TerminalS } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return shouldBlockIncorrectClicks(); } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { return EMPTY; } @Override - protected boolean onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) { + public boolean onClickSlot(int slot, ItemStack stack, int screenId) { return stack.isOf(Items.LIME_STAINED_GLASS_PANE); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java index 05998988..e628cf8f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java @@ -1,8 +1,9 @@ package de.hysky.skyblocker.skyblock.dungeon.terminal; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.container.AbstractContainerSolver; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -12,7 +13,7 @@ import java.util.Collections; import java.util.List; public final class OrderTerminal extends ContainerSolver implements TerminalSolver { - private final int PANES_NUM = 14; + private static final int PANES_NUM = 14; private int[] orderedSlots; private int currentNum = Integer.MAX_VALUE; @@ -21,14 +22,14 @@ public final class OrderTerminal extends ContainerSolver implements TerminalSolv } @Override - protected boolean isEnabled() { + public boolean isEnabled() { orderedSlots = null; currentNum = 0; return SkyblockerConfigManager.get().dungeons.terminals.solveOrder; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { if(orderedSlots == null && !orderSlots(slots)) return Collections.emptyList(); while(currentNum < PANES_NUM && Items.LIME_STAINED_GLASS_PANE.equals(slots.get(orderedSlots[currentNum]).getItem())) @@ -42,22 +43,21 @@ public final class OrderTerminal extends ContainerSolver implements TerminalSolv } public boolean orderSlots(Int2ObjectMap<ItemStack> slots) { - trimEdges(slots, 4); + AbstractContainerSolver.trimEdges(slots, 4); orderedSlots = new int[PANES_NUM]; for(Int2ObjectMap.Entry<ItemStack> slot : slots.int2ObjectEntrySet()) { if(Items.AIR.equals(slot.getValue().getItem())) { orderedSlots = null; return false; } - else - orderedSlots[slot.getValue().getCount() - 1] = slot.getIntKey(); + else orderedSlots[slot.getValue().getCount() - 1] = slot.getIntKey(); } currentNum = 0; return true; } @Override - protected boolean onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) { + public boolean onClickSlot(int slot, ItemStack stack, int screenId) { if (stack == null || stack.isEmpty()) return false; if (!stack.isOf(Items.RED_STAINED_GLASS_PANE) || stack.getCount() != currentNum + 1) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java index 8b0f1801..a9ff0e80 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java @@ -1,8 +1,9 @@ package de.hysky.skyblocker.skyblock.dungeon.terminal; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.container.AbstractContainerSolver; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectSet; @@ -22,13 +23,13 @@ public final class StartsWithTerminal extends ContainerSolver implements Termina } @Override - protected boolean isEnabled() { + public boolean isEnabled() { return SkyblockerConfigManager.get().dungeons.terminals.solveStartsWith; } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { - trimEdges(slots, 6); + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { + AbstractContainerSolver.trimEdges(slots, 6); setupState(slots); String prefix = groups[0]; @@ -50,7 +51,7 @@ public final class StartsWithTerminal extends ContainerSolver implements Termina } @Override - protected boolean onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) { + public boolean onClickSlot(int slot, ItemStack stack, int screenId) { //Some random glass pane was clicked or something if (!trackedItemStates.containsKey(slot) || stack == null || stack.isEmpty()) return false; @@ -74,7 +75,7 @@ public final class StartsWithTerminal extends ContainerSolver implements Termina return false; } - //We only setup the state when all items aren't null or empty. This prevents the state from being reset due to unsent items or server lag spikes/bad TPS (fix ur servers Hypixel) + //We only set up the state when all items aren't null or empty. This prevents the state from being reset due to unsent items or server lag spikes/bad TPS (fix ur servers Hypixel) private void setupState(Int2ObjectMap<ItemStack> usefulSlots) { Predicate<Int2ObjectMap.Entry<ItemStack>> notNullOrEmpty = e -> e.getValue() != null && !e.getValue().isEmpty(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/TerminalSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/TerminalSolver.java index f20c35b5..cf384f08 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/TerminalSolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/terminal/TerminalSolver.java @@ -3,7 +3,6 @@ package de.hysky.skyblocker.skyblock.dungeon.terminal; import de.hysky.skyblocker.config.SkyblockerConfigManager; public sealed interface TerminalSolver permits ColorTerminal, LightsOnTerminal, OrderTerminal, StartsWithTerminal { - default boolean shouldBlockIncorrectClicks() { return SkyblockerConfigManager.get().dungeons.terminals.blockIncorrectClicks; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/experiment/ChronomatronSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/experiment/ChronomatronSolver.java index 308452ef..a4d34a1b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/experiment/ChronomatronSolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/experiment/ChronomatronSolver.java @@ -103,7 +103,7 @@ public final class ChronomatronSolver extends ExperimentSolver { } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { List<ColorHighlight> highlights = new ArrayList<>(); if (getState() == State.SHOW && chronomatronSlots.size() > chronomatronCurrentOrdinal) { for (Int2ObjectMap.Entry<ItemStack> indexStack : slots.int2ObjectEntrySet()) { @@ -119,8 +119,7 @@ public final class ChronomatronSolver extends ExperimentSolver { } @Override - protected void reset() { - super.reset(); + public void reset() { chronomatronSlots.clear(); chronomatronChainLengthCount = 0; chronomatronCurrentSlot = 0; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/experiment/ExperimentSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/experiment/ExperimentSolver.java index ad2800e0..6339eb39 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/experiment/ExperimentSolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/experiment/ExperimentSolver.java @@ -2,16 +2,18 @@ package de.hysky.skyblocker.skyblock.experiment; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.HelperConfig; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import de.hysky.skyblocker.utils.container.ContainerSolver; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.item.ItemStack; +import org.intellij.lang.annotations.Language; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; -public sealed abstract class ExperimentSolver extends ContainerSolver permits ChronomatronSolver, SuperpairsSolver, UltrasequencerSolver { +public abstract sealed class ExperimentSolver extends ContainerSolver permits ChronomatronSolver, SuperpairsSolver, UltrasequencerSolver { public enum State { REMEMBER, WAIT, SHOW, END } @@ -19,7 +21,7 @@ public sealed abstract class ExperimentSolver extends ContainerSolver permits Ch private State state = State.REMEMBER; private final Map<Integer, ItemStack> slots = new HashMap<>(); - protected ExperimentSolver(String containerName) { + protected ExperimentSolver(@NotNull @Language("RegExp") String containerName) { super(containerName); } @@ -36,22 +38,20 @@ public sealed abstract class ExperimentSolver extends ContainerSolver permits Ch } @Override - protected final boolean isEnabled() { + public final boolean isEnabled() { return isEnabled(SkyblockerConfigManager.get().helpers.experiments); } protected abstract boolean isEnabled(HelperConfig.Experiments experimentsConfig); @Override - protected void start(GenericContainerScreen screen) { - super.start(screen); + public void start(GenericContainerScreen screen) { state = State.REMEMBER; ScreenEvents.afterTick(screen).register(this::tick); } @Override - protected void reset() { - super.reset(); + public void reset() { state = State.REMEMBER; slots.clear(); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/experiment/SuperpairsSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/experiment/SuperpairsSolver.java index 5c2ed152..f2d4c55d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/experiment/SuperpairsSolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/experiment/SuperpairsSolver.java @@ -33,14 +33,12 @@ public final class SuperpairsSolver extends ExperimentSolver { } @Override - protected void start(GenericContainerScreen screen) { - super.start(screen); + public void start(GenericContainerScreen screen) { setState(State.SHOW); } @Override - protected void reset() { - super.reset(); + public void reset() { superpairsPrevClickedSlot = 0; superpairsCurrentSlot = null; superpairsDuplicatedSlots.clear(); @@ -63,7 +61,7 @@ public final class SuperpairsSolver extends ExperimentSolver { } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> displaySlots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> displaySlots) { List<ColorHighlight> highlights = new ArrayList<>(); if (getState() == State.SHOW) { for (Int2ObjectMap.Entry<ItemStack> indexStack : displaySlots.int2ObjectEntrySet()) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/experiment/UltrasequencerSolver.java b/src/main/java/de/hysky/skyblocker/skyblock/experiment/UltrasequencerSolver.java index a4d1e4b6..796c80ee 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/experiment/UltrasequencerSolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/experiment/UltrasequencerSolver.java @@ -2,6 +2,7 @@ package de.hysky.skyblocker.skyblock.experiment; import de.hysky.skyblocker.config.configs.HelperConfig; import de.hysky.skyblocker.utils.render.gui.ColorHighlight; +import de.hysky.skyblocker.utils.container.AbstractContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; @@ -55,7 +56,7 @@ public final class UltrasequencerSolver extends ExperimentSolver { case WAIT -> { if (genericContainerScreen.getScreenHandler().getInventory().getStack(49).getName().getString().startsWith("Timer: ")) { setState(State.SHOW); - markHighlightsDirty(); + AbstractContainerSolver.markHighlightsDirty(); } } case END -> { @@ -76,7 +77,7 @@ public final class UltrasequencerSolver extends ExperimentSolver { } @Override - protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) { + public List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots) { return getState() == State.SHOW && ultrasequencerNextSlot != 0 ? List.of(ColorHighlight.green(ultrasequencerNextSlot)) : new ArrayList<>(); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java index 71d9aa30..7ac403df 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java @@ -1,18 +1,18 @@ package de.hysky.skyblocker.skyblock.item.slottext; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.utils.render.gui.AbstractContainerMatcher; -import net.minecraft.screen.slot.Slot; +import de.hysky.skyblocker.utils.container.AbstractSlotTextAdder; +import de.hysky.skyblocker.utils.container.RegexContainerMatcher; import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; -import java.util.List; import java.util.regex.Pattern; /** + * Simple implementation of a slot text adder. * Extend this class and add it to {@link SlotTextManager#adders} to add text to any arbitrary slot. */ -public abstract class SlotTextAdder extends AbstractContainerMatcher { +public abstract class SlotTextAdder extends RegexContainerMatcher implements AbstractSlotTextAdder { /** * Utility constructor that will compile the given string into a pattern. * @@ -38,20 +38,7 @@ public abstract class SlotTextAdder extends AbstractContainerMatcher { super(); } - /** - * This method will be called for each rendered slot. Consider using a switch statement on {@link Slot#id} if you wish to add different text to different slots. - * - * @return A list of positioned text to be rendered. Return {@link List#of()} if no text should be rendered. - * @implNote By minecraft's design, scaled text inexplicably moves around. - * So, limit your text to 3 characters (or roughly less than 20 width) if you want it to not look horrible. - */ - public abstract @NotNull List<SlotText> getText(Slot slot); - - /** - * Override this method to add conditions to enable or disable this adder. - * @return Whether this adder is enabled. - * @implNote The slot text adders only work while in skyblock, so no need to check for that again. - */ + @Override public boolean isEnabled() { return SkyblockerConfigManager.get().general.itemInfoDisplay.slotText; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java index aa9bf939..fe38e340 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java @@ -3,8 +3,8 @@ package de.hysky.skyblocker.skyblock.item.slottext; import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.skyblock.item.slottext.adders.*; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.container.AbstractSlotTextAdder; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; -import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.screen.slot.Slot; import org.jetbrains.annotations.NotNull; @@ -13,7 +13,7 @@ import java.util.ArrayList; import java.util.List; public class SlotTextManager { - private static final SlotTextAdder[] adders = new SlotTextAdder[]{ + private static final AbstractSlotTextAdder[] adders = new AbstractSlotTextAdder[]{ new EssenceShopAdder(), new EnchantmentLevelAdder(), new MinionLevelAdder(), @@ -34,25 +34,24 @@ public class SlotTextManager { new BazaarHelper(), new StatsTuningAdder() }; - private static final ArrayList<SlotTextAdder> currentScreenAdders = new ArrayList<>(); + private static final ArrayList<AbstractSlotTextAdder> currentScreenAdders = new ArrayList<>(); private SlotTextManager() { } public static void init() { ScreenEvents.AFTER_INIT.register((client, screen, width, height) -> { - if (screen instanceof HandledScreen<?> && Utils.isOnSkyblock()) { - onScreenChange(screen); + if (screen instanceof HandledScreen<?> handledScreen && Utils.isOnSkyblock()) { + onScreenChange(handledScreen); ScreenEvents.remove(screen).register(ignored -> currentScreenAdders.clear()); } }); } - private static void onScreenChange(Screen screen) { - final String title = screen.getTitle().getString(); - for (SlotTextAdder adder : adders) { + private static void onScreenChange(HandledScreen<?> screen) { + for (AbstractSlotTextAdder adder : adders) { if (!adder.isEnabled()) continue; - if (adder.titlePattern == null || adder.titlePattern.matcher(title).find()) { + if (adder.test(screen)) { currentScreenAdders.add(adder); } } @@ -68,7 +67,7 @@ public class SlotTextManager { @NotNull public static List<SlotText> getText(Slot slot) { if (currentScreenAdders.isEmpty()) return List.of(); - for (SlotTextAdder adder : currentScreenAdders) { + for (AbstractSlotTextAdder adder : currentScreenAdders) { List<SlotText> text = adder.getText(slot); if (!text.isEmpty()) return text; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java index f3395def..84571149 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java @@ -1,46 +1,57 @@ package de.hysky.skyblocker.skyblock.item.tooltip; -import de.hysky.skyblocker.utils.render.gui.AbstractContainerMatcher; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.slot.Slot; -import net.minecraft.text.Text; +import de.hysky.skyblocker.utils.container.RegexContainerMatcher; +import de.hysky.skyblocker.utils.container.AbstractTooltipAdder; import org.intellij.lang.annotations.Language; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; -import java.util.List; import java.util.regex.Pattern; /** + * Simple implementation of a tooltip adder. * Extend this class and add it to {@link TooltipManager#adders} to add additional text to tooltips. */ -public abstract class TooltipAdder extends AbstractContainerMatcher { +public abstract class TooltipAdder extends RegexContainerMatcher implements AbstractTooltipAdder { /** * The priority of this adder. Lower priority means it will be applied first. - * @apiNote Consider taking this value on your class' constructor and setting it from {@link TooltipManager#adders} to make it easy to read and maintain. + * @apiNote Consider adding this as a parameter to your class' constructor and + * setting it from {@link TooltipManager#adders} to make it easy to read and maintain. */ - public final int priority; + private final int priority; - protected TooltipAdder(@Language("RegExp") String titlePattern, int priority) { + /** + * Utility constructor that will compile the given string into a pattern. + * + * @see #TooltipAdder(Pattern, int) + */ + protected TooltipAdder(@NotNull @Language("RegExp") String titlePattern, int priority) { super(titlePattern); this.priority = priority; } - protected TooltipAdder(Pattern titlePattern, int priority) { + /** + * Creates a TooltipAdder that will be applied to screens with titles that match the given pattern. + * + * @param titlePattern The pattern to match the screen title against. + * @param priority The priority of this adder. Lower priority means it will be applied first. + */ + protected TooltipAdder(@NotNull Pattern titlePattern, int priority) { super(titlePattern); this.priority = priority; } /** * Creates a TooltipAdder that will be applied to all screens. + * + * @param priority The priority of this adder. Lower priority means it will be applied first. */ protected TooltipAdder(int priority) { super(); this.priority = priority; } - /** - * @implNote The first element of the lines list holds the item's display name, - * as it's a list of all lines that will be displayed in the tooltip. - */ - public abstract void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines); + @Override + public int getPriority() { + return priority; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java index 46f4cb58..d8327383 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java @@ -118,16 +118,6 @@ public enum TooltipInfoType implements Runnable { } /** - * Checks if the tooltip is enabled and the data has the given member name and sends a warning message if data is null. - * - * @param memberName the member name to check - * @return whether the tooltip is enabled and the data has the given member name or not - */ - public boolean isTooltipEnabledAndHasOrNullWarning(String memberName) { - return isTooltipEnabled() && hasOrNullWarning(memberName); - } - - /** * Downloads the data if it is enabled. * * @param futureList the list to add the future to diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java index c3399b58..2c81cff4 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java @@ -6,10 +6,10 @@ import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.item.tooltip.adders.*; import de.hysky.skyblocker.skyblock.item.tooltip.adders.CraftPriceTooltip; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.container.AbstractTooltipAdder; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; @@ -21,7 +21,7 @@ import java.util.Comparator; import java.util.List; public class TooltipManager { - private static final TooltipAdder[] adders = new TooltipAdder[]{ + private static final AbstractTooltipAdder[] adders = new AbstractTooltipAdder[]{ new LineSmoothener(), // Applies before anything else new SupercraftReminder(), new ChocolateFactorySolver.Tooltip(), @@ -39,7 +39,7 @@ public class TooltipManager { new ColorTooltip(11), new AccessoryTooltip(12), }; - private static final ArrayList<TooltipAdder> currentScreenAdders = new ArrayList<>(); + private static final ArrayList<AbstractTooltipAdder> currentScreenAdders = new ArrayList<>(); private TooltipManager() { } @@ -53,20 +53,21 @@ public class TooltipManager { } }); ScreenEvents.AFTER_INIT.register((client, screen, width, height) -> { - onScreenChange(screen); + if (screen instanceof HandledScreen<?> handledScreen) { + onScreenChange(handledScreen); + } ScreenEvents.remove(screen).register(ignored -> currentScreenAdders.clear()); }); } - private static void onScreenChange(Screen screen) { - final String title = screen.getTitle().getString(); + private static void onScreenChange(HandledScreen<?> screen) { currentScreenAdders.clear(); - for (TooltipAdder adder : adders) { - if (adder.titlePattern == null || adder.titlePattern.matcher(title).find()) { + for (AbstractTooltipAdder adder : adders) { + if (adder.isEnabled() && adder.test(screen)) { currentScreenAdders.add(adder); } } - currentScreenAdders.sort(Comparator.comparingInt(adder -> adder.priority)); + currentScreenAdders.sort(Comparator.comparingInt(AbstractTooltipAdder::getPriority)); } /** @@ -84,7 +85,7 @@ public class TooltipManager { @Deprecated public static List<Text> addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { if (!Utils.isOnSkyblock()) return lines; - for (TooltipAdder adder : currentScreenAdders) { + for (AbstractTooltipAdder adder : currentScreenAdders) { adder.addToTooltip(focusedSlot, stack, lines); } return lines; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AccessoryTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AccessoryTooltip.java index caed0e0e..0aeb1cc6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AccessoryTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AccessoryTooltip.java @@ -21,7 +21,7 @@ public class AccessoryTooltip extends TooltipAdder { @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { final String internalID = stack.getSkyblockId(); - if (TooltipInfoType.ACCESSORIES.isTooltipEnabledAndHasOrNullWarning(internalID)) { + if (TooltipInfoType.ACCESSORIES.hasOrNullWarning(internalID)) { Pair<AccessoriesHelper.AccessoryReport, String> report = AccessoriesHelper.calculateReport4Accessory(internalID); if (report.left() != AccessoriesHelper.AccessoryReport.INELIGIBLE) { @@ -42,4 +42,9 @@ public class AccessoryTooltip extends TooltipAdder { } } } + + @Override + public boolean isEnabled() { + return TooltipInfoType.ACCESSORIES.isTooltipEnabled(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AvgBinTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AvgBinTooltip.java index d7a56b95..1f0180ff 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AvgBinTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/AvgBinTooltip.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.skyblock.item.tooltip.adders; -import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.GeneralConfig; import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip; import de.hysky.skyblocker.skyblock.item.tooltip.TooltipAdder; @@ -24,40 +23,44 @@ public class AvgBinTooltip extends TooltipAdder { String internalID = stack.getSkyblockId(); if (neuName == null || internalID == null) return; - if (SkyblockerConfigManager.get().general.itemTooltip.enableAvgBIN) { - if (TooltipInfoType.ONE_DAY_AVERAGE.getData() == null || TooltipInfoType.THREE_DAY_AVERAGE.getData() == null) { - ItemTooltip.nullWarning(); - } else { + if (TooltipInfoType.ONE_DAY_AVERAGE.getData() == null || TooltipInfoType.THREE_DAY_AVERAGE.getData() == null) { + ItemTooltip.nullWarning(); + } else { /* We are skipping check average prices for potions, runes and enchanted books because there is no data for their in API. */ - if (!neuName.isEmpty() && LBinTooltip.lbinExist) { - GeneralConfig.Average type = ItemTooltip.config.avg; + if (!neuName.isEmpty() && LBinTooltip.lbinExist) { + GeneralConfig.Average type = ItemTooltip.config.avg; - // "No data" line because of API not keeping old data, it causes NullPointerException - if (type == GeneralConfig.Average.ONE_DAY || type == GeneralConfig.Average.BOTH) { - lines.add( - Text.literal(String.format("%-19s", "1 Day Avg. Price:")) - .formatted(Formatting.GOLD) - .append(TooltipInfoType.ONE_DAY_AVERAGE.getData().get(neuName) == null - ? Text.literal("No data").formatted(Formatting.RED) - : ItemTooltip.getCoinsMessage(TooltipInfoType.ONE_DAY_AVERAGE.getData().get(neuName).getAsDouble(), stack.getCount()) - ) - ); - } - if (type == GeneralConfig.Average.THREE_DAY || type == GeneralConfig.Average.BOTH) { - lines.add( - Text.literal(String.format("%-19s", "3 Day Avg. Price:")) - .formatted(Formatting.GOLD) - .append(TooltipInfoType.THREE_DAY_AVERAGE.getData().get(neuName) == null - ? Text.literal("No data").formatted(Formatting.RED) - : ItemTooltip.getCoinsMessage(TooltipInfoType.THREE_DAY_AVERAGE.getData().get(neuName).getAsDouble(), stack.getCount()) - ) - ); - } + // "No data" line because of API not keeping old data, it causes NullPointerException + if (type == GeneralConfig.Average.ONE_DAY || type == GeneralConfig.Average.BOTH) { + lines.add( + Text.literal(String.format("%-19s", "1 Day Avg. Price:")) + .formatted(Formatting.GOLD) + .append(TooltipInfoType.ONE_DAY_AVERAGE.getData().get(neuName) == null + ? Text.literal("No data").formatted(Formatting.RED) + : ItemTooltip.getCoinsMessage(TooltipInfoType.ONE_DAY_AVERAGE.getData().get(neuName).getAsDouble(), stack.getCount()) + ) + ); + } + if (type == GeneralConfig.Average.THREE_DAY || type == GeneralConfig.Average.BOTH) { + lines.add( + Text.literal(String.format("%-19s", "3 Day Avg. Price:")) + .formatted(Formatting.GOLD) + .append(TooltipInfoType.THREE_DAY_AVERAGE.getData().get(neuName) == null + ? Text.literal("No data").formatted(Formatting.RED) + : ItemTooltip.getCoinsMessage(TooltipInfoType.THREE_DAY_AVERAGE.getData().get(neuName).getAsDouble(), stack.getCount()) + ) + ); } } } } + + @Override + public boolean isEnabled() { + //Both 1 day and 3 day averages use the same config option, so we only need to check one + return TooltipInfoType.THREE_DAY_AVERAGE.isTooltipEnabled(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/BazaarPriceTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/BazaarPriceTooltip.java index d2fa563b..36023182 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/BazaarPriceTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/BazaarPriceTooltip.java @@ -30,7 +30,7 @@ public class BazaarPriceTooltip extends TooltipAdder { if (name.startsWith("ISSHINY_")) name = "SHINY_" + internalID; - if (TooltipInfoType.BAZAAR.isTooltipEnabledAndHasOrNullWarning(name)) { + if (TooltipInfoType.BAZAAR.hasOrNullWarning(name)) { int amount; if (lines.get(1).getString().endsWith("Sack")) { //The amount is in the 2nd sibling of the 3rd line of the lore. here V @@ -54,4 +54,9 @@ public class BazaarPriceTooltip extends TooltipAdder { bazaarExist = true; } } + + @Override + public boolean isEnabled() { + return TooltipInfoType.BAZAAR.isTooltipEnabled(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ColorTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ColorTooltip.java index 7546d37a..d66ca378 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ColorTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ColorTooltip.java @@ -26,9 +26,14 @@ public class ColorTooltip extends TooltipAdder { } @Override + public boolean isEnabled() { + return TooltipInfoType.COLOR.isTooltipEnabled(); + } + + @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { final String internalID = stack.getSkyblockId(); - if (TooltipInfoType.COLOR.isTooltipEnabledAndHasOrNullWarning(internalID) && stack.contains(DataComponentTypes.DYED_COLOR)) { + if (TooltipInfoType.COLOR.hasOrNullWarning(internalID) && stack.contains(DataComponentTypes.DYED_COLOR)) { //DyedColorComponent#getColor can be ARGB so we mask out the alpha bits int dyeColor = stack.get(DataComponentTypes.DYED_COLOR).rgb() & 0x00FFFFFF; String colorHex = String.format("%06X", dyeColor); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DungeonQualityTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DungeonQualityTooltip.java index 0b1d993d..4cd1d2b5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DungeonQualityTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DungeonQualityTooltip.java @@ -19,7 +19,6 @@ public class DungeonQualityTooltip extends TooltipAdder { @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { - if (!SkyblockerConfigManager.get().general.itemTooltip.dungeonQuality) return; NbtCompound customData = ItemUtils.getCustomData(stack); if (customData == null || !customData.contains("baseStatBoostPercentage")) return; int baseStatBoostPercentage = customData.getInt("baseStatBoostPercentage"); @@ -40,7 +39,7 @@ public class DungeonQualityTooltip extends TooltipAdder { } } - final String getItemTierFloor(int tier) { + private String getItemTierFloor(int tier) { return switch (tier) { case 0 -> "E"; case 1 -> "F1"; @@ -56,4 +55,9 @@ public class DungeonQualityTooltip extends TooltipAdder { default -> "Unknown"; }; } + + @Override + public boolean isEnabled() { + return SkyblockerConfigManager.get().general.itemTooltip.dungeonQuality; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LBinTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LBinTooltip.java index e6930c32..b2186203 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LBinTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LBinTooltip.java @@ -19,6 +19,11 @@ public class LBinTooltip extends TooltipAdder { } @Override + public boolean isEnabled() { + return TooltipInfoType.LOWEST_BINS.isTooltipEnabled(); + } + + @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { lbinExist = false; final String internalID = stack.getSkyblockId(); @@ -30,7 +35,7 @@ public class LBinTooltip extends TooltipAdder { // bazaarOpened & bazaarExist check for lbin, because Skytils keeps some bazaar item data in lbin api - if (TooltipInfoType.LOWEST_BINS.isTooltipEnabledAndHasOrNullWarning(name) && !BazaarPriceTooltip.bazaarExist) { + if (TooltipInfoType.LOWEST_BINS.hasOrNullWarning(name) && !BazaarPriceTooltip.bazaarExist) { lines.add(Text.literal(String.format("%-19s", "Lowest BIN Price:")) .formatted(Formatting.GOLD) .append(ItemTooltip.getCoinsMessage(TooltipInfoType.LOWEST_BINS.getData().get(name).getAsDouble(), stack.getCount()))); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LineSmoothener.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LineSmoothener.java index 0e997834..c459f76b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LineSmoothener.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/LineSmoothener.java @@ -17,6 +17,11 @@ public class LineSmoothener extends TooltipAdder { return Text.literal(" ").formatted(Formatting.DARK_GRAY, Formatting.STRIKETHROUGH, Formatting.BOLD); } + @Override + public boolean isEnabled() { + return true; + } + public LineSmoothener() { super(Integer.MIN_VALUE); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MotesTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MotesTooltip.java index a0aa8d94..6a612594 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MotesTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MotesTooltip.java @@ -21,13 +21,18 @@ public class MotesTooltip extends TooltipAdder { @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { final String internalID = stack.getSkyblockId(); - if (internalID != null && TooltipInfoType.MOTES.isTooltipEnabledAndHasOrNullWarning(internalID)) { + if (internalID != null && TooltipInfoType.MOTES.hasOrNullWarning(internalID)) { lines.add(Text.literal(String.format("%-20s", "Motes Price:")) .formatted(Formatting.LIGHT_PURPLE) .append(getMotesMessage(TooltipInfoType.MOTES.getData().get(internalID).getAsInt(), stack.getCount()))); } } + @Override + public boolean isEnabled() { + return TooltipInfoType.MOTES.isTooltipEnabled(); + } + private static Text getMotesMessage(int price, int count) { float motesMultiplier = SkyblockerConfigManager.get().otherLocations.rift.mcGrubberStacks * 0.05f + 1; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MuseumTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MuseumTooltip.java index 5c21d2df..e6e06064 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MuseumTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/MuseumTooltip.java @@ -19,9 +19,14 @@ public class MuseumTooltip extends TooltipAdder { } @Override + public boolean isEnabled() { + return TooltipInfoType.MOTES.isTooltipEnabled(); + } + + @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { final String internalID = stack.getSkyblockId(); - if (TooltipInfoType.MUSEUM.isTooltipEnabledAndHasOrNullWarning(internalID)) { + if (TooltipInfoType.MUSEUM.hasOrNullWarning(internalID)) { String itemCategory = TooltipInfoType.MUSEUM.getData().get(internalID).getAsString(); String format = switch (itemCategory) { case "Weapons" -> "%-18s"; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/NpcPriceTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/NpcPriceTooltip.java index d556c9b2..fcdd15e6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/NpcPriceTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/NpcPriceTooltip.java @@ -18,9 +18,14 @@ public class NpcPriceTooltip extends TooltipAdder { } @Override + public boolean isEnabled() { + return TooltipInfoType.NPC.isTooltipEnabled(); + } + + @Override public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { final String internalID = stack.getSkyblockId(); - if (internalID != null && TooltipInfoType.NPC.isTooltipEnabledAndHasOrNullWarning(internalID)) { + if (internalID != null && TooltipInfoType.NPC.hasOrNullWarning(internalID)) { int amount; if (lines.get(1).getString().endsWith("Sack")) { //The amount is in the 2nd sibling of the 3rd line of the lore. here V diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ObtainedDateTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ObtainedDateTooltip.java index 9f405c58..fc3ac28d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ObtainedDateTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/ObtainedDateTooltip.java @@ -27,15 +27,17 @@ public class ObtainedDateTooltip extends TooltipAdder { } @Override - public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { - if (TooltipInfoType.OBTAINED.isTooltipEnabled()) { - String timestamp = getTimestamp(stack); + public boolean isEnabled() { + return TooltipInfoType.OBTAINED.isTooltipEnabled(); + } - if (!timestamp.isEmpty()) { - lines.add(Text.empty() - .append(Text.literal(String.format("%-21s", "Obtained: ")).formatted(Formatting.LIGHT_PURPLE)) - .append(Text.literal(timestamp).formatted(Formatting.RED))); - } + @Override + public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { + String timestamp = getTimestamp(stack); + if (!timestamp.isEmpty()) { + lines.add(Text.empty() + .append(Text.literal(String.format("%-21s", "Obtained: ")).formatted(Formatting.LIGHT_PURPLE)) + .append(Text.literal(timestamp).formatted(Formatting.RED))); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/SupercraftReminder.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/SupercraftReminder.java index 47d2bd48..767832c0 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/SupercraftReminder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/SupercraftReminder.java @@ -29,4 +29,9 @@ public class SupercraftReminder extends TooltipAdder { if (lines.get(lines.size() - 2).getString().equals("Recipe not unlocked!")) index--; //Place it right below the "Right-Click to set amount" line lines.add(index, Text.literal("Shift-Click to maximize the amount!").formatted(Formatting.GOLD)); } + + @Override + public boolean isEnabled() { + return true; + } } diff --git a/src/main/java/de/hysky/skyblocker/utils/container/AbstractContainerMatcher.java b/src/main/java/de/hysky/skyblocker/utils/container/AbstractContainerMatcher.java new file mode 100644 index 00000000..5509b9a4 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/AbstractContainerMatcher.java @@ -0,0 +1,17 @@ +package de.hysky.skyblocker.utils.container; + +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import org.jetbrains.annotations.NotNull; + +public interface AbstractContainerMatcher { + /** + * Tests if the given screen should be handled by this matcher. + * @return {@code true} if this matcher should apply to the given screen, {@code false} otherwise + */ + boolean test(@NotNull HandledScreen<?> screen); + + /** + * @return {@code true} if this matcher is enabled, {@code false} otherwise + */ + boolean isEnabled(); +} diff --git a/src/main/java/de/hysky/skyblocker/utils/container/AbstractContainerSolver.java b/src/main/java/de/hysky/skyblocker/utils/container/AbstractContainerSolver.java new file mode 100644 index 00000000..38bc32dd --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/AbstractContainerSolver.java @@ -0,0 +1,37 @@ +package de.hysky.skyblocker.utils.container; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.render.gui.ColorHighlight; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.item.ItemStack; + +import java.util.List; + +public interface AbstractContainerSolver extends AbstractContainerMatcher { + + List<ColorHighlight> getColors(Int2ObjectMap<ItemStack> slots); + + default void start(GenericContainerScreen screen) {} + + default void reset() {} + + default boolean onClickSlot(int slot, ItemStack stack, int screenId) { + return false; + } + + static void markHighlightsDirty() { + SkyblockerMod.getInstance().containerSolverManager.markDirty(); + } + + static void trimEdges(Int2ObjectMap<ItemStack> slots, int rows) { + for (int i = 0; i < rows; i++) { + slots.remove(9 * i); + slots.remove(9 * i + 8); + } + for (int i = 1; i < 8; i++) { + slots.remove(i); + slots.remove((rows - 1) * 9 + i); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/container/AbstractSlotTextAdder.java b/src/main/java/de/hysky/skyblocker/utils/container/AbstractSlotTextAdder.java new file mode 100644 index 00000000..4034e88d --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/AbstractSlotTextAdder.java @@ -0,0 +1,21 @@ +package de.hysky.skyblocker.utils.container; + +import de.hysky.skyblocker.skyblock.item.slottext.SlotText; +import net.minecraft.screen.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface AbstractSlotTextAdder extends AbstractContainerMatcher { + + /** + * This method will be called for each rendered slot. Consider using a switch statement on {@link Slot#id} if you wish to add different text to different slots. + * + * @return A list of positioned text to be rendered. Return {@link List#of()} if no text should be rendered. + * @implNote By minecraft's design, scaled text inexplicably moves around. + * It's also not anti-aliased, so it looks horribly jagged and unreadable when scaled down too much. + * So, limit your text to 3 characters (or roughly less than 20 width) if you want it to not look horrible. + */ + @NotNull + List<SlotText> getText(Slot slot); +} diff --git a/src/main/java/de/hysky/skyblocker/utils/container/AbstractTooltipAdder.java b/src/main/java/de/hysky/skyblocker/utils/container/AbstractTooltipAdder.java new file mode 100644 index 00000000..3cc84f35 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/AbstractTooltipAdder.java @@ -0,0 +1,18 @@ +package de.hysky.skyblocker.utils.container; + +import net.minecraft.item.ItemStack; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public interface AbstractTooltipAdder extends AbstractContainerMatcher { + /** + * @implNote The first element of the lines list holds the item's display name, + * as it's a list of all lines that will be displayed in the tooltip. + */ + void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines); + + int getPriority(); +} diff --git a/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolver.java b/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolver.java new file mode 100644 index 00000000..6d3240ea --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolver.java @@ -0,0 +1,38 @@ +package de.hysky.skyblocker.utils.container; + +import org.intellij.lang.annotations.Language; +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +/** + * Simple implementation of a container solver. Extend this class to add a new gui solver, + * like terminal solvers or experiment solvers and add it to {@link ContainerSolverManager#solvers}. + */ +public abstract class ContainerSolver extends RegexContainerMatcher implements AbstractContainerSolver { + /** + * Utility constructor that will compile the given string into a pattern. + * + * @see #ContainerSolver(Pattern) + */ + protected ContainerSolver(@NotNull @Language("RegExp") String titlePattern) { + super(titlePattern); + } + + /** + * Creates a ContainerSolver that will be applied to screens with titles that match the given pattern. + * + * @param titlePattern The pattern to match the screen title against. + */ + protected ContainerSolver(@NotNull Pattern titlePattern) { + super(titlePattern); + } + + // A container solver that applies to every screen doesn't make sense, + // so we don't provide a constructor for that and force getTitlePattern to be @NotNull + @Override + public @NotNull Pattern getTitlePattern() { + assert super.getTitlePattern() != null; + return super.getTitlePattern(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java b/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java new file mode 100644 index 00000000..77833a67 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java @@ -0,0 +1,150 @@ +package de.hysky.skyblocker.utils.container; + +import com.mojang.blaze3d.systems.RenderSystem; +import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; +import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakeBagHelper; +import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakesHelper; +import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; +import de.hysky.skyblocker.skyblock.dungeon.CroesusHelper; +import de.hysky.skyblocker.skyblock.dungeon.CroesusProfit; +import de.hysky.skyblocker.skyblock.dungeon.terminal.ColorTerminal; +import de.hysky.skyblocker.skyblock.dungeon.terminal.LightsOnTerminal; +import de.hysky.skyblocker.skyblock.dungeon.terminal.OrderTerminal; +import de.hysky.skyblocker.skyblock.dungeon.terminal.StartsWithTerminal; +import de.hysky.skyblocker.skyblock.experiment.ChronomatronSolver; +import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver; +import de.hysky.skyblocker.skyblock.experiment.UltrasequencerSolver; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.gui.ColorHighlight; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Manager class for {@link ContainerSolver}s like terminal solvers and experiment solvers. To add a new gui solver, extend {@link ContainerSolver} and register it in {@link #ContainerSolverManager()}. + */ +public class ContainerSolverManager { + private final AbstractContainerSolver[] solvers; + private AbstractContainerSolver currentSolver = null; + private List<ColorHighlight> highlights; + /** + * Useful for keeping track of a solver's state in a Screen instance, such as if Hypixel closes & reopens a screen after every click (as they do with terminals). + */ + private int screenId = 0; + + public ContainerSolverManager() { + solvers = new AbstractContainerSolver[]{ + new ColorTerminal(), + new OrderTerminal(), + new StartsWithTerminal(), + new LightsOnTerminal(), + new CroesusHelper(), + new CroesusProfit(), + new ChronomatronSolver(), + new SuperpairsSolver(), + UltrasequencerSolver.INSTANCE, + new NewYearCakeBagHelper(), + NewYearCakesHelper.INSTANCE, + new ChocolateFactorySolver() + }; + } + + public AbstractContainerSolver getCurrentSolver() { + return currentSolver; + } + + public void init() { + ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> { + if (Utils.isOnSkyblock() && screen instanceof GenericContainerScreen genericContainerScreen) { + ScreenEvents.afterRender(screen).register((screen1, context, mouseX, mouseY, delta) -> { + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(((HandledScreenAccessor) genericContainerScreen).getX(), ((HandledScreenAccessor) genericContainerScreen).getY(), 300); + onDraw(context, genericContainerScreen.getScreenHandler().slots.subList(0, genericContainerScreen.getScreenHandler().getRows() * 9)); + matrices.pop(); + }); + ScreenEvents.remove(screen).register(screen1 -> clearScreen()); + onSetScreen(genericContainerScreen); + } else { + clearScreen(); + } + }); + } + + public void onSetScreen(@NotNull GenericContainerScreen screen) { + String screenName = screen.getTitle().getString(); + for (AbstractContainerSolver solver : solvers) { + if (solver.isEnabled()) { + if (solver instanceof ContainerSolver containerSolver && containerSolver.test(screenName)) { + ++screenId; + currentSolver = containerSolver; + currentSolver.start(screen); + markDirty(); + + return; + } else if (solver.test(screen)) { + ++screenId; + currentSolver = solver; + currentSolver.start(screen); + markDirty(); + + return; + } + } + } + clearScreen(); + } + + public void clearScreen() { + if (currentSolver != null) { + currentSolver.reset(); + currentSolver = null; + } + } + + public void markDirty() { + highlights = null; + } + + /** + * @return Whether the click should be disallowed. + */ + public boolean onSlotClick(int slot, ItemStack stack) { + if (currentSolver != null) { + return currentSolver.onClickSlot(slot, stack, screenId); + } + + return false; + } + + public void onDraw(DrawContext context, List<Slot> slots) { + if (currentSolver == null) + return; + if (highlights == null) + highlights = currentSolver.getColors(slotMap(slots)); + RenderSystem.enableDepthTest(); + RenderSystem.colorMask(true, true, true, false); + for (ColorHighlight highlight : highlights) { + Slot slot = slots.get(highlight.slot()); + int color = highlight.color(); + context.fill(slot.x, slot.y, slot.x + 16, slot.y + 16, color); + } + RenderSystem.colorMask(true, true, true, true); + } + + private Int2ObjectMap<ItemStack> slotMap(List<Slot> slots) { + Int2ObjectMap<ItemStack> slotMap = new Int2ObjectRBTreeMap<>(); + for (int i = 0; i < slots.size(); i++) { + slotMap.put(i, slots.get(i).getStack()); + } + return slotMap; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/container/RegexContainerMatcher.java b/src/main/java/de/hysky/skyblocker/utils/container/RegexContainerMatcher.java new file mode 100644 index 00000000..a8a8e3c2 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/container/RegexContainerMatcher.java @@ -0,0 +1,68 @@ +package de.hysky.skyblocker.utils.container; + +import de.hysky.skyblocker.skyblock.ChestValue; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import org.intellij.lang.annotations.Language; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A regex implementation of {@link AbstractContainerMatcher} that matches the title of the screen. + */ +public abstract class RegexContainerMatcher implements AbstractContainerMatcher { + /** + * The title of the screen must match this pattern for this to be applied. Null means it will be applied to all screens. + * + * @implNote Don't end your regex with a {@code $} as {@link ChestValue} appends text to the end of the title, + * so the regex will stop matching if the player uses chest value. + */ + @Nullable + public final Pattern titlePattern; + + @Nullable + public String[] groups = null; + + @Override + public boolean test(@NotNull HandledScreen<?> screen) { + return test(screen.getTitle().getString()); + } + + public boolean test(@NotNull String title) { + if (titlePattern == null) return true; + Matcher matcher = titlePattern.matcher(title); + if (matcher.matches()) { + int groupCount = matcher.groupCount(); + if (groupCount >= 1) { //No need to initialize the array if there are no groups + groups = new String[groupCount]; + for (int i = 0; i < groupCount; i++) { + groups[i] = matcher.group(i + 1); // +1 because first group is the whole match, which is useless + } + } + return true; + } + return false; + } + + protected RegexContainerMatcher() { + this((Pattern) null); + } + + protected RegexContainerMatcher(@NotNull @Language("RegExp") String titlePattern) { + this(Pattern.compile(titlePattern)); + } + + protected RegexContainerMatcher(@Nullable Pattern titlePattern) { + this.titlePattern = titlePattern; + } + + public @Nullable Pattern getTitlePattern() { + return titlePattern; + } + + public final @Nullable String[] getGroups() { + return groups; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractContainerMatcher.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractContainerMatcher.java deleted file mode 100644 index bf255218..00000000 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractContainerMatcher.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.hysky.skyblocker.utils.render.gui; - -import de.hysky.skyblocker.skyblock.ChestValue; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.regex.Pattern; - -public abstract class AbstractContainerMatcher { - /** - * The title of the screen must match this pattern for this to be applied. Null means it will be applied to all screens. - * @implNote Don't end your regex with a {@code $} as {@link ChestValue} appends text to the end of the title, - * so the regex will stop matching if the player uses chest value. - */ - @Nullable - public final Pattern titlePattern; - - protected AbstractContainerMatcher() { - this((Pattern) null); - } - - protected AbstractContainerMatcher(@NotNull String titlePattern) { - this(Pattern.compile(titlePattern)); - } - - protected AbstractContainerMatcher(@Nullable Pattern titlePattern) { - this.titlePattern = titlePattern; - } -} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java index 9a9d0907..e69de29b 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java @@ -1,52 +0,0 @@ -package de.hysky.skyblocker.utils.render.gui; - -import de.hysky.skyblocker.SkyblockerMod; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; -import net.minecraft.item.ItemStack; -import org.intellij.lang.annotations.Language; - -import java.util.List; -import java.util.regex.Pattern; - -/** - * Abstract class for gui solvers. Extend this class to add a new gui solver, like terminal solvers or experiment solvers. - */ -public abstract class ContainerSolver extends AbstractContainerMatcher { - protected ContainerSolver(@Language("RegExp") String titlePattern) { - super(titlePattern); - } - - protected abstract boolean isEnabled(); - - public final Pattern getName() { - return titlePattern; - } - - protected void start(GenericContainerScreen screen) { - } - - protected void reset() { - } - - protected void markHighlightsDirty() { - SkyblockerMod.getInstance().containerSolverManager.markDirty(); - } - - protected boolean onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) { - return false; - } - - protected abstract List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots); - - protected final void trimEdges(Int2ObjectMap<ItemStack> slots, int rows) { - for (int i = 0; i < rows; i++) { - slots.remove(9 * i); - slots.remove(9 * i + 8); - } - for (int i = 1; i < 8; i++) { - slots.remove(i); - slots.remove((rows - 1) * 9 + i); - } - } -} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java index 79cc78f5..e69de29b 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java @@ -1,157 +0,0 @@ -package de.hysky.skyblocker.utils.render.gui; - -import com.mojang.blaze3d.systems.RenderSystem; -import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; -import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakeBagHelper; -import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakesHelper; -import de.hysky.skyblocker.skyblock.bazaar.ReorderHelper; -import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; -import de.hysky.skyblocker.skyblock.dungeon.CroesusHelper; -import de.hysky.skyblocker.skyblock.dungeon.CroesusProfit; -import de.hysky.skyblocker.skyblock.dungeon.terminal.ColorTerminal; -import de.hysky.skyblocker.skyblock.dungeon.terminal.LightsOnTerminal; -import de.hysky.skyblocker.skyblock.dungeon.terminal.OrderTerminal; -import de.hysky.skyblocker.skyblock.dungeon.terminal.StartsWithTerminal; -import de.hysky.skyblocker.skyblock.dwarven.CommissionHighlight; -import de.hysky.skyblocker.skyblock.experiment.ChronomatronSolver; -import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver; -import de.hysky.skyblocker.skyblock.experiment.UltrasequencerSolver; -import de.hysky.skyblocker.utils.Utils; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap; -import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.slot.Slot; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Manager class for {@link ContainerSolver}s like terminal solvers and experiment solvers. To add a new gui solver, extend {@link ContainerSolver} and register it in {@link #ContainerSolverManager()}. - */ -public class ContainerSolverManager { - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(""); - private final ContainerSolver[] solvers; - private ContainerSolver currentSolver = null; - private String[] groups; - private List<ColorHighlight> highlights; - /** - * Useful for keeping track of a solver's state in a Screen instance, such as if Hypixel closes & reopens a screen after every click (as they do with terminals). - */ - private int screenId = 0; - - public ContainerSolverManager() { - solvers = new ContainerSolver[]{ - new ColorTerminal(), - new OrderTerminal(), - new StartsWithTerminal(), - new LightsOnTerminal(), - new CroesusHelper(), - new CommissionHighlight(), - new CroesusProfit(), - new ChronomatronSolver(), - new SuperpairsSolver(), - UltrasequencerSolver.INSTANCE, - new NewYearCakeBagHelper(), - NewYearCakesHelper.INSTANCE, - new ChocolateFactorySolver(), - new ReorderHelper() - }; - } - - public ContainerSolver getCurrentSolver() { - return currentSolver; - } - - public void init() { - ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> { - if (Utils.isOnSkyblock() && screen instanceof GenericContainerScreen genericContainerScreen) { - ScreenEvents.afterRender(screen).register((screen1, context, mouseX, mouseY, delta) -> { - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(((HandledScreenAccessor) genericContainerScreen).getX(), ((HandledScreenAccessor) genericContainerScreen).getY(), 300); - onDraw(context, genericContainerScreen.getScreenHandler().slots.subList(0, genericContainerScreen.getScreenHandler().getRows() * 9)); - matrices.pop(); - }); - ScreenEvents.remove(screen).register(screen1 -> clearScreen()); - onSetScreen(genericContainerScreen); - } else { - clearScreen(); - } - }); - } - - public void onSetScreen(@NotNull GenericContainerScreen screen) { - String screenName = screen.getTitle().getString(); - Matcher matcher = PLACEHOLDER_PATTERN.matcher(screenName); - for (ContainerSolver solver : solvers) { - if (solver.isEnabled()) { - matcher.usePattern(solver.getName()); - matcher.reset(); - if (matcher.matches()) { - ++screenId; - currentSolver = solver; - groups = new String[matcher.groupCount()]; - for (int i = 0; i < groups.length; i++) { - groups[i] = matcher.group(i + 1); - } - currentSolver.start(screen); - markDirty(); - - return; - } - } - } - clearScreen(); - } - - public void clearScreen() { - if (currentSolver != null) { - currentSolver.reset(); - currentSolver = null; - } - } - - public void markDirty() { - highlights = null; - } - - /** - * @return Whether the click should be disallowed. - */ - public boolean onSlotClick(int slot, ItemStack stack) { - if (currentSolver != null) { - return currentSolver.onClickSlot(slot, stack, screenId, groups); - } - - return false; - } - - public void onDraw(DrawContext context, List<Slot> slots) { - if (currentSolver == null) - return; - if (highlights == null) - highlights = currentSolver.getColors(groups, slotMap(slots)); - RenderSystem.enableDepthTest(); - RenderSystem.colorMask(true, true, true, false); - for (ColorHighlight highlight : highlights) { - Slot slot = slots.get(highlight.slot()); - int color = highlight.color(); - context.fill(slot.x, slot.y, slot.x + 16, slot.y + 16, color); - } - RenderSystem.colorMask(true, true, true, true); - } - - private Int2ObjectMap<ItemStack> slotMap(List<Slot> slots) { - Int2ObjectMap<ItemStack> slotMap = new Int2ObjectRBTreeMap<>(); - for (int i = 0; i < slots.size(); i++) { - slotMap.put(i, slots.get(i).getStack()); - } - return slotMap; - } -} |