diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java index 8a4933340a..2a9f9a602f 100644 --- a/src/main/java/de/hysky/skyblocker/debug/Debug.java +++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java @@ -7,6 +7,7 @@ import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; +import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; @@ -64,6 +65,7 @@ public static void init() { .then(toggleShowingInvisibleArmorStands()) .then(dumpArmorStandHeadTextures()) .then(toggleWebSocketDebug()) + .then(EventNotifications.debugToasts()) ) )); ClientTickEvents.END_CLIENT_TICK.register(client -> { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index 184ccd9e16..943f81265d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -5,6 +5,7 @@ import com.google.gson.JsonObject; import com.mojang.brigadier.arguments.BoolArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.logging.LogUtils; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.annotations.Init; @@ -15,7 +16,7 @@ import de.hysky.skyblocker.utils.scheduler.Scheduler; import it.unimi.dsi.fastutil.ints.IntList; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.item.ItemStack; @@ -57,32 +58,28 @@ public class EventNotifications { @Init public static void init() { Scheduler.INSTANCE.scheduleCyclic(EventNotifications::timeUpdate, 20); - SkyblockEvents.JOIN.register(EventNotifications::refreshEvents); - ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( - ClientCommandManager.literal("skyblocker").then( - ClientCommandManager.literal("debug").then( - ClientCommandManager.literal("toasts").then( - ClientCommandManager.argument("time", IntegerArgumentType.integer(0)) - .then(ClientCommandManager.argument("jacob", BoolArgumentType.bool()).executes(context -> { - long time = System.currentTimeMillis() / 1000 + context.getArgument("time", int.class); - if (context.getArgument("jacob", Boolean.class)) { - MinecraftClient.getInstance().getToastManager().add( - new JacobEventToast(time, "Jacob's farming contest", new String[]{"Cactus", "Cocoa Beans", "Pumpkin"}) - ); - } else { - MinecraftClient.getInstance().getToastManager().add( - new EventToast(time, "Jacob's or something idk", new ItemStack(Items.PAPER)) - ); - } - return 0; - } - ) - ) + } + + public static LiteralArgumentBuilder debugToasts() { + return ClientCommandManager.literal("toasts").then( + ClientCommandManager.argument("time", IntegerArgumentType.integer(0)) + .then(ClientCommandManager.argument("jacob", BoolArgumentType.bool()).executes(context -> { + long time = System.currentTimeMillis() / 1000 + context.getArgument("time", int.class); + if (context.getArgument("jacob", Boolean.class)) { + MinecraftClient.getInstance().getToastManager().add( + new JacobEventToast(time, "Jacob's farming contest", new String[]{"Cactus", "Cocoa Beans", "Pumpkin"}) + ); + } else { + MinecraftClient.getInstance().getToastManager().add( + new EventToast(time, "Jacob's or something idk", new ItemStack(Items.PAPER)) + ); + } + return 0; + } ) ) - ) - )); + ); } private static final Map> events = new ConcurrentHashMap<>(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/PetInfo.java b/src/main/java/de/hysky/skyblocker/skyblock/item/PetInfo.java index 585db88aab..02e3826b44 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/PetInfo.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/PetInfo.java @@ -5,19 +5,19 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -public record PetInfo(String type, double exp, String tier, Optional uuid, Optional item, Optional skin) { +public record PetInfo(String type, double exp, SkyblockItemRarity tier, Optional uuid, Optional item, Optional skin) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.STRING.fieldOf("type").forGetter(PetInfo::type), Codec.DOUBLE.fieldOf("exp").forGetter(PetInfo::exp), - Codec.STRING.fieldOf("tier").forGetter(PetInfo::tier), + SkyblockItemRarity.CODEC.fieldOf("tier").forGetter(PetInfo::tier), Codec.STRING.optionalFieldOf("uuid").forGetter(PetInfo::uuid), Codec.STRING.optionalFieldOf("heldItem").forGetter(PetInfo::item), Codec.STRING.optionalFieldOf("skin").forGetter(PetInfo::skin) ).apply(instance, PetInfo::new)); - public static final PetInfo EMPTY = new PetInfo("", 0, "", Optional.empty(), Optional.empty(), Optional.empty()); + public static final PetInfo EMPTY = new PetInfo("", 0, SkyblockItemRarity.UNKNOWN, Optional.empty(), Optional.empty(), Optional.empty()); public SkyblockItemRarity rarity() { - return SkyblockItemRarity.valueOf(tier); + return tier; } public int tierIndex() { 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 b21b587876..a5043e0650 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java @@ -1,8 +1,10 @@ package de.hysky.skyblocker.skyblock.item; +import com.mojang.serialization.Codec; import net.minecraft.util.Formatting; +import net.minecraft.util.StringIdentifiable; -public enum SkyblockItemRarity { +public enum SkyblockItemRarity implements StringIdentifiable { COMMON(Formatting.WHITE), UNCOMMON(Formatting.GREEN), RARE(Formatting.BLUE), @@ -13,19 +15,32 @@ public enum SkyblockItemRarity { SPECIAL(Formatting.RED), VERY_SPECIAL(Formatting.RED), ULTIMATE(Formatting.DARK_RED), - ADMIN(Formatting.DARK_RED); + ADMIN(Formatting.DARK_RED), + UNKNOWN(Formatting.DARK_GRAY); + public static final Codec CODEC = StringIdentifiable.createCodec(SkyblockItemRarity::values); + public final Formatting formatting; public final int color; public final float r; public final float g; public final float b; SkyblockItemRarity(Formatting formatting) { - //noinspection DataFlowIssue - this.color = formatting.getColorValue(); + this.formatting = formatting; + //noinspection DataFlowIssue + this.color = formatting.getColorValue(); this.r = ((color >> 16) & 0xFF) / 255f; this.g = ((color >> 8) & 0xFF) / 255f; this.b = (color & 0xFF) / 255f; } + + @Override + public String asString() { + return name(); + } + + public SkyblockItemRarity next() { + return values()[(ordinal() + 1) % values().length]; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java index 9f9dbca09a..7e35d8bf94 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock.profileviewer.inventory; 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.skyblock.profileviewer.utils.LevelFinder; import de.hysky.skyblocker.skyblock.profileviewer.utils.ProfileViewerUtils; @@ -9,12 +10,6 @@ import io.github.moulberry.repo.constants.PetNumbers; import io.github.moulberry.repo.data.NEUItem; import io.github.moulberry.repo.data.Rarity; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntMaps; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.LoreComponent; import net.minecraft.component.type.ProfileComponent; @@ -23,9 +18,13 @@ import net.minecraft.text.Style; import net.minecraft.text.Text; import net.minecraft.util.Formatting; + import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,7 +36,7 @@ public class Pet { private final String name; private final double xp; - private final String tier; + private final SkyblockItemRarity tier; private final Optional heldItem; private final Optional skin; private final Optional skinTexture; @@ -47,20 +46,6 @@ public class Pet { private final long nextLevelXP; private final ItemStack icon; - private static final Object2IntMap TIER_MAP = Object2IntMaps.unmodifiable(new Object2IntOpenHashMap<>(Map.of( - "COMMON", 0, "UNCOMMON", 1, "RARE", 2, "EPIC", 3, "LEGENDARY", 4, "MYTHIC", 5 - ))); - - private static final Int2ObjectMap RARITY_COLOR_MAP = Int2ObjectMaps.unmodifiable(new Int2ObjectOpenHashMap<>(Map.of( - 0, Formatting.WHITE, // COMMON - 1, Formatting.GREEN, // UNCOMMON - 2, Formatting.BLUE, // RARE - 3, Formatting.DARK_PURPLE, // EPIC - 4, Formatting.GOLD, // LEGENDARY - 5, Formatting.LIGHT_PURPLE, // MYTHIC - 6, Formatting.AQUA // DIVINE (future proofing, because why not) - ))); - public Pet(PetInfo petData) { LevelFinder.LevelInfo info = LevelFinder.getLevelInfo(petData.type().equals("GOLDEN_DRAGON") ? "PET_GREG" : "PET_" + petData.tier(), (long) petData.exp()); this.name = petData.type(); @@ -84,12 +69,12 @@ public long getXP() { return (long) xp; } - private int getTier() { - return TIER_MAP.getOrDefault(tier, 0); + public SkyblockItemRarity getRarity() { + return tier; } - public String getTierAsString() { - return tier; + public int getTier() { + return tier.ordinal(); } private Optional calculateSkinTexture() { @@ -167,12 +152,12 @@ private ItemStack fromNEUItem(NEUItem item, ItemStack heldItem) { petStack.set(DataComponentTypes.PROFILE, skinTexture.get()); } - if ((boosted())) formattedLore.set(formattedLore.size() - 1, Text.literal(Rarity.values()[getTier() + 1].toString()).setStyle(style).formatted(Formatting.BOLD, RARITY_COLOR_MAP.get(getTier() + 1))); + if ((boosted())) formattedLore.set(formattedLore.size() - 1, Text.literal(getRarity().next().toString()).setStyle(style).formatted(Formatting.BOLD, getRarity().next().formatting)); // Update the lore and name petStack.set(DataComponentTypes.LORE, new LoreComponent(formattedLore)); String displayName = Formatting.strip(item.getDisplayName()).replace("[Lvl {LVL}]", "§7[Lvl " + this.level + "]§r"); - petStack.set(DataComponentTypes.CUSTOM_NAME, Text.literal(displayName).setStyle(style).formatted(RARITY_COLOR_MAP.get(this.getTier() + (boosted() ? 1 : 0)))); + petStack.set(DataComponentTypes.CUSTOM_NAME, Text.literal(displayName).setStyle(style).formatted((boosted() ? getRarity().next() : getRarity()).formatting)); return petStack; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/itemLoaders/PetsInventoryItemLoader.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/itemLoaders/PetsInventoryItemLoader.java index 8ac5831eaf..5059c570fb 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/itemLoaders/PetsInventoryItemLoader.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/itemLoaders/PetsInventoryItemLoader.java @@ -13,8 +13,6 @@ import java.util.List; public class PetsInventoryItemLoader extends ItemLoader { - private static final List TIER_ORDER = List.of("MYTHIC", "LEGENDARY", "EPIC", "RARE", "UNCOMMON", "COMMON"); - @Override public List loadItems(JsonObject data) { List petList = new ArrayList<>(); @@ -31,7 +29,7 @@ public List loadItems(JsonObject data) { } // Sort pets by tier (in reverse order) and level (in reverse order) - petList.sort(Comparator.comparingInt((Pet pet) -> TIER_ORDER.indexOf(pet.getTierAsString())).reversed().thenComparingInt(Pet::getLevel).reversed()); + petList.sort(Comparator.comparingInt(Pet::getTier).thenComparingInt(Pet::getLevel).reversed()); List itemList = new ArrayList<>(); for (Pet pet : petList) { diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java b/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java index 00594e816d..ca16bd4e00 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java +++ b/src/main/java/de/hysky/skyblocker/utils/ApiAuthentication.java @@ -1,14 +1,17 @@ package de.hysky.skyblocker.utils; import com.google.gson.JsonParser; +import com.mojang.brigadier.Command; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.annotations.Init; +import de.hysky.skyblocker.debug.Debug; import de.hysky.skyblocker.mixins.accessors.MinecraftClientAccessor; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.SharedConstants; import net.minecraft.client.MinecraftClient; @@ -27,6 +30,8 @@ import java.util.Objects; import java.util.UUID; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + /** * This class is responsible for communicating with the API to retrieve a fully custom token used to gain access to more privileged APIs * such as the Hypixel API Proxy. The main point of this is to verify that a person is most likely playing Minecraft, and thus is likely to be @@ -47,6 +52,14 @@ public class ApiAuthentication { public static void init() { //Update token after the profileKeys instance is initialized ClientLifecycleEvents.CLIENT_STARTED.register(_client -> updateToken()); + if (Debug.debugEnabled()) { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> + dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("updateToken").executes(context -> { + updateToken(); + return Command.SINGLE_SUCCESS; + }))) + ); + } } /** diff --git a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java index d024720ff3..cca4da09d7 100644 --- a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java +++ b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.utils.scheduler; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.mojang.brigadier.Command; import com.mojang.brigadier.context.CommandContext; import it.unimi.dsi.fastutil.ints.AbstractInt2ObjectMap; @@ -10,14 +9,13 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.profiler.Profiler; import net.minecraft.util.profiler.Profilers; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.ForkJoinPool; import java.util.function.Function; import java.util.function.Supplier; @@ -28,8 +26,8 @@ public class Scheduler { protected static final Logger LOGGER = LoggerFactory.getLogger(Scheduler.class); public static final Scheduler INSTANCE = new Scheduler(); private int currentTick = 0; - private final AbstractInt2ObjectMap> tasks = new Int2ObjectOpenHashMap<>(); - private final ExecutorService executors = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Skyblocker-Scheduler-%d").build()); + private final AbstractInt2ObjectMap> tasks = new Int2ObjectOpenHashMap<>(); + private final ExecutorService executors = ForkJoinPool.commonPool(); protected Scheduler() { } @@ -57,7 +55,7 @@ public void scheduleCyclic(Runnable task, int period) { */ public void schedule(Runnable task, int delay, boolean multithreaded) { if (delay >= 0) { - addTask(new ScheduledTask(task, multithreaded), currentTick + delay); + addTask(multithreaded ? new ScheduledTask(task, true) : task, currentTick + delay); } else { LOGGER.warn("Scheduled a task with negative delay"); } @@ -111,9 +109,9 @@ public static Command queueOpenScreenCommand(Screen s /** * Schedules a screen to open in the next tick. Used in commands to avoid screen immediately closing after the command is executed. * - * @deprecated Use {@link #queueOpenScreen(Screen)} instead * @param screenSupplier the supplier of the screen to open * @see #queueOpenScreenCommand(Supplier) + * @deprecated Use {@link #queueOpenScreen(Screen)} instead */ @Deprecated(forRemoval = true) public static int queueOpenScreen(Supplier screenSupplier) { @@ -132,15 +130,15 @@ public static int queueOpenScreen(Screen screen) { } public void tick() { - Profiler profiler = Profilers.get(); - profiler.push("skyblockerSchedulerTick"); + Profiler profiler = Profilers.get(); + profiler.push("skyblockerSchedulerTick"); if (tasks.containsKey(currentTick)) { - List currentTickTasks = tasks.get(currentTick); + List currentTickTasks = tasks.get(currentTick); //noinspection ForLoopReplaceableByForEach (or else we get a ConcurrentModificationException) for (int i = 0; i < currentTickTasks.size(); i++) { - ScheduledTask task = currentTickTasks.get(i); - if (!runTask(task, task.multithreaded)) { + Runnable task = currentTickTasks.get(i); + if (!runTask(task, task instanceof ScheduledTask scheduledTask && scheduledTask.multithreaded)) { tasks.computeIfAbsent(currentTick + 1, key -> new ArrayList<>()).add(task); } } @@ -167,12 +165,12 @@ protected boolean runTask(Runnable task, boolean multithreaded) { return true; } - private void addTask(ScheduledTask scheduledTask, int schedule) { + private void addTask(Runnable task, int schedule) { if (tasks.containsKey(schedule)) { - tasks.get(schedule).add(scheduledTask); + tasks.get(schedule).add(task); } else { - List list = new ArrayList<>(); - list.add(scheduledTask); + List list = new ArrayList<>(); + list.add(task); tasks.put(schedule, list); } }