aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2025-03-12 16:02:07 -0400
committerGitHub <noreply@github.com>2025-03-12 16:02:07 -0400
commita59d65a022fc9baf26b8cd7398a7d7b04041eb06 (patch)
tree0785e93d5bb3b182991928b0c5022066bbb2b014 /src/main/java/de
parentf2dcdb0ce81a36bd2f4e7bcfb16df61d610c6732 (diff)
downloadSkyblocker-a59d65a022fc9baf26b8cd7398a7d7b04041eb06.tar.gz
Skyblocker-a59d65a022fc9baf26b8cd7398a7d7b04041eb06.tar.bz2
Skyblocker-a59d65a022fc9baf26b8cd7398a7d7b04041eb06.zip
Auto Pet support for the Pet Cache (#1207)
Fixes a longstanding gap in the pet cache that has caused some bugs. Fixes #992
Diffstat (limited to 'src/main/java/de')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/PetCache.java87
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java13
2 files changed, 100 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/PetCache.java b/src/main/java/de/hysky/skyblocker/skyblock/PetCache.java
index 603f1017..05824f9d 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/PetCache.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/PetCache.java
@@ -3,16 +3,35 @@ package de.hysky.skyblocker.skyblock;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.skyblock.item.PetInfo;
+import de.hysky.skyblocker.skyblock.item.SkyblockItemRarity;
+import de.hysky.skyblocker.skyblock.itemlist.ItemRepository;
import de.hysky.skyblocker.utils.ItemUtils;
+import de.hysky.skyblocker.utils.RegexUtils;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.profile.ProfiledData;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
+import net.azureaaron.networth.utils.PetConstants;
+import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.NbtComponent;
import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NbtCompound;
import net.minecraft.screen.slot.Slot;
+import net.minecraft.text.OrderedText;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+import org.apache.commons.lang3.mutable.MutableInt;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Path;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Doesn't work with auto pet right now because that's complicated.
@@ -22,6 +41,7 @@ import java.nio.file.Path;
public class PetCache {
private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("pet_cache.json");
private static final ProfiledData<PetInfo> CACHED_PETS = new ProfiledData<>(FILE, PetInfo.CODEC, true, true);
+ private static final Pattern AUTOPET_PATTERN = Pattern.compile("^Autopet equipped your \\[Lvl (?<level>\\d+)\\] (?<name>[A-Za-z ]+)(?: ✦)?! VIEW RULE$");
/**
* Used in case the server lags to prevent the screen tick check from overwriting the clicked pet logic
@@ -54,6 +74,8 @@ public class PetCache {
}
}
});
+ ClientReceiveMessageEvents.GAME.register(PetCache::onMessage);
+ ClientReceiveMessageEvents.GAME_CANCELED.register(PetCache::onMessage);
}
public static void handlePetEquip(Slot slot, int slotId) {
@@ -88,6 +110,71 @@ public class PetCache {
}
}
+ /**
+ * Parses the Auto Pet messages to try and detect the active pet
+ */
+ private static void onMessage(Text text, boolean overlay) {
+ if (!Utils.isOnSkyblock() || overlay) return;
+
+ String stringified = Formatting.strip(text.getString());
+ Matcher matcher = AUTOPET_PATTERN.matcher(stringified);
+
+ if (matcher.matches()) {
+ int level = RegexUtils.parseIntFromMatcher(matcher, "level");
+ String name = matcher.group("name");
+
+ OrderedText ordered = text.asOrderedText();
+ int nameIndex = stringified.indexOf(name);
+ MutableInt codePointIndex = new MutableInt(0);
+ MutableInt color = new MutableInt(-1);
+
+ //The index has nothing to do with the codepoint's position so we must track it ourselves
+ //The visitor automatically folds section symbols into regular Style instances so we don't need to care about those either :)
+ ordered.accept((index, style, codePoint) -> {
+ if (codePointIndex.getValue() == nameIndex) {
+ color.setValue(style.getColor().getRgb());
+
+ return false;
+ }
+
+ codePointIndex.getAndIncrement();
+ return true;
+ });
+
+ SkyblockItemRarity rarity = SkyblockItemRarity.fromColor(color.getValue());
+
+ if (rarity != null) {
+ //This is technically an internal class but I don't feel like copying it out right now and I got no plans to change/remove it :shrug:
+ int petOffset = PetConstants.RARITY_OFFSETS.getOrDefault(rarity.name(), 0);
+ //The list is copied due to a FastUtil bug with sub list iterators
+ IntList petLevels = new IntArrayList(PetConstants.PET_LEVELS.subList(petOffset, petOffset + level - 1));
+ double exp = petLevels.intStream().sum();
+
+ //Find pet in NEU repo
+ ItemStack stack = ItemRepository.getItemsStream()
+ .filter(s -> s.getName().getString().contains("] " + name))
+ .findFirst()
+ .orElse(ItemStack.EMPTY);
+
+ if (!stack.isEmpty()) {
+ //We need to change the item id of the stack in order for the pet info to parse properly cause the id in the custom data is the neu id
+ ItemStack copied = stack.copy();
+ NbtCompound customData = copied.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).copyNbt();
+
+ customData.putString("id", "PET");
+ copied.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(customData));
+
+ //If the pet from the NEU repo is missing the data then try to guess the type
+ String type = !copied.getPetInfo().isEmpty() ? copied.getPetInfo().type() : name.toUpperCase(Locale.ENGLISH).replace(" ", "_");
+ PetInfo petInfo = new PetInfo(type, exp, rarity, Optional.empty(), Optional.empty(), Optional.empty());
+
+ CACHED_PETS.put(petInfo);
+ CACHED_PETS.save();
+ }
+ }
+ }
+ }
+
@Nullable
public static PetInfo getCurrentPet() {
return CACHED_PETS.get();
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
index 9008fb4e..913f7ac9 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
@@ -1,9 +1,14 @@
package de.hysky.skyblocker.skyblock.item;
+import java.util.Arrays;
+
+import org.jetbrains.annotations.Nullable;
+
import com.mojang.serialization.Codec;
import de.hysky.skyblocker.utils.EnumUtils;
import net.minecraft.util.Formatting;
import net.minecraft.util.StringIdentifiable;
+import net.minecraft.util.math.ColorHelper;
public enum SkyblockItemRarity implements StringIdentifiable {
COMMON(Formatting.WHITE),
@@ -44,4 +49,12 @@ public enum SkyblockItemRarity implements StringIdentifiable {
public SkyblockItemRarity next() {
return EnumUtils.cycle(this);
}
+
+ @Nullable
+ public static SkyblockItemRarity fromColor(int color) {
+ return Arrays.stream(SkyblockItemRarity.values())
+ .filter(rarity -> ColorHelper.fromFloats(1f, rarity.r, rarity.g, rarity.b) == ColorHelper.fullAlpha(color))
+ .findFirst()
+ .orElse(null);
+ }
}