diff options
Diffstat (limited to 'src/main/java/de/hysky/skyblocker')
19 files changed, 926 insertions, 169 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 9840c02f..77b1ec2a 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -3,6 +3,7 @@ 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.debug.Debug; @@ -18,10 +19,7 @@ import de.hysky.skyblocker.skyblock.dungeon.puzzle.boulder.Boulder; import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Waterboard; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker; -import de.hysky.skyblocker.skyblock.dwarven.CrystalsHud; -import de.hysky.skyblocker.skyblock.dwarven.CrystalsLocationsManager; -import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud; -import de.hysky.skyblocker.skyblock.dwarven.MetalDetector; +import de.hysky.skyblocker.skyblock.dwarven.*; import de.hysky.skyblocker.skyblock.end.BeaconHighlighter; import de.hysky.skyblocker.skyblock.end.EnderNodes; import de.hysky.skyblocker.skyblock.end.TheEnd; @@ -102,6 +100,7 @@ public class SkyblockerMod implements ClientModInitializer { @Override public void onInitializeClient() { ClientTickEvents.END_CLIENT_TICK.register(this::tick); + ConfigDataFixer.apply(); Utils.init(); SkyblockerConfigManager.init(); SkyblockerScreen.initClass(); @@ -124,6 +123,7 @@ public class SkyblockerMod implements ClientModInitializer { ItemCooldowns.init(); TabHud.init(); DwarvenHud.init(); + CommissionLabels.init(); CrystalsHud.init(); FarmingHud.init(); LowerSensitivity.init(); diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index c591ba14..b7a711ab 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -5,7 +5,7 @@ import dev.isxander.yacl3.config.v2.api.SerialEntry; public class SkyblockerConfig { @SerialEntry - public int version = 2; + public int version = SkyblockerConfigManager.CONFIG_VERSION; @SerialEntry public GeneralConfig general = new GeneralConfig(); diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index 4b8e56df..688b85aa 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -26,10 +26,11 @@ import java.lang.StackWalker.Option; import java.nio.file.Path; public class SkyblockerConfigManager { - private static final Path PATH = FabricLoader.getInstance().getConfigDir().resolve("skyblocker-2.json"); + public static final int CONFIG_VERSION = 2; + private static final Path CONFIG_FILE = FabricLoader.getInstance().getConfigDir().resolve("skyblocker.json"); private static final ConfigClassHandler<SkyblockerConfig> HANDLER = ConfigClassHandler.createBuilder(SkyblockerConfig.class) .serializer(config -> GsonConfigSerializerBuilder.create(config) - .setPath(PATH) + .setPath(CONFIG_FILE) .setJson5(false) .appendGsonBuilder(builder -> builder .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java index 8809ba44..8dc587fd 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java @@ -160,6 +160,56 @@ public class MiningCategory { .build()) .build()) + + //commission waypoints + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.mining.commissionWaypoints")) + .collapsed(false) + .option(Option.<MiningConfig.CommissionWaypointMode>createBuilder() + .name(Text.translatable("skyblocker.config.mining.commissionWaypoints.mode")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.commissionWaypoints.mode.@Tooltip[0]"), + Text.translatable("skyblocker.config.mining.commissionWaypoints.mode.@Tooltip[1]"), + Text.translatable("skyblocker.config.mining.commissionWaypoints.mode.@Tooltip[2]"), + Text.translatable("skyblocker.config.mining.commissionWaypoints.mode.@Tooltip[3]"), + Text.translatable("skyblocker.config.mining.commissionWaypoints.mode.@Tooltip[4]"))) + .binding(defaults.mining.commissionWaypoints.mode, + () -> config.mining.commissionWaypoints.mode, + newValue -> config.mining.commissionWaypoints.mode = newValue) + .controller(ConfigUtils::createEnumCyclingListController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.mining.commissionWaypoints.useColor")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.commissionWaypoints.useColor.@Tooltip"))) + .binding(defaults.mining.commissionWaypoints.useColor, + () -> config.mining.commissionWaypoints.useColor, + newValue -> config.mining.commissionWaypoints.useColor = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Float>createBuilder() + .name(Text.translatable("skyblocker.config.mining.commissionWaypoints.textScale")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.commissionWaypoints.textScale.@Tooltip"))) + .binding(defaults.mining.commissionWaypoints.textScale, + () -> config.mining.commissionWaypoints.textScale, + newValue -> config.mining.commissionWaypoints.textScale = newValue) + .controller(FloatFieldControllerBuilder::create) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.mining.commissionWaypoints.showBaseCamp")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.commissionWaypoints.showBaseCamp.@Tooltip"))) + .binding(defaults.mining.commissionWaypoints.showBaseCamp, + () -> config.mining.commissionWaypoints.showBaseCamp, + newValue -> config.mining.commissionWaypoints.showBaseCamp = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.mining.commissionWaypoints.showEmissary")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.commissionWaypoints.showEmissary.@Tooltip"))) + .binding(defaults.mining.commissionWaypoints.showEmissary, + () -> config.mining.commissionWaypoints.showEmissary, + newValue -> config.mining.commissionWaypoints.showEmissary = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) .build(); } } diff --git a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java index 1200261d..64c67417 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java @@ -48,14 +48,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button1.item.count, () -> config.quickNav.button1.item.count, newValue -> config.quickNav.button1.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button1.item.nbt, - () -> config.quickNav.button1.item.nbt, - newValue -> config.quickNav.button1.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button1.item.components, + () -> config.quickNav.button1.item.components, + newValue -> config.quickNav.button1.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -97,14 +97,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button2.item.count, () -> config.quickNav.button2.item.count, newValue -> config.quickNav.button2.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button2.item.nbt, - () -> config.quickNav.button2.item.nbt, - newValue -> config.quickNav.button2.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button2.item.components, + () -> config.quickNav.button2.item.components, + newValue -> config.quickNav.button2.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -146,14 +146,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button3.item.count, () -> config.quickNav.button3.item.count, newValue -> config.quickNav.button3.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button3.item.nbt, - () -> config.quickNav.button3.item.nbt, - newValue -> config.quickNav.button3.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button3.item.components, + () -> config.quickNav.button3.item.components, + newValue -> config.quickNav.button3.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -195,14 +195,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button4.item.count, () -> config.quickNav.button4.item.count, newValue -> config.quickNav.button4.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button4.item.nbt, - () -> config.quickNav.button4.item.nbt, - newValue -> config.quickNav.button4.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button4.item.components, + () -> config.quickNav.button4.item.components, + newValue -> config.quickNav.button4.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -244,14 +244,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button5.item.count, () -> config.quickNav.button5.item.count, newValue -> config.quickNav.button5.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button5.item.nbt, - () -> config.quickNav.button5.item.nbt, - newValue -> config.quickNav.button5.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button5.item.components, + () -> config.quickNav.button5.item.components, + newValue -> config.quickNav.button5.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -293,14 +293,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button6.item.count, () -> config.quickNav.button6.item.count, newValue -> config.quickNav.button6.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button6.item.nbt, - () -> config.quickNav.button6.item.nbt, - newValue -> config.quickNav.button6.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button6.item.components, + () -> config.quickNav.button6.item.components, + newValue -> config.quickNav.button6.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -342,14 +342,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button7.item.count, () -> config.quickNav.button7.item.count, newValue -> config.quickNav.button7.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button7.item.nbt, - () -> config.quickNav.button7.item.nbt, - newValue -> config.quickNav.button7.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button7.item.components, + () -> config.quickNav.button7.item.components, + newValue -> config.quickNav.button7.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -391,14 +391,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button8.item.count, () -> config.quickNav.button8.item.count, newValue -> config.quickNav.button8.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button8.item.nbt, - () -> config.quickNav.button8.item.nbt, - newValue -> config.quickNav.button8.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button8.item.components, + () -> config.quickNav.button8.item.components, + newValue -> config.quickNav.button8.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -440,14 +440,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button9.item.count, () -> config.quickNav.button9.item.count, newValue -> config.quickNav.button9.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button9.item.nbt, - () -> config.quickNav.button9.item.nbt, - newValue -> config.quickNav.button9.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button9.item.components, + () -> config.quickNav.button9.item.components, + newValue -> config.quickNav.button9.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -489,14 +489,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button10.item.count, () -> config.quickNav.button10.item.count, newValue -> config.quickNav.button10.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button10.item.nbt, - () -> config.quickNav.button10.item.nbt, - newValue -> config.quickNav.button10.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button10.item.components, + () -> config.quickNav.button10.item.components, + newValue -> config.quickNav.button10.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -538,14 +538,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button11.item.count, () -> config.quickNav.button11.item.count, newValue -> config.quickNav.button11.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button11.item.nbt, - () -> config.quickNav.button11.item.nbt, - newValue -> config.quickNav.button11.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button11.item.components, + () -> config.quickNav.button11.item.components, + newValue -> config.quickNav.button11.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() @@ -587,14 +587,14 @@ public class QuickNavigationCategory { .binding(defaults.quickNav.button12.item.count, () -> config.quickNav.button12.item.count, newValue -> config.quickNav.button12.item.count = newValue) - .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) + .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99)) .build()) .option(Option.<String>createBuilder() - .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) - .binding(defaults.quickNav.button12.item.nbt, - () -> config.quickNav.button12.item.nbt, - newValue -> config.quickNav.button12.item.nbt = newValue) + .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) + .binding(defaults.quickNav.button12.item.components, + () -> config.quickNav.button12.item.components, + newValue -> config.quickNav.button12.item.components = newValue) .controller(StringControllerBuilder::create) .build()) .option(Option.<String>createBuilder() diff --git a/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java index fe845e55..65fd63ca 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java @@ -21,6 +21,9 @@ public class MiningConfig { @SerialEntry public CrystalsWaypoints crystalsWaypoints = new CrystalsWaypoints(); + @SerialEntry + public CommissionWaypoints commissionWaypoints = new CommissionWaypoints(); + public static class DwarvenMines { @SerialEntry public boolean solveFetchur = true; @@ -85,6 +88,37 @@ public class MiningConfig { public boolean findInChat = true; } + public static class CommissionWaypoints { + @SerialEntry + public CommissionWaypointMode mode = CommissionWaypointMode.BOTH; + + @SerialEntry + public boolean useColor = true; + + @SerialEntry + public float textScale = 1; + + @SerialEntry + public boolean showBaseCamp = false; + + @SerialEntry + public boolean showEmissary = true; + } + + public enum CommissionWaypointMode { + OFF, DWARVEN, GLACITE, BOTH; + + @Override + public String toString() { + return switch (this) { + case OFF -> "Off"; + case DWARVEN -> "Dwarven"; + case GLACITE -> "Glacite"; + case BOTH -> "Both"; + }; + } + } + public enum DwarvenHudStyle { SIMPLE, FANCY, CLASSIC; diff --git a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java index 2c4347b6..ba863e33 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java @@ -25,12 +25,12 @@ public class QuickNavigationConfig { */ @SerialEntry public QuickNavItem button4 = new QuickNavItem(true, - new ItemData("leather_chestplate", 1, "tag:{display:{color:8991416}}"), "Wardrobe \\([12]/2\\)", + new ItemData("leather_chestplate", 1, "[minecraft:dyed_color={rgb:8991416}]"), "Wardrobe \\([12]/2\\)", "/wardrobe"); @SerialEntry public QuickNavItem button5 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;-2081424676,-57521078,-2073572414,158072763],Properties:{textures:[{Value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}}}"), + "[minecraft:profile={id:[I;-2081424676,-57521078,-2073572414,158072763],name:\"\",properties:[{name:\"textures\",value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}]"), "Sack of Sacks", "/sacks"); /* REGEX Explanation @@ -44,17 +44,17 @@ public class QuickNavigationConfig { @SerialEntry public QuickNavItem button7 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;-300151517,-631415889,-1193921967,-1821784279],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}}}"), + "[minecraft:profile={id:[I;-300151517,-631415889,-1193921967,-1821784279],name:\"\",properties:[{name:\"textures\",value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}]"), "none", "/hub"); @SerialEntry public QuickNavItem button8 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;1605800870,415127827,-1236127084,15358548],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}}}"), + "[minecraft:profile={id:[I;1605800870,415127827,-1236127084,15358548],name:\"\",properties:[{name:\"textures\",value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}]"), "none", "/warp dungeon_hub"); @SerialEntry public QuickNavItem button9 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;-562285948,532499670,-1705302742,775653035],Properties:{textures:[{Value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}}}"), + "[minecraft:profile={id:[I;-562285948,532499670,-1705302742,775653035],name:\"\",properties:[{name:\"textures\",value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}]"), "Visit prtl", "/visit prtl"); @SerialEntry @@ -68,73 +68,6 @@ public class QuickNavigationConfig { @SerialEntry public QuickNavItem button12 = new QuickNavItem(true, new ItemData("crafting_table"), "Craft Item", "/craft"); - public static class QuickNav { - @SerialEntry - public boolean enableQuickNav = true; - - @SerialEntry - public QuickNavItem button1 = new QuickNavItem(true, new ItemData("diamond_sword"), "Your Skills", "/skills"); - - @SerialEntry - public QuickNavItem button2 = new QuickNavItem(true, new ItemData("painting"), "Collections", "/collection"); - - /* REGEX Explanation - * "Pets" : simple match on letters - * "(?: \\(\\d+\\/\\d+\\))?" : optional match on the non-capturing group for the page in the format " ($number/$number)" - */ - @SerialEntry - public QuickNavItem button3 = new QuickNavItem(true, new ItemData("bone"), "Pets(:? \\(\\d+\\/\\d+\\))?", "/pets"); - - /* REGEX Explanation - * "Wardrobe" : simple match on letters - * " \\([12]\\/2\\)" : match on the page either " (1/2)" or " (2/2)" - */ - @SerialEntry - public QuickNavItem button4 = new QuickNavItem(true, - new ItemData("leather_chestplate", 1, "tag:{display:{color:8991416}}"), "Wardrobe \\([12]/2\\)", - "/wardrobe"); - - @SerialEntry - public QuickNavItem button5 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;-2081424676,-57521078,-2073572414,158072763],Properties:{textures:[{Value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}}}"), - "Sack of Sacks", "/sacks"); - - /* REGEX Explanation - * "(?:Rift )?" : optional match on the non-capturing group "Rift " - * "Storage" : simple match on letters - * "(?: \\([12]\\/2\\))?" : optional match on the non-capturing group " (1/2)" or " (2/2)" - */ - @SerialEntry - public QuickNavItem button6 = new QuickNavItem(true, new ItemData("ender_chest"), - "(?:Rift )?Storage(?: \\(1/2\\))?", "/storage"); - - @SerialEntry - public QuickNavItem button7 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;-300151517,-631415889,-1193921967,-1821784279],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}}}"), - "none", "/hub"); - - @SerialEntry - public QuickNavItem button8 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;1605800870,415127827,-1236127084,15358548],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}}}"), - "none", "/warp dungeon_hub"); - - @SerialEntry - public QuickNavItem button9 = new QuickNavItem(true, new ItemData("player_head", 1, - "tag:{SkullOwner:{Id:[I;-562285948,532499670,-1705302742,775653035],Properties:{textures:[{Value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}}}"), - "Visit prtl", "/visit prtl"); - - @SerialEntry - public QuickNavItem button10 = new QuickNavItem(true, new ItemData("enchanting_table"), "Enchant Item", - "/etable"); - - - @SerialEntry - public QuickNavItem button11 = new QuickNavItem(true, new ItemData("anvil"), "Anvil", "/anvil"); - - @SerialEntry - public QuickNavItem button12 = new QuickNavItem(true, new ItemData("crafting_table"), "Craft Item", "/craft"); - } - public static class QuickNavItem { public QuickNavItem(Boolean render, ItemData itemData, String uiTitle, String clickEvent) { this.render = render; @@ -157,16 +90,16 @@ public class QuickNavigationConfig { } public static class ItemData { - public ItemData(String id, int count, String nbt) { + public ItemData(String id, int count, String components) { this.id = id; this.count = count; - this.nbt = nbt; + this.components = components; } public ItemData(String id) { this.id = id; this.count = 1; - this.nbt = ""; + this.components = "[]"; } @SerialEntry @@ -176,6 +109,6 @@ public class QuickNavigationConfig { public int count; @SerialEntry - public String nbt; + public String components; } } diff --git a/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigDataFixer.java b/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigDataFixer.java new file mode 100644 index 00000000..97261c76 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigDataFixer.java @@ -0,0 +1,90 @@ +package de.hysky.skyblocker.config.datafixer; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.DataFixerBuilder; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.JsonOps; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.datafixer.JsonHelper; +import net.fabricmc.loader.api.FabricLoader; +import org.slf4j.Logger; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.nio.file.Files; +import java.nio.file.Path; + +public class ConfigDataFixer { + protected static final Logger LOGGER = LogUtils.getLogger(); + private static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir(); + public static final DSL.TypeReference CONFIG_TYPE = () -> "config"; + + public static void apply() { + apply(CONFIG_DIR.resolve("skyblocker.json"), CONFIG_DIR.resolve("skyblocker.json.old")); + } + + public static void apply(Path configDir, Path backupDir) { + //User is new - has no config file (or maybe config folder) + if (!Files.exists(CONFIG_DIR) || !Files.exists(configDir)) return; + + //Should never be null if the file exists unless its malformed JSON or something in which case well it gets reset + JsonObject oldConfig = loadConfig(configDir); + if (oldConfig == null || JsonHelper.getInt(oldConfig, "version").orElse(1) == SkyblockerConfigManager.CONFIG_VERSION) return; + + JsonObject newConfig = apply(oldConfig); + + //Write the updated file + if (!writeConfig(configDir, newConfig)) { + LOGGER.error(LogUtils.FATAL_MARKER, "[Skyblocker Config Data Fixer] Failed to fix up config file!"); + writeConfig(backupDir, oldConfig); + } + } + + public static JsonObject apply(JsonObject oldConfig) { + long start = System.currentTimeMillis(); + + JsonObject newConfig = build().update(CONFIG_TYPE, new Dynamic<>(JsonOps.INSTANCE, oldConfig), JsonHelper.getInt(oldConfig, "version").orElse(1), SkyblockerConfigManager.CONFIG_VERSION).getValue().getAsJsonObject(); + + long end = System.currentTimeMillis(); + LOGGER.info("[Skyblocker Config Data Fixer] Applied datafixers in {} ms!", end - start); + return newConfig; + } + + private static DataFixer build() { + DataFixerBuilder builder = new DataFixerBuilder(SkyblockerConfigManager.CONFIG_VERSION); + + builder.addSchema(1, ConfigSchema::new); + Schema schema2 = builder.addSchema(2, Schema::new); + builder.addFixer(new ConfigFix1(schema2, true)); + + return builder.buildUnoptimized(); + } + + private static JsonObject loadConfig(Path path) { + try (BufferedReader reader = Files.newBufferedReader(path)) { + return JsonParser.parseReader(reader).getAsJsonObject(); + } catch (Throwable t) { + LOGGER.error("[Skyblocker Config Data Fixer] Failed to load config file!", t); + } + + return null; + } + + private static boolean writeConfig(Path path, JsonObject config) { + try (BufferedWriter writer = Files.newBufferedWriter(path)) { + SkyblockerMod.GSON.toJson(config, writer); + + return true; + } catch (Throwable t) { + LOGGER.error("[Skyblocker Config Data Fixer] Failed to save config file at {}!", path, t); + } + + return false; + } +} diff --git a/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigFix1.java b/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigFix1.java new file mode 100644 index 00000000..405a2781 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigFix1.java @@ -0,0 +1,227 @@ +package de.hysky.skyblocker.config.datafixer; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFix; +import com.mojang.datafixers.DataFixUtils; +import com.mojang.datafixers.TypeRewriteRule; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.OptionalDynamic; +import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.StringNbtReader; + +import java.util.Locale; + +public class ConfigFix1 extends DataFix { + public ConfigFix1(Schema outputSchema, boolean changesType) { + super(outputSchema, changesType); + } + + @Override + protected TypeRewriteRule makeRule() { + return fixTypeEverywhereTyped( + "ConfigFix1", + getInputSchema().getType(ConfigDataFixer.CONFIG_TYPE), + typed -> typed.update(DSL.remainderFinder(), this::fix) + ); + } + + private <T> Dynamic<T> fix(Dynamic<T> dynamic) { + return fixMisc(fixQuickNav(fixChat(fixSlayers(fixOtherLocations(fixFarming(fixMining(fixCrimsonIsle(fixDungeons(fixHelpers(fixUIAndVisuals(fixGeneral(fixVersion(dynamic))))))))))))); + } + + private <T> Dynamic<T> fixVersion(Dynamic<T> dynamic) { + return dynamic.set("version", dynamic.createInt(DataFixUtils.getVersion(getVersionKey()))); + } + + private static <T> Dynamic<T> fixGeneral(Dynamic<T> dynamic) { + return dynamic.update("general", general -> general.update("itemTooltip", itemTooltip -> itemTooltip.setFieldIfPresent("dungeonQuality", general.get("dungeonQuality").result())).remove("dungeonQuality")); + } + + private static <T> Dynamic<T> fixUIAndVisuals(Dynamic<T> dynamic) { + OptionalDynamic<T> general = dynamic.get("general"); + return dynamic.set("uiAndVisuals", dynamic.emptyMap() + .setFieldIfPresent("compactorDeletorPreview", general.get("compactorDeletorPreview").result()) + .setFieldIfPresent("dontStripSkinAlphaValues", general.get("dontStripSkinAlphaValues").result()) + .setFieldIfPresent("backpackPreviewWithoutShift", general.get("backpackPreviewWithoutShift").result()) + .setFieldIfPresent("hideEmptyTooltips", general.get("hideEmptyTooltips").result()) + .setFieldIfPresent("fancyCraftingTable", general.get("fancyCraftingTable").result()) + .setFieldIfPresent("hideStatusEffectOverlay", general.get("hideStatusEffectOverlay").result()) + .setFieldIfPresent("chestValue", general.get("chestValue").result()) + .setFieldIfPresent("itemCooldown", general.get("itemCooldown").result()) + .setFieldIfPresent("titleContainer", general.get("titleContainer").result()) + .setFieldIfPresent("tabHud", general.get("tabHud").result()) + .setFieldIfPresent("fancyAuctionHouse", general.get("fancyAuctionHouse").result()) + .setFieldIfPresent("bars", general.get("bars").result()) + .setFieldIfPresent("waypoints", general.get("waypoints").result()) + .setFieldIfPresent("teleportOverlay", general.get("teleportOverlay").result()) + .setFieldIfPresent("searchOverlay", general.get("searchOverlay").result()) + .setFieldIfPresent("flameOverlay", general.get("flameOverlay").result()) + ).update("general", newGeneral -> newGeneral + .remove("compactorDeletorPreview") + .remove("dontStripSkinAlphaValues") + .remove("backpackPreviewWithoutShift") + .remove("hideEmptyTooltips") + .remove("fancyCraftingTable") + .remove("hideStatusEffectOverlay") + .remove("chestValue") + .remove("itemCooldown") + .remove("titleContainer") + .remove("tabHud") + .remove("fancyAuctionHouse") + .remove("bars") + .remove("waypoints") + .remove("teleportOverlay") + .remove("searchOverlay") + .remove("flameOverlay") + ); + } + + private static <T> Dynamic<T> fixHelpers(Dynamic<T> dynamic) { + OptionalDynamic<T> general = dynamic.get("general"); + return dynamic.set("helpers", dynamic.emptyMap() + .setFieldIfPresent("enableNewYearCakesHelper", general.get("enableNewYearCakesHelper").result()) + .setFieldIfPresent("mythologicalRitual", general.get("mythologicalRitual").result()) + .setFieldIfPresent("experiments", general.get("experiments").result()) + .setFieldIfPresent("fishing", general.get("fishing").result()) + .setFieldIfPresent("fairySouls", general.get("fairySouls").result()) + ).update("general", newGeneral -> newGeneral + .remove("enableNewYearCakesHelper") + .remove("mythologicalRitual") + .remove("experiments") + .remove("fishing") + .remove("fairySouls") + ); + } + + private static <T> Dynamic<T> fixDungeons(Dynamic<T> dynamic) { + OptionalDynamic<T> general = dynamic.get("general"); + OptionalDynamic<T> dungeons = dynamic.get("locations").get("dungeons"); + return dynamic.set("dungeons", dynamic.emptyMap() + .setFieldIfPresent("fancyPartyFinder", general.get("betterPartyFinder").result()) + .setFieldIfPresent("croesusHelper", dungeons.get("croesusHelper").result()) + .setFieldIfPresent("playerSecretsTracker", dungeons.get("playerSecretsTracker").result()) + .setFieldIfPresent("starredMobGlow", dungeons.get("starredMobGlow").result()) + .setFieldIfPresent("starredMobBoundingBoxes", dungeons.get("starredMobBoundingBoxes").result()) + .setFieldIfPresent("allowDroppingProtectedItems", dungeons.get("allowDroppingProtectedItems").result()) + .set("dungeonMap", dynamic.emptyMap() + .setFieldIfPresent("enableMap", dungeons.get("enableMap").result()) + .setFieldIfPresent("mapScaling", dungeons.get("mapScaling").result()) + .setFieldIfPresent("mapX", dungeons.get("mapX").result()) + .setFieldIfPresent("mapY", dungeons.get("mapY").result()) + ) + .set("puzzleSolvers", dynamic.emptyMap() + .setFieldIfPresent("solveThreeWeirdos", dungeons.get("solveThreeWeirdos").result()) + .setFieldIfPresent("blazeSolver", dungeons.get("blazeSolver").result()) + .setFieldIfPresent("creeperSolver", dungeons.get("creeperSolver").result()) + .setFieldIfPresent("solveTrivia", dungeons.get("solveTrivia").result()) + .setFieldIfPresent("solveTicTacToe", dungeons.get("solveTicTacToe").result()) + .setFieldIfPresent("solveWaterboard", dungeons.get("solveWaterboard").result()) + .setFieldIfPresent("solveBoulder", dungeons.get("solveBoulder").result()) + .setFieldIfPresent("solveIceFill", dungeons.get("solveIceFill").result()) + .setFieldIfPresent("solveSilverfish", dungeons.get("solveSilverfish").result()) + ) + .set("theProfessor", dynamic.emptyMap() + .setFieldIfPresent("fireFreezeStaffTimer", dungeons.get("fireFreezeStaffTimer").result()) + .setFieldIfPresent("floor3GuardianHealthDisplay", dungeons.get("floor3GuardianHealthDisplay").result()) + ) + .setFieldIfPresent("livid", dungeons.get("lividColor").result()) + .setFieldIfPresent("terminals", dungeons.get("terminals").result()) + .setFieldIfPresent("secretWaypoints", dungeons.get("secretWaypoints").result()) + .setFieldIfPresent("mimicMessage", dungeons.get("mimicMessage").result()) + .setFieldIfPresent("doorHighlight", dungeons.get("doorHighlight").result()) + .setFieldIfPresent("dungeonScore", dungeons.get("dungeonScore").result()) + .setFieldIfPresent("dungeonChestProfit", dungeons.get("dungeonChestProfit").result()) + ).update("locations", locations -> locations.remove("dungeons")).update("general", newGeneral -> newGeneral.remove("betterPartyFinder")); + } + + private static <T> Dynamic<T> fixCrimsonIsle(Dynamic<T> dynamic) { + return dynamic.setFieldIfPresent("crimsonIsle", dynamic.get("locations").get("crimsonIsle").result()).update("locations", locations -> locations.remove("crimsonIsle")); + } + + private static <T> Dynamic<T> fixMining(Dynamic<T> dynamic) { + OptionalDynamic<T> dwarvenMines = dynamic.get("locations").get("dwarvenMines"); + return dynamic.set("mining", dynamic.emptyMap() + .setFieldIfPresent("enableDrillFuel", dwarvenMines.get("enableDrillFuel").result()) + .set("dwarvenMines", dynamic.emptyMap() + .setFieldIfPresent("solveFetchur", dwarvenMines.get("solveFetchur").result()) + .setFieldIfPresent("solvePuzzler", dwarvenMines.get("solvePuzzler").result()) + ) + .set("dwarvenHud", dwarvenMines.get("dwarvenHud").result().orElseThrow() + .renameField("x", "commissionsX") + .renameField("y", "commissionsY") + ) + .setFieldIfPresent("crystalsHud", dwarvenMines.get("crystalsHud").result()) + .setFieldIfPresent("crystalsWaypoints", dwarvenMines.get("crystalsWaypoints").result()) + .set("crystalHollows", dynamic.emptyMap() + .setFieldIfPresent("metalDetectorHelper", dwarvenMines.get("metalDetectorHelper").result()) + ) + ).update("locations", locations -> locations.remove("dwarvenMines")); + } + + private static <T> Dynamic<T> fixFarming(Dynamic<T> dynamic) { + return dynamic.set("farming", dynamic.emptyMap() + .setFieldIfPresent("garden", dynamic.get("locations").get("garden").result()) + ).update("locations", locations -> locations.remove("garden")); + } + + private static <T> Dynamic<T> fixOtherLocations(Dynamic<T> dynamic) { + return dynamic.renameField("locations", "otherLocations"); + } + + private static <T> Dynamic<T> fixSlayers(Dynamic<T> dynamic) { + return dynamic.renameField("slayer", "slayers"); + } + + private static <T> Dynamic<T> fixChat(Dynamic<T> dynamic) { + return dynamic.renameField("messages", "chat"); + } + + private static <T> Dynamic<T> fixQuickNav(Dynamic<T> dynamic) { + return dynamic.update("quickNav", quickNav -> quickNav + .update("button1", ConfigFix1::fixQuickNavButton) + .update("button2", ConfigFix1::fixQuickNavButton) + .update("button3", ConfigFix1::fixQuickNavButton) + .update("button4", ConfigFix1::fixQuickNavButton) + .update("button5", ConfigFix1::fixQuickNavButton) + .update("button6", ConfigFix1::fixQuickNavButton) + .update("button7", ConfigFix1::fixQuickNavButton) + .update("button8", ConfigFix1::fixQuickNavButton) + .update("button9", ConfigFix1::fixQuickNavButton) + .update("button10", ConfigFix1::fixQuickNavButton) + .update("button11", ConfigFix1::fixQuickNavButton) + .update("button12", ConfigFix1::fixQuickNavButton)); + } + + private static <T> Dynamic<T> fixQuickNavButton(Dynamic<T> button) { + return button.update("item", item -> item + .renameField("itemName", "id") + .renameAndFixField("nbt", "components", nbt -> fixNbt(item.get("itemName"), nbt)) + ); + } + + private static Dynamic<?> fixNbt(OptionalDynamic<?> id, Dynamic<?> nbt) { + try { + String itemNbt = "{id:\"minecraft:" + id.asString().getOrThrow().toLowerCase(Locale.ROOT) + "\",Count:1"; + String extraNbt = nbt.asString().getOrThrow(); + if (extraNbt.length() > 2) itemNbt += "," + extraNbt; + itemNbt += "}"; + + ItemStack fixed = ItemStackComponentizationFixer.fixUpItem(StringNbtReader.parse(itemNbt)); + + return nbt.createString(ItemStackComponentizationFixer.componentsAsString(fixed)); + } catch (Exception e) { + ConfigDataFixer.LOGGER.error(LogUtils.FATAL_MARKER, "[Skyblocker Config Data Fixer] Failed to convert nbt to components!", e); + } + + return nbt.createString("[]"); + } + + private static <T> Dynamic<T> fixMisc(Dynamic<T> dynamic) { + return dynamic.set("misc", dynamic.emptyMap() + .setFieldIfPresent("richPresence", dynamic.get("richPresence").result()) + ).remove("richPresence"); + } +} diff --git a/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigSchema.java b/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigSchema.java new file mode 100644 index 00000000..4c821169 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/datafixer/ConfigSchema.java @@ -0,0 +1,29 @@ +package de.hysky.skyblocker.config.datafixer; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.datafixers.types.templates.TypeTemplate; + +import java.util.Map; +import java.util.function.Supplier; + +public class ConfigSchema extends Schema { + public ConfigSchema(int versionKey, Schema parent) { + super(versionKey, parent); + } + + @Override + public void registerTypes(Schema schema, Map<String, Supplier<TypeTemplate>> entityTypes, Map<String, Supplier<TypeTemplate>> blockEntityTypes) { + schema.registerType(true, ConfigDataFixer.CONFIG_TYPE, DSL::remainder); + } + + @Override + public Map<String, Supplier<TypeTemplate>> registerEntities(Schema schema) { + return Map.of(); + } + + @Override + public Map<String, Supplier<TypeTemplate>> registerBlockEntities(Schema schema) { + return Map.of(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java index af931eb1..f3db2a25 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java @@ -5,6 +5,7 @@ import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.render.gui.AbstractCustomHypixelGUI; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.PopupScreen; +import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.DirectionalLayoutWidget; import net.minecraft.client.gui.widget.SimplePositioningWidget; @@ -21,7 +22,9 @@ import net.minecraft.text.TextColor; import net.minecraft.util.Colors; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; +import org.lwjgl.glfw.GLFW; +import java.time.Duration; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -56,6 +59,15 @@ public class AuctionViewScreen extends AbstractCustomHypixelGUI<AuctionHouseScre } @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == GLFW.GLFW_KEY_ESCAPE) { + clickSlot(BACK_BUTTON_SLOT); + return true; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override protected void init() { super.init(); verticalLayout.spacing(2).getMainPositioner().alignHorizontalCenter(); @@ -78,10 +90,13 @@ public class AuctionViewScreen extends AbstractCustomHypixelGUI<AuctionHouseScre verticalLayout.forEachChild(this::addDrawableChild); updateLayout(); - addDrawableChild(new ButtonWidget.Builder(Text.literal("<"), button -> this.clickSlot(BACK_BUTTON_SLOT)) + ButtonWidget backButton = new ButtonWidget.Builder(Text.literal("<"), button -> this.clickSlot(BACK_BUTTON_SLOT)) .position(x + backgroundWidth - 16, y + 4) .size(12, 12) - .build()); + .tooltip(Tooltip.of(Text.literal("or press ESC!"))) + .build(); + backButton.setTooltipDelay(Duration.ofSeconds(1)); + addDrawableChild(backButton); } @@ -189,7 +204,7 @@ public class AuctionViewScreen extends AbstractCustomHypixelGUI<AuctionHouseScre @Override public void onSlotChange(AuctionHouseScreenHandler handler, int slotId, ItemStack stack) { - if (stack.isOf(Items.BLACK_STAINED_GLASS_PANE) || slotId == 13) return; + if (stack.isOf(Items.BLACK_STAINED_GLASS_PANE) || slotId == 13 || slotId >= handler.getRows() * 9) return; assert client != null; if (stack.isOf(Items.RED_TERRACOTTA)) { // Red terracotta shows up when you can cancel it changeState(BuyState.CANCELLABLE_AUCTION); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CommissionLabels.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CommissionLabels.java new file mode 100644 index 00000000..a14c71f7 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CommissionLabels.java @@ -0,0 +1,99 @@ +package de.hysky.skyblocker.skyblock.dwarven; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.config.configs.MiningConfig; +import de.hysky.skyblocker.utils.Utils; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.util.math.BlockPos; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class CommissionLabels { + + private static final Map<String, MiningLocationLabel.DwarvenCategory> DWARVEN_LOCATIONS = Arrays.stream(MiningLocationLabel.DwarvenCategory.values()).collect(Collectors.toMap(MiningLocationLabel.DwarvenCategory::toString, Function.identity())); + private static final List<MiningLocationLabel.DwarvenEmissaries> DWARVEN_EMISSARIES = Arrays.stream(MiningLocationLabel.DwarvenEmissaries.values()).toList(); + private static final Map<String, MiningLocationLabel.GlaciteCategory> GLACITE_LOCATIONS = Arrays.stream(MiningLocationLabel.GlaciteCategory.values()).collect(Collectors.toMap(MiningLocationLabel.GlaciteCategory::toString, Function.identity())); + + protected static List<MiningLocationLabel> activeWaypoints = new ArrayList<>(); + + public static void init() { + WorldRenderEvents.AFTER_TRANSLUCENT.register(CommissionLabels::render); + } + + /** + * update the activeWaypoints when there is a change in commissions + * + * @param newCommissions the new commissions to get the waypoints from + * @param completed if there is a commission completed + */ + protected static void update(List<String> newCommissions, boolean completed) { + MiningConfig.CommissionWaypointMode currentMode = SkyblockerConfigManager.get().mining.commissionWaypoints.mode; + if (currentMode == MiningConfig.CommissionWaypointMode.OFF) { + return; + } + activeWaypoints.clear(); + String location = Utils.getIslandArea().substring(2); + //find commission locations in glacite + if (location.equals("Dwarven Base Camp") || location.equals("Glacite Tunnels") || location.equals("Glacite Mineshafts") || location.equals("Glacite Lake")) { + if (currentMode != MiningConfig.CommissionWaypointMode.BOTH && currentMode != MiningConfig.CommissionWaypointMode.GLACITE) { + return; + } + + for (String commission : newCommissions) { + for (Map.Entry<String, MiningLocationLabel.GlaciteCategory> glaciteLocation : GLACITE_LOCATIONS.entrySet()) { + if (commission.contains(glaciteLocation.getKey())) { + MiningLocationLabel.GlaciteCategory category = glaciteLocation.getValue(); + for (BlockPos gemstoneLocation : category.getLocations()) { + activeWaypoints.add(new MiningLocationLabel(category, gemstoneLocation)); + } + } + } + } + //add base waypoint if enabled + if (SkyblockerConfigManager.get().mining.commissionWaypoints.showBaseCamp) { + activeWaypoints.add(new MiningLocationLabel(MiningLocationLabel.GlaciteCategory.CAMPFIRE, MiningLocationLabel.GlaciteCategory.CAMPFIRE.getLocations()[0])); + } + return; + } + //find commission locations in dwarven mines + if (currentMode != MiningConfig.CommissionWaypointMode.BOTH && currentMode != MiningConfig.CommissionWaypointMode.DWARVEN) { + return; + } + + for (String commission : newCommissions) { + for (Map.Entry<String, MiningLocationLabel.DwarvenCategory> dwarvenLocation : DWARVEN_LOCATIONS.entrySet()) { + if (commission.contains(dwarvenLocation.getKey())) { + MiningLocationLabel.DwarvenCategory category = dwarvenLocation.getValue(); + category.isTitanium = commission.contains("Titanium"); + activeWaypoints.add(new MiningLocationLabel(category, category.getLocation())); + } + } + } + //if there is a commission completed and enabled show emissary + if (SkyblockerConfigManager.get().mining.commissionWaypoints.showEmissary && completed) { + for (MiningLocationLabel.DwarvenEmissaries emissaries : DWARVEN_EMISSARIES) { + activeWaypoints.add(new MiningLocationLabel(emissaries, emissaries.getLocation())); + } + } + } + + /** + * render all the active waypoints + * + * @param context render context + */ + private static void render(WorldRenderContext context) { + if (!Utils.isInDwarvenMines() || SkyblockerConfigManager.get().mining.commissionWaypoints.mode == MiningConfig.CommissionWaypointMode.OFF) { + return; + } + for (MiningLocationLabel MiningLocationLabel : activeWaypoints) { + MiningLocationLabel.render(context); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java index a74dbc5e..63430489 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsHud.java @@ -21,7 +21,7 @@ import java.util.Map; public class CrystalsHud { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - protected static final Identifier MAP_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/crystals_map.png"); + protected static final Identifier MAP_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/crystals_map.png"); private static final Identifier MAP_ICON = new Identifier("textures/map/decorations/player.png"); private static final List<String> SMALL_LOCATIONS = List.of("Fairy Grotto", "King Yolkar", "Corleone", "Odawa", "Key Guardian"); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java index 053f3536..dc40f82c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsWaypoint.java @@ -42,7 +42,7 @@ public class CrystalsWaypoint extends Waypoint { @Override public boolean shouldRender() { - return super.shouldRender() ; + return super.shouldRender(); } @Override @@ -84,7 +84,7 @@ public class CrystalsWaypoint extends Waypoint { private final String name; private final float[] colorComponents; - Category(String name,Color color) { + Category(String name, Color color) { this.name = name; this.color = color; this.colorComponents = color.getColorComponents(null); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java index 242c513a..2cf0ea9d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHud.java @@ -168,9 +168,9 @@ public class DwarvenHud { || !Utils.isInCrystalHollows() && !Utils.isInDwarvenMines()) { return; } - + List<String> oldCommissionNames = commissionList.stream().map(Commission::commission).toList(); + boolean oldCompleted = commissionList.stream().anyMatch(commission -> commission.progression.equals("DONE")); commissionList = new ArrayList<>(); - for (PlayerListEntry playerListEntry : CLIENT.getNetworkHandler().getPlayerList().stream().sorted(PlayerListHudAccessor.getOrdering()).toList()) { if (playerListEntry.getDisplayName() == null) { continue; @@ -197,6 +197,11 @@ public class DwarvenHud { glacitePowder = glaciteMatcher.group(0).split(": ")[1]; } } + List<String> newCommissionNames = commissionList.stream().map(Commission::commission).toList(); + boolean newCompleted = commissionList.stream().anyMatch(commission -> commission.progression.equals("DONE")); + if (!oldCommissionNames.equals(newCommissionNames) || oldCompleted != newCompleted) { + CommissionLabels.update(newCommissionNames, newCompleted); + } } // steamroller tactics to get visibility from outside classes (HudCommsWidget) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java new file mode 100644 index 00000000..1f373b55 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/MiningLocationLabel.java @@ -0,0 +1,157 @@ +package de.hysky.skyblocker.skyblock.dwarven; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.render.Renderable; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.MinecraftClient; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public record MiningLocationLabel(Category category, Vec3d centerPos) implements Renderable { + public MiningLocationLabel(Category category, BlockPos pos) { + this(category, pos.toCenterPos()); + } + + private Text getName() { + if (SkyblockerConfigManager.get().mining.commissionWaypoints.useColor) { + return Text.literal(category.getName()).withColor(category.getColor()); + } + return Text.literal(category.getName()); + } + + /** + * Renders the name and distance to the label scaled so can be seen at a distance + * @param context render context + */ + @Override + public void render(WorldRenderContext context) { + Vec3d posUp = centerPos.add(0, 1, 0); + double distance = context.camera().getPos().distanceTo(centerPos); + float scale = (float) (SkyblockerConfigManager.get().mining.commissionWaypoints.textScale * (distance / 10)); + RenderHelper.renderText(context, getName(), posUp, scale, true); + RenderHelper.renderText(context, Text.literal(Math.round(distance) + "m").formatted(Formatting.YELLOW), posUp, scale, MinecraftClient.getInstance().textRenderer.fontHeight + 1, true); + } + + public interface Category { + String getName(); + + int getColor(); //all the color codes are the color of the block the waypoint is for + } + + enum DwarvenCategory implements Category { + LAVA_SPRINGS("Lava Springs", new BlockPos(60, 197, -15)), + CLIFFSIDE_VEINS("Cliffside Veins", new BlockPos(40, 128, 40)), + RAMPARTS_QUARRY("Rampart's Quarry", new BlockPos(-100, 150, -20)), + UPPER_MINES("Upper Mines", new BlockPos(-130, 174, -50)), + ROYAL_MINES("Royal Mines", new BlockPos(130, 154, 30)), + GLACITE_WALKER("Glacite Walker", new BlockPos(0, 128, 150)); + + + boolean isTitanium; + private final String name; + private final BlockPos location; + + DwarvenCategory(String name, BlockPos location) { + this.name = name; + this.location = location; + } + + public BlockPos getLocation() { + return location; + } + + @Override + public String toString() { + return name; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getColor() { + if (isTitanium) { + return 0xd8d6d8; + } + return 0x45bde0; + } + } + + enum DwarvenEmissaries implements Category { + LAVA_SPRINGS(new BlockPos(58, 198, -8)), + CLIFFSIDE_VEINS(new BlockPos(42, 134, 22)), + RAMPARTS_QUARRY(new BlockPos(-72, 153, -10)), + UPPER_MINES(new BlockPos(-132, 174, -50)), + ROYAL_MINES(new BlockPos(171, 150, 31)), + DWARVEN_VILLAGE(new BlockPos(-37, 200, -92)), + DWARVEN_MINES(new BlockPos(89, 198, -92)); + + private final BlockPos location; + + DwarvenEmissaries(BlockPos location) { + + this.location = location; + } + + public BlockPos getLocation() { + return location; + } + + @Override + public String toString() { + return "Emissary"; + } + + @Override + public String getName() { + return "Emissary"; + } + + @Override + public int getColor() { + return 0xffffff; + } + } + + enum GlaciteCategory implements Category { + AQUAMARINE("Aquamarine", 0x334cb1, new BlockPos[]{new BlockPos(-1, 139, 437), new BlockPos(90, 151, 229), new BlockPos(56, 151, 400), new BlockPos(51, 117, 303)}), + ONYX("Onyx", 0x191919, new BlockPos[]{new BlockPos(79, 119, 411), new BlockPos(-14, 132, 386), new BlockPos(18, 136, 370), new BlockPos(16, 138, 411), new BlockPos(-68, 130, 408)}), + PERIDOT("Peridot", 0x667f33, new BlockPos[]{new BlockPos(-61, 147, 302), new BlockPos(91, 122, 397), new BlockPos(-73, 122, 458), new BlockPos(-77, 120, 282)}), + CITRINE("Citrine", 0x664c33, new BlockPos[]{new BlockPos(-104, 144, 244), new BlockPos(39, 119, 386), new BlockPos(-57, 144, 421), new BlockPos(-47, 126, 418)}), + CAMPFIRE("Base Camp", 0x983333, new BlockPos[]{new BlockPos(-7, 126, 229)}); + + private final String name; + private final int color; + private final BlockPos[] location; + + GlaciteCategory(String name, int color, BlockPos[] location) { + this.name = name; + this.color = color; + this.location = location; + } + + public BlockPos[] getLocations() { + return location; + } + + @Override + public String toString() { + return name; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getColor() { + return color; + } + } +} 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 d2fda215..c6caaf41 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 @@ -40,6 +40,8 @@ public class ItemTooltip { public static void getTooltip(ItemStack stack, Item.TooltipContext tooltipContext, TooltipType tooltipType, List<Text> lines) { if (!Utils.isOnSkyblock() || client.player == null) return; + smoothenLines(lines); + String name = getInternalNameFromNBT(stack, false); String internalID = getInternalNameFromNBT(stack, true); String neuName = name; @@ -392,6 +394,15 @@ public class ItemTooltip { return message; } + private static void smoothenLines(List<Text> lines) { + for (int i = 0; i < lines.size(); i++) { + Text line = lines.get(i); + if (line.getString().equals("-----------------")) { + lines.set(i, Text.literal(" ").formatted(Formatting.DARK_GRAY, Formatting.STRIKETHROUGH, Formatting.BOLD)); + } + } + } + // If these options is true beforehand, the client will get first data of these options while loading. // After then, it will only fetch the data if it is on Skyblock. public static int minute = 0; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNav.java b/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNav.java index 5529e466..a6adf66b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNav.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNav.java @@ -11,15 +11,15 @@ import net.fabricmc.fabric.api.client.screen.v1.Screens; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.nbt.StringNbtReader; +import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.regex.PatternSyntaxException; public class QuickNav { @@ -59,10 +59,9 @@ public class QuickNav { private static QuickNavButton parseButton(QuickNavigationConfig.QuickNavItem buttonInfo, String screenTitle, int id) throws CommandSyntaxException { QuickNavigationConfig.ItemData itemData = buttonInfo.item; - String nbtString = "{id:\"minecraft:" + itemData.id.toLowerCase(Locale.ROOT) + "\",Count:1"; - if (itemData.nbt.length() > 2) nbtString += "," + itemData.nbt; - nbtString += "}"; + ItemStack stack = ItemStackComponentizationFixer.fromComponentsString(itemData.id, Math.clamp(itemData.count, 1, 99), itemData.components); boolean uiTitleMatches = false; + try { uiTitleMatches = screenTitle.matches(buttonInfo.uiTitle); } catch (PatternSyntaxException e) { @@ -75,6 +74,6 @@ public class QuickNav { return new QuickNavButton(id, uiTitleMatches, buttonInfo.clickEvent, - ItemStackComponentizationFixer.fixUpItem(StringNbtReader.parse(nbtString))); + stack); } } diff --git a/src/main/java/de/hysky/skyblocker/utils/datafixer/JsonHelper.java b/src/main/java/de/hysky/skyblocker/utils/datafixer/JsonHelper.java new file mode 100644 index 00000000..f7646d31 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/datafixer/JsonHelper.java @@ -0,0 +1,107 @@ +package de.hysky.skyblocker.utils.datafixer; + +import java.util.Optional; +import java.util.OptionalInt; + +import com.google.gson.JsonObject; + +import net.minecraft.util.annotation.MethodsReturnNonnullByDefault; + +/** + * Helper methods to assist in retrieving values nested in JSON objects. + * + * All methods are fully null safe, whether it be from passing a {@code null} root object or from encountering a nonexistent or null object/value. + * + * @author AzureAaron + * @see <a href="https://github.com/AzureAaron/aaron-mod/blob/1.20/src/main/java/net/azureaaron/mod/utils/JsonHelper.java">Aaron's Mod's JSON Helper</a> + */ +@MethodsReturnNonnullByDefault +public class JsonHelper { + + public static OptionalInt getInt(JsonObject root, String path) { + //If root is null + if (root == null) return OptionalInt.empty(); + + //Fast path for if we just want the field itself + if (!path.contains(".")) { + return root.has(path) && !root.get(path).isJsonNull() ? OptionalInt.of(root.get(path).getAsInt()) : OptionalInt.empty(); + } + + String[] split = path.split("\\."); + String propertyName = split[split.length - 1]; + String[] objects2Traverse = new String[split.length - 1]; + + //Get the traversal path + System.arraycopy(split, 0, objects2Traverse, 0, split.length - 1); + + JsonObject currentLevel = root; + + for (String objectName : objects2Traverse) { + if (currentLevel.has(objectName) && !currentLevel.get(objectName).isJsonNull()) { + currentLevel = currentLevel.getAsJsonObject(objectName); + } else { + return OptionalInt.empty(); + } + } + + return currentLevel.has(propertyName) && !currentLevel.get(propertyName).isJsonNull() ? OptionalInt.of(currentLevel.get(propertyName).getAsInt()) : OptionalInt.empty(); + } + + public static Optional<Boolean> getBoolean(JsonObject root, String path) { + //If root is null + if (root == null) return Optional.empty(); + + //Fast path for if we just want the field itself + if (!path.contains(".")) { + return root.has(path) && !root.get(path).isJsonNull() ? Optional.of(root.get(path).getAsBoolean()) : Optional.empty(); + } + + String[] split = path.split("\\."); + String propertyName = split[split.length - 1]; + String[] objects2Traverse = new String[split.length - 1]; + + //Get the traversal path + System.arraycopy(split, 0, objects2Traverse, 0, split.length - 1); + + JsonObject currentLevel = root; + + for (String objectName : objects2Traverse) { + if (currentLevel.has(objectName) && !currentLevel.get(objectName).isJsonNull()) { + currentLevel = currentLevel.getAsJsonObject(objectName); + } else { + return Optional.empty(); + } + } + + return currentLevel.has(propertyName) && !currentLevel.get(propertyName).isJsonNull() ? Optional.of(currentLevel.get(propertyName).getAsBoolean()) : Optional.empty(); + } + + public static Optional<String> getString(JsonObject root, String path) { + //If root is null + if (root == null) return Optional.empty(); + + //Fast path for if we just want the field itself + if (!path.contains(".")) { + return root.has(path) && !root.get(path).isJsonNull() ? Optional.of(root.get(path).getAsString()) : Optional.empty(); + } + + String[] split = path.split("\\."); + String propertyName = split[split.length - 1]; + String[] objects2Traverse = new String[split.length - 1]; + + //Get the traversal path + System.arraycopy(split, 0, objects2Traverse, 0, split.length - 1); + + JsonObject currentLevel = root; + + for (String objectName : objects2Traverse) { + if (currentLevel.has(objectName) && !currentLevel.get(objectName).isJsonNull()) { + currentLevel = currentLevel.getAsJsonObject(objectName); + } else { + return Optional.empty(); + } + } + + return currentLevel.has(propertyName) && !currentLevel.get(propertyName).isJsonNull() ? Optional.of(currentLevel.get(propertyName).getAsString()) : Optional.empty(); + } +} |