From a8c689dd3a0fd6823053f1580993008c84d29ae2 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sat, 4 May 2024 15:20:10 +0300 Subject: Add chocolate factory helper Highlights the best pick based on the price and CPS gain. --- src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index f662be7c..87b1bc79 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -4,6 +4,7 @@ import com.llamalad7.mixinextras.sugar.Local; import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.experiment.ChronomatronSolver; import de.hysky.skyblocker.skyblock.experiment.ExperimentSolver; import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver; @@ -284,6 +285,9 @@ public abstract class HandledScreenMixin extends Screen default -> { /*Do Nothing*/ } } } + if (currentSolver instanceof ChocolateFactorySolver chocolateFactorySolver) { + chocolateFactorySolver.markDirty(); + } } @Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawItem(Lnet/minecraft/item/ItemStack;III)V")) -- cgit From 0ec2707b63961ea0f7acab1c38311ef696ba8003 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sun, 5 May 2024 16:26:29 +0300 Subject: Updated for 1.20.6 PR compatibility Add EggFinderDebugUtil for finding egg locations quickly, to be removed later. Not tested. --- .../skyblocker/mixins/HandledScreenMixin.java | 4 -- .../chocolatefactory/ChocolateFactorySolver.java | 35 ++++++++-------- .../chocolatefactory/EggFinderDebugUtil.java | 48 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinderDebugUtil.java (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index 87b1bc79..f662be7c 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -4,7 +4,6 @@ import com.llamalad7.mixinextras.sugar.Local; import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.experiment.ChronomatronSolver; import de.hysky.skyblocker.skyblock.experiment.ExperimentSolver; import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver; @@ -285,9 +284,6 @@ public abstract class HandledScreenMixin extends Screen default -> { /*Do Nothing*/ } } } - if (currentSolver instanceof ChocolateFactorySolver chocolateFactorySolver) { - chocolateFactorySolver.markDirty(); - } } @Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawItem(Lnet/minecraft/item/ItemStack;III)V")) 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 ef79cd41..cc5ae471 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java @@ -6,6 +6,9 @@ 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; @@ -34,18 +37,26 @@ public class ChocolateFactorySolver extends ContainerSolver { } @Override - protected List getColors(String[] groups, Map slots) { + protected void start(GenericContainerScreen screen) { + 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 getColors(String[] groups, Int2ObjectMap slots) { Int2DoubleMap cpsIncreaseFactors = new Int2DoubleLinkedOpenHashMap(5); //There are only 5 rabbits on the screen. - for (Map.Entry entry : slots.entrySet()) { + for (Int2ObjectMap.Entry entry : slots.int2ObjectEntrySet()) { + if (entry.getIntKey() < 29 || entry.getIntKey() > 33) continue; //Only check the rabbit slots (29,30,31,32,33) ItemStack item = entry.getValue(); - if (item.getItem() != Items.PLAYER_HEAD || !item.hasNbt() || item.isEmpty()) continue; + if (item.getItem() != Items.PLAYER_HEAD || item.isEmpty()) continue; String lore = getLore(item); if (lore.isBlank()) continue; OptionalDouble cpsIncreaseFactor = getCPSIncreaseFactor(lore); if (cpsIncreaseFactor.isEmpty()) continue; //Something went wrong, skip this item - cpsIncreaseFactors.put(entry.getKey().intValue(), cpsIncreaseFactor.getAsDouble()); + cpsIncreaseFactors.put(entry.getIntKey(), cpsIncreaseFactor.getAsDouble()); } Optional bestSlot = cpsIncreaseFactors.int2DoubleEntrySet().stream().max(Map.Entry.comparingByValue()); if (bestSlot.isEmpty()) return List.of(); //No valid slots found, somehow. This means something went wrong, despite all the checks thus far. @@ -53,13 +64,10 @@ public class ChocolateFactorySolver extends ContainerSolver { } private String getLore(ItemStack item) { - NbtCompound display = item.getSubNbt(ItemStack.DISPLAY_KEY); - if (display == null || display.isEmpty() || !display.contains(ItemStack.LORE_KEY, NbtElement.LIST_TYPE)) return ""; - NbtList lore = display.getList(ItemStack.LORE_KEY, NbtElement.STRING_TYPE); - return lore.stream() - .map(NbtElement::asString) - .map(Text.Serialization::fromJson) //Serialize the nbt string into a text to get the content string - .filter(Objects::nonNull) + 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, @@ -85,9 +93,4 @@ public class ChocolateFactorySolver extends ContainerSolver { int cost = Integer.parseInt(costMatcher.group(1).replace(",", "")); return OptionalDouble.of((nextCps - currentCps) / (double) cost); } - - //Publicize this method so that the HandledScreenMixin can call it, as the values change on upgrade (when clicked) and there is a need for recalculation - public void markDirty() { - super.markHighlightsDirty(); - } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinderDebugUtil.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinderDebugUtil.java new file mode 100644 index 00000000..6dc7a9e4 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinderDebugUtil.java @@ -0,0 +1,48 @@ +package de.hysky.skyblocker.skyblock.chocolatefactory; + +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.text.Text; +import net.minecraft.world.World; + +public class EggFinderDebugUtil { + public static void init() { + ClientEntityEvents.ENTITY_LOAD.register(EggFinderDebugUtil::printIfEgg); + } + + public static void printIfEgg(Entity entity, World world) { + if (entity.getType() != EntityType.ARMOR_STAND) return; + ArmorStandEntity armorStand = (ArmorStandEntity) entity; + ItemStack firstItem = armorStand.getArmorItems().iterator().next(); + if (firstItem.isEmpty() || firstItem.getItem() != Items.PLAYER_HEAD) return; + String texture; + try { + texture = firstItem.get(DataComponentTypes.PROFILE) + .properties() + .get("textures") + .iterator() + .next() + .value(); + } catch (Exception ignored) { //Why bother null-checking everything when you can throw a try-catch around it? + return; + } + + if (texture.equals("ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjY3MzE0OSwKICAicHJvZmlsZUlkIiA6ICJiN2I4ZTlhZjEwZGE0NjFmOTY2YTQxM2RmOWJiM2U4OCIsCiAgInByb2ZpbGVOYW1lIiA6ICJBbmFiYW5hbmFZZzciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTQ5MzMzZDg1YjhhMzE1ZDAzMzZlYjJkZjM3ZDhhNzE0Y2EyNGM1MWI4YzYwNzRmMWI1YjkyN2RlYjUxNmMyNCIKICAgIH0KICB9Cn0") + || texture.equals("ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjY0OTcwMSwKICAicHJvZmlsZUlkIiA6ICI3NGEwMzQxNWY1OTI0ZTA4YjMyMGM2MmU1NGE3ZjJhYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZXp6aXIiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTVlMzYxNjU4MTlmZDI4NTBmOTg1NTJlZGNkNzYzZmY5ODYzMTMxMTkyODNjMTI2YWNlMGM0Y2M0OTVlNzZhOCIKICAgIH0KICB9Cn0") + || texture.equals("ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjU2ODExMiwKICAicHJvZmlsZUlkIiA6ICI3NzUwYzFhNTM5M2Q0ZWQ0Yjc2NmQ4ZGUwOWY4MjU0NiIsCiAgInByb2ZpbGVOYW1lIiA6ICJSZWVkcmVsIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzdhZTZkMmQzMWQ4MTY3YmNhZjk1MjkzYjY4YTRhY2Q4NzJkNjZlNzUxZGI1YTM0ZjJjYmM2NzY2YTAzNTZkMGEiCiAgICB9CiAgfQp9")) { + debugLog("Egg found!"); + debugLog(entity.getBlockX() + " " + entity.getBlockY() + " " + entity.getBlockZ()); + } + entity.setGlowing(true); + } + + public static void debugLog(String message) { + MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(Text.of(message)); + } +} -- cgit From 9fea533e30fdb5c825a72d2cf560958187764c6f Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 9 May 2024 21:36:20 +0300 Subject: Egg Finder initial commit Current issues: - Rendered waypoints do not turn off, can't figure out why - Entity equipment is sent before the chat message for new eggs, creating situations where the "found" message is repeated twice --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 2 + .../mixins/ClientPlayNetworkHandlerMixin.java | 6 + .../skyblock/chocolatefactory/EggFinder.java | 132 +++++++++++++++++++++ .../java/de/hysky/skyblocker/utils/ColorUtils.java | 16 +++ 4 files changed, 156 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/ColorUtils.java (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index e6b2d25a..e0e30b3c 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -11,6 +11,7 @@ import de.hysky.skyblocker.skyblock.*; import de.hysky.skyblocker.skyblock.calculators.CalculatorCommand; import de.hysky.skyblocker.skyblock.chat.ChatRuleAnnouncementScreen; import de.hysky.skyblocker.skyblock.chat.ChatRulesHandler; +import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra; import de.hysky.skyblocker.skyblock.dungeon.*; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; @@ -183,6 +184,7 @@ public class SkyblockerMod implements ClientModInitializer { BeaconHighlighter.init(); WarpAutocomplete.init(); MobBoundingBoxes.init(); + EggFinder.init(); Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20); Scheduler.INSTANCE.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 200); diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 2c2c1376..34e8264d 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -6,6 +6,7 @@ import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.CompactDamage; import de.hysky.skyblocker.skyblock.FishingHelper; +import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.end.BeaconHighlighter; @@ -118,4 +119,9 @@ public abstract class ClientPlayNetworkHandlerMixin { LOGGER.error("[Skyblocker Compact Damage] Failed to compact damage number", e); } } + + @Inject(method = "onEntityEquipmentUpdate", at = @At(value = "TAIL")) + private void skyblocker$onEntityEquip(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { + EggFinder.checkIfEgg(entity); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java new file mode 100644 index 00000000..d5e1a540 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java @@ -0,0 +1,132 @@ +package de.hysky.skyblocker.skyblock.chocolatefactory; + +import de.hysky.skyblocker.utils.ColorUtils; +import de.hysky.skyblocker.utils.Constants; +import de.hysky.skyblocker.utils.waypoint.Waypoint; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +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; +import org.slf4j.LoggerFactory; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class EggFinder { + private static final Pattern eggFoundPattern = Pattern.compile("^(?:HOPPITY'S HUNT You found a Chocolate|You have already collected this Chocolate) (Breakfast|Lunch|Dinner)"); + private static final Pattern newEggPattern = Pattern.compile("^HOPPITY'S HUNT A Chocolate (Breakfast|Lunch|Dinner) Egg has appeared!$"); + private static final MutableObject breakfastEgg = new MutableObject<>(null); + private static final MutableObject lunchEgg = new MutableObject<>(null); + private static final MutableObject dinnerEgg = new MutableObject<>(null); + private static final Logger logger = LoggerFactory.getLogger("Skyblocker Egg Finder"); + + private EggFinder() { + } + + public static void init() { + ClientPlayConnectionEvents.JOIN.register((ignored, ignored2, ignored3) -> { + breakfastEgg.setValue(null); + lunchEgg.setValue(null); + dinnerEgg.setValue(null); + }); + ClientReceiveMessageEvents.GAME.register(EggFinder::onChatMessage); + WorldRenderEvents.AFTER_TRANSLUCENT.register(EggFinder::renderWaypoints); + } + + public static void checkIfEgg(Entity entity) { + if (breakfastEgg.getValue() != null && dinnerEgg.getValue() != null && lunchEgg.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(); + + //Don't turn this into a switch statement, it's unreadable + if (texture.equals("ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjY3MzE0OSwKICAicHJvZmlsZUlkIiA6ICJiN2I4ZTlhZjEwZGE0NjFmOTY2YTQxM2RmOWJiM2U4OCIsCiAgInByb2ZpbGVOYW1lIiA6ICJBbmFiYW5hbmFZZzciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTQ5MzMzZDg1YjhhMzE1ZDAzMzZlYjJkZjM3ZDhhNzE0Y2EyNGM1MWI4YzYwNzRmMWI1YjkyN2RlYjUxNmMyNCIKICAgIH0KICB9Cn0")) { + handleFoundEgg(armorStand, EggType.BREAKFAST); + } else if (texture.equals("ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjY0OTcwMSwKICAicHJvZmlsZUlkIiA6ICI3NGEwMzQxNWY1OTI0ZTA4YjMyMGM2MmU1NGE3ZjJhYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZXp6aXIiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTVlMzYxNjU4MTlmZDI4NTBmOTg1NTJlZGNkNzYzZmY5ODYzMTMxMTkyODNjMTI2YWNlMGM0Y2M0OTVlNzZhOCIKICAgIH0KICB9Cn0")) { + handleFoundEgg(armorStand, EggType.DINNER); + } else if (texture.equals("ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjU2ODExMiwKICAicHJvZmlsZUlkIiA6ICI3NzUwYzFhNTM5M2Q0ZWQ0Yjc2NmQ4ZGUwOWY4MjU0NiIsCiAgInByb2ZpbGVOYW1lIiA6ICJSZWVkcmVsIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzdhZTZkMmQzMWQ4MTY3YmNhZjk1MjkzYjY4YTRhY2Q4NzJkNjZlNzUxZGI1YTM0ZjJjYmM2NzY2YTAzNTZkMGEiCiAgICB9CiAgfQp9")) { + handleFoundEgg(armorStand, EggType.LUNCH); + } + } + } 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. + } + } + } + + private static void handleFoundEgg(ArmorStandEntity entity, EggType eggType) { + eggType.egg.setValue(new Egg(entity, new Waypoint(entity.getBlockPos().up(2), () -> Waypoint.Type.WAYPOINT, ColorUtils.getFloatComponents(eggType.color)))); + MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append("Found a ").append(Text.literal("Chocolate " + eggType + " Egg").withColor(eggType.color)).append(" at " + entity.getBlockPos().up(2).toShortString() + "!")); + } + + private static void renderWaypoints(WorldRenderContext context) { + if (breakfastEgg.getValue() != null && breakfastEgg.getValue().waypoint.shouldRender()) breakfastEgg.getValue().waypoint.render(context); + if (lunchEgg.getValue() != null && lunchEgg.getValue().waypoint.shouldRender()) lunchEgg.getValue().waypoint.render(context); + if (dinnerEgg.getValue() != null && dinnerEgg.getValue().waypoint.shouldRender()) dinnerEgg.getValue().waypoint.render(context); + } + + private static void onChatMessage(Text text, boolean overlay) { + if (overlay) return; + Matcher matcher = eggFoundPattern.matcher(text.getString()); + if (matcher.matches()) { + try { + Egg egg = EggType.valueOf(matcher.group(1).toUpperCase()).egg.getValue(); + if (egg != null) egg.waypoint.setFound(); + } catch (IllegalArgumentException e) { + logger.error("Failed to find egg type for egg found message. Tried to match against: " + matcher.group(0), e); + } + } + + //There's only one egg of the same type at any given time, so we can set the changed egg to null + matcher = newEggPattern.matcher(text.getString()); + if (matcher.matches()) { + try { + EggType.valueOf(matcher.group(1).toUpperCase()).egg.setValue(null); + } catch (IllegalArgumentException e) { + logger.error("Failed to find egg type for egg spawn message. Tried to match against: " + matcher.group(0), e); + } + } + } + + private record Egg(ArmorStandEntity entity, Waypoint waypoint) { } + + private enum EggType { + LUNCH(lunchEgg, 0x5555FF), + DINNER(dinnerEgg, 0x55FF55), + BREAKFAST(breakfastEgg, 0xFFAA00); + + public final MutableObject egg; + public final int color; + + EggType(MutableObject egg, int color) { + this.egg = egg; + this.color = color; + } + + @Override + public String toString() { + return switch (this) { + case LUNCH -> "Lunch"; + case DINNER -> "Dinner"; + case BREAKFAST -> "Breakfast"; + }; + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/ColorUtils.java b/src/main/java/de/hysky/skyblocker/utils/ColorUtils.java new file mode 100644 index 00000000..0196edf2 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/ColorUtils.java @@ -0,0 +1,16 @@ +package de.hysky.skyblocker.utils; + +public class ColorUtils { + /** + * Takes an RGB color as an integer and returns an array of the color's components as floats, in RGB format. + * @param color The color to get the components of. + * @return An array of the color's components as floats. + */ + public static float[] getFloatComponents(int color) { + return new float[] { + ((color >> 16) & 0xFF) / 255f, + ((color >> 8) & 0xFF) / 255f, + (color & 0xFF) / 255f + }; + } +} -- cgit From ba5047d708858ed863bbc207de20afcd42337451 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Tue, 14 May 2024 03:50:00 +0300 Subject: Mixin into ClientPlayNetworkHandler.onEntityTrackerUpdate to check for egg spawns --- .../de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 34e8264d..9ff1fc84 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -124,4 +124,9 @@ public abstract class ClientPlayNetworkHandlerMixin { private void skyblocker$onEntityEquip(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { EggFinder.checkIfEgg(entity); } + + @Inject(method = "onEntityTrackerUpdate", at = @At(value = "TAIL")) + private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { + EggFinder.checkIfEgg(entity); + } } -- cgit From 5b7c40ea4cf6495dad5c935eb566f851d9062e57 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Wed, 15 May 2024 01:21:00 +0300 Subject: Refactor EggFinder for CompactDamage compatibility --- .../mixins/ClientPlayNetworkHandlerMixin.java | 183 ++++++++++----------- .../hysky/skyblocker/skyblock/CompactDamage.java | 1 + .../skyblock/chocolatefactory/EggFinder.java | 6 +- 3 files changed, 96 insertions(+), 94 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 9ff1fc84..3ca68df3 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -35,98 +35,95 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientPlayNetworkHandler.class) public abstract class ClientPlayNetworkHandlerMixin { - @Shadow - private ClientWorld world; - - @Shadow - @Final - private static Logger LOGGER; - - @Inject(method = "onBlockUpdate", at = @At("RETURN")) - private void skyblocker$onBlockUpdate(BlockUpdateS2CPacket packet, CallbackInfo ci) { - if (Utils.isInTheEnd() && SlayerUtils.isInSlayer()) { - BeaconHighlighter.beaconPositions.remove(packet.getPos()); - if (packet.getState().isOf(Blocks.BEACON)) { - BeaconHighlighter.beaconPositions.add(packet.getPos()); - } - } - } - - @Inject(method = "method_37472", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V")) - private void skyblocker$onItemDestroy(int entityId, CallbackInfo ci) { - if (world.getEntityById(entityId) instanceof ItemEntity itemEntity) { - DungeonManager.onItemPickup(itemEntity); - } - } - - @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V", ordinal = 0)) - private ItemEntity skyblocker$onItemPickup(ItemEntity itemEntity) { - DungeonManager.onItemPickup(itemEntity); - return itemEntity; - } - - @WrapWithCondition(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false)) - private boolean skyblocker$cancelEntityPassengersWarning(Logger instance, String msg) { - return !Utils.isOnHypixel(); - } - - @WrapWithCondition(method = "onPlayerList", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$cancelPlayerListWarning(Logger instance, String format, Object arg1, Object arg2) { - return !Utils.isOnHypixel(); - } - - @Inject(method = "onPlaySound", at = @At("RETURN")) - private void skyblocker$onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) { - FishingHelper.onSound(packet); - } - - @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) { - return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion")); - } - - @WrapWithCondition(method = { "onScoreboardScoreUpdate", "onScoreboardScoreReset" }, at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$cancelUnknownScoreboardObjectiveWarnings(Logger instance, String message, Object objectiveName) { - return !Utils.isOnHypixel(); - } - - @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) { - return !Utils.isOnHypixel(); - } - - @Inject(method = "onParticle", at = @At("RETURN")) - private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) { - MythologicalRitual.onParticle(packet); - EnderNodes.onParticle(packet); - } - - @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) - private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) { - if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) { - DungeonScore.handleEntityDeath(entity); - TheEnd.onEntityDeath(entity); - } - return entity; - } - - @Inject(method = "onEntityTrackerUpdate", at = @At("TAIL")) - private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { - if (!SkyblockerConfigManager.get().uiAndVisuals.compactDamage.enabled || !(entity instanceof ArmorStandEntity armorStandEntity)) return; - try { //Prevent packet handling fails if something goes wrong so that entity trackers still update, just without compact damage numbers + @Shadow + private ClientWorld world; + + @Shadow + @Final + private static Logger LOGGER; + + @Inject(method = "onBlockUpdate", at = @At("RETURN")) + private void skyblocker$onBlockUpdate(BlockUpdateS2CPacket packet, CallbackInfo ci) { + if (Utils.isInTheEnd() && SlayerUtils.isInSlayer()) { + BeaconHighlighter.beaconPositions.remove(packet.getPos()); + if (packet.getState().isOf(Blocks.BEACON)) { + BeaconHighlighter.beaconPositions.add(packet.getPos()); + } + } + } + + @Inject(method = "method_37472", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V")) + private void skyblocker$onItemDestroy(int entityId, CallbackInfo ci) { + if (world.getEntityById(entityId) instanceof ItemEntity itemEntity) { + DungeonManager.onItemPickup(itemEntity); + } + } + + @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V", ordinal = 0)) + private ItemEntity skyblocker$onItemPickup(ItemEntity itemEntity) { + DungeonManager.onItemPickup(itemEntity); + return itemEntity; + } + + @WrapWithCondition(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false)) + private boolean skyblocker$cancelEntityPassengersWarning(Logger instance, String msg) { + return !Utils.isOnHypixel(); + } + + @WrapWithCondition(method = "onPlayerList", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$cancelPlayerListWarning(Logger instance, String format, Object arg1, Object arg2) { + return !Utils.isOnHypixel(); + } + + @Inject(method = "onPlaySound", at = @At("RETURN")) + private void skyblocker$onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) { + FishingHelper.onSound(packet); + } + + @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) { + return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion")); + } + + @WrapWithCondition(method = {"onScoreboardScoreUpdate", "onScoreboardScoreReset"}, at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$cancelUnknownScoreboardObjectiveWarnings(Logger instance, String message, Object objectiveName) { + return !Utils.isOnHypixel(); + } + + @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) { + return !Utils.isOnHypixel(); + } + + @Inject(method = "onParticle", at = @At("RETURN")) + private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) { + MythologicalRitual.onParticle(packet); + EnderNodes.onParticle(packet); + } + + @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) + private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) { + if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) { + DungeonScore.handleEntityDeath(entity); + TheEnd.onEntityDeath(entity); + } + return entity; + } + + @Inject(method = "onEntityTrackerUpdate", at = @At("TAIL")) + private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { + if (!(entity instanceof ArmorStandEntity armorStandEntity)) return; + + EggFinder.checkIfEgg(armorStandEntity); + try { //Prevent packet handling fails if something goes wrong so that entity trackers still update, just without compact damage numbers CompactDamage.compactDamage(armorStandEntity); - } catch (Exception e) { - LOGGER.error("[Skyblocker Compact Damage] Failed to compact damage number", e); - } - } - - @Inject(method = "onEntityEquipmentUpdate", at = @At(value = "TAIL")) - private void skyblocker$onEntityEquip(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { - EggFinder.checkIfEgg(entity); - } - - @Inject(method = "onEntityTrackerUpdate", at = @At(value = "TAIL")) - private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { - EggFinder.checkIfEgg(entity); - } + } catch (Exception e) { + LOGGER.error("[Skyblocker Compact Damage] Failed to compact damage number", e); + } + } + + @Inject(method = "onEntityEquipmentUpdate", at = @At(value = "TAIL")) + private void skyblocker$onEntityEquip(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { + EggFinder.checkIfEgg(entity); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/CompactDamage.java b/src/main/java/de/hysky/skyblocker/skyblock/CompactDamage.java index 2837364b..8285a823 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/CompactDamage.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/CompactDamage.java @@ -19,6 +19,7 @@ public class CompactDamage { } public static void compactDamage(ArmorStandEntity entity) { + if (!SkyblockerConfigManager.get().uiAndVisuals.compactDamage.enabled) return; if (!entity.isInvisible() || !entity.hasCustomName() || !entity.isCustomNameVisible()) return; Text customName = entity.getCustomName(); String customNameStringified = customName.getString(); 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 0e887fd2..ee16abd9 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java @@ -39,9 +39,13 @@ public class EggFinder { } public static void checkIfEgg(Entity entity) { + if (entity instanceof ArmorStandEntity armorStand) checkIfEgg(armorStand); + } + + public static void checkIfEgg(ArmorStandEntity armorStand) { if (!SkyblockerConfigManager.get().helpers.chocolateFactory.enableEggFinder) return; if (SkyblockTime.skyblockSeason.get() != SkyblockTime.Season.SPRING) return; - if (!(entity instanceof ArmorStandEntity armorStand) || armorStand.hasCustomName() || !armorStand.isInvisible() || !armorStand.shouldHideBasePlate()) return; + if (armorStand.hasCustomName() || !armorStand.isInvisible() || !armorStand.shouldHideBasePlate()) return; for (ItemStack itemStack : armorStand.getArmorItems()) { ItemUtils.getHeadTexture(itemStack).ifPresent(texture -> { for (EggType type : EggType.entries) { -- cgit From 5de131909a2e8461c2c19329aa8e9c4d34672e4b Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 17 May 2024 06:33:14 +0300 Subject: Remove unused import --- .../java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 3ca68df3..bc555e6b 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -3,7 +3,6 @@ package de.hysky.skyblocker.mixins; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; -import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.CompactDamage; import de.hysky.skyblocker.skyblock.FishingHelper; import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; -- cgit From 2bbeccd147b715f1eb766d2c34f9326986160557 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Thu, 23 May 2024 02:01:32 -0400 Subject: Clean up small formatting --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 3 +- .../config/categories/HelperCategory.java | 5 +- .../mixins/ClientPlayNetworkHandlerMixin.java | 180 ++++++++++----------- .../chocolatefactory/ChocolateFactorySolver.java | 5 +- .../skyblock/item/tooltip/ItemTooltip.java | 5 +- .../de/hysky/skyblocker/utils/SkyblockTime.java | 6 +- 6 files changed, 99 insertions(+), 105 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker/mixins') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 79f241b8..a57b4177 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -2,10 +2,9 @@ package de.hysky.skyblocker; import com.google.gson.Gson; import com.google.gson.GsonBuilder; - -import de.hysky.skyblocker.config.datafixer.ConfigDataFixer; import de.hysky.skyblocker.config.ImageRepoLoader; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.config.datafixer.ConfigDataFixer; import de.hysky.skyblocker.debug.Debug; import de.hysky.skyblocker.skyblock.*; import de.hysky.skyblocker.skyblock.calculators.CalculatorCommand; diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index 79bd0d65..9e4935cb 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -3,13 +3,11 @@ package de.hysky.skyblocker.config.categories; import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.utils.waypoint.Waypoint; -import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.ConfigCategory; import dev.isxander.yacl3.api.Option; import dev.isxander.yacl3.api.OptionDescription; +import dev.isxander.yacl3.api.OptionGroup; import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder; -import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder; -import dev.isxander.yacl3.config.v2.api.autogen.TickBox; import net.minecraft.text.Text; public class HelperCategory { @@ -184,7 +182,6 @@ public class HelperCategory { newValue -> config.helpers.chocolateFactory.enableTimeTowerReminder = newValue) .controller(ConfigUtils::createBooleanController) .build()) - .build()) .build(); diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index bc555e6b..48389d40 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -34,95 +34,95 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientPlayNetworkHandler.class) public abstract class ClientPlayNetworkHandlerMixin { - @Shadow - private ClientWorld world; - - @Shadow - @Final - private static Logger LOGGER; - - @Inject(method = "onBlockUpdate", at = @At("RETURN")) - private void skyblocker$onBlockUpdate(BlockUpdateS2CPacket packet, CallbackInfo ci) { - if (Utils.isInTheEnd() && SlayerUtils.isInSlayer()) { - BeaconHighlighter.beaconPositions.remove(packet.getPos()); - if (packet.getState().isOf(Blocks.BEACON)) { - BeaconHighlighter.beaconPositions.add(packet.getPos()); - } - } - } - - @Inject(method = "method_37472", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V")) - private void skyblocker$onItemDestroy(int entityId, CallbackInfo ci) { - if (world.getEntityById(entityId) instanceof ItemEntity itemEntity) { - DungeonManager.onItemPickup(itemEntity); - } - } - - @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V", ordinal = 0)) - private ItemEntity skyblocker$onItemPickup(ItemEntity itemEntity) { - DungeonManager.onItemPickup(itemEntity); - return itemEntity; - } - - @WrapWithCondition(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false)) - private boolean skyblocker$cancelEntityPassengersWarning(Logger instance, String msg) { - return !Utils.isOnHypixel(); - } - - @WrapWithCondition(method = "onPlayerList", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$cancelPlayerListWarning(Logger instance, String format, Object arg1, Object arg2) { - return !Utils.isOnHypixel(); - } - - @Inject(method = "onPlaySound", at = @At("RETURN")) - private void skyblocker$onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) { - FishingHelper.onSound(packet); - } - - @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) { - return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion")); - } - - @WrapWithCondition(method = {"onScoreboardScoreUpdate", "onScoreboardScoreReset"}, at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$cancelUnknownScoreboardObjectiveWarnings(Logger instance, String message, Object objectiveName) { - return !Utils.isOnHypixel(); - } - - @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false)) - private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) { - return !Utils.isOnHypixel(); - } - - @Inject(method = "onParticle", at = @At("RETURN")) - private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) { - MythologicalRitual.onParticle(packet); - EnderNodes.onParticle(packet); - } - - @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) - private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) { - if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) { - DungeonScore.handleEntityDeath(entity); - TheEnd.onEntityDeath(entity); - } - return entity; - } - - @Inject(method = "onEntityTrackerUpdate", at = @At("TAIL")) - private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { - if (!(entity instanceof ArmorStandEntity armorStandEntity)) return; - - EggFinder.checkIfEgg(armorStandEntity); - try { //Prevent packet handling fails if something goes wrong so that entity trackers still update, just without compact damage numbers + @Shadow + private ClientWorld world; + + @Shadow + @Final + private static Logger LOGGER; + + @Inject(method = "onBlockUpdate", at = @At("RETURN")) + private void skyblocker$onBlockUpdate(BlockUpdateS2CPacket packet, CallbackInfo ci) { + if (Utils.isInTheEnd() && SlayerUtils.isInSlayer()) { + BeaconHighlighter.beaconPositions.remove(packet.getPos()); + if (packet.getState().isOf(Blocks.BEACON)) { + BeaconHighlighter.beaconPositions.add(packet.getPos()); + } + } + } + + @Inject(method = "method_37472", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V")) + private void skyblocker$onItemDestroy(int entityId, CallbackInfo ci) { + if (world.getEntityById(entityId) instanceof ItemEntity itemEntity) { + DungeonManager.onItemPickup(itemEntity); + } + } + + @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V", ordinal = 0)) + private ItemEntity skyblocker$onItemPickup(ItemEntity itemEntity) { + DungeonManager.onItemPickup(itemEntity); + return itemEntity; + } + + @WrapWithCondition(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false)) + private boolean skyblocker$cancelEntityPassengersWarning(Logger instance, String msg) { + return !Utils.isOnHypixel(); + } + + @WrapWithCondition(method = "onPlayerList", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$cancelPlayerListWarning(Logger instance, String format, Object arg1, Object arg2) { + return !Utils.isOnHypixel(); + } + + @Inject(method = "onPlaySound", at = @At("RETURN")) + private void skyblocker$onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) { + FishingHelper.onSound(packet); + } + + @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) { + return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion")); + } + + @WrapWithCondition(method = {"onScoreboardScoreUpdate", "onScoreboardScoreReset"}, at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$cancelUnknownScoreboardObjectiveWarnings(Logger instance, String message, Object objectiveName) { + return !Utils.isOnHypixel(); + } + + @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false)) + private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) { + return !Utils.isOnHypixel(); + } + + @Inject(method = "onParticle", at = @At("RETURN")) + private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) { + MythologicalRitual.onParticle(packet); + EnderNodes.onParticle(packet); + } + + @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) + private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) { + if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) { + DungeonScore.handleEntityDeath(entity); + TheEnd.onEntityDeath(entity); + } + return entity; + } + + @Inject(method = "onEntityTrackerUpdate", at = @At("TAIL")) + private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { + if (!(entity instanceof ArmorStandEntity armorStandEntity)) return; + + EggFinder.checkIfEgg(armorStandEntity); + try { //Prevent packet handling fails if something goes wrong so that entity trackers still update, just without compact damage numbers CompactDamage.compactDamage(armorStandEntity); - } catch (Exception e) { - LOGGER.error("[Skyblocker Compact Damage] Failed to compact damage number", e); - } - } - - @Inject(method = "onEntityEquipmentUpdate", at = @At(value = "TAIL")) - private void skyblocker$onEntityEquip(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { - EggFinder.checkIfEgg(entity); - } + } catch (Exception e) { + LOGGER.error("[Skyblocker Compact Damage] Failed to compact damage number", e); + } + } + + @Inject(method = "onEntityEquipmentUpdate", at = @At(value = "TAIL")) + private void skyblocker$onEntityEquip(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { + EggFinder.checkIfEgg(entity); + } } 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 306d09ee..33bf7b11 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.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 it.unimi.dsi.fastutil.ints.*; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; import net.minecraft.client.MinecraftClient; @@ -24,7 +24,6 @@ import org.apache.commons.lang3.math.NumberUtils; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.*; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -156,7 +155,7 @@ public class ChocolateFactorySolver extends ContainerSolver { } //Rabbits else if (stack.isOf(Items.PLAYER_HEAD)) { - shouldAddLine = addRabbitStatsToLore(lines, stack) || shouldAddLine ; + shouldAddLine = addRabbitStatsToLore(lines, stack) || shouldAddLine; } //This is an ArrayList, so this operation is probably not very efficient, but logically it's pretty much the only way I can think of diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java index 70586d89..8c083e25 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java @@ -2,7 +2,6 @@ package de.hysky.skyblocker.skyblock.item.tooltip; import com.google.gson.JsonObject; import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.GeneralConfig; import de.hysky.skyblocker.skyblock.item.MuseumItemCache; @@ -395,13 +394,13 @@ public class ItemTooltip { } //This is static to not create a new text object for each line in every item - private static final Text bumpyLine = Text.literal("-----------------").formatted(Formatting.DARK_GRAY, Formatting.STRIKETHROUGH); + private static final Text BUMPY_LINE = Text.literal("-----------------").formatted(Formatting.DARK_GRAY, Formatting.STRIKETHROUGH); private static void smoothenLines(List lines) { for (int i = 0; i < lines.size(); i++) { List lineSiblings = lines.get(i).getSiblings(); //Compare the first sibling rather than the whole object as the style of the root object can change while visually staying the same - if (lineSiblings.size() == 1 && lineSiblings.getFirst().equals(bumpyLine)) { + if (lineSiblings.size() == 1 && lineSiblings.getFirst().equals(BUMPY_LINE)) { lines.set(i, createSmoothLine()); } } diff --git a/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java b/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java index 36db4ef3..5a6074e1 100644 --- a/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java +++ b/src/main/java/de/hysky/skyblocker/utils/SkyblockTime.java @@ -45,17 +45,17 @@ public class SkyblockTime { skyblockSeason.set(Season.values()[getSkyblockMonth() / 3]); skyblockMonth.set(Month.values()[getSkyblockMonth()]); skyblockDay.set(getSkyblockDay()); - LOGGER.info("[Skyblocker Time] Skyblock time updated to Year {}, Season {}, Month {}, Day {}",skyblockYear.get(), skyblockSeason.get(), skyblockMonth.get(), skyblockDay.get()); + LOGGER.info("[Skyblocker Time] Skyblock time updated to Year {}, Season {}, Month {}, Day {}", skyblockYear.get(), skyblockSeason.get(), skyblockMonth.get(), skyblockDay.get()); } public enum Season { - SPRING, SUMMER, FALL, WINTER; + SPRING, SUMMER, FALL, WINTER } public enum Month { EARLY_SPRING, SPRING, LATE_SPRING, EARLY_SUMMER, SUMMER, LATE_SUMMER, EARLY_FALL, FALL, LATE_FALL, - EARLY_WINTER, WINTER, LATE_WINTER; + EARLY_WINTER, WINTER, LATE_WINTER } } -- cgit