diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2023-05-17 16:42:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-17 16:42:29 -0700 |
commit | 33b467fa42d4bc6bb841512ae839b678297d920a (patch) | |
tree | 1a569075ace64e29c30559928bf9a948eb7d149b /src | |
parent | d6caa2fe1a6f792c3ea310d2b5e76dfa25e27ec4 (diff) | |
parent | 02b6c6e8ae49e888605964ac8a70b2eaaac7b50d (diff) | |
download | Skyblocker-33b467fa42d4bc6bb841512ae839b678297d920a.tar.gz Skyblocker-33b467fa42d4bc6bb841512ae839b678297d920a.tar.bz2 Skyblocker-33b467fa42d4bc6bb841512ae839b678297d920a.zip |
Merge branch 'master' into master
Diffstat (limited to 'src')
23 files changed, 477 insertions, 364 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerInitializer.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerInitializer.java index 3d713727..f17ab1fb 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerInitializer.java +++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerInitializer.java @@ -4,6 +4,7 @@ import me.xmrvizzy.skyblocker.chat.ChatMessageListener; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.discord.DiscordRPCManager; import me.xmrvizzy.skyblocker.skyblock.HotbarSlotLock; +import me.xmrvizzy.skyblocker.skyblock.api.RepositoryUpdate; import me.xmrvizzy.skyblocker.skyblock.api.StatsCommand; import me.xmrvizzy.skyblocker.skyblock.dwarven.DwarvenHud; import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip; @@ -20,6 +21,7 @@ public class SkyblockerInitializer implements ClientModInitializer { PriceInfoTooltip.init(); WikiLookup.init(); ItemRegistry.init(); + RepositoryUpdate.init(); StatsCommand.init(); DwarvenHud.init(); ChatMessageListener.init(); diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java index f804d90e..c519109a 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java +++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java @@ -1,6 +1,6 @@ package me.xmrvizzy.skyblocker; -import me.xmrvizzy.skyblocker.container.ContainerSolverManager; +import me.xmrvizzy.skyblocker.gui.ContainerSolverManager; import me.xmrvizzy.skyblocker.discord.DiscordRPCManager; import me.xmrvizzy.skyblocker.skyblock.BackpackPreview; import me.xmrvizzy.skyblocker.skyblock.StatusBarTracker; diff --git a/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java b/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java index 9ee87f2b..9e6b5f64 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java +++ b/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java @@ -3,17 +3,25 @@ package me.xmrvizzy.skyblocker.chat; import me.xmrvizzy.skyblocker.chat.filters.*; import me.xmrvizzy.skyblocker.skyblock.api.ApiKeyListener; import me.xmrvizzy.skyblocker.skyblock.barn.HungryHiker; +import me.xmrvizzy.skyblocker.skyblock.barn.TreasureHunter; import me.xmrvizzy.skyblocker.skyblock.dungeon.Reparty; import me.xmrvizzy.skyblocker.skyblock.dungeon.ThreeWeirdos; import me.xmrvizzy.skyblocker.skyblock.dungeon.Trivia; import me.xmrvizzy.skyblocker.skyblock.dwarven.Fetchur; import me.xmrvizzy.skyblocker.skyblock.dwarven.Puzzler; -import me.xmrvizzy.skyblocker.skyblock.barn.TreasureHunter; +import me.xmrvizzy.skyblocker.utils.Utils; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.text.Text; +@FunctionalInterface public interface ChatMessageListener { + /** + * An event called when a game message is received. Register your listeners in {@link ChatMessageListener#init()}. + */ Event<ChatMessageListener> EVENT = EventFactory.createArrayBacked(ChatMessageListener.class, (listeners) -> (message, asString) -> { for (ChatMessageListener listener : listeners) { @@ -23,6 +31,9 @@ public interface ChatMessageListener { return ChatFilterResult.PASS; }); + /** + * Registers {@link ChatMessageListener}s to {@link ChatMessageListener#EVENT} and registers {@link ChatMessageListener#EVENT} to {@link ClientReceiveMessageEvents#ALLOW_GAME} + */ static void init() { ChatMessageListener[] listeners = new ChatMessageListener[]{ // Features @@ -45,8 +56,33 @@ public interface ChatMessageListener { new TeleportPadFilter(), new AutopetFilter(), }; - for (ChatMessageListener listener : listeners) + // Register all listeners to EVENT + for (ChatMessageListener listener : listeners) { EVENT.register(listener); + } + // Register EVENT to ClientReceiveMessageEvents.ALLOW_GAME from fabric api + ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> { + if (!Utils.isOnSkyblock) { + return true; + } + ChatFilterResult result = EVENT.invoker().onMessage(message, message.getString()); + switch (result) { + case ACTION_BAR -> { + if (overlay) { + return true; + } + ClientPlayerEntity player = MinecraftClient.getInstance().player; + if (player != null) { + player.sendMessage(message, true); + return false; + } + } + case FILTER -> { + return false; + } + } + return true; + }); } ChatFilterResult onMessage(Text message, String asString); diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index 48eb31c7..9ecfe215 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -177,7 +177,7 @@ public class SkyblockerConfig implements ConfigData { NONE; @Override - public String toString() { + public String toString() { return I18n.translate("text.autoconfig.skyblocker.option.general.bars.barpositions." + name()); } @@ -215,7 +215,7 @@ public class SkyblockerConfig implements ConfigData { BOTH; @Override - public String toString() { + public String toString() { return I18n.translate("text.autoconfig.skyblocker.option.general.itemTooltip.avg." + name()); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/container/ColorHighlight.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java index c4380eab..5120ceac 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/container/ColorHighlight.java +++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java @@ -1,4 +1,4 @@ -package me.xmrvizzy.skyblocker.container; +package me.xmrvizzy.skyblocker.gui; public record ColorHighlight(int slot, int color) { }
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/container/ContainerSolver.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java index ec086934..84de64eb 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/container/ContainerSolver.java +++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java @@ -1,4 +1,4 @@ -package me.xmrvizzy.skyblocker.container; +package me.xmrvizzy.skyblocker.gui; import net.minecraft.item.ItemStack; @@ -6,6 +6,9 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; +/** + * Abstract class for gui solvers. Extend this class to add a new gui solver, like terminal solvers or experiment solvers. + */ public abstract class ContainerSolver { private final Pattern CONTAINER_NAME; protected final static int GREEN_HIGHLIGHT = 128 << 24 | 64 << 16 | 196 << 8 | 64; diff --git a/src/main/java/me/xmrvizzy/skyblocker/container/ContainerSolverManager.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java index 276ac3b9..c965154f 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/container/ContainerSolverManager.java +++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java @@ -1,4 +1,4 @@ -package me.xmrvizzy.skyblocker.container; +package me.xmrvizzy.skyblocker.gui; import com.mojang.blaze3d.systems.RenderSystem; import me.xmrvizzy.skyblocker.skyblock.dungeon.CroesusHelper; @@ -18,6 +18,9 @@ import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Manager class for {@link ContainerSolver}s like terminal solvers and experiment solvers. To add a new gui solver, extend {@link ContainerSolver} and register it in {@link #ContainerSolverManager()}. + */ public class ContainerSolverManager extends DrawableHelper { private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(""); private final ContainerSolver[] solvers; diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ChatHudListenerMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ChatHudListenerMixin.java deleted file mode 100644 index 8176a810..00000000 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/ChatHudListenerMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package me.xmrvizzy.skyblocker.mixin; - -import me.xmrvizzy.skyblocker.chat.ChatFilterResult; -import me.xmrvizzy.skyblocker.chat.ChatMessageListener; -import me.xmrvizzy.skyblocker.utils.Utils; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.hud.ChatHud; -import net.minecraft.client.gui.hud.MessageIndicator; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.network.message.MessageSignatureData; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ChatHud.class) -public abstract class ChatHudListenerMixin { - @Shadow - @Final - private MinecraftClient client; - - @Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;ILnet/minecraft/client/gui/hud/MessageIndicator;Z)V", at = @At("HEAD"), cancellable = true) - public void skyblocker$onMessage(Text message, MessageSignatureData signature, int ticks, MessageIndicator indicator, boolean refresh, CallbackInfo ci) { - if (!Utils.isOnSkyblock) - return; - String asString = message.getString(); - ChatFilterResult result = ChatMessageListener.EVENT.invoker().onMessage(message, asString); - switch (result) { - case ACTION_BAR: - ClientPlayerEntity player = client.player; - if (player != null) - player.sendMessage(message, true); - case FILTER: - ci.cancel(); - } - } - -} diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java index 2bc47bba..1f9009b7 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java @@ -1,7 +1,7 @@ package me.xmrvizzy.skyblocker.mixin; import me.xmrvizzy.skyblocker.SkyblockerMod; -import me.xmrvizzy.skyblocker.container.ContainerSolverManager; +import me.xmrvizzy.skyblocker.gui.ContainerSolverManager; import me.xmrvizzy.skyblocker.skyblock.HotbarSlotLock; import me.xmrvizzy.skyblocker.utils.Utils; import net.minecraft.client.MinecraftClient; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java new file mode 100644 index 00000000..3854dd88 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java @@ -0,0 +1,56 @@ +package me.xmrvizzy.skyblocker.skyblock.api; + +import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.minecraft.text.Text; + +import java.io.File; +import java.nio.file.Files; +import java.util.concurrent.CompletableFuture; + +public class RepositoryUpdate { + + /** + * Adds command to update repository manually from ingame. + * <p></p> + * TODO A button could be added to the settings menu that will trigger this command. + */ + public static void init(){ + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( + ClientCommandManager.literal("skyblocker") + .then(ClientCommandManager.literal("updaterepository") + .executes(context -> { + CompletableFuture.runAsync(() -> { + try { + ItemRegistry.filesImported = false; + File dir = ItemRegistry.LOCAL_ITEM_REPO_DIR.toFile(); + recursiveDelete(dir); + } catch (Exception ex) { + ItemRegistry.client.player.sendMessage( + Text.translatable("skyblocker.updaterepository.failed") + , false + ); + return; + } + + ItemRegistry.init(); + }); + + return 1; + }) + ) + ) + ); + + } + + private static void recursiveDelete(File dir) { + if (dir.isDirectory() && !Files.isSymbolicLink(dir.toPath())) { + for (File child : dir.listFiles()) { + recursiveDelete(child); + } + } + dir.delete(); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java index c536542b..ec3655f0 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java @@ -1,8 +1,8 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; -import me.xmrvizzy.skyblocker.container.ColorHighlight; -import me.xmrvizzy.skyblocker.container.ContainerSolver; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import me.xmrvizzy.skyblocker.gui.ContainerSolver; import net.minecraft.item.ItemStack; import java.util.ArrayList; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java index f5c97738..0bfc0d60 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java @@ -1,8 +1,8 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.terminal; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; -import me.xmrvizzy.skyblocker.container.ColorHighlight; -import me.xmrvizzy.skyblocker.container.ContainerSolver; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import me.xmrvizzy.skyblocker.gui.ContainerSolver; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java index c61395f4..1cf0dcfc 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java @@ -1,8 +1,8 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.terminal; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; -import me.xmrvizzy.skyblocker.container.ColorHighlight; -import me.xmrvizzy.skyblocker.container.ContainerSolver; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import me.xmrvizzy.skyblocker.gui.ContainerSolver; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java index 7c56746f..26d2a2c4 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java @@ -1,8 +1,8 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.terminal; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; -import me.xmrvizzy.skyblocker.container.ColorHighlight; -import me.xmrvizzy.skyblocker.container.ContainerSolver; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import me.xmrvizzy.skyblocker.gui.ContainerSolver; import net.minecraft.item.ItemStack; import java.util.ArrayList; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/PriceInfoTooltip.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/PriceInfoTooltip.java index 8d8c86b4..d9263f9a 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/PriceInfoTooltip.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/PriceInfoTooltip.java @@ -23,8 +23,10 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.zip.GZIPInputStream; @@ -40,6 +42,7 @@ public class PriceInfoTooltip { private static JsonObject isMuseumJson; private static boolean nullMsgSend = false; private final static Gson gson = new Gson(); + private static final Map<String, String> apiAddresses; public static void onInjectTooltip(ItemStack stack, TooltipContext context, List<Text> lines) { if (!Utils.isOnSkyblock || client.player == null) return; @@ -48,16 +51,13 @@ public class PriceInfoTooltip { if (name == null) return; int count = stack.getCount(); - String timestamp = getTimestamp(stack); boolean bazaarOpened = lines.stream().anyMatch(each -> each.getString().contains("Buy price:") || each.getString().contains("Sell price:")); if (SkyblockerConfig.get().general.itemTooltip.enableNPCPrice) { if (npcPricesJson == null) { - if (!nullMsgSend) { - client.player.sendMessage(Text.translatable("skyblocker.itemTooltip.nullMessage"), false); - nullMsgSend = true; - } - } else if (npcPricesJson.has(name)) { + nullWarning(); + } + else if (npcPricesJson.has(name)) { lines.add(Text.literal(String.format("%-21s", "NPC Price:")) .formatted(Formatting.YELLOW) .append(getCoinsMessage(npcPricesJson.get(name).getAsDouble(), count))); @@ -67,11 +67,9 @@ public class PriceInfoTooltip { boolean bazaarExist = false; if (SkyblockerConfig.get().general.itemTooltip.enableBazaarPrice && !bazaarOpened) { if (bazaarPricesJson == null) { - if (!nullMsgSend) { - client.player.sendMessage(Text.translatable("skyblocker.itemTooltip.nullMessage"), false); - nullMsgSend = true; - } - } else if (bazaarPricesJson.has(name)) { + nullWarning(); + } + else if (bazaarPricesJson.has(name)) { JsonObject getItem = bazaarPricesJson.getAsJsonObject(name); lines.add(Text.literal(String.format("%-18s", "Bazaar buy Price:")) .formatted(Formatting.GOLD) @@ -88,101 +86,115 @@ public class PriceInfoTooltip { } // bazaarOpened & bazaarExist check for lbin, because Skytils keeps some bazaar item data in lbin api + boolean lbinExist = false; if (SkyblockerConfig.get().general.itemTooltip.enableLowestBIN && !bazaarOpened && !bazaarExist) { if (lowestPricesJson == null) { - if (!nullMsgSend) { - client.player.sendMessage(Text.translatable("skyblocker.itemTooltip.nullMessage"), false); - nullMsgSend = true; - } - } else if (lowestPricesJson.has(name)) { + nullWarning(); + } + else if (lowestPricesJson.has(name)) { lines.add(Text.literal(String.format("%-19s", "Lowest BIN Price:")) .formatted(Formatting.GOLD) .append(getCoinsMessage(lowestPricesJson.get(name).getAsDouble(), count))); + lbinExist = true; } } if (SkyblockerConfig.get().general.itemTooltip.enableAvgBIN) { if (threeDayAvgPricesJson == null || oneDayAvgPricesJson == null) { - if (!nullMsgSend) { - client.player.sendMessage(Text.translatable("skyblocker.itemTooltip.nullMessage"), false); - nullMsgSend = true; - } - } else if (threeDayAvgPricesJson.has(name) || oneDayAvgPricesJson.has(name)) { + nullWarning(); + } + else { /* - We are skipping check average prices for potions and runes - because there is no data for their in API. + We are skipping check average prices for potions, runes + and enchanted books because there is no data for their in API. */ if (name.contains("PET-")) { name = name.replace("PET-", "") - .replace("COMMON", "0") .replace("UNCOMMON", "1") + .replace("COMMON", "0") .replace("RARE", "2") .replace("EPIC", "3") .replace("LEGENDARY", "4") .replace("MYTHIC", "5") .replace("-", ";"); - } else if (name.contains("ENCHANTED_BOOK-")) { - name = name.replace("ENCHANTED_BOOK-", "").replace("-", ";"); - } else if (name.contains("POTION-")) { - name = ""; } else if (name.contains("RUNE-")) { + name = name.replace("RUNE-", ""); + name = name.substring(0, name.indexOf("-")) + "_RUNE;" + name.substring(name.lastIndexOf("-") + 1); + } else if (name.contains("POTION-") || name.contains("ENCHANTED_BOOK-")) { name = ""; } else { name = name.replace(":", "-"); } - SkyblockerConfig.Average type = SkyblockerConfig.get().general.itemTooltip.avg; + if (!name.isEmpty() && lbinExist) { + SkyblockerConfig.Average type = SkyblockerConfig.get().general.itemTooltip.avg; - // "No data" line because of API not keeping old data, it causes NullPointerException - if (!name.isEmpty() && (type == SkyblockerConfig.Average.ONE_DAY || type == SkyblockerConfig.Average.BOTH)) { - lines.add(Text.literal(String.format("%-19s", "1 Day Avg. Price:")) - .formatted(Formatting.GOLD) - .append(oneDayAvgPricesJson.get(name) == null - ? Text.literal("No data").formatted(Formatting.RED) - : getCoinsMessage(oneDayAvgPricesJson.get(name).getAsDouble(), count))); - } - if (!name.isEmpty() && (type == SkyblockerConfig.Average.THREE_DAY || type == SkyblockerConfig.Average.BOTH)) { - lines.add(Text.literal(String.format("%-19s", "3 Day Avg. Price:")) - .formatted(Formatting.GOLD) - .append(threeDayAvgPricesJson.get(name) == null - ? Text.literal("No data").formatted(Formatting.RED) - : getCoinsMessage(threeDayAvgPricesJson.get(name).getAsDouble(), count))); + // "No data" line because of API not keeping old data, it causes NullPointerException + if (type == SkyblockerConfig.Average.ONE_DAY || type == SkyblockerConfig.Average.BOTH) { + lines.add( + Text.literal(String.format("%-19s", "1 Day Avg. Price:")) + .formatted(Formatting.GOLD) + .append(oneDayAvgPricesJson.get(name) == null + ? Text.literal("No data").formatted(Formatting.RED) + : getCoinsMessage(oneDayAvgPricesJson.get(name).getAsDouble(), count) + ) + ); + } + if (type == SkyblockerConfig.Average.THREE_DAY || type == SkyblockerConfig.Average.BOTH) { + lines.add( + Text.literal(String.format("%-19s", "3 Day Avg. Price:")) + .formatted(Formatting.GOLD) + .append(threeDayAvgPricesJson.get(name) == null + ? Text.literal("No data").formatted(Formatting.RED) + : getCoinsMessage(threeDayAvgPricesJson.get(name).getAsDouble(), count) + ) + ); + } } } } if (SkyblockerConfig.get().general.itemTooltip.enableMuseumDate && !bazaarOpened) { if (isMuseumJson == null) { - if (!nullMsgSend) { - client.player.sendMessage(Text.translatable("skyblocker.itemTooltip.nullMessage"), false); - nullMsgSend = true; + nullWarning(); + } + else { + String timestamp = getTimestamp(stack); + + if (isMuseumJson.has(name)) { + String itemCategory = isMuseumJson.get(name).toString().replaceAll("\"", ""); + String format = switch (itemCategory) { + case "Weapons" -> "%-18s"; + case "Armor" -> "%-19s"; + default -> "%-20s"; + }; + lines.add(Text.literal(String.format(format, "Museum: (" + itemCategory + ")")) + .formatted(Formatting.LIGHT_PURPLE) + .append(Text.literal(timestamp).formatted(Formatting.RED))); + } else if (!timestamp.isEmpty()) { + lines.add(Text.literal(String.format("%-21s", "Obtained: ")) + .formatted(Formatting.LIGHT_PURPLE) + .append(Text.literal(timestamp).formatted(Formatting.RED))); } - } else if (isMuseumJson.has(name)) { - String itemCategory = isMuseumJson.get(name).toString().replaceAll("\"", ""); - String format = switch (itemCategory) { - case "Weapons" -> "%-18s"; - case "Armor" -> "%-19s"; - default -> "%-20s"; - }; - lines.add(Text.literal(String.format(format, "Museum: (" + itemCategory + ")")) - .formatted(Formatting.LIGHT_PURPLE) - .append(Text.literal(timestamp != null ? timestamp : "").formatted(Formatting.RED))); - } else if (timestamp != null) { - lines.add(Text.literal(String.format("%-21s", "Obtained: ")) - .formatted(Formatting.LIGHT_PURPLE) - .append(Text.literal(timestamp).formatted(Formatting.RED))); } } } + + private static void nullWarning() { + if (!nullMsgSend && client.player != null) { + client.player.sendMessage(Text.translatable("skyblocker.itemTooltip.nullMessage"), false); + nullMsgSend = true; + } + } - public static NbtCompound getInternalNameForItem(ItemStack stack) { + public static NbtCompound getItemNBT(ItemStack stack) { if (stack == null) return null; return stack.getNbt(); } /** * this method converts the "timestamp" variable into the same date format as Hypixel represents it in the museum. - * Currently there are two types of timestamps the legacy which is built like this + * Currently, there are two types of timestamps the legacy which is built like this * "dd/MM/yy hh:mm" ("25/04/20 16:38") and the current which is built like this * "MM/dd/yy hh:mm aa" ("12/24/20 11:08 PM"). Since Hypixel transforms the two formats into one format without * taking into account of their formats, we do the same. The final result looks like this @@ -192,83 +204,89 @@ public class PriceInfoTooltip { * This causes the museum rank to be much worse than it should be. * * @param stack the item under the pointer - * @return if the item have an "Timestamp" it will be shown formated on the tooltip + * @return if the item have a "Timestamp" it will be shown formated on the tooltip */ public static String getTimestamp(ItemStack stack) { - NbtCompound tag = getInternalNameForItem(stack); - String internalName = null; + NbtCompound tag = getItemNBT(stack); + if (tag != null && tag.contains("ExtraAttributes", 10)) { NbtCompound ea = tag.getCompound("ExtraAttributes"); if (ea.contains("timestamp", 8)) { - internalName = ea.getString("timestamp"); - SimpleDateFormat dt = new SimpleDateFormat("MM/dd/yy"); + SimpleDateFormat nbtFormat = new SimpleDateFormat("MM/dd/yy"); try { - Date date = dt.parse(internalName); - SimpleDateFormat dt1 = new SimpleDateFormat("MMMM dd, yyyy", Locale.ENGLISH); - internalName = dt1.format(date); + Date date = nbtFormat.parse(ea.getString("timestamp")); + SimpleDateFormat skyblockerFormat = new SimpleDateFormat("MMMM dd, yyyy", Locale.ENGLISH); + return skyblockerFormat.format(date); } catch (ParseException e) { LOGGER.warn("[Skyblocker-tooltip] getTimestamp", e); } } } - return internalName; + + return ""; } public static String getInternalNameFromNBT(ItemStack stack) { - NbtCompound tag = getInternalNameForItem(stack); - String internalName = null; + NbtCompound tag = getItemNBT(stack); if (tag != null && tag.contains("ExtraAttributes", 10)) { NbtCompound ea = tag.getCompound("ExtraAttributes"); if (ea.contains("id", 8)) { - internalName = ea.getString("id"); - } else { - return null; - } + String internalName = ea.getString("id"); - if ("ENCHANTED_BOOK".equals(internalName)) { - if (ea.contains("enchantments")) { - NbtCompound enchants = ea.getCompound("enchantments"); - String enchant = enchants.getKeys().stream().findFirst().get(); - internalName += "-" + enchant.toUpperCase(Locale.ENGLISH) + "-" + enchants.getInt(enchant); - } - } else if ("PET".equals(internalName)) { - if (ea.contains("petInfo")) { - JsonObject petInfo = gson.fromJson(ea.getString("petInfo"), JsonObject.class); - internalName += "-" + petInfo.get("type").getAsString() + "-" + petInfo.get("tier").getAsString(); - } - } else if ("POTION".equals(internalName)) { - String enhanced = ea.contains("enhanced") ? "-ENHANCED" : ""; - String extended = ea.contains("extended") ? "-EXTENDED" : ""; - String splash = ea.contains("splash") ? "-SPLASH" : ""; - if (ea.contains("potion") && ea.contains("potion_level")) { - internalName += "-" + ea.getString("potion").toUpperCase(Locale.ENGLISH) + "-" + ea.getInt("potion_level") - + enhanced + extended + splash; - } - } else if ("RUNE".equals(internalName)) { - if (ea.contains("runes")) { - NbtCompound runes = ea.getCompound("runes"); - String rune = runes.getKeys().stream().findFirst().get(); - internalName += "-" + rune.toUpperCase(Locale.ENGLISH) + "-" + runes.getInt(rune); + // Transformation to API format. + if ("ENCHANTED_BOOK".equals(internalName)) { + if (ea.contains("enchantments")) { + NbtCompound enchants = ea.getCompound("enchantments"); + String enchant = enchants.getKeys().stream().findFirst().get(); + return internalName + "-" + enchant.toUpperCase(Locale.ENGLISH) + "-" + enchants.getInt(enchant); + } + } else if ("PET".equals(internalName)) { + if (ea.contains("petInfo")) { + JsonObject petInfo = gson.fromJson(ea.getString("petInfo"), JsonObject.class); + return internalName + "-" + petInfo.get("type").getAsString() + "-" + petInfo.get("tier").getAsString(); + } + } else if ("POTION".equals(internalName)) { + // New API just contains 'enhanced' tag. + String enhanced = ea.contains("enhanced") ? "-ENHANCED" : ""; + //String extended = ea.contains("extended") ? "-EXTENDED" : ""; + //String splash = ea.contains("splash") ? "-SPLASH" : ""; + if (ea.contains("potion") && ea.contains("potion_level")) { + return internalName + "-" + ea.getString("potion").toUpperCase(Locale.ENGLISH) + "-" + ea.getInt("potion_level") + + enhanced; //+ extended + splash; + } + } else if ("RUNE".equals(internalName)) { + if (ea.contains("runes")) { + NbtCompound runes = ea.getCompound("runes"); + String rune = runes.getKeys().stream().findFirst().get(); + return internalName + "-" + rune.toUpperCase(Locale.ENGLISH) + "-" + runes.getInt(rune); + } } - } + return internalName; + } + else + return null; } - return internalName; + else + return null; } private static Text getCoinsMessage(double price, int count) { if (count == 1) { String priceString = String.format(Locale.ENGLISH, "%1$,.1f", price); return Text.literal(priceString + " Coins").formatted(Formatting.DARK_AQUA); - } else { - String priceString = String.format(Locale.ENGLISH, "%1$,.1f", price * count); - MutableText priceText = Text.literal(priceString + " Coins ").formatted(Formatting.DARK_AQUA); - priceString = String.format(Locale.ENGLISH, "%1$,.1f", price); - MutableText priceText2 = Text.literal( "(" + priceString + " each)").formatted(Formatting.GRAY); - return priceText.append(priceText2); + } + else { + String priceStringTotal = String.format(Locale.ENGLISH, "%1$,.1f", price * count); + MutableText priceTextTotal = Text.literal(priceStringTotal + " Coins ").formatted(Formatting.DARK_AQUA); + + String priceStringEach = String.format(Locale.ENGLISH, "%1$,.1f", price); + MutableText priceTextEach = Text.literal( "(" + priceStringEach + " each)").formatted(Formatting.GRAY); + + return priceTextTotal.append(priceTextEach); } } @@ -287,108 +305,59 @@ public class PriceInfoTooltip { SkyblockerConfig.Average type = SkyblockerConfig.get().general.itemTooltip.avg; if (type == SkyblockerConfig.Average.BOTH || oneDayAvgPricesJson == null || threeDayAvgPricesJson == null) { - futureList.add(CompletableFuture.runAsync(() -> downloadAvgPrices(SkyblockerConfig.Average.THREE_DAY))); - futureList.add(CompletableFuture.runAsync(() -> downloadAvgPrices(SkyblockerConfig.Average.ONE_DAY))); - } else { - futureList.add(CompletableFuture.runAsync(() -> downloadAvgPrices(type))); + futureList.add(CompletableFuture.runAsync(() -> oneDayAvgPricesJson = downloadPrices("1 day avg"))); + futureList.add(CompletableFuture.runAsync(() -> threeDayAvgPricesJson = downloadPrices("3 day avg"))); + } + else if (type == SkyblockerConfig.Average.ONE_DAY) { + futureList.add(CompletableFuture.runAsync(() -> oneDayAvgPricesJson = downloadPrices("1 day avg"))); + } + else if (type == SkyblockerConfig.Average.THREE_DAY) { + futureList.add(CompletableFuture.runAsync(() -> threeDayAvgPricesJson = downloadPrices("3 day avg"))); } } - if (SkyblockerConfig.get().general.itemTooltip.enableLowestBIN) { - futureList.add(CompletableFuture.runAsync(PriceInfoTooltip::downloadLowestPrices)); - } - if (SkyblockerConfig.get().general.itemTooltip.enableBazaarPrice) { - futureList.add(CompletableFuture.runAsync(PriceInfoTooltip::downloadBazaarPrices)); - } - if (SkyblockerConfig.get().general.itemTooltip.enableNPCPrice && npcPricesJson == null) { - futureList.add(CompletableFuture.runAsync(PriceInfoTooltip::downloadNPCPrices)); - } - if (SkyblockerConfig.get().general.itemTooltip.enableMuseumDate && isMuseumJson == null) { - futureList.add(CompletableFuture.runAsync(PriceInfoTooltip::downloadIsMuseum)); - } + if (SkyblockerConfig.get().general.itemTooltip.enableLowestBIN) + futureList.add(CompletableFuture.runAsync(() -> lowestPricesJson = downloadPrices("lowest bins"))); + + if (SkyblockerConfig.get().general.itemTooltip.enableBazaarPrice) + futureList.add(CompletableFuture.runAsync(() -> bazaarPricesJson = downloadPrices("bazaar"))); + + if (SkyblockerConfig.get().general.itemTooltip.enableNPCPrice && npcPricesJson == null) + futureList.add(CompletableFuture.runAsync(() -> npcPricesJson = downloadPrices("npc"))); + + if (SkyblockerConfig.get().general.itemTooltip.enableMuseumDate && isMuseumJson == null) + futureList.add(CompletableFuture.runAsync(() -> isMuseumJson = downloadPrices("museum"))); + minute++; CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0])) .whenComplete((unused, throwable) -> nullMsgSend = false); }, 1200); } - private static void downloadAvgPrices(SkyblockerConfig.Average type) { - JsonObject result = null; - String avgDay = null; - switch (type) { - case ONE_DAY -> avgDay = "1day.json.gz"; - case THREE_DAY -> avgDay = "3day.json.gz"; - } + private static JsonObject downloadPrices(String type) { try { - URL apiAddr = new URL("https://moulberry.codes/auction_averages_lbin/" + avgDay); - try (InputStream src = apiAddr.openStream()) { - try (GZIPInputStream gzipOutput = new GZIPInputStream(src)) { - try (InputStreamReader reader = new InputStreamReader(gzipOutput)) { - result = new Gson().fromJson(reader, JsonObject.class); - } - } - } + String url = apiAddresses.get(type); + URL apiAddress = new URL(url); + InputStream src = apiAddress.openStream(); + InputStreamReader reader = new InputStreamReader(url.contains(".gz") ? new GZIPInputStream(src) : src); + return new Gson().fromJson(reader, JsonObject.class); } catch (IOException e) { - LOGGER.warn("[Skyblocker] Failed to download average BIN prices!", e); - } - switch (type) { - case ONE_DAY -> oneDayAvgPricesJson = result; - case THREE_DAY -> threeDayAvgPricesJson = result; - } - } + LOGGER.warn("[Skyblocker] Failed to download " + type + " prices!", e); - private static void downloadBazaarPrices() { - JsonObject result = null; - try { - URL apiAddr = new URL("https://hysky.de/api/bazaar"); - InputStreamReader reader = new InputStreamReader(apiAddr.openStream()); - result = new Gson().fromJson(reader, JsonObject.class); - } catch (IOException e) { - LOGGER.warn("[Skyblocker] Failed to download bazaar prices!", e); - } - bazaarPricesJson = result; - } + if (type.equals("lowest bins")) + lowestPricesJson = downloadPrices("lowest bins backup"); - private static void downloadLowestPrices() { - JsonObject result = null; - try { - URL apiAddr = new URL("https://lb.tricked.pro/lowestbins"); - InputStreamReader reader = new InputStreamReader(apiAddr.openStream()); - result = new Gson().fromJson(reader, JsonObject.class); - } catch (IOException e) { - LOGGER.warn("[Skyblocker] Failed to download lowest BIN prices from the main source!", e); - try { - URL apiAddr = new URL("https://lb2.tricked.pro/lowestbins"); - InputStreamReader reader = new InputStreamReader(apiAddr.openStream()); - result = new Gson().fromJson(reader, JsonObject.class); - } catch (IOException e2) { - LOGGER.warn("[Skyblocker] Failed to download lowest BIN prices from the backup source!", e2); - } + return null; } - lowestPricesJson = result; } - private static void downloadNPCPrices() { - JsonObject result = null; - try { - URL apiAddr = new URL("https://hysky.de/api/npcprice"); - InputStreamReader reader = new InputStreamReader(apiAddr.openStream()); - result = new Gson().fromJson(reader, JsonObject.class); - } catch (IOException e) { - LOGGER.warn("[Skyblocker] Failed to download NPC prices!", e); - } - npcPricesJson = result; - } - - private static void downloadIsMuseum() { - JsonObject result = null; - try { - URL apiAddr = new URL("https://hysky.de/api/museum"); - InputStreamReader reader = new InputStreamReader(apiAddr.openStream()); - result = new Gson().fromJson(reader, JsonObject.class); - } catch (IOException e) { - LOGGER.warn("[Skyblocker] Failed to download museum items!", e); - } - isMuseumJson = result; + static { + apiAddresses = new HashMap<>(); + apiAddresses.put("1 day avg", "https://moulberry.codes/auction_averages_lbin/1day.json.gz"); + apiAddresses.put("3 day avg", "https://moulberry.codes/auction_averages_lbin/3day.json.gz"); + apiAddresses.put("bazaar", "https://hysky.de/api/bazaar"); + apiAddresses.put("lowest bins", "https://lb.tricked.pro/lowestbins"); + apiAddresses.put("lowest bins backup", "https://lb2.tricked.pro/lowestbins"); + apiAddresses.put("npc", "https://hysky.de/api/npcprice"); + apiAddresses.put("museum", "https://hysky.de/api/museum"); } - } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/WikiLookup.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/WikiLookup.java index 82c9fdf4..305720d0 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/WikiLookup.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/WikiLookup.java @@ -1,9 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.item; import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; import me.xmrvizzy.skyblocker.utils.Utils; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.MinecraftClient; @@ -16,11 +14,7 @@ import net.minecraft.text.Text; import net.minecraft.util.Util; import org.lwjgl.glfw.GLFW; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; +import java.util.concurrent.CompletableFuture; public class WikiLookup { public static KeyBinding wikiLookup; @@ -51,23 +45,12 @@ public class WikiLookup { if (Utils.isOnSkyblock) { id = getSkyblockId(slot); try { - //Setting up a connection with the repo - String urlString = "https://raw.githubusercontent.com/NotEnoughUpdates/NotEnoughUpdates-REPO/master/items/" + id + ".json"; - URL url = new URL(urlString); - URLConnection request = url.openConnection(); - request.connect(); - - //yoinking the wiki link - JsonElement root = JsonParser.parseReader(new InputStreamReader((InputStream) request.getContent())); - JsonObject rootobj = root.getAsJsonObject(); - String wikiLink = rootobj.get("info").getAsJsonArray().get(1).getAsString(); - Util.getOperatingSystem().open(wikiLink); - } catch (IOException | NullPointerException e) { - e.printStackTrace(); - client.player.sendMessage(Text.of("Can't locate a wiki article for this item..."), false); + String wikiLink = ItemRegistry.getWikiLink(id); + CompletableFuture.runAsync(() -> Util.getOperatingSystem().open(wikiLink)); } catch (IndexOutOfBoundsException | IllegalStateException e) { e.printStackTrace(); - client.player.sendMessage(Text.of("Error while retrieving wiki article..."), false); + if (client.player != null) + client.player.sendMessage(Text.of("Error while retrieving wiki article..."), false); } } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java index 99a06337..d9acc75c 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java @@ -1,7 +1,6 @@ package me.xmrvizzy.skyblocker.skyblock.itemlist; import com.mojang.blaze3d.systems.RenderSystem; - import me.xmrvizzy.skyblocker.mixin.RecipeBookWidgetAccessor; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -40,8 +39,10 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select this.searchField = ((RecipeBookWidgetAccessor)this).getSearchField(); int x = (this.parentWidth - 147) / 2 - this.leftOffset; int y = (this.parentHeight - 166) / 2; - this.results = new SearchResultsWidget(this.client, x , y); - this.updateSearchResult(); + if (ItemRegistry.filesImported) { + this.results = new SearchResultsWidget(this.client, x, y); + this.updateSearchResult(); + } } @Override @@ -57,34 +58,45 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select int j = (this.parentHeight - 166) / 2; DrawableHelper.drawTexture(matrices, i, j, 1, 1, 147, 166); this.searchField = ((RecipeBookWidgetAccessor)this).getSearchField(); - if (!this.searchField.isFocused() && this.searchField.getText().isEmpty()) { + + if (!ItemRegistry.filesImported && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) { + Text hintText = (Text.literal("Loading...")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); + drawTextWithShadow(matrices, this.client.textRenderer, hintText, i + 25, j + 14, -1); + } else if (!this.searchField.isFocused() && this.searchField.getText().isEmpty()) { Text hintText = (Text.translatable("gui.recipebook.search_hint")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); drawTextWithShadow(matrices, this.client.textRenderer, hintText, i + 25, j + 14, -1); } else { this.searchField.render(matrices, mouseX, mouseY, delta); } - this.updateSearchResult(); - this.results.render(matrices, mouseX, mouseY, delta); + if (ItemRegistry.filesImported){ + if (results == null) { + int x = (this.parentWidth - 147) / 2 - this.leftOffset; + int y = (this.parentHeight - 166) / 2; + this.results = new SearchResultsWidget(this.client, x, y); + } + this.updateSearchResult(); + this.results.render(matrices, mouseX, mouseY, delta); + } matrices.pop(); } } @Override public void drawTooltip(MatrixStack matrices, int x, int y, int mouseX, int mouseY) { - if (this.isOpen()) { + if (this.isOpen() && ItemRegistry.filesImported && results != null) { this.results.drawTooltip(matrices, mouseX, mouseY); } } @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (!this.isOpen() || this.client.player.isSpectator()) { - return false; - } - if (this.searchField != null && this.searchField.mouseClicked(mouseX, mouseY, button)) { - this.results.closeRecipeView(); - return true; - } - return this.results.mouseClicked(mouseX, mouseY, button); - } + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.isOpen() && !this.client.player.isSpectator() && ItemRegistry.filesImported && results != null) { + if (this.searchField != null && this.searchField.mouseClicked(mouseX, mouseY, button)) { + this.results.closeRecipeView(); + return true; + } else + return this.results.mouseClicked(mouseX, mouseY, button); + } else + return false; + } }
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java index d0f92731..a1507b95 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java @@ -4,30 +4,46 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.text.Text; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.PullResult; +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.*; +import java.util.concurrent.CompletableFuture; public class ItemRegistry { - protected static final String REMOTE_ITEM_REPO = "https://github.com/KonaeAkira/NotEnoughUpdates-REPO.git"; - protected static final Path LOCAL_ITEM_REPO_DIR = FabricLoader.getInstance().getConfigDir().resolve("skyblocker/item-repo"); + private static final Logger LOGGER = LoggerFactory.getLogger(ItemRegistry.class); + protected static final String REMOTE_ITEM_REPO = "https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO"; + public static final Path LOCAL_ITEM_REPO_DIR = FabricLoader.getInstance().getConfigDir().resolve("skyblocker/item-repo"); - private static final Path ITEM_LIST_DIR = LOCAL_ITEM_REPO_DIR.resolve("items"); + protected static final Path ITEM_LIST_DIR = LOCAL_ITEM_REPO_DIR.resolve("items"); protected static final List<ItemStack> items = new ArrayList<>(); protected static final Map<String, ItemStack> itemsMap = new HashMap<>(); protected static final List<SkyblockCraftingRecipe> recipes = new ArrayList<>(); + public static final MinecraftClient client = MinecraftClient.getInstance(); + public static boolean filesImported = false; - // TODO: make async public static void init() { - updateItemRepo(); - ItemStackBuilder.init(); - importItemFiles(); + CompletableFuture.runAsync(ItemRegistry::updateItemRepo) + .whenComplete((result, ex) -> { + if (ex == null) { + ItemStackBuilder.init(); + importItemFiles(); + } + else { + LOGGER.error("[Skyblocker-ItemRegistry] " + ex); + } + }); } private static void updateItemRepo() { @@ -44,7 +60,14 @@ public class ItemRegistry { } } else { try { - Git.open(LOCAL_ITEM_REPO_DIR.toFile()).pull().call(); + PullResult pull = Git.open(LOCAL_ITEM_REPO_DIR.toFile()).pull().setRebase(true).call(); + if (pull.getRebaseResult() == null) { + LOGGER.info("[Skyblocker Repository Update] No update result"); + } else if (pull.getRebaseResult().getStatus().isSuccessful()) { + LOGGER.info("[Skyblocker Repository Update] Status: " + pull.getRebaseResult().getStatus().name()); + } else if (!pull.getRebaseResult().getStatus().isSuccessful()) { + LOGGER.warn("[Skyblocker Repository Update] Status: " + pull.getRebaseResult().getStatus().name()); + } } catch (Exception e) { e.printStackTrace(); } @@ -91,6 +114,24 @@ public class ItemRegistry { } 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) { + e.printStackTrace(); + client.player.sendMessage(Text.of("Can't locate a wiki article for this item..."), false); + return null; + } } public static List<SkyblockCraftingRecipe> getRecipes(String internalName) { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 0ff95ccc..4809b8ab 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -195,5 +195,7 @@ "text.autoconfig.skyblocker.option.general.enableUpdateNotification": "Update Notification", "text.autoconfig.skyblocker.option.general.hideEmptyTooltips": "Hide empty item tooltips in menus", + "skyblocker.updaterepository.failed": "§b[§6Skyblocker§b] §cUpdating local repository failed. Remove files manually and restart game.", + "skyblocker.api.got_key": "§b[§6Skyblocker§b] §2Automatically set your API key!" } diff --git a/src/main/resources/assets/skyblocker/lang/es_ES.json b/src/main/resources/assets/skyblocker/lang/es_ES.json new file mode 100644 index 00000000..5aa55294 --- /dev/null +++ b/src/main/resources/assets/skyblocker/lang/es_ES.json @@ -0,0 +1,51 @@ +{ + "key.categories.skyblocker": "Skyblocker", + "key.hotbarSlotLock": "Bloqueo de Slot (Hotbar)", + "key.wikiLookup": "Búsqueda en la Wiki", + "text.autoconfig.skyblocker.title": "Ajustes de Skyblocker", + "text.autoconfig.skyblocker.category.general": "General", + "text.autoconfig.skyblocker.option.general.bars": "Salud, Mana, Defensa & Barra de XP", + "text.autoconfig.skyblocker.option.general.bars.enableBars": "Habilitar Barras", + "text.autoconfig.skyblocker.option.general.bars.barpositions": "Configurar Posición de Barras", + "text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER1": "Capa 1", + "text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER2": "Capa 2", + "text.autoconfig.skyblocker.option.general.bars.barpositions.RIGHT": "Derecha", + "text.autoconfig.skyblocker.option.general.bars.barpositions.NONE": "Deshabilitado", + "text.autoconfig.skyblocker.option.general.bars.barpositions.healthBarPosition": "Posición de la Barra de Salud", + "text.autoconfig.skyblocker.option.general.bars.barpositions.manaBarPosition": "Posición de la Barra de Mana", + "text.autoconfig.skyblocker.option.general.bars.barpositions.defenceBarPosition": "Posición de la Barra de Defensa", + "text.autoconfig.skyblocker.option.general.bars.barpositions.experienceBarPosition": "Posición de la Barra de Experiencia", + "text.autoconfig.skyblocker.option.general.backpackPreviewWithoutShift": "Ver la previsualización de la mochila sin sostener Shift", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableNPCPrice": "Habilitar Precios de NPC", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableAvgBIN": "Habilitar Precios Promedio de BIN", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg": "Tipo Promedio", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg.@Tooltip": "Puedes elegir cuantos días de precio promedio sera", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg.ONE_DAY": "Precio de 1 día", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg.THREE_DAY": "Precio de 3 días", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg.BOTH": "Ambos", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableLowestBIN": "Habilitar el precio mas bajo de BIN", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableBazaarPrice": "Habilitar los precios de compra/venta del Bazar", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate": "Habilitar Museo & datos", + "text.autoconfig.skyblocker.option.general.hitbox": "Cajas de Colisión", + "text.autoconfig.skyblocker.option.general.hitbox.oldFarmlandHitbox": "Habilitar la Caja de Colisión de la 1.8 para la tierra de cultivo", + "text.autoconfig.skyblocker.option.general.hitbox.oldLeverHitbox": "Habilitar la Caja de Colisión de la 1.8 para la palanca", + "skyblocker.itemTooltip.noData": "§cSin Información", + "text.autoconfig.skyblocker.category.richPresence": "Discord Rich Presence", + "text.autoconfig.skyblocker.option.richPresence.info": "Información de Skyblock", + "text.autoconfig.skyblocker.option.richPresence.info.PURSE": "CARTERA", + "text.autoconfig.skyblocker.option.richPresence.info.BITS": "BITS", + "text.autoconfig.skyblocker.option.richPresence.info.LOCATION": "LOCALIZACIÓN", + "text.autoconfig.skyblocker.option.richPresence.cycleMode": "Ciclar Información de Skyblock", + "text.autoconfig.skyblocker.option.richPresence.enableRichPresence": "Habilitado", + "text.autoconfig.skyblocker.option.richPresence.customMessage": "Mensaje Personalizado", + "text.autoconfig.skyblocker.category.quickNav": "Navegación Rápida", + "text.autoconfig.skyblocker.option.quickNav.enableQuickNav": "Habilitar Navegación Rápida", + "text.autoconfig.skyblocker.option.quickNav.button1": "Botón 1", + "text.autoconfig.skyblocker.option.quickNav.button2.item.nbt": "NBT", + "text.autoconfig.skyblocker.option.quickNav.button2.uiTitle": "Titulo de la Interfaz", + "text.autoconfig.skyblocker.option.quickNav.button3": "Botón 3", + "text.autoconfig.skyblocker.option.quickNav.button4": "Botón 4", + "text.autoconfig.skyblocker.option.quickNav.button5": "Botón 5", + "text.autoconfig.skyblocker.option.quickNav.button6": "Botón 6", + "text.autoconfig.skyblocker.option.quickNav.button7": "Botón 7" +} diff --git a/src/main/resources/assets/skyblocker/lang/ru_ru.json b/src/main/resources/assets/skyblocker/lang/ru_ru.json index 693d2e8f..8240f0cb 100644 --- a/src/main/resources/assets/skyblocker/lang/ru_ru.json +++ b/src/main/resources/assets/skyblocker/lang/ru_ru.json @@ -1,61 +1,57 @@ { - "key.categories.skyblocker": "Skyblocker", - "key.hotbarSlotLock": "Блокировка слотов (В хотбаре)", - "text.autoconfig.skyblocker.title": "Настройки Skyblocker", - - "text.autoconfig.skyblocker.category.general": "Основные", - "text.autoconfig.skyblocker.option.general.bars": "Полоски здоровья, маны, защиты и опыта", - "text.autoconfig.skyblocker.option.general.bars.enableBars": "Включить полоски", - - "text.autoconfig.skyblocker.category.locations": "Локации", - "text.autoconfig.skyblocker.option.locations.dungeons": "Катакомбы", - "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Включить карту", - "text.autoconfig.skyblocker.option.locations.dungeons.solveThreeWeirdos": "Решать головоломку \"Три чудака\"", - "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver": "Решать головоломку с ифритами", - "text.autoconfig.skyblocker.option.locations.dungeons.solveTrivia": "Решать головоломку с вопросами", - "text.autoconfig.skyblocker.option.locations.dwarvenMines": "Гномьи шахты", - "text.autoconfig.skyblocker.option.locations.dwarvenMines.enableDrillFuel": "Показывать топливо дрели", - "text.autoconfig.skyblocker.option.locations.dwarvenMines.solveFetchur": "Решать загадку Fetchur-а", - "text.autoconfig.skyblocker.option.locations.dwarvenMines.solvePuzzler": "Решать загадку Puzzler-а", - - "text.autoconfig.skyblocker.category.messages": "Сообщения", - "text.autoconfig.skyblocker.option.messages.hideAbility": "Скрывать перезарядку способностей", - "text.autoconfig.skyblocker.option.messages.hideHeal": "Скрывать сообщения об исцелении", - "text.autoconfig.skyblocker.option.messages.hideAOTE": "Скрывать сообщения AOTE/AOTV", - "text.autoconfig.skyblocker.option.messages.hideImplosion": "Скрывать сообщения Implosion", - "text.autoconfig.skyblocker.option.messages.hideMoltenWave": "Скрывать сообщения Molten Wave", - "text.autoconfig.skyblocker.option.messages.hideAds": "Скрывать рекламу в чате", - "text.autoconfig.skyblocker.option.locations.dungeons.oldLevers": "Хитбокс рычагов из 1.8", - "text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Авто-решение терминалов", - "text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveColor": "Решать выбор по цвету", - "text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveOrder": "Решать клик по возрастанию", - "text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveStartsWith": "Решать начинается с", - "skyblocker.itemTooltip.nullMessage": "§b[§6Skyblocker§b] §cИнформация о цене предмета обновится через менее чем 60 секунд. Если нет, проверьте latest.log.", - "text.autoconfig.skyblocker.option.messages.hideTeleportPad": "Скрывать сообщения телепортаторов", - "skyblocker.update.update_link": " §2§nНажми,§r", - "text.autoconfig.skyblocker.option.general.quicknav": "Кнопки быстрого доступа", - "text.autoconfig.skyblocker.option.general.quicknav.enableQuicknav": "Включено", - "text.autoconfig.skyblocker.option.general.itemTooltip.enableAvgBIN": "Показать средние цены на BIN", - "text.autoconfig.skyblocker.option.general.itemTooltip.avg": "Период времени (для средней цены)", - "text.autoconfig.skyblocker.option.general.itemTooltip.avg.@Tooltip": "Можно выбрать, за сколько дней будет браться средняя цена", - "text.autoconfig.skyblocker.option.general.itemTooltip.enableLowestBIN": "Показать минимальную цену на BIN", - "text.autoconfig.skyblocker.option.general.itemTooltip.enableBazaarPrice": "Показать цены на Bazaar-е", - "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate": "Показать дату получения", - "text.autoconfig.skyblocker.category.richPresence": "Активность в Discord", - "text.autoconfig.skyblocker.option.richPresence.info": "Отображаемая информация", - "text.autoconfig.skyblocker.option.richPresence.info.@Tooltip": "Не имеет значения при цикличном отбражении", - "text.autoconfig.skyblocker.option.richPresence.cycleMode": "Отображать все опции циклично", - "text.autoconfig.skyblocker.option.richPresence.enableRichPresence": "Включено", - "text.autoconfig.skyblocker.option.richPresence.customMessage": "Своё сообщение", - "text.autoconfig.skyblocker.option.general.itemList": "Список предметов", - "text.autoconfig.skyblocker.option.general.itemList.enableItemList": "Включено", - "text.autoconfig.skyblocker.option.messages.hideCombo": "Скрывать сообщения о комбо", - "skyblocker.update.update_message": "§b[§6Skyblocker§b] §2Доступна новая версия!", - "skyblocker.update.update_message_end": " §aчтобы узнать об изменениях.", - "skyblocker.update.hover_text": "Открыть Modrinth", - "text.autoconfig.skyblocker.option.general.enableUpdateNotification": "Оповещать об обновлениях", - "skyblocker.api.got_key": "§b[§6Skyblocker§b] §2Ключ API установлен автоматически!", - "key.wikiLookup": "Быстрый переход на вики", - "text.autoconfig.skyblocker.option.general.itemTooltip": "Описание предметов", - "text.autoconfig.skyblocker.option.general.itemTooltip.enableNPCPrice": "Показать цены у NPC" -}
\ No newline at end of file + "key.categories.skyblocker": "Skyblocker", + "key.hotbarSlotLock": "Блокировка слотов (В хотбаре)", + "text.autoconfig.skyblocker.title": "Настройки Skyblocker", + "text.autoconfig.skyblocker.category.general": "Основные", + "text.autoconfig.skyblocker.option.general.bars": "Полоски здоровья, маны, защиты и опыта", + "text.autoconfig.skyblocker.option.general.bars.enableBars": "Включить полоски", + "text.autoconfig.skyblocker.category.locations": "Локации", + "text.autoconfig.skyblocker.option.locations.dungeons": "Катакомбы", + "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Включить карту", + "text.autoconfig.skyblocker.option.locations.dungeons.solveThreeWeirdos": "Решать головоломку \"Три чудака\"", + "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver": "Решать головоломку с ифритами", + "text.autoconfig.skyblocker.option.locations.dungeons.solveTrivia": "Решать головоломку с вопросами", + "text.autoconfig.skyblocker.option.locations.dwarvenMines": "Гномьи шахты", + "text.autoconfig.skyblocker.option.locations.dwarvenMines.enableDrillFuel": "Показывать топливо дрели", + "text.autoconfig.skyblocker.option.locations.dwarvenMines.solveFetchur": "Решать загадку Fetchur-а", + "text.autoconfig.skyblocker.option.locations.dwarvenMines.solvePuzzler": "Решать загадку Puzzler-а", + "text.autoconfig.skyblocker.category.messages": "Сообщения", + "text.autoconfig.skyblocker.option.messages.hideAbility": "Скрывать перезарядку способностей", + "text.autoconfig.skyblocker.option.messages.hideHeal": "Скрывать сообщения об исцелении", + "text.autoconfig.skyblocker.option.messages.hideAOTE": "Скрывать сообщения AOTE/AOTV", + "text.autoconfig.skyblocker.option.messages.hideImplosion": "Скрывать сообщения Implosion", + "text.autoconfig.skyblocker.option.messages.hideMoltenWave": "Скрывать сообщения Molten Wave", + "text.autoconfig.skyblocker.option.messages.hideAds": "Скрывать рекламу в чате", + "text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Авто-решение терминалов", + "text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveColor": "Решать выбор по цвету", + "text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveOrder": "Решать клик по возрастанию", + "text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveStartsWith": "Решать начинается с", + "skyblocker.itemTooltip.nullMessage": "§b[§6Skyblocker§b] §cИнформация о цене предмета обновится через менее чем 60 секунд. Если нет, проверьте latest.log.", + "text.autoconfig.skyblocker.option.messages.hideTeleportPad": "Скрывать сообщения телепортаторов", + "skyblocker.update.update_link": " §2§nНажми,§r", + "text.autoconfig.skyblocker.option.general.quicknav": "Кнопки быстрого доступа", + "text.autoconfig.skyblocker.option.general.quicknav.enableQuicknav": "Включено", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableAvgBIN": "Показать средние цены на BIN", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg": "Период времени (для средней цены)", + "text.autoconfig.skyblocker.option.general.itemTooltip.avg.@Tooltip": "Можно выбрать, за сколько дней будет браться средняя цена", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableLowestBIN": "Показать минимальную цену на BIN", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableBazaarPrice": "Показать цены на Bazaar-е", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate": "Показать дату получения", + "text.autoconfig.skyblocker.category.richPresence": "Активность в Discord", + "text.autoconfig.skyblocker.option.richPresence.info": "Отображаемая информация", + "text.autoconfig.skyblocker.option.richPresence.info.@Tooltip": "Не имеет значения при цикличном отбражении", + "text.autoconfig.skyblocker.option.richPresence.cycleMode": "Отображать все опции циклично", + "text.autoconfig.skyblocker.option.richPresence.enableRichPresence": "Включено", + "text.autoconfig.skyblocker.option.richPresence.customMessage": "Своё сообщение", + "text.autoconfig.skyblocker.option.general.itemList": "Список предметов", + "text.autoconfig.skyblocker.option.general.itemList.enableItemList": "Включено", + "text.autoconfig.skyblocker.option.messages.hideCombo": "Скрывать сообщения о комбо", + "skyblocker.update.update_message": "§b[§6Skyblocker§b] §2Доступна новая версия!", + "skyblocker.update.update_message_end": " §aчтобы узнать об изменениях.", + "skyblocker.update.hover_text": "Открыть Modrinth", + "text.autoconfig.skyblocker.option.general.enableUpdateNotification": "Оповещать об обновлениях", + "skyblocker.api.got_key": "§b[§6Skyblocker§b] §2Ключ API установлен автоматически!", + "key.wikiLookup": "Быстрый переход на вики", + "text.autoconfig.skyblocker.option.general.itemTooltip": "Описание предметов", + "text.autoconfig.skyblocker.option.general.itemTooltip.enableNPCPrice": "Показать цены у NPC" +} diff --git a/src/main/resources/assets/skyblocker/lang/tr_TR.json b/src/main/resources/assets/skyblocker/lang/tr_TR.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/src/main/resources/assets/skyblocker/lang/tr_TR.json @@ -0,0 +1 @@ +{} diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 4a6be779..1fc53632 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -3,7 +3,6 @@ "package": "me.xmrvizzy.skyblocker.mixin", "compatibilityLevel": "JAVA_17", "client": [ - "ChatHudListenerMixin", "ClientPlayerEntityMixin", "InGameHudMixin", "ItemRendererMixin", |