aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/hysky')
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/Debug.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java77
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java17
6 files changed, 68 insertions, 65 deletions
diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java
index d9ac668c..038e7a5a 100644
--- a/src/main/java/de/hysky/skyblocker/debug/Debug.java
+++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java
@@ -83,9 +83,9 @@ public class Debug {
Iterable<ItemStack> equippedItems = armorStand.getEquippedItems();
for (ItemStack stack : equippedItems) {
- String texture = ItemUtils.getHeadTexture(stack);
-
- if (!texture.isEmpty()) context.getSource().sendFeedback(Text.of(texture));
+ ItemUtils.getHeadTexture(stack).ifPresent(texture -> {
+ context.getSource().sendFeedback(Text.of(texture));
+ });
}
}
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 a59a5147..94c2b209 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java
@@ -1,23 +1,15 @@
package de.hysky.skyblocker.skyblock.chocolatefactory;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
-import de.hysky.skyblocker.skyblock.experiment.ExperimentSolver;
+import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.render.gui.ColorHighlight;
import de.hysky.skyblocker.utils.render.gui.ContainerSolver;
import it.unimi.dsi.fastutil.ints.*;
-import net.fabricmc.loader.impl.lib.sat4j.minisat.core.Solver;
-import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
-import net.minecraft.component.DataComponentTypes;
-import net.minecraft.component.type.LoreComponent;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
-import net.minecraft.nbt.NbtCompound;
-import net.minecraft.nbt.NbtElement;
-import net.minecraft.nbt.NbtList;
import net.minecraft.text.Text;
-import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
@@ -27,6 +19,7 @@ import java.util.stream.Collectors;
public class ChocolateFactorySolver extends ContainerSolver {
private static final Pattern CPS_PATTERN = Pattern.compile("\\+([\\d,]+) Chocolate per second");
private static final Pattern COST_PATTERN = Pattern.compile("Cost ([\\d,]+) Chocolate");
+ private static final Pattern HIRE_PATTERN = Pattern.compile("(HIRE|PROMOTE) ➜ \\[\\d+] \\S+ *");
public ChocolateFactorySolver() {
super("^Chocolate Factory$");
@@ -42,7 +35,6 @@ public class ChocolateFactorySolver extends ContainerSolver {
markHighlightsDirty(); //Recalculate highlights when the screen is opened, which happens when upgrading rabbits
}
- //Todo: Handle unemployed rabbits as well. They have a different lore format.
@Override
protected List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots) {
Int2DoubleMap cpsIncreaseFactors = new Int2DoubleLinkedOpenHashMap(5); //There are only 5 rabbits on the screen.
@@ -51,7 +43,7 @@ public class ChocolateFactorySolver extends ContainerSolver {
ItemStack item = entry.getValue();
if (item.getItem() != Items.PLAYER_HEAD || item.isEmpty()) continue;
- String lore = getLore(item);
+ String lore = getConcattedLore(item);
if (lore.isBlank()) continue;
OptionalDouble cpsIncreaseFactor = getCPSIncreaseFactor(lore);
@@ -63,15 +55,13 @@ public class ChocolateFactorySolver extends ContainerSolver {
return List.of(ColorHighlight.green(bestSlot.get().getIntKey()));
}
- private String getLore(ItemStack item) {
- LoreComponent lore = item.get(DataComponentTypes.LORE);
- if (lore == null || lore.lines().isEmpty()) return "";
- return lore.lines()
- .stream()
- .map(Text::getString)
- .collect(Collectors.joining(" ")); //Join all lore lines into one string for ease of regexing
-// The space is so that the regex pattern still matches even if the word is split into 2 lines,
-// as normally the line end and line start contain no spaces and would not match the pattern when concatenated
+ private String getConcattedLore(ItemStack item) {
+ return ItemUtils.getLore(item)
+ .stream()
+ .map(Text::getString)
+ .collect(Collectors.joining(" ")); //Join all lore lines into one string for ease of regexing
+// The space is so that the regex pattern still matches even if the word is split into 2 lines,
+// as normally the line end and the line start contain no spaces and would not match the pattern when concatenated
}
/**
@@ -82,15 +72,42 @@ public class ChocolateFactorySolver extends ContainerSolver {
* @return The CPS increase factor of the item, or an empty optional if it couldn't be found
*/
private OptionalDouble getCPSIncreaseFactor(String lore) {
- Matcher cpsMatcher = CPS_PATTERN.matcher(lore);
- if (!cpsMatcher.find()) return OptionalDouble.empty();
- int currentCps = Integer.parseInt(cpsMatcher.group(1).replace(",", ""));
- if (!cpsMatcher.find()) return OptionalDouble.empty(); //If there is no second match, we can't get the CPS increase
- int nextCps = Integer.parseInt(cpsMatcher.group(1).replace(",", ""));
-
- Matcher costMatcher = COST_PATTERN.matcher(lore);
- if (!costMatcher.find(cpsMatcher.end())) return OptionalDouble.empty(); //Cost is always at the end of the string, so we can start check from the end of the last match
- int cost = Integer.parseInt(costMatcher.group(1).replace(",", ""));
- return OptionalDouble.of((nextCps - currentCps) / (double) cost);
+ Matcher hireMatcher = HIRE_PATTERN.matcher(lore);
+ if (!hireMatcher.find()) return OptionalDouble.empty(); //Not a hireable/promotable rabbit. Could be a locked or maxed rabbit.
+
+ switch (hireMatcher.group(1)) {
+ case "HIRE" -> {
+ Matcher cpsMatcher = CPS_PATTERN.matcher(lore);
+ OptionalInt cps = getValueFromMatcher(cpsMatcher, hireMatcher.end()); //Cps line is right after the hire line
+ if (cps.isEmpty()) return OptionalDouble.empty();
+
+ Matcher costMatcher = COST_PATTERN.matcher(lore);
+ OptionalInt cost = getValueFromMatcher(costMatcher, cpsMatcher.end()); //Cost comes after the cps line
+ if (cost.isEmpty()) return OptionalDouble.empty();
+ return OptionalDouble.of(cps.getAsInt() / (double) cost.getAsInt());
+ }
+ case "PROMOTE" -> {
+ Matcher cpsMatcher = CPS_PATTERN.matcher(lore);
+ OptionalInt currentCps = getValueFromMatcher(cpsMatcher); //Current cps is before the hire line
+ if (currentCps.isEmpty()) return OptionalDouble.empty();
+ OptionalInt nextCps = getValueFromMatcher(cpsMatcher, hireMatcher.end()); //Next cps is right after the hire line
+ if (nextCps.isEmpty()) return OptionalDouble.empty();
+
+ Matcher costMatcher = COST_PATTERN.matcher(lore);
+ OptionalInt cost = getValueFromMatcher(costMatcher, cpsMatcher.end()); //Cost comes after the cps line
+ if (cost.isEmpty()) return OptionalDouble.empty();
+ return OptionalDouble.of((nextCps.getAsInt() - currentCps.getAsInt()) / (double) cost.getAsInt());
+ }
+ default -> { return OptionalDouble.empty(); }
+ }
+ }
+
+ private OptionalInt getValueFromMatcher(Matcher matcher) {
+ return getValueFromMatcher(matcher, matcher.hasMatch() ? matcher.end() : 0);
+ }
+
+ private OptionalInt getValueFromMatcher(Matcher matcher, int startingIndex) {
+ if (!matcher.find(startingIndex)) return OptionalInt.empty();
+ return OptionalInt.of(Integer.parseInt(matcher.group(1).replace(",", "")));
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java
index 7f8e9879..ee1d4aa7 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java
@@ -3,6 +3,7 @@ package de.hysky.skyblocker.skyblock.chocolatefactory;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.ColorUtils;
import de.hysky.skyblocker.utils.Constants;
+import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.waypoint.Waypoint;
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
@@ -10,11 +11,9 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.client.MinecraftClient;
-import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.Entity;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
import net.minecraft.text.Text;
import org.apache.commons.lang3.mutable.MutableObject;
import org.slf4j.Logger;
@@ -46,26 +45,14 @@ public class EggFinder {
if (BREAKFAST.egg.getValue() != null && DINNER.egg.getValue() != null && LUNCH.egg.getValue() != null) return; //Don't check for eggs if we already found all of them
if (!(entity instanceof ArmorStandEntity armorStand) || armorStand.hasCustomName() || !armorStand.isInvisible() || !armorStand.shouldHideBasePlate()) return;
for (ItemStack itemStack : armorStand.getArmorItems()) {
- try {
- if (!itemStack.isEmpty() || itemStack.getItem() == Items.PLAYER_HEAD) {
- String texture = itemStack.getComponents()
- .get(DataComponentTypes.PROFILE)
- .properties()
- .get("textures")
- .iterator()
- .next()
- .value();
-
- for (EggType type : EggType.entries) {
- if (texture.equals(type.texture)) {
- handleFoundEgg(armorStand, type);
- return;
- }
+ ItemUtils.getHeadTexture(itemStack).ifPresent(texture -> {
+ for (EggType type : EggType.entries) {
+ if (texture.equals(type.texture)) {
+ handleFoundEgg(armorStand, type);
+ return;
}
}
- } catch (Exception e) {
- //Ignored. This simply exists to make the code cleaner without a bunch of if statements to check the existence of each key.
- }
+ });
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
index d6f9410b..df9a32c6 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
@@ -104,7 +104,7 @@ public class MobGlow {
// eb07594e2df273921a77c101d0bfdfa1115abed5b9b2029eb496ceba9bdbb4b3 is texture id for the nukekubi head,
// compare against it to exclusively find armorstands that are nukekubi heads
// get the texture of the nukekubi head item itself and compare it
- String texture = ItemUtils.getHeadTexture(armorItem);
+ String texture = ItemUtils.getHeadTexture(armorItem).orElse("");
return texture.contains("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWIwNzU5NGUyZGYyNzM5MjFhNzdjMTAxZDBiZmRmYTExMTVhYmVkNWI5YjIwMjllYjQ5NmNlYmE5YmRiYjRiMyJ9fX0=");
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java
index 682933f4..0f349a4f 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java
@@ -94,9 +94,7 @@ public class VisitorHelper {
}
private static @Nullable String getTextureOrNull(ItemStack stack) {
- String texture = ItemUtils.getHeadTexture(stack);
-
- return texture.isEmpty() ? null : texture;
+ return ItemUtils.getHeadTexture(stack).orElse(null);
}
private static void processLore(String visitorName, @Nullable String visitorTexture, List<Text> loreList) {
diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
index 1aa77080..6b850b3b 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
@@ -33,6 +33,7 @@ import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
@@ -202,16 +203,16 @@ public class ItemUtils {
return Codecs.GAME_PROFILE_PROPERTY_MAP.parse(JsonOps.INSTANCE, JsonParser.parseString("[{\"name\":\"textures\",\"value\":\"" + textureValue + "\"}]")).getOrThrow();
}
- public static String getHeadTexture(ItemStack stack) {
- if (!stack.isOf(Items.PLAYER_HEAD) || !stack.contains(DataComponentTypes.PROFILE)) return "";
+ public static Optional<String> getHeadTexture(ItemStack stack) {
+ if (!stack.isOf(Items.PLAYER_HEAD) || !stack.contains(DataComponentTypes.PROFILE)) return Optional.empty();
- ProfileComponent profile = stack.get(DataComponentTypes.PROFILE);
- String texture = profile.properties().get("textures").stream()
- .map(Property::value)
- .findFirst()
- .orElse("");
+ Iterator<Property> iterator = stack.get(DataComponentTypes.PROFILE)
+ .properties()
+ .get("textures")
+ .iterator();
- return texture;
+ if (!iterator.hasNext()) return Optional.empty();
+ return Optional.of(iterator.next().value());
}
public static ItemStack getSkyblockerStack() {