From 00340f5d7df495f7351159e9da86e74b1b5fd2a9 Mon Sep 17 00:00:00 2001 From: Kevin <92656833+kevinthegreat1@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:53:55 -0400 Subject: [PATCH] Refactor NEU Repo (#364) Add RepoParser Fix Golden Dragon stats leveling Add wiki option Fix recipe output count --- build.gradle | 8 +- gradle.properties | 8 +- .../de/hysky/skyblocker/SkyblockerMod.java | 10 +- .../compatibility/emi/SkyblockEmiRecipe.java | 2 +- .../emi/SkyblockerEMIPlugin.java | 6 +- .../rei/SkyblockCraftingDisplayGenerator.java | 6 +- .../rei/SkyblockerREIClientPlugin.java | 4 +- .../skyblocker/config/SkyblockerConfig.java | 231 +++++++++--------- .../config/categories/GeneralCategory.java | 22 ++ .../skyblocker/mixin/HandledScreenMixin.java | 2 +- .../hysky/skyblocker/skyblock/FairySouls.java | 28 +-- .../item/CompactorDeletorPreview.java | 4 +- .../skyblocker/skyblock/item/WikiLookup.java | 30 +-- .../skyblock/itemlist/ItemListWidget.java | 10 +- .../skyblock/itemlist/ItemRegistry.java | 129 ---------- .../skyblock/itemlist/ItemRepository.java | 136 +++++++++++ .../skyblock/itemlist/ItemStackBuilder.java | 94 ++++--- .../itemlist/SearchResultsWidget.java | 28 +-- .../itemlist/SkyblockCraftingRecipe.java | 51 ++-- .../{NEURepo.java => NEURepoManager.java} | 30 ++- .../assets/skyblocker/lang/en_us.json | 5 + 21 files changed, 436 insertions(+), 408 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRegistry.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java rename src/main/java/de/hysky/skyblocker/utils/{NEURepo.java => NEURepoManager.java} (79%) diff --git a/build.gradle b/build.gradle index 3e4a13d3cc..66c56e2119 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,6 @@ plugins { id 'com.modrinth.minotaur' version '2.+' } -import com.modrinth.minotaur.dependencies.ModDependency - version = "${project.mod_version}+${project.minecraft_version}" group = project.maven_group @@ -59,7 +57,7 @@ dependencies { // EMI modCompileOnly "dev.emi:emi-fabric:${project.emi_version}:api" -// modLocalRuntime "dev.emi:emi-fabric:${project.emi_version}" TODO uncomment when EMI is updated + modLocalRuntime "dev.emi:emi-fabric:${project.emi_version}" // Renderer (https://github.com/0x3C50/Renderer) include modImplementation("com.github.0x3C50:Renderer:${project.renderer_version}") { @@ -80,8 +78,8 @@ dependencies { // Occlusion Culling (https://github.com/LogisticsCraft/OcclusionCulling) include implementation("com.logisticscraft:occlusionculling:${project.occlusionculling_version}") - // neu repoparser | implement it if this is being used - // include implementation("moe.nea:neurepoparser:${project.repoparser_version}") + // NEU RepoParser + include implementation("moe.nea:neurepoparser:${project.repoparser_version}") } loom { diff --git a/gradle.properties b/gradle.properties index 7b749d9231..abe5d2f748 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,20 +17,20 @@ yacl_version=3.2.1+1.20.2 ## Mod Menu (https://modrinth.com/mod/modmenu/versions) mod_menu_version = 8.0.0 ## REI (https://modrinth.com/mod/rei/versions?l=fabric) -rei_version = 13.0.661 +rei_version = 13.0.666 ## EMI (https://modrinth.com/mod/emi/versions) -emi_version = 1.0.19+1.20.1 +emi_version = 1.0.22+1.20.2 ## Renderer (https://github.com/0x3C50/Renderer) renderer_version = master-SNAPSHOT ## Mixin Extras (https://github.com/LlamaLad7/MixinExtras) -mixin_extras_version = 0.2.0-rc.5 +mixin_extras_version = 0.2.0 ## Better Inject (https://github.com/caoimhebyrne/BetterInject) betterinject_version=0.1.3 ## Occlusion Culling (https://github.com/LogisticsCraft/OcclusionCulling) occlusionculling_version = 0.0.7-SNAPSHOT ## neu repoparser (https://repo.nea.moe/#/releases/moe/nea/neurepoparser/) -repoparser_version = 1.3.2 +repoparser_version = 1.4.0 # Mod Properties mod_version = 1.14.0 diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index bd1cd5bd37..115f90eca1 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -9,7 +9,7 @@ import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.skyblock.quicknav.QuickNav; import de.hysky.skyblocker.skyblock.rift.TheRift; import de.hysky.skyblocker.skyblock.shortcut.Shortcuts; @@ -17,7 +17,7 @@ import de.hysky.skyblocker.skyblock.spidersden.Relics; import de.hysky.skyblocker.skyblock.tabhud.TabHud; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; -import de.hysky.skyblocker.utils.NEURepo; +import de.hysky.skyblocker.utils.NEURepoManager; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.chat.ChatMessageListener; import de.hysky.skyblocker.utils.discord.DiscordRPCManager; @@ -68,12 +68,12 @@ public static SkyblockerMod getInstance() { public void onInitializeClient() { ClientTickEvents.END_CLIENT_TICK.register(this::tick); Utils.init(); - HotbarSlotLock.init(); SkyblockerConfigManager.init(); + NEURepoManager.init(); + ItemRepository.init(); + HotbarSlotLock.init(); PriceInfoTooltip.init(); WikiLookup.init(); - ItemRegistry.init(); - NEURepo.init(); FairySouls.init(); Relics.init(); BackpackPreview.init(); diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java index 191da283da..b52d6ff5a8 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java @@ -16,7 +16,7 @@ public class SkyblockEmiRecipe extends EmiCraftingRecipe { private final String craftText; public SkyblockEmiRecipe(SkyblockCraftingRecipe recipe) { - super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()).comparison(Comparison.compareNbt()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_'))); + super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()).comparison(Comparison.compareNbt()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_') + "_" + recipe.getResult().getCount())); this.craftText = recipe.getCraftText(); } diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java index c614701673..6ed6a32a7c 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java @@ -1,7 +1,7 @@ package de.hysky.skyblocker.compatibility.emi; import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.utils.ItemUtils; import dev.emi.emi.api.EmiPlugin; import dev.emi.emi.api.EmiRegistry; @@ -21,9 +21,9 @@ public class SkyblockerEMIPlugin implements EmiPlugin { @Override public void register(EmiRegistry registry) { - ItemRegistry.getItemsStream().map(EmiStack::of).forEach(registry::addEmiStack); + ItemRepository.getItemsStream().map(EmiStack::of).forEach(registry::addEmiStack); registry.addCategory(SKYBLOCK); registry.addWorkstation(SKYBLOCK, EmiStack.of(Items.CRAFTING_TABLE)); - ItemRegistry.getRecipesStream().map(SkyblockEmiRecipe::new).forEach(registry::addRecipe); + ItemRepository.getRecipesStream().map(SkyblockEmiRecipe::new).forEach(registry::addRecipe); } } diff --git a/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockCraftingDisplayGenerator.java b/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockCraftingDisplayGenerator.java index 60e39b797e..33cee20bd6 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockCraftingDisplayGenerator.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockCraftingDisplayGenerator.java @@ -1,6 +1,6 @@ package de.hysky.skyblocker.compatibility.rei; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.skyblock.itemlist.SkyblockCraftingRecipe; import de.hysky.skyblocker.utils.ItemUtils; import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator; @@ -19,7 +19,7 @@ public class SkyblockCraftingDisplayGenerator implements DynamicDisplayGenerator public Optional> getRecipeFor(EntryStack entry) { if (!(entry.getValue() instanceof ItemStack)) return Optional.empty(); EntryStack inputItem = EntryStacks.of((ItemStack) entry.getValue()); - List filteredRecipes = ItemRegistry.getRecipesStream() + List filteredRecipes = ItemRepository.getRecipesStream() .filter(recipe -> { ItemStack itemStack = inputItem.getValue(); ItemStack itemStack1 = recipe.getResult(); @@ -34,7 +34,7 @@ public Optional> getRecipeFor(EntryStack entry) public Optional> getUsageFor(EntryStack entry) { if (!(entry.getValue() instanceof ItemStack)) return Optional.empty(); EntryStack inputItem = EntryStacks.of((ItemStack) entry.getValue()); - List filteredRecipes = ItemRegistry.getRecipesStream() + List filteredRecipes = ItemRepository.getRecipesStream() .filter(recipe -> { for (ItemStack item : recipe.getGrid()) { if(!ItemUtils.getItemId(item).isEmpty()) { diff --git a/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockerREIClientPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockerREIClientPlugin.java index 97651718bf..7ed322a061 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockerREIClientPlugin.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/rei/SkyblockerREIClientPlugin.java @@ -1,7 +1,7 @@ package de.hysky.skyblocker.compatibility.rei; import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; import me.shedaniel.rei.api.client.registry.display.DisplayRegistry; @@ -29,6 +29,6 @@ public void registerDisplays(DisplayRegistry displayRegistry) { @Override public void registerEntries(EntryRegistry entryRegistry) { - entryRegistry.addEntries(ItemRegistry.getItemsStream().map(EntryStacks::of).toList()); + entryRegistry.addEntries(ItemRepository.getItemsStream().map(EntryStacks::of).toList()); } } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 189c6af7ea..107fe26e64 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -16,7 +16,7 @@ public class SkyblockerConfig { @SerialEntry public int version = 1; - + @SerialEntry public General general = new General(); @@ -117,7 +117,7 @@ public QuickNavItem(Boolean render, ItemData itemData, String uiTitle, String cl @SerialEntry public String uiTitle; - + @SerialEntry public String clickEvent; } @@ -137,10 +137,10 @@ public ItemData(String itemName) { @SerialEntry public String itemName; - + @SerialEntry public int count; - + @SerialEntry public String nbt; } @@ -148,16 +148,16 @@ public ItemData(String itemName) { public static class General { @SerialEntry public boolean acceptReparty = true; - + @SerialEntry public boolean backpackPreviewWithoutShift = false; - + @SerialEntry public boolean compactorDeletorPreview = true; - + @SerialEntry public boolean hideEmptyTooltips = true; - + @SerialEntry public boolean hideStatusEffectOverlay = false; @@ -181,7 +181,7 @@ public static class General { @SerialEntry public Shortcuts shortcuts = new Shortcuts(); - + @SerialEntry public QuiverWarning quiverWarning = new QuiverWarning(); @@ -193,7 +193,10 @@ public static class General { @SerialEntry public ItemInfoDisplay itemInfoDisplay = new ItemInfoDisplay(); - + + @SerialEntry + public WikiLookup wikiLookup = new WikiLookup(); + @SerialEntry public SpecialEffects specialEffects = new SpecialEffects(); @@ -208,7 +211,7 @@ public static class General { @SerialEntry public List lockedSlots = new ArrayList<>(); - + @SerialEntry public ObjectOpenHashSet protectedItems = new ObjectOpenHashSet<>(); @@ -228,10 +231,10 @@ public static class TabHudConf { @SerialEntry public int tabHudScale = 100; - + @SerialEntry public boolean plainPlayerNames = false; - + @SerialEntry public NameSorting nameSorting = NameSorting.DEFAULT; } @@ -259,13 +262,13 @@ public static class Bars { public static class BarPositions { @SerialEntry public BarPosition healthBarPosition = BarPosition.LAYER1; - + @SerialEntry public BarPosition manaBarPosition = BarPosition.LAYER1; - + @SerialEntry public BarPosition defenceBarPosition = BarPosition.LAYER1; - + @SerialEntry public BarPosition experienceBarPosition = BarPosition.LAYER1; @@ -292,10 +295,10 @@ public int toInt() { public static class Experiments { @SerialEntry public boolean enableChronomatronSolver = true; - + @SerialEntry public boolean enableSuperpairsSolver = true; - + @SerialEntry public boolean enableUltrasequencerSolver = true; } @@ -308,10 +311,10 @@ public static class Fishing { public static class FairySouls { @SerialEntry public boolean enableFairySoulsHelper = false; - + @SerialEntry public boolean highlightFoundSouls = true; - + @SerialEntry public boolean highlightOnlyNearbySouls = false; } @@ -324,14 +327,14 @@ public static class ItemCooldown { public static class Shortcuts { @SerialEntry public boolean enableShortcuts = true; - + @SerialEntry public boolean enableCommandShortcuts = true; - + @SerialEntry public boolean enableCommandArgShortcuts = true; } - + public static class QuiverWarning { @SerialEntry public boolean enableQuiverWarning = true; @@ -346,7 +349,7 @@ public static class QuiverWarning { public static class Hitbox { @SerialEntry public boolean oldFarmlandHitbox = true; - + @SerialEntry public boolean oldLeverHitbox = false; } @@ -354,16 +357,16 @@ public static class Hitbox { public static class TitleContainer { @SerialEntry public float titleContainerScale = 100; - + @SerialEntry public int x = 540; - + @SerialEntry public int y = 10; - + @SerialEntry public Direction direction = Direction.HORIZONTAL; - + @SerialEntry public Alignment alignment = Alignment.MIDDLE; } @@ -371,19 +374,19 @@ public static class TitleContainer { public static class TeleportOverlay { @SerialEntry public boolean enableTeleportOverlays = true; - + @SerialEntry public boolean enableWeirdTransmission = true; - + @SerialEntry public boolean enableInstantTransmission = true; - + @SerialEntry public boolean enableEtherTransmission = true; - + @SerialEntry public boolean enableSinrecallTransmission = true; - + @SerialEntry public boolean enableWitherImpact = true; } @@ -419,10 +422,10 @@ public static class RichPresence { @SerialEntry public Info info = Info.LOCATION; - + @SerialEntry public boolean cycleMode = false; - + @SerialEntry public String customMessage = "Playing Skyblock"; } @@ -444,22 +447,22 @@ public String toString() { public static class ItemTooltip { @SerialEntry public boolean enableNPCPrice = true; - + @SerialEntry public boolean enableMotesPrice = true; - + @SerialEntry public boolean enableAvgBIN = true; - + @SerialEntry public Average avg = Average.THREE_DAY; - + @SerialEntry public boolean enableLowestBIN = true; - + @SerialEntry public boolean enableBazaarPrice = true; - + @SerialEntry public boolean enableMuseumDate = true; } @@ -467,14 +470,22 @@ public static class ItemTooltip { public static class ItemInfoDisplay { @SerialEntry public boolean attributeShardInfo = true; - + @SerialEntry public boolean itemRarityBackgrounds = false; @SerialEntry public float itemRarityBackgroundsOpacity = 1f; } - + + public static class WikiLookup { + @SerialEntry + public boolean enableWikiLookup = true; + + @SerialEntry + public boolean officialWiki = false; + } + public static class SpecialEffects { @SerialEntry public boolean rareDungeonDropEffects = true; @@ -492,7 +503,7 @@ public static class Locations { @SerialEntry public Rift rift = new Rift(); - + @SerialEntry public SpidersDen spidersDen = new SpidersDen(); } @@ -500,46 +511,46 @@ public static class Locations { public static class Dungeons { @SerialEntry public SecretWaypoints secretWaypoints = new SecretWaypoints(); - + @SerialEntry public DungeonChestProfit dungeonChestProfit = new DungeonChestProfit(); - + @SerialEntry public boolean croesusHelper = true; - + @SerialEntry public boolean enableMap = true; - + @SerialEntry public float mapScaling = 1f; - + @SerialEntry public int mapX = 2; - + @SerialEntry public int mapY = 2; - + @SerialEntry public boolean starredMobGlow = true; - + @SerialEntry public boolean solveThreeWeirdos = true; - + @SerialEntry public boolean blazeSolver = true; @SerialEntry public boolean creeperSolver = true; - + @SerialEntry public boolean solveTrivia = true; - + @SerialEntry public boolean solveTicTacToe = true; - + @SerialEntry public LividColor lividColor = new LividColor(); - + @SerialEntry public Terminals terminals = new Terminals(); } @@ -547,72 +558,72 @@ public static class Dungeons { public static class SecretWaypoints { @SerialEntry public boolean enableSecretWaypoints = true; - + @SerialEntry public boolean noInitSecretWaypoints = false; - + @SerialEntry public boolean enableEntranceWaypoints = true; - + @SerialEntry public boolean enableSuperboomWaypoints = true; - + @SerialEntry public boolean enableChestWaypoints = true; - + @SerialEntry public boolean enableItemWaypoints = true; - + @SerialEntry public boolean enableBatWaypoints = true; - + @SerialEntry public boolean enableWitherWaypoints = true; - + @SerialEntry public boolean enableLeverWaypoints = true; - + @SerialEntry public boolean enableFairySoulWaypoints = true; - + @SerialEntry public boolean enableStonkWaypoints = true; - + @SerialEntry public boolean enableDefaultWaypoints = true; } - + public static class DungeonChestProfit { @SerialEntry public boolean enableProfitCalculator = true; - + @SerialEntry public boolean includeKismet = false; - + @SerialEntry public boolean includeEssence = true; - + @SerialEntry public int neutralThreshold = 1000; - + @SerialEntry public Formatting neutralColor = Formatting.DARK_GRAY; - + @SerialEntry public Formatting profitColor = Formatting.DARK_GREEN; - + @SerialEntry public Formatting lossColor = Formatting.RED; - + @SerialEntry public Formatting incompleteColor = Formatting.BLUE; - + } public static class LividColor { @SerialEntry public boolean enableLividColor = true; - + @SerialEntry public String lividColorText = "The livid color is [color]"; } @@ -620,10 +631,10 @@ public static class LividColor { public static class Terminals { @SerialEntry public boolean solveColor = true; - + @SerialEntry public boolean solveOrder = true; - + @SerialEntry public boolean solveStartsWith = true; } @@ -631,13 +642,13 @@ public static class Terminals { public static class DwarvenMines { @SerialEntry public boolean enableDrillFuel = true; - + @SerialEntry public boolean solveFetchur = true; - + @SerialEntry public boolean solvePuzzler = true; - + @SerialEntry public DwarvenHud dwarvenHud = new DwarvenHud(); } @@ -645,16 +656,16 @@ public static class DwarvenMines { public static class DwarvenHud { @SerialEntry public boolean enabled = true; - + @SerialEntry public DwarvenHudStyle style = DwarvenHudStyle.SIMPLE; - + @SerialEntry public boolean enableBackground = true; - + @SerialEntry public int x = 10; - + @SerialEntry public int y = 10; } @@ -675,7 +686,7 @@ public String toString() { public static class Barn { @SerialEntry public boolean solveHungryHiker = true; - + @SerialEntry public boolean solveTreasureHunter = true; } @@ -683,20 +694,20 @@ public static class Barn { public static class Rift { @SerialEntry public boolean mirrorverseWaypoints = true; - + @SerialEntry public int mcGrubberStacks = 0; } - + public static class SpidersDen { @SerialEntry public Relics relics = new Relics(); } - + public static class Relics { @SerialEntry public boolean enableRelicsHelper = false; - + @SerialEntry public boolean highlightFoundRelics = true; } @@ -709,34 +720,34 @@ public static class Slayer { public static class VampireSlayer { @SerialEntry public boolean enableEffigyWaypoints = true; - + @SerialEntry public boolean compactEffigyWaypoints; - + @SerialEntry public int effigyUpdateFrequency = 5; - + @SerialEntry public boolean enableHolyIceIndicator = true; - + @SerialEntry public int holyIceIndicatorTickDelay = 10; @SerialEntry public int holyIceUpdateFrequency = 5; - + @SerialEntry public boolean enableHealingMelonIndicator = true; - + @SerialEntry public float healingMelonHealthThreshold = 4f; - + @SerialEntry public boolean enableSteakStakeIndicator = true; @SerialEntry public int steakStakeUpdateFrequency = 5; - + @SerialEntry public boolean enableManiaIndicator = true; @@ -747,34 +758,34 @@ public static class VampireSlayer { public static class Messages { @SerialEntry public ChatFilterResult hideAbility = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideHeal = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideAOTE = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideImplosion = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideMoltenWave = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideAds = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideTeleportPad = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideCombo = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideAutopet = ChatFilterResult.PASS; - + @SerialEntry public ChatFilterResult hideShowOff = ChatFilterResult.PASS; - + @SerialEntry public boolean hideMana = false; } diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index 6a39386816..80792ab941 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -375,6 +375,28 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .build()) .build()) + //Wiki Lookup + .group(OptionGroup.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.wikiLookup")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup.@Tooltip"))) + .binding(defaults.general.wikiLookup.enableWikiLookup, + () -> config.general.wikiLookup.enableWikiLookup, + newValue -> config.general.wikiLookup.enableWikiLookup = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki.@Tooltip"))) + .binding(defaults.general.wikiLookup.officialWiki, + () -> config.general.wikiLookup.officialWiki, + newValue -> config.general.wikiLookup.officialWiki = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) + //Special Effects .group(OptionGroup.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.general.specialEffects")) diff --git a/src/main/java/de/hysky/skyblocker/mixin/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixin/HandledScreenMixin.java index b037d45a66..e65bc5765d 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/HandledScreenMixin.java @@ -61,7 +61,7 @@ protected HandledScreenMixin(Text title) { @Inject(at = @At("HEAD"), method = "keyPressed") public void skyblocker$keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) { if (this.client != null && this.focusedSlot != null && keyCode != 256 && !this.client.options.inventoryKey.matchesKey(keyCode, scanCode) && WikiLookup.wikiLookup.matchesKey(keyCode, scanCode)) { - WikiLookup.openWiki(this.focusedSlot); + WikiLookup.openWiki(this.focusedSlot, client.player); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java index 24465e0603..b2ea2b168e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.skyblock; -import com.google.common.collect.ImmutableSet; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -9,7 +8,7 @@ import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.utils.NEURepo; +import de.hysky.skyblocker.utils.NEURepoManager; import de.hysky.skyblocker.utils.PosUtils; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; @@ -32,6 +31,7 @@ import java.io.*; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; @@ -64,25 +64,10 @@ public static void init() { } private static void loadFairySouls() { - fairySoulsLoaded = NEURepo.runAsyncAfterLoad(() -> { - try (BufferedReader reader = new BufferedReader(new FileReader(NEURepo.LOCAL_REPO_DIR.resolve("constants").resolve("fairy_souls.json").toFile()))) { - for (Map.Entry 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 fairySoulsForLocation = ImmutableSet.builder(); - for (JsonElement fairySoul : fairySoulJson.getValue().getAsJsonArray().asList()) { - fairySoulsForLocation.add(PosUtils.parsePosString(fairySoul.getAsString())); - } - fairySouls.put(fairySoulJson.getKey(), fairySoulsForLocation.build()); - } - LOGGER.debug("[Skyblocker] Loaded fairy soul locations"); - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to load fairy soul locations", e); - } + fairySoulsLoaded = NEURepoManager.runAsyncAfterLoad(() -> { + maxSouls = NEURepoManager.NEU_REPO.getConstants().getFairySouls().getMaxSouls(); + NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairySoulsForLocation) -> fairySouls.put(location, fairySoulsForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableSet()))); + LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size()); try (BufferedReader reader = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile()))) { for (Map.Entry foundFairiesForProfileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { @@ -101,6 +86,7 @@ private static void loadFairySouls() { } catch (IOException e) { LOGGER.error("[Skyblocker] Failed to load found fairy souls", e); } + LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations and {} found fairy souls across {} locations in {} profiles", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size(), foundFairies.values().stream().map(Map::values).flatMap(Collection::stream).mapToInt(Set::size).sum(), foundFairies.values().stream().mapToInt(Map::size).sum(), foundFairies.size()); }); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/CompactorDeletorPreview.java b/src/main/java/de/hysky/skyblocker/skyblock/item/CompactorDeletorPreview.java index 7f5b96b95d..1e3dd7d25c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/CompactorDeletorPreview.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/CompactorDeletorPreview.java @@ -1,7 +1,7 @@ package de.hysky.skyblocker.skyblock.item; import de.hysky.skyblocker.mixin.accessor.DrawContextInvoker; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.utils.ItemUtils; import it.unimi.dsi.fastutil.ints.IntIntPair; import it.unimi.dsi.fastutil.ints.IntObjectPair; @@ -43,7 +43,7 @@ public static boolean drawPreview(DrawContext context, ItemStack stack, String t NbtCompound extraAttributes = ItemUtils.getExtraAttributes(stack); if (extraAttributes == null) return false; // Get the slots and their items from the nbt, which is in the format personal_compact_ or personal_deletor_ - List> slots = extraAttributes.getKeys().stream().filter(slot -> slot.contains(type.toLowerCase().substring(0, 7))).map(slot -> IntObjectPair.of(Integer.parseInt(slot.substring(17)), ItemRegistry.getItemStack(extraAttributes.getString(slot)))).toList(); + List> slots = extraAttributes.getKeys().stream().filter(slot -> slot.contains(type.toLowerCase().substring(0, 7))).map(slot -> IntObjectPair.of(Integer.parseInt(slot.substring(17)), ItemRepository.getItemStack(extraAttributes.getString(slot)))).toList(); List components = tooltips.stream().map(Text::asOrderedText).map(TooltipComponent::of).collect(Collectors.toList()); IntIntPair dimensions = DIMENSIONS.getOrDefault(size, DEFAULT_DIMENSION); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/WikiLookup.java b/src/main/java/de/hysky/skyblocker/skyblock/item/WikiLookup.java index d4e6a0dff4..38121ea3b6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/WikiLookup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/WikiLookup.java @@ -1,23 +1,25 @@ package de.hysky.skyblocker.skyblock.item; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.utils.ItemUtils; -import de.hysky.skyblocker.utils.Utils; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.screen.slot.Slot; import net.minecraft.text.Text; import net.minecraft.util.Util; import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.concurrent.CompletableFuture; public class WikiLookup { + private static final Logger LOGGER = LoggerFactory.getLogger(WikiLookup.class); public static KeyBinding wikiLookup; - static final MinecraftClient client = MinecraftClient.getInstance(); - static String id; + private static String id; public static void init() { wikiLookup = KeyBindingHelper.registerKeyBinding(new KeyBinding( @@ -28,22 +30,22 @@ public static void init() { )); } - public static String getSkyblockId(Slot slot) { + public static void getSkyblockId(Slot slot) { //Grabbing the skyblock NBT data ItemUtils.getItemIdOptional(slot.getStack()).ifPresent(newId -> id = newId); - return id; } - public static void openWiki(Slot slot) { - if (Utils.isOnSkyblock()) { - id = getSkyblockId(slot); + public static void openWiki(Slot slot, PlayerEntity player) { + if (SkyblockerConfigManager.get().general.wikiLookup.enableWikiLookup) { + getSkyblockId(slot); try { - String wikiLink = ItemRegistry.getWikiLink(id); + String wikiLink = ItemRepository.getWikiLink(id, player); CompletableFuture.runAsync(() -> Util.getOperatingSystem().open(wikiLink)); } catch (IndexOutOfBoundsException | IllegalStateException e) { - e.printStackTrace(); - if (client.player != null) - client.player.sendMessage(Text.of("Error while retrieving wiki article..."), false); + LOGGER.error("[Skyblocker] Error while retrieving wiki article...", e); + if (player != null) { + player.sendMessage(Text.of("[Skyblocker] Error while retrieving wiki article, see logs..."), false); + } } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java index afdcaca89f..5570c4f7f7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java @@ -38,7 +38,7 @@ public void initialize(int parentWidth, int parentHeight, MinecraftClient client this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField(); int x = (this.parentWidth - 147) / 2 - this.leftOffset; int y = (this.parentHeight - 166) / 2; - if (ItemRegistry.filesImported) { + if (ItemRepository.filesImported()) { this.results = new SearchResultsWidget(this.client, x, y); this.updateSearchResult(); } @@ -57,7 +57,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { context.drawTexture(TEXTURE, i, j, 1, 1, 147, 166); this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField(); - if (!ItemRegistry.filesImported && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) { + if (!ItemRepository.filesImported() && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) { Text hintText = (Text.literal("Loading...")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); context.drawTextWithShadow(this.client.textRenderer, hintText, i + 25, j + 14, -1); } else if (!this.searchField.isFocused() && this.searchField.getText().isEmpty()) { @@ -66,7 +66,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } else { this.searchField.render(context, mouseX, mouseY, delta); } - if (ItemRegistry.filesImported) { + if (ItemRepository.filesImported()) { if (results == null) { int x = (this.parentWidth - 147) / 2 - this.leftOffset; int y = (this.parentHeight - 166) / 2; @@ -81,14 +81,14 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { @Override public void drawTooltip(DrawContext context, int x, int y, int mouseX, int mouseY) { - if (this.isOpen() && ItemRegistry.filesImported && results != null) { + if (this.isOpen() && ItemRepository.filesImported() && results != null) { this.results.drawTooltip(context, mouseX, mouseY); } } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.isOpen() && this.client.player != null && !this.client.player.isSpectator() && ItemRegistry.filesImported && this.searchField != null && results != null) { + if (this.isOpen() && this.client.player != null && !this.client.player.isSpectator() && ItemRepository.filesImported() && this.searchField != null && results != null) { if (this.searchField.mouseClicked(mouseX, mouseY, button)) { this.results.closeRecipeView(); this.searchField.setFocused(true); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRegistry.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRegistry.java deleted file mode 100644 index b958a85dce..0000000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRegistry.java +++ /dev/null @@ -1,129 +0,0 @@ -package de.hysky.skyblocker.skyblock.itemlist; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import de.hysky.skyblocker.utils.ItemUtils; -import de.hysky.skyblocker.utils.NEURepo; -import net.minecraft.client.MinecraftClient; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.text.Text; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -public class ItemRegistry { - protected static final Logger LOGGER = LoggerFactory.getLogger(ItemRegistry.class); - protected static final Path ITEM_LIST_DIR = NEURepo.LOCAL_REPO_DIR.resolve("items"); - - protected static final List items = new ArrayList<>(); - protected static final Map itemsMap = new HashMap<>(); - protected static final List recipes = new ArrayList<>(); - public static final MinecraftClient client = MinecraftClient.getInstance(); - public static boolean filesImported = false; - - public static void init() { - NEURepo.runAsyncAfterLoad(ItemStackBuilder::loadPetNums); - NEURepo.runAsyncAfterLoad(ItemRegistry::importItemFiles); - } - - private static void importItemFiles() { - List jsonObjs = new ArrayList<>(); - - File dir = ITEM_LIST_DIR.toFile(); - File[] files = dir.listFiles(); - if (files == null) { - return; - } - for (File file : files) { - Path path = ITEM_LIST_DIR.resolve(file.getName()); - try { - String fileContent = Files.readString(path); - jsonObjs.add(JsonParser.parseString(fileContent).getAsJsonObject()); - } catch (Exception e) { - LOGGER.error("Failed to read file " + path, e); - } - } - - for (JsonObject jsonObj : jsonObjs) { - String internalName = jsonObj.get("internalname").getAsString(); - ItemStack itemStack = ItemStackBuilder.parseJsonObj(jsonObj); - items.add(itemStack); - itemsMap.put(internalName, itemStack); - } - for (JsonObject jsonObj : jsonObjs) - if (jsonObj.has("recipe")) { - recipes.add(SkyblockCraftingRecipe.fromJsonObject(jsonObj)); - } - - items.sort((lhs, rhs) -> { - String lhsInternalName = ItemUtils.getItemId(lhs); - String lhsFamilyName = lhsInternalName.replaceAll(".\\d+$", ""); - String rhsInternalName = ItemUtils.getItemId(rhs); - String rhsFamilyName = rhsInternalName.replaceAll(".\\d+$", ""); - if (lhsFamilyName.equals(rhsFamilyName)) { - if (lhsInternalName.length() != rhsInternalName.length()) - return lhsInternalName.length() - rhsInternalName.length(); - else return lhsInternalName.compareTo(rhsInternalName); - } - return lhsFamilyName.compareTo(rhsFamilyName); - }); - filesImported = true; - } - - public static String getWikiLink(String internalName) { - try { - String fileContent = Files.readString(ITEM_LIST_DIR.resolve(internalName + ".json")); - JsonObject fileJson = JsonParser.parseString(fileContent).getAsJsonObject(); - //TODO optional official or unofficial wiki link - try { - return fileJson.get("info").getAsJsonArray().get(1).getAsString(); - } catch (IndexOutOfBoundsException e) { - return fileJson.get("info").getAsJsonArray().get(0).getAsString(); - } - } catch (IOException | NullPointerException e) { - LOGGER.error("Failed to read item file " + internalName + ".json", e); - if (client.player != null) { - client.player.sendMessage(Text.of("Can't locate a wiki article for this item..."), false); - } - return null; - } - } - - public static List getRecipes(String internalName) { - List result = new ArrayList<>(); - for (SkyblockCraftingRecipe recipe : recipes) { - if (ItemUtils.getItemId(recipe.result).equals(internalName)) result.add(recipe); - } - for (SkyblockCraftingRecipe recipe : recipes) - for (ItemStack ingredient : recipe.grid) { - if (!ingredient.getItem().equals(Items.AIR) && ItemUtils.getItemId(ingredient).equals(internalName)) { - result.add(recipe); - break; - } - } - return result; - } - - public static Stream getRecipesStream() { - return recipes.stream(); - } - - public static Stream getItemsStream() { - return items.stream(); - } - - public static ItemStack getItemStack(String internalName) { - return itemsMap.get(internalName); - } -} - diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java new file mode 100644 index 0000000000..a8e9210431 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java @@ -0,0 +1,136 @@ +package de.hysky.skyblocker.skyblock.itemlist; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.ItemUtils; +import de.hysky.skyblocker.utils.NEURepoManager; +import io.github.moulberry.repo.data.NEUCraftingRecipe; +import io.github.moulberry.repo.data.NEUItem; +import io.github.moulberry.repo.data.NEURecipe; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +public class ItemRepository { + protected static final Logger LOGGER = LoggerFactory.getLogger(ItemRepository.class); + + private static final List items = new ArrayList<>(); + private static final Map itemsMap = new HashMap<>(); + private static final List recipes = new ArrayList<>(); + private static boolean filesImported = false; + + public static void init() { + NEURepoManager.runAsyncAfterLoad(ItemStackBuilder::loadPetNums); + NEURepoManager.runAsyncAfterLoad(ItemRepository::importItemFiles); + } + + private static void importItemFiles() { + NEURepoManager.NEU_REPO.getItems().getItems().values().forEach(ItemRepository::loadItem); + NEURepoManager.NEU_REPO.getItems().getItems().values().forEach(ItemRepository::loadRecipes); + + items.sort((lhs, rhs) -> { + String lhsInternalName = ItemUtils.getItemId(lhs); + String lhsFamilyName = lhsInternalName.replaceAll(".\\d+$", ""); + String rhsInternalName = ItemUtils.getItemId(rhs); + String rhsFamilyName = rhsInternalName.replaceAll(".\\d+$", ""); + if (lhsFamilyName.equals(rhsFamilyName)) { + if (lhsInternalName.length() != rhsInternalName.length()) + return lhsInternalName.length() - rhsInternalName.length(); + else return lhsInternalName.compareTo(rhsInternalName); + } + return lhsFamilyName.compareTo(rhsFamilyName); + }); + filesImported = true; + } + + private static void loadItem(NEUItem item) { + ItemStack stack = ItemStackBuilder.fromNEUItem(item); + items.add(stack); + itemsMap.put(item.getSkyblockItemId(), stack); + } + + private static void loadRecipes(NEUItem item) { + for (NEURecipe recipe : item.getRecipes()) { + if (recipe instanceof NEUCraftingRecipe neuCraftingRecipe) { + recipes.add(SkyblockCraftingRecipe.fromNEURecipe(neuCraftingRecipe)); + } + } + } + + public static String getWikiLink(String internalName, PlayerEntity player) { + NEUItem item = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(internalName); + if (item == null || item.getInfo().isEmpty()) { + warnNoWikiLink(player); + return null; + } + + List info = item.getInfo(); + String wikiLink0 = info.get(0); + String wikiLink1 = info.size() > 1 ? info.get(1) : ""; + String wikiDomain = SkyblockerConfigManager.get().general.wikiLookup.officialWiki ? "https://wiki.hypixel.net" : "https://hypixel-skyblock.fandom.com"; + if (wikiLink0.startsWith(wikiDomain)) { + return wikiLink0; + } else if (wikiLink1.startsWith(wikiDomain)) { + return wikiLink1; + } + warnNoWikiLink(player); + return null; + } + + private static void warnNoWikiLink(PlayerEntity player) { + if (player != null) { + player.sendMessage(Text.of("[Skyblocker] Unable to locate a wiki article for this item..."), false); + } + } + + public static List getRecipes(String internalName) { + List result = new ArrayList<>(); + for (SkyblockCraftingRecipe recipe : recipes) { + if (ItemUtils.getItemId(recipe.getResult()).equals(internalName)) result.add(recipe); + } + for (SkyblockCraftingRecipe recipe : recipes) { + for (ItemStack ingredient : recipe.getGrid()) { + if (!ingredient.getItem().equals(Items.AIR) && ItemUtils.getItemId(ingredient).equals(internalName)) { + result.add(recipe); + break; + } + } + } + return result; + } + + public static boolean filesImported() { + return filesImported; + } + + public static void setFilesImported(boolean filesImported) { + ItemRepository.filesImported = filesImported; + } + + public static List getItems() { + return items; + } + + public static Stream getItemsStream() { + return items.stream(); + } + + @Nullable + public static ItemStack getItemStack(String internalName) { + return itemsMap.get(internalName); + } + + public static Stream getRecipesStream() { + return recipes.stream(); + } +} + diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java index 4a6d3474f0..cc7c0bc16f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java @@ -1,45 +1,41 @@ package de.hysky.skyblocker.skyblock.itemlist; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import de.hysky.skyblocker.utils.ItemUtils; -import de.hysky.skyblocker.utils.NEURepo; +import de.hysky.skyblocker.utils.NEURepoManager; +import io.github.moulberry.repo.constants.PetNumbers; +import io.github.moulberry.repo.data.NEUItem; +import io.github.moulberry.repo.data.Rarity; import net.minecraft.item.FireworkRocketItem; import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; import net.minecraft.text.Text; import net.minecraft.util.Pair; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ItemStackBuilder { - private final static Path PETNUMS_PATH = NEURepo.LOCAL_REPO_DIR.resolve("constants/petnums.json"); - private static JsonObject petNums; + private static Map> petNums; public static void loadPetNums() { try { - petNums = JsonParser.parseString(Files.readString(PETNUMS_PATH)).getAsJsonObject(); + petNums = NEURepoManager.NEU_REPO.getConstants().getPetNumbers(); } catch (Exception e) { - ItemRegistry.LOGGER.error("Failed to load petnums.json"); + ItemRepository.LOGGER.error("Failed to load petnums.json"); } } - public static ItemStack parseJsonObj(JsonObject obj) { - String internalName = obj.get("internalname").getAsString(); + public static ItemStack fromNEUItem(NEUItem item) { + String internalName = item.getSkyblockItemId(); List> injectors = new ArrayList<>(petData(internalName)); NbtCompound root = new NbtCompound(); - root.put("Count", NbtByte.of((byte)1)); + root.put("Count", NbtByte.of((byte) 1)); - String id = obj.get("itemid").getAsString(); - int damage = obj.get("damage").getAsInt(); + String id = item.getMinecraftItemId(); + int damage = item.getDamage(); root.put("id", NbtString.of(ItemFixerUpper.convertItemId(id, damage))); NbtCompound tag = new NbtCompound(); @@ -52,16 +48,14 @@ public static ItemStack parseJsonObj(JsonObject obj) { NbtCompound display = new NbtCompound(); tag.put("display", display); - String name = injectData(obj.get("displayname").getAsString(), injectors); + String name = injectData(item.getDisplayName(), injectors); display.put("Name", NbtString.of(Text.Serializer.toJson(Text.of(name)))); NbtList lore = new NbtList(); display.put("Lore", lore); - obj.get("lore").getAsJsonArray().forEach(el -> - lore.add(NbtString.of(Text.Serializer.toJson(Text.of(injectData(el.getAsString(), injectors))))) - ); + item.getLore().forEach(el -> lore.add(NbtString.of(Text.Serializer.toJson(Text.of(injectData(el, injectors)))))); - String nbttag = obj.get("nbttag").getAsString(); + String nbttag = item.getNbttag(); // add skull texture Matcher skullUuid = Pattern.compile("(?<=SkullOwner:\\{)Id:\"(.{36})\"").matcher(nbttag); Matcher skullTexture = Pattern.compile("(?<=Properties:\\{textures:\\[0:\\{Value:)\"(.+?)\"").matcher(nbttag); @@ -92,55 +86,56 @@ public static ItemStack parseJsonObj(JsonObject obj) { enchantments.add(new NbtCompound()); tag.put("Enchantments", enchantments); } - + // Add firework star color - Matcher explosionColorMatcher = Pattern.compile("\\{Explosion:\\{(?:Type:[0-9a-z]+,)?Colors:\\[(?[0-9]+)\\]\\}").matcher(nbttag); + Matcher explosionColorMatcher = Pattern.compile("\\{Explosion:\\{(?:Type:[0-9a-z]+,)?Colors:\\[(?[0-9]+)]\\}").matcher(nbttag); if (explosionColorMatcher.find()) { NbtCompound explosion = new NbtCompound(); - + explosion.putInt("Type", FireworkRocketItem.Type.SMALL_BALL.getId()); //Forget about the actual ball type because it probably doesn't matter - explosion.putIntArray("Colors", new int[] { Integer.parseInt(explosionColorMatcher.group("color")) }); + explosion.putIntArray("Colors", new int[]{Integer.parseInt(explosionColorMatcher.group("color"))}); tag.put("Explosion", explosion); } return ItemStack.fromNbt(root); } - // TODO: fix stats for GOLDEN_DRAGON (lv1 -> lv200) private static List> petData(String internalName) { List> list = new ArrayList<>(); String petName = internalName.split(";")[0]; - if (!internalName.contains(";") || !petNums.has(petName)) return list; - - list.add(new Pair<>("\\{LVL\\}", "1 ➡ 100")); - - final String[] rarities = { - "COMMON", - "UNCOMMON", - "RARE", - "EPIC", - "LEGENDARY", - "MYTHIC" + if (!internalName.contains(";") || !petNums.containsKey(petName)) return list; + + final Rarity[] rarities = { + Rarity.COMMON, + Rarity.UNCOMMON, + Rarity.RARE, + Rarity.EPIC, + Rarity.LEGENDARY, + Rarity.MYTHIC, }; - String rarity = rarities[Integer.parseInt(internalName.split(";")[1])]; - JsonObject data = petNums.get(petName).getAsJsonObject().get(rarity).getAsJsonObject(); + Rarity rarity = rarities[Integer.parseInt(internalName.split(";")[1])]; + PetNumbers data = petNums.get(petName).get(rarity); + + int minLevel = data.getLowLevel(); + int maxLevel = data.getHighLevel(); + list.add(new Pair<>("\\{LVL\\}", minLevel + " ➡ " + maxLevel)); - JsonObject statNumsMin = data.get("1").getAsJsonObject().get("statNums").getAsJsonObject(); - JsonObject statNumsMax = data.get("100").getAsJsonObject().get("statNums").getAsJsonObject(); - Set> entrySet = statNumsMin.entrySet(); - for (Map.Entry entry : entrySet) { + Map statNumsMin = data.getStatsAtLowLevel().getStatNumbers(); + Map statNumsMax = data.getStatsAtHighLevel().getStatNumbers(); + Set> entrySet = statNumsMin.entrySet(); + for (Map.Entry entry : entrySet) { String key = entry.getKey(); - String left = "\\{" + key+ "\\}"; - String right = statNumsMin.get(key).getAsString() + " ➡ " + statNumsMax.get(key).getAsString(); + String left = "\\{" + key + "\\}"; + String right = statNumsMin.get(key) + " ➡ " + statNumsMax.get(key); list.add(new Pair<>(left, right)); } - JsonArray otherNumsMin = data.get("1").getAsJsonObject().get("otherNums").getAsJsonArray(); - JsonArray otherNumsMax = data.get("100").getAsJsonObject().get("otherNums").getAsJsonArray(); + List otherNumsMin = data.getStatsAtLowLevel().getOtherNumbers(); + List otherNumsMax = data.getStatsAtHighLevel().getOtherNumbers(); for (int i = 0; i < otherNumsMin.size(); ++i) { String left = "\\{" + i + "\\}"; - String right = otherNumsMin.get(i).getAsString() + " ➡ " + otherNumsMax.get(i).getAsString(); + String right = otherNumsMin.get(i) + " ➡ " + otherNumsMax.get(i); list.add(new Pair<>(left, right)); } @@ -148,8 +143,9 @@ private static List> petData(String internalName) { } private static String injectData(String string, List> injectors) { - for (Pair injector : injectors) + for (Pair injector : injectors) { string = string.replaceAll(injector.getLeft(), injector.getRight()); + } return string; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java index 8a266d65db..44e336d9ce 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java @@ -72,7 +72,7 @@ protected void updateSearchResult(String searchText) { if (!searchText.equals(this.searchText)) { this.searchText = searchText; this.searchResults.clear(); - for (ItemStack entry : ItemRegistry.items) { + for (ItemStack entry : ItemRepository.getItems()) { String name = entry.getName().toString().toLowerCase(Locale.ENGLISH); if (entry.getNbt() == null) { continue; @@ -93,16 +93,16 @@ private void updateButtons() { SkyblockCraftingRecipe recipe = this.recipeResults.get(this.currentPage); for (ResultButtonWidget button : resultButtons) button.clearItemStack(); - resultButtons.get(5).setItemStack(recipe.grid.get(0)); - resultButtons.get(6).setItemStack(recipe.grid.get(1)); - resultButtons.get(7).setItemStack(recipe.grid.get(2)); - resultButtons.get(10).setItemStack(recipe.grid.get(3)); - resultButtons.get(11).setItemStack(recipe.grid.get(4)); - resultButtons.get(12).setItemStack(recipe.grid.get(5)); - resultButtons.get(15).setItemStack(recipe.grid.get(6)); - resultButtons.get(16).setItemStack(recipe.grid.get(7)); - resultButtons.get(17).setItemStack(recipe.grid.get(8)); - resultButtons.get(14).setItemStack(recipe.result); + resultButtons.get(5).setItemStack(recipe.getGrid().get(0)); + resultButtons.get(6).setItemStack(recipe.getGrid().get(1)); + resultButtons.get(7).setItemStack(recipe.getGrid().get(2)); + resultButtons.get(10).setItemStack(recipe.getGrid().get(3)); + resultButtons.get(11).setItemStack(recipe.getGrid().get(4)); + resultButtons.get(12).setItemStack(recipe.getGrid().get(5)); + resultButtons.get(15).setItemStack(recipe.getGrid().get(6)); + resultButtons.get(16).setItemStack(recipe.getGrid().get(7)); + resultButtons.get(17).setItemStack(recipe.getGrid().get(8)); + resultButtons.get(14).setItemStack(recipe.getResult()); } else { for (int i = 0; i < resultButtons.size(); ++i) { int index = this.currentPage * resultButtons.size() + i; @@ -122,7 +122,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { RenderSystem.disableDepthTest(); if (this.displayRecipes) { //Craft text - usually a requirement for the recipe - String craftText = this.recipeResults.get(this.currentPage).craftText; + String craftText = this.recipeResults.get(this.currentPage).getCraftText(); if (textRenderer.getWidth(craftText) > MAX_TEXT_WIDTH) { drawTooltip(textRenderer, context, craftText, this.parentX + 11, this.parentY + 31, mouseX, mouseY); craftText = textRenderer.trimToWidth(craftText, MAX_TEXT_WIDTH) + ELLIPSIS; @@ -130,7 +130,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { context.drawTextWithShadow(textRenderer, craftText, this.parentX + 11, this.parentY + 31, 0xffffffff); //Item name - Text resultText = this.recipeResults.get(this.currentPage).result.getName(); + Text resultText = this.recipeResults.get(this.currentPage).getResult().getName(); if (textRenderer.getWidth(Formatting.strip(resultText.getString())) > MAX_TEXT_WIDTH) { drawTooltip(textRenderer, context, resultText, this.parentX + 11, this.parentY + 43, mouseX, mouseY); resultText = Text.literal(getLegacyFormatting(resultText.getString()) + textRenderer.trimToWidth(Formatting.strip(resultText.getString()), MAX_TEXT_WIDTH) + ELLIPSIS).setStyle(resultText.getStyle()); @@ -202,7 +202,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { if (internalName.isEmpty()) { continue; } - List recipes = ItemRegistry.getRecipes(internalName); + List recipes = ItemRepository.getRecipes(internalName); if (!recipes.isEmpty()) { this.recipeResults = recipes; this.currentPage = 0; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java index b738dfeff3..f5b379dc43 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock.itemlist; -import com.google.gson.JsonObject; +import io.github.moulberry.repo.data.NEUCraftingRecipe; +import io.github.moulberry.repo.data.NEUIngredient; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import org.slf4j.Logger; @@ -11,37 +12,31 @@ public class SkyblockCraftingRecipe { private static final Logger LOGGER = LoggerFactory.getLogger(SkyblockCraftingRecipe.class); - String craftText = ""; - final List grid = new ArrayList<>(9); - ItemStack result; - - public static SkyblockCraftingRecipe fromJsonObject(JsonObject jsonObj) { - SkyblockCraftingRecipe recipe = new SkyblockCraftingRecipe(); - if (jsonObj.has("crafttext")) recipe.craftText = jsonObj.get("crafttext").getAsString(); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("A1").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("A2").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("A3").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("B1").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("B2").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("B3").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("C1").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("C2").getAsString())); - recipe.grid.add(getItemStack(jsonObj.getAsJsonObject("recipe").get("C3").getAsString())); - recipe.result = ItemRegistry.itemsMap.get(jsonObj.get("internalname").getAsString()); + private final String craftText; + private final List grid = new ArrayList<>(9); + private ItemStack result; + + public SkyblockCraftingRecipe(String craftText) { + this.craftText = craftText; + } + + public static SkyblockCraftingRecipe fromNEURecipe(NEUCraftingRecipe neuCraftingRecipe) { + SkyblockCraftingRecipe recipe = new SkyblockCraftingRecipe(neuCraftingRecipe.getExtraText() != null ? neuCraftingRecipe.getExtraText() : ""); + for (NEUIngredient input : neuCraftingRecipe.getInputs()) { + recipe.grid.add(getItemStack(input)); + } + recipe.result = getItemStack(neuCraftingRecipe.getOutput()); return recipe; } - private static ItemStack getItemStack(String internalName) { - try { - if (internalName.length() > 0) { - int count = internalName.split(":").length == 1 ? 1 : Integer.parseInt(internalName.split(":")[1]); - internalName = internalName.split(":")[0]; - ItemStack itemStack = ItemRegistry.itemsMap.get(internalName).copy(); - itemStack.setCount(count); - return itemStack; + private static ItemStack getItemStack(NEUIngredient input) { + if (input != NEUIngredient.SENTINEL_EMPTY) { + ItemStack stack = ItemRepository.getItemStack(input.getItemId()); + if (stack != null) { + return stack.copyWithCount((int) input.getAmount()); + } else { + LOGGER.warn("[Skyblocker Recipe] Unable to find item {}", input.getItemId()); } - } catch (Exception e) { - LOGGER.error("[Skyblocker-Recipe] " + internalName, e); } return Items.AIR.getDefaultStack(); } diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepo.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java similarity index 79% rename from src/main/java/de/hysky/skyblocker/utils/NEURepo.java rename to src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java index 9bc6b24512..e6ede5421b 100644 --- a/src/main/java/de/hysky/skyblocker/utils/NEURepo.java +++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java @@ -1,7 +1,8 @@ package de.hysky.skyblocker.utils; import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; +import io.github.moulberry.repo.NEURepository; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; @@ -21,11 +22,15 @@ /** * Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized. */ -public class NEURepo { - private static final Logger LOGGER = LoggerFactory.getLogger(NEURepo.class); +public class NEURepoManager { + private static final Logger LOGGER = LoggerFactory.getLogger(NEURepoManager.class); public static final String REMOTE_REPO_URL = "https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO.git"; - public static final Path LOCAL_REPO_DIR = SkyblockerMod.CONFIG_DIR.resolve("item-repo"); - private static final CompletableFuture REPO_INITIALIZED = initRepository(); + /** + * Use {@link #NEU_REPO}. + */ + private static final Path LOCAL_REPO_DIR = SkyblockerMod.CONFIG_DIR.resolve("item-repo"); // TODO rename to NotEnoughUpdates-REPO + private static final CompletableFuture REPO_INITIALIZED = loadRepository(); + public static final NEURepository NEU_REPO = NEURepository.of(LOCAL_REPO_DIR); /** * Adds command to update repository manually from ingame. @@ -41,18 +46,19 @@ public static void init() { })))); } - private static CompletableFuture initRepository() { + private static CompletableFuture loadRepository() { return CompletableFuture.runAsync(() -> { try { - if (Files.isDirectory(NEURepo.LOCAL_REPO_DIR)) { - try (Git localRepo = Git.open(NEURepo.LOCAL_REPO_DIR.toFile())) { + if (Files.isDirectory(NEURepoManager.LOCAL_REPO_DIR)) { + try (Git localRepo = Git.open(NEURepoManager.LOCAL_REPO_DIR.toFile())) { localRepo.pull().setRebase(true).call(); LOGGER.info("[Skyblocker] NEU Repository Updated"); } } else { - Git.cloneRepository().setURI(REMOTE_REPO_URL).setDirectory(NEURepo.LOCAL_REPO_DIR.toFile()).setBranchesToClone(List.of("refs/heads/master")).setBranch("refs/heads/master").call().close(); + Git.cloneRepository().setURI(REMOTE_REPO_URL).setDirectory(NEURepoManager.LOCAL_REPO_DIR.toFile()).setBranchesToClone(List.of("refs/heads/master")).setBranch("refs/heads/master").call().close(); LOGGER.info("[Skyblocker] NEU Repository Downloaded"); } + NEU_REPO.reload(); } catch (TransportException e){ LOGGER.error("[Skyblocker] Transport operation failed. Most likely unable to connect to the remote NEU repo on github", e); } catch (RepositoryNotFoundException e) { @@ -67,15 +73,15 @@ private static CompletableFuture initRepository() { private static void deleteAndDownloadRepository() { CompletableFuture.runAsync(() -> { try { - ItemRegistry.filesImported = false; - File dir = NEURepo.LOCAL_REPO_DIR.toFile(); + ItemRepository.setFilesImported(false); + File dir = NEURepoManager.LOCAL_REPO_DIR.toFile(); recursiveDelete(dir); } catch (Exception ex) { if (MinecraftClient.getInstance().player != null) MinecraftClient.getInstance().player.sendMessage(Text.translatable("skyblocker.updaterepository.failed"), false); return; } - initRepository(); + loadRepository(); }); } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 3d0c010f5f..90805b3164 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -81,6 +81,11 @@ "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds": "Item Rarity Backgrounds", "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds.@Tooltip": "Displays a colored background behind an item, the color represents the item's rarity.", "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundsOpacity": "Item Rarity Backgrounds Opacity", + "text.autoconfig.skyblocker.option.general.wikiLookup": "Wiki Lookup", + "text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup": "Enable Wiki Lookup", + "text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup.@Tooltip": "Opens the wiki page of the hovered item with the F4 key.", + "text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki": "Use Official Wiki", + "text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki.@Tooltip": "Use the official wiki instead of the Fandom wiki.", "text.autoconfig.skyblocker.option.general.specialEffects": "Special Effects", "text.autoconfig.skyblocker.option.general.specialEffects.rareDungeonDropEffects": "Rare Dungeon Drop Effects", "text.autoconfig.skyblocker.option.general.specialEffects.rareDungeonDropEffects.@Tooltip": "Adds a special visual effect triggered upon obtaining rare dungeon loot!",