diff options
author | msg-programs <msgdoesstuff@gmail.com> | 2023-08-14 18:18:00 +0200 |
---|---|---|
committer | msg-programs <msgdoesstuff@gmail.com> | 2023-08-14 18:18:00 +0200 |
commit | cfef2d401c80d58871c7d5c236946777d1915d00 (patch) | |
tree | 52f7eea8f0fb18bcc3327e098838fff07f61b8a1 /src/main | |
parent | 54133f9aa5d4b5134943d3e8d2916100ae7e1f3a (diff) | |
parent | ada74ef6b54168a1793c76bf3dd1c2c9d379c604 (diff) | |
download | Skyblocker-cfef2d401c80d58871c7d5c236946777d1915d00.tar.gz Skyblocker-cfef2d401c80d58871c7d5c236946777d1915d00.tar.bz2 Skyblocker-cfef2d401c80d58871c7d5c236946777d1915d00.zip |
Merge branch 'master' of https://github.com/SkyblockerMod/Skyblocker into json-tabhud
# Conflicts:
# src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java
Pull new upstream things into branch
Diffstat (limited to 'src/main')
19 files changed, 329 insertions, 47 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java index 6014ed51..8c09f5b1 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java +++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java @@ -11,6 +11,8 @@ import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonBlaze; import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonMap; import me.xmrvizzy.skyblocker.skyblock.dungeon.LividColor; import me.xmrvizzy.skyblocker.skyblock.dwarven.DwarvenHud; +import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorDyeColors; +import me.xmrvizzy.skyblocker.skyblock.item.CustomItemNames; import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip; import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup; import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; @@ -74,6 +76,7 @@ public class SkyblockerMod implements ClientModInitializer { WikiLookup.init(); ItemRegistry.init(); NEURepo.init(); + FairySouls.init(); BackpackPreview.init(); QuickNav.init(); DwarvenHud.init(); @@ -82,7 +85,6 @@ public class SkyblockerMod implements ClientModInitializer { DiscordRPCManager.init(); LividColor.init(); FishingHelper.init(); - FairySouls.init(); TabHud.init(); DungeonMap.init(); TheRift.init(); @@ -90,6 +92,8 @@ public class SkyblockerMod implements ClientModInitializer { ScreenMaster.init(); OcclusionCulling.init(); TeleportOverlay.init(); + CustomItemNames.init(); + CustomArmorDyeColors.init(); containerSolverManager.init(); scheduler.scheduleCyclic(Utils::update, 20); scheduler.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 100); diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index ec4bc3ce..5110b181 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -1,16 +1,25 @@ package me.xmrvizzy.skyblocker.config; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import me.shedaniel.autoconfig.AutoConfig; import me.shedaniel.autoconfig.ConfigData; import me.shedaniel.autoconfig.annotation.Config; import me.shedaniel.autoconfig.annotation.ConfigEntry; +import me.shedaniel.autoconfig.serializer.ConfigSerializer; import me.shedaniel.autoconfig.serializer.GsonConfigSerializer; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.chat.ChatFilterResult; +import me.xmrvizzy.skyblocker.utils.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.resource.language.I18n; +import net.minecraft.text.Style; +import net.minecraft.text.Text; import java.util.ArrayList; import java.util.List; @@ -187,6 +196,10 @@ public class SkyblockerConfig implements ConfigData { @ConfigEntry.Gui.Excluded public List<Integer> lockedSlots = new ArrayList<>(); + + public Object2ObjectOpenHashMap<String, Text> customItemNames = new Object2ObjectOpenHashMap<>(); + + public Object2IntOpenHashMap<String> customDyeColors = new Object2IntOpenHashMap<>(); } public static class TabHudConf { @@ -428,13 +441,13 @@ public class SkyblockerConfig implements ConfigData { public boolean enabled = true; @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) @ConfigEntry.Gui.Tooltip(count = 3) - public Style style = Style.SIMPLE; + public DwarvenHudStyle style = DwarvenHudStyle.SIMPLE; public boolean enableBackground = true; public int x = 10; public int y = 10; } - public enum Style { + public enum DwarvenHudStyle { SIMPLE, FANCY, CLASSIC; @@ -528,10 +541,18 @@ public class SkyblockerConfig implements ConfigData { } /** - * Registers the config to AutoConfig and register commands to open the config screen. + * Registers the config to AutoConfig and registers commands to open the config screen. */ public static void init() { - AutoConfig.register(SkyblockerConfig.class, GsonConfigSerializer::new); + Gson gson = new GsonBuilder() + .setPrettyPrinting() + .registerTypeHierarchyAdapter(Text.class, new Text.Serializer()) + .registerTypeHierarchyAdapter(Style.class, new Style.Serializer()) + .create(); + + ConfigSerializer.Factory<SkyblockerConfig> serializer = (cfg, cfgClass) -> new GsonConfigSerializer<>(cfg, cfgClass, gson); + + AutoConfig.register(SkyblockerConfig.class, serializer); ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options"))))); } @@ -543,10 +564,14 @@ public class SkyblockerConfig implements ConfigData { */ private static LiteralArgumentBuilder<FabricClientCommandSource> optionsLiteral(String name) { // Don't immediately open the next screen as it will be closed by ChatScreen right after this command is executed - return literal(name).executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(AutoConfig.getConfigScreen(SkyblockerConfig.class, null))); + return literal(name).executes(Scheduler.queueOpenScreenCommand(AutoConfig.getConfigScreen(SkyblockerConfig.class, null))); } public static SkyblockerConfig get() { return AutoConfig.getConfigHolder(SkyblockerConfig.class).getConfig(); } + + public static void save() { + AutoConfig.getConfigHolder(SkyblockerConfig.class).save(); + } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/DyeableItemMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/DyeableItemMixin.java new file mode 100644 index 00000000..f04c4cdd --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/DyeableItemMixin.java @@ -0,0 +1,27 @@ +package me.xmrvizzy.skyblocker.mixin; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Utils; +import net.minecraft.item.DyeableItem; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(DyeableItem.class) +public interface DyeableItemMixin { + @ModifyReturnValue(method = "getColor", at = @At("RETURN")) + private int skyblocker$customDyeColor(int originalColor, ItemStack stack) { + NbtCompound nbt = stack.getNbt(); + + if (Utils.isOnSkyblock() && nbt != null && nbt.contains("ExtraAttributes")) { + NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes"); + String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null; + + return SkyblockerConfig.get().general.customDyeColors.getOrDefault(itemUuid, originalColor); + } + + return originalColor; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ItemStackMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ItemStackMixin.java new file mode 100644 index 00000000..63dc6624 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/ItemStackMixin.java @@ -0,0 +1,33 @@ +package me.xmrvizzy.skyblocker.mixin; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; + +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Utils; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.text.Text; + +@Mixin(ItemStack.class) +public abstract class ItemStackMixin { + @Shadow + @Nullable + private NbtCompound nbt; + + @ModifyReturnValue(method = "getName", at = @At("RETURN")) + private Text skyblocker$customItemNames(Text original) { + if (Utils.isOnSkyblock() && nbt != null && nbt.contains("ExtraAttributes")) { + NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes"); + String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null; + + return SkyblockerConfig.get().general.customItemNames.getOrDefault(itemUuid, original); + } + + return original; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java index ccffdcca..b7c4ff2f 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java @@ -20,6 +20,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.DyeColor; import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,15 +33,31 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.lit public class FairySouls { private static final Logger LOGGER = LoggerFactory.getLogger(FairySouls.class); private static CompletableFuture<Void> fairySoulsLoaded; + private static int maxSouls = 0; private static final Map<String, Set<BlockPos>> fairySouls = new HashMap<>(); private static final Map<String, Map<String, Set<BlockPos>>> foundFairies = new HashMap<>(); + public static CompletableFuture<Void> runAsyncAfterFairySoulsLoad(Runnable runnable) { + if (fairySoulsLoaded == null) { + LOGGER.error("Fairy Souls have not being initialized yet! Please ensure the Fairy Souls module is initialized before modules calling this method in SkyblockerMod#onInitializeClient. This error can be safely ignore in a test environment."); + return CompletableFuture.completedFuture(null); + } + return fairySoulsLoaded.thenRunAsync(runnable); + } + + public static int getFairySoulsSize(@Nullable String location) { + return location == null ? maxSouls : fairySouls.get(location).size(); + } + public static void init() { fairySoulsLoaded = NEURepo.runAsyncAfterLoad(() -> { try { BufferedReader reader = new BufferedReader(new FileReader(NEURepo.LOCAL_REPO_DIR.resolve("constants").resolve("fairy_souls.json").toFile())); for (Map.Entry<String, JsonElement> fairySoulJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { if (fairySoulJson.getKey().equals("//") || fairySoulJson.getKey().equals("Max Souls")) { + if (fairySoulJson.getKey().equals("Max Souls")) { + maxSouls = fairySoulJson.getValue().getAsInt(); + } continue; } ImmutableSet.Builder<BlockPos> fairySoulsForLocation = ImmutableSet.builder(); diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java index 29a6e687..040c8aed 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java @@ -1,7 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon; -import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; @@ -56,6 +56,6 @@ public class DungeonMap { ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker") .then(ClientCommandManager.literal("hud") .then(ClientCommandManager.literal("dungeonmap") - .executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(DungeonMapConfigScreen::new)))))); + .executes(Scheduler.queueOpenScreenCommand(DungeonMapConfigScreen::new)))))); } }
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/Trivia.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/Trivia.java index f7598af5..9c7452ac 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/Trivia.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/Trivia.java @@ -1,19 +1,18 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; - import me.xmrvizzy.skyblocker.chat.ChatFilterResult; import me.xmrvizzy.skyblocker.chat.ChatPatternListener; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.skyblock.FairySouls; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.regex.Matcher; public class Trivia extends ChatPatternListener { private static final Map<String, String[]> answers; @@ -38,8 +37,7 @@ public class Trivia extends ChatPatternListener { MinecraftClient.getInstance().player.sendMessage(Text.of(" " + Formatting.GOLD + matcher.group(2) + Formatting.RED + " " + riddle), false); return player != null; } - } else - updateSolutions(matcher.group(0)); + } else updateSolutions(matcher.group(0)); return false; } @@ -56,7 +54,7 @@ public class Trivia extends ChatPatternListener { } static { - answers = new HashMap<>(); + answers = Collections.synchronizedMap(new HashMap<>()); answers.put("What is the status of The Watcher?", new String[]{"Stalker"}); answers.put("What is the status of Bonzo?", new String[]{"New Necromancer"}); answers.put("What is the status of Scarf?", new String[]{"Apprentice Necromancer"}); @@ -69,18 +67,6 @@ public class Trivia extends ChatPatternListener { answers.put("What is the status of Storm?", new String[]{"The Wither Lords"}); answers.put("What is the status of Necron?", new String[]{"The Wither Lords"}); answers.put("What is the status of Maxor, Storm, Goldor and Necron?", new String[]{"The Wither Lords"}); - answers.put("How many total Fairy Souls are there?", new String[]{"242 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Spider's Den?", new String[]{"19 Fairy Souls"}); - answers.put("How many Fairy Souls are there in The End?", new String[]{"12 Fairy Souls"}); - answers.put("How many Fairy Souls are there in The Farming Islands?", new String[]{"20 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Crimson Isle?", new String[]{"29 Fairy Souls"}); - answers.put("How many Fairy Souls are there in The Park?", new String[]{"11 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Jerry's Workshop?", new String[]{"5 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Hub?", new String[]{"79 Fairy Souls"}); - answers.put("How many Fairy Souls are there in The Hub?", new String[]{"79 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Deep Caverns?", new String[]{"21 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Gold Mine?", new String[]{"12 Fairy Souls"}); - answers.put("How many Fairy Souls are there in Dungeon Hub?", new String[]{"7 Fairy Souls"}); answers.put("Which brother is on the Spider's Den?", new String[]{"Rick"}); answers.put("What is the name of Rick's brother?", new String[]{"Pat"}); answers.put("What is the name of the Painter in the Hub?", new String[]{"Marco"}); @@ -88,10 +74,27 @@ public class Trivia extends ChatPatternListener { answers.put("What is the name of the lady of the Nether?", new String[]{"Elle"}); answers.put("Which villager in the Village gives you a Rogue Sword?", new String[]{"Jamie"}); answers.put("How many unique minions are there?", new String[]{"59 Minions"}); - answers.put("Which of these enemies does not spawn in the Spider's Den?", new String[]{"Zombie Spider", "Cave Spider", "Wither Skeleton", - "Dashing Spooder", "Broodfather", "Night Spider"}); + answers.put("Which of these enemies does not spawn in the Spider's Den?", new String[]{"Zombie Spider", "Cave Spider", "Wither Skeleton", "Dashing Spooder", "Broodfather", "Night Spider"}); answers.put("Which of these monsters only spawns at night?", new String[]{"Zombie Villager", "Ghast"}); - answers.put("Which of these is not a dragon in The End?", new String[]{"Zoomer Dragon", "Weak Dragon", "Stonk Dragon", "Holy Dragon", "Boomer Dragon", - "Booger Dragon", "Older Dragon", "Elder Dragon", "Stable Dragon", "Professor Dragon"}); + answers.put("Which of these is not a dragon in The End?", new String[]{"Zoomer Dragon", "Weak Dragon", "Stonk Dragon", "Holy Dragon", "Boomer Dragon", "Booger Dragon", "Older Dragon", "Elder Dragon", "Stable Dragon", "Professor Dragon"}); + FairySouls.runAsyncAfterFairySoulsLoad(() -> { + answers.put("How many total Fairy Souls are there?", getFairySoulsSizeString(null)); + answers.put("How many Fairy Souls are there in Spider's Den?", getFairySoulsSizeString("combat_1")); + answers.put("How many Fairy Souls are there in The End?", getFairySoulsSizeString("combat_3")); + answers.put("How many Fairy Souls are there in The Farming Islands?", getFairySoulsSizeString("farming_1")); + answers.put("How many Fairy Souls are there in Crimson Isle?", getFairySoulsSizeString("crimson_isle")); + answers.put("How many Fairy Souls are there in The Park?", getFairySoulsSizeString("foraging_1")); + answers.put("How many Fairy Souls are there in Jerry's Workshop?", getFairySoulsSizeString("winter")); + answers.put("How many Fairy Souls are there in Hub?", getFairySoulsSizeString("hub")); + answers.put("How many Fairy Souls are there in The Hub?", getFairySoulsSizeString("hub")); + answers.put("How many Fairy Souls are there in Deep Caverns?", getFairySoulsSizeString("mining_2")); + answers.put("How many Fairy Souls are there in Gold Mine?", getFairySoulsSizeString("mining_1")); + answers.put("How many Fairy Souls are there in Dungeon Hub?", getFairySoulsSizeString("dungeon_hub")); + }); + } + + @NotNull + private static String[] getFairySoulsSizeString(@Nullable String location) { + return new String[]{"%d Fairy Souls".formatted(FairySouls.getFairySoulsSize(location))}; } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java index 999a3163..083cdcdf 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java @@ -1,8 +1,8 @@ package me.xmrvizzy.skyblocker.skyblock.dwarven; -import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.hud.HudCommsWidget; +import me.xmrvizzy.skyblocker.utils.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; @@ -39,12 +39,10 @@ public class DwarvenHud { .collect(Collectors.toList()); public static void init() { - ClientCommandRegistrationCallback.EVENT.register((dispatcher, - registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker") - .then(ClientCommandManager.literal("hud") - .then(ClientCommandManager.literal("dwarven") - .executes(context -> SkyblockerMod.getInstance().scheduler - .queueOpenScreen(DwarvenHudConfigScreen::new)))))); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker") + .then(ClientCommandManager.literal("hud") + .then(ClientCommandManager.literal("dwarven") + .executes(Scheduler.queueOpenScreenCommand(DwarvenHudConfigScreen::new)))))); HudRenderCallback.EVENT.register((context, tickDelta) -> { if (!SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enabled diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java new file mode 100644 index 00000000..9385b4a1 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java @@ -0,0 +1,81 @@ +package me.xmrvizzy.skyblocker.skyblock.item; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Utils; +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.command.CommandRegistryAccess; +import net.minecraft.item.DyeableArmorItem; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.text.Text; + +public class CustomArmorDyeColors { + public static void init() { + ClientCommandRegistrationCallback.EVENT.register(CustomArmorDyeColors::registerCommands); + } + + private static void registerCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) { + dispatcher.register(ClientCommandManager.literal("skyblocker") + .then(ClientCommandManager.literal("dyeColor") + .executes(context -> customizeDyeColor(context.getSource(), null)) + .then(ClientCommandManager.argument("hexCode", StringArgumentType.string()) + .executes(context -> customizeDyeColor(context.getSource(), StringArgumentType.getString(context, "hexCode")))))); + } + + @SuppressWarnings("SameReturnValue") + private static int customizeDyeColor(FabricClientCommandSource source, String hex) { + ItemStack heldItem = source.getPlayer().getMainHandStack(); + NbtCompound nbt = (heldItem != null) ? heldItem.getNbt() : null; + + if (hex != null && !isHexadecimalColor(hex)) { + source.sendError(Text.translatable("skyblocker.customDyeColors.invalidHex")); + return Command.SINGLE_SUCCESS; + } + + if (Utils.isOnSkyblock() && heldItem != null) { + if (heldItem.getItem() instanceof DyeableArmorItem) { + if (nbt != null && nbt.contains("ExtraAttributes")) { + NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes"); + String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null; + + if (itemUuid != null) { + Object2IntOpenHashMap<String> customDyeColors = SkyblockerConfig.get().general.customDyeColors; + + if (hex == null) { + if (customDyeColors.containsKey(itemUuid)) { + customDyeColors.removeInt(itemUuid); + SkyblockerConfig.save(); + source.sendFeedback(Text.translatable("skyblocker.customDyeColors.removed")); + } else { + source.sendFeedback(Text.translatable("skyblocker.customDyeColors.neverHad")); + } + } else { + customDyeColors.put(itemUuid, Integer.decode("0x" + hex.replace("#", "")).intValue()); + SkyblockerConfig.save(); + source.sendFeedback(Text.translatable("skyblocker.customDyeColors.added")); + } + } else { + source.sendError(Text.translatable("skyblocker.customDyeColors.noItemUuid")); + } + } + } else { + source.sendError(Text.translatable("skyblocker.customDyeColors.notDyeable")); + return Command.SINGLE_SUCCESS; + } + } else { + source.sendError(Text.translatable("skyblocker.customDyeColors.unableToSetColor")); + } + + return Command.SINGLE_SUCCESS; + } + + private static boolean isHexadecimalColor(String s) { + return s.replace("#", "").chars().allMatch(c -> "0123456789ABCDEFabcdef".indexOf(c) >= 0) && s.replace("#", "").length() == 6; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java new file mode 100644 index 00000000..5d410947 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java @@ -0,0 +1,66 @@ +package me.xmrvizzy.skyblocker.skyblock.item; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Utils; +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.command.CommandRegistryAccess; +import net.minecraft.command.argument.TextArgumentType; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.text.Text; + +public class CustomItemNames { + public static void init() { + ClientCommandRegistrationCallback.EVENT.register(CustomItemNames::registerCommands); + } + + private static void registerCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) { + dispatcher.register(ClientCommandManager.literal("skyblocker") + .then(ClientCommandManager.literal("renameItem") + .executes(context -> renameItem(context.getSource(), null)) + .then(ClientCommandManager.argument("textComponent", TextArgumentType.text()) + .executes(context -> renameItem(context.getSource(), context.getArgument("textComponent", Text.class)))))); + } + + @SuppressWarnings("SameReturnValue") + private static int renameItem(FabricClientCommandSource source, Text text) { + ItemStack heldItem = source.getPlayer().getMainHandStack(); + NbtCompound nbt = (heldItem != null) ? heldItem.getNbt() : null; + + if (Utils.isOnSkyblock() && nbt != null && nbt.contains("ExtraAttributes")) { + NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes"); + String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null; + + if (itemUuid != null) { + Object2ObjectOpenHashMap<String, Text> customItemNames = SkyblockerConfig.get().general.customItemNames; + + if (text == null) { + if (customItemNames.containsKey(itemUuid)) { + //Remove custom item name when the text argument isn't passed + customItemNames.remove(itemUuid); + SkyblockerConfig.save(); + source.sendFeedback(Text.translatable("skyblocker.customItemNames.removed")); + } else { + source.sendFeedback(Text.translatable("skyblocker.customItemNames.neverHad")); + } + } else { + //If the text is provided then set the item's custom name to it + customItemNames.put(itemUuid, text); + SkyblockerConfig.save(); + source.sendFeedback(Text.translatable("skyblocker.customItemNames.added")); + } + } else { + source.sendError(Text.translatable("skyblocker.customItemNames.noItemUuid")); + } + } else { + source.sendError(Text.translatable("skyblocker.customItemNames.unableToSetName")); + } + + return Command.SINGLE_SUCCESS; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java index 44077b3e..36ff98c9 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java @@ -7,6 +7,7 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; @@ -179,7 +180,7 @@ public class Shortcuts { } return Command.SINGLE_SUCCESS; // Queue the screen or else the screen will be immediately closed after executing this command - })).then(literal("shortcuts").executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(ShortcutsConfigScreen::new)))); + })).then(literal("shortcuts").executes(Scheduler.queueOpenScreenCommand(ShortcutsConfigScreen::new)))); } private static String modifyCommand(String command) { diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/DungeonDeathWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/DungeonDeathWidget.java index 6cdf946a..80134b66 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/DungeonDeathWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/DungeonDeathWidget.java @@ -20,7 +20,7 @@ public class DungeonDeathWidget extends Widget { // match the deaths entry // group 1: amount of deaths - private static final Pattern DEATH_PATTERN = Pattern.compile("\\S*: \\((?<deathnum>\\d+)\\).*"); + private static final Pattern DEATH_PATTERN = Pattern.compile("Team Deaths: (?<deathnum>\\d+).*"); public DungeonDeathWidget() { super(TITLE, Formatting.DARK_PURPLE.getColorValue()); diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/MessageScheduler.java b/src/main/java/me/xmrvizzy/skyblocker/utils/MessageScheduler.java index ac6aa293..ffb16632 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/MessageScheduler.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/MessageScheduler.java @@ -32,10 +32,10 @@ public class MessageScheduler extends Scheduler { private void sendMessage(String message) { if (MinecraftClient.getInstance().player != null) { - MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(message); if (message.startsWith("/")) { MinecraftClient.getInstance().player.networkHandler.sendCommand(message.substring(1)); } else { + MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(message); MinecraftClient.getInstance().player.networkHandler.sendChatMessage(message); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java index fbe79ade..1ee3e040 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java @@ -2,6 +2,7 @@ package me.xmrvizzy.skyblocker.utils; import com.mojang.brigadier.Command; import me.xmrvizzy.skyblocker.SkyblockerMod; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import org.slf4j.Logger; @@ -54,10 +55,15 @@ public class Scheduler { } } + public static Command<FabricClientCommandSource> queueOpenScreenCommand(Supplier<Screen> screenSupplier) { + return context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(screenSupplier); + } + /** * Schedules a screen to open in the next tick. Used in commands to avoid screen immediately closing after the command is executed. * * @param screenSupplier the supplier of the screen to open + * @see #queueOpenScreenCommand(Supplier) */ public int queueOpenScreen(Supplier<Screen> screenSupplier) { MinecraftClient.getInstance().send(() -> MinecraftClient.getInstance().setScreen(screenSupplier.get())); diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java index 71e3b44f..25e481b9 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java @@ -129,9 +129,10 @@ public class Utils { return; } String string = sidebar.toString(); + String serverAddress = (client.getCurrentServerEntry() != null) ? client.getCurrentServerEntry().address : ""; if (sidebar.isEmpty()) return; - if (sidebar.get(sidebar.size() - 1).equals("www.hypixel.net")) { + if (serverAddress.contains("hypixel.net") || serverAddress.contains("hypixel.io")) { if (!isOnHypixel) { isOnHypixel = true; } diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java b/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java index 7b92fff6..a485d37b 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java @@ -2,6 +2,7 @@ package me.xmrvizzy.skyblocker.utils.title; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; @@ -29,7 +30,7 @@ public class TitleContainer { ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker") .then(ClientCommandManager.literal("hud") .then(ClientCommandManager.literal("titleContainer") - .executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(TitleContainerConfigScreen::new)))))); + .executes(Scheduler.queueOpenScreenCommand(TitleContainerConfigScreen::new)))))); } /** diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index db0f1526..c87959a4 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -292,5 +292,19 @@ "skyblocker.shortcuts.deleteQuestion": "Are you sure you want to remove this shortcut?", "skyblocker.shortcuts.deleteWarning": "Shortcut '%s' will be lost forever! (A long time!)", "skyblocker.shortcuts.new": "New Shortcut", - "skyblocker.shortcuts.commandSuggestionTooltip": "Due to limitations of Minecraft, command suggestions will only work after a restart of the game." + "skyblocker.shortcuts.commandSuggestionTooltip": "Due to limitations of Minecraft, command suggestions will only work after a restart of the game.", + + "skyblocker.customItemNames.removed": "§b[§6Skyblocker§b] §fRemoved this item's custom name.", + "skyblocker.customItemNames.neverHad": "§b[§6Skyblocker§b] §fThis item doesn't have a custom name set, but why not add one? ;)", + "skyblocker.customItemNames.added": "§b[§6Skyblocker§b] §fSet a custom name for your currently held item!", + "skyblocker.customItemNames.noItemUuid": "§b[§6Skyblocker§b] §cYou must be holding an item that has a uuid in order to set a custom name!", + "skyblocker.customItemNames.unableToSetName": "§b[§6Skyblocker§b] §cUnable to set a custom item name :( (Are you in skyblock?, are you holding an item?)", + + "skyblocker.customDyeColors.invalidHex": "§b[§6Skyblocker§b] §cInvalid HEX color code!", + "skyblocker.customDyeColors.notDyeable": "§b[§6Skyblocker§b] §cThis item isn't a dyeable armor piece!", + "skyblocker.customDyeColors.removed": "§b[§6Skyblocker§b] §fRemoved this item's custom dye color.", + "skyblocker.customDyeColors.neverHad": "§b[§6Skyblocker§b] §fThis item doesn't have a custom dye color set, but why not add one? ;)", + "skyblocker.customDyeColors.added": "§b[§6Skyblocker§b] §fSet a custom dye color for your currently held item!", + "skyblocker.customDyeColors.noItemUuid": "§b[§6Skyblocker§b] §cYou must be holding an item that has a uuid in order to set a custom dye color!", + "skyblocker.customDyeColors.unableToSetColor": "§b[§6Skyblocker§b] §cUnable to set a custom dye color :( (Are you in skyblock?)" } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 71d9763e..596fe8cf 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -37,6 +37,9 @@ "cloth-config2": "*", "minecraft": "~1.20" }, + "conflicts": { + "immediatelyfast": "<=1.1.26+1.20.1" + }, "custom": { "modmenu": { "links": { diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 360a966a..522c3af0 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -6,11 +6,13 @@ "ClientPlayerEntityMixin", "ClientPlayNetworkHandlerMixin", "DrawContextMixin", + "DyeableItemMixin", "FarmlandBlockMixin", "GenericContainerScreenHandlerMixin", "HandledScreenMixin", "InGameHudMixin", "InventoryScreenMixin", + "ItemStackMixin", "LeverBlockMixin", "MinecraftClientMixin", "PlayerListHudMixin", |