diff options
| author | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2025-03-12 16:02:07 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-12 16:02:07 -0400 |
| commit | a59d65a022fc9baf26b8cd7398a7d7b04041eb06 (patch) | |
| tree | 0785e93d5bb3b182991928b0c5022066bbb2b014 /src/main/java/de | |
| parent | f2dcdb0ce81a36bd2f4e7bcfb16df61d610c6732 (diff) | |
| download | Skyblocker-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.java | 87 | ||||
| -rw-r--r-- | src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java | 13 |
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); + } } |
