aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin <92656833+kevinthegreat1@users.noreply.github.com>2023-05-17 16:42:29 -0700
committerGitHub <noreply@github.com>2023-05-17 16:42:29 -0700
commit33b467fa42d4bc6bb841512ae839b678297d920a (patch)
tree1a569075ace64e29c30559928bf9a948eb7d149b /src
parentd6caa2fe1a6f792c3ea310d2b5e76dfa25e27ec4 (diff)
parent02b6c6e8ae49e888605964ac8a70b2eaaac7b50d (diff)
downloadSkyblocker-33b467fa42d4bc6bb841512ae839b678297d920a.tar.gz
Skyblocker-33b467fa42d4bc6bb841512ae839b678297d920a.tar.bz2
Skyblocker-33b467fa42d4bc6bb841512ae839b678297d920a.zip
Merge branch 'master' into master
Diffstat (limited to 'src')
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/SkyblockerInitializer.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java40
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java (renamed from src/main/java/me/xmrvizzy/skyblocker/container/ColorHighlight.java)2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java (renamed from src/main/java/me/xmrvizzy/skyblocker/container/ContainerSolver.java)5
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java (renamed from src/main/java/me/xmrvizzy/skyblocker/container/ContainerSolverManager.java)5
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/ChatHudListenerMixin.java41
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java56
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/item/PriceInfoTooltip.java363
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/item/WikiLookup.java29
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java46
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java57
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json2
-rw-r--r--src/main/resources/assets/skyblocker/lang/es_ES.json51
-rw-r--r--src/main/resources/assets/skyblocker/lang/ru_ru.json116
-rw-r--r--src/main/resources/assets/skyblocker/lang/tr_TR.json1
-rw-r--r--src/main/resources/skyblocker.mixins.json1
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",