aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/utils
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2024-05-04 19:14:06 -0400
committerGitHub <noreply@github.com>2024-05-04 19:14:06 -0400
commit4a4234d7c9d4f038d4fa418fb15ef24ce3fcc501 (patch)
tree6e87c6b67aabeb82dbe075d68c16b5492ff92c9b /src/main/java/de/hysky/skyblocker/utils
parented0489539902d77595625aaa3bca4e328e1f7e88 (diff)
parentf7b13895a4605e1d22e2c00e7b62c7365902d1aa (diff)
downloadSkyblocker-4a4234d7c9d4f038d4fa418fb15ef24ce3fcc501.tar.gz
Skyblocker-4a4234d7c9d4f038d4fa418fb15ef24ce3fcc501.tar.bz2
Skyblocker-4a4234d7c9d4f038d4fa418fb15ef24ce3fcc501.zip
Merge pull request #669 from SkyblockerMod/1.20.5
1.20.5 & 1.20.6
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/utils')
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Constants.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java168
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java16
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java82
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/FrustumUtils.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/MatrixHelper.java30
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java29
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java9
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java23
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/tictactoe/BoardIndex.java5
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/tictactoe/TicTacToeUtils.java210
15 files changed, 382 insertions, 213 deletions
diff --git a/src/main/java/de/hysky/skyblocker/utils/Constants.java b/src/main/java/de/hysky/skyblocker/utils/Constants.java
index 403689ac..d900f917 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Constants.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Constants.java
@@ -12,7 +12,7 @@ import java.util.function.Supplier;
* Holds generic static constants
*/
public interface Constants {
- String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u0FC7\uA925\uA56A\u12DE";
+ String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u0FC7\uA925\uA56A\u2592\u12DE";
Supplier<MutableText> PREFIX = () -> {
LocalDate time = LocalDate.now();
return Text.empty()
diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
index 70a8c241..086686a7 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
@@ -1,29 +1,41 @@
package de.hysky.skyblocker.utils;
+import com.google.gson.Gson;
+import com.google.gson.JsonParser;
+import com.mojang.authlib.properties.Property;
+import com.mojang.authlib.properties.PropertyMap;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
-import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import de.hysky.skyblocker.mixin.accessor.ItemStackAccessor;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.JsonOps;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.component.ComponentChanges;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.LoreComponent;
+import net.minecraft.component.type.NbtComponent;
+import net.minecraft.component.type.ProfileComponent;
+import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
-import net.minecraft.nbt.StringNbtReader;
+import net.minecraft.registry.Registries;
+import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.text.Text;
-import net.minecraft.text.Texts;
import net.minecraft.util.Formatting;
+import net.minecraft.util.dynamic.Codecs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.time.temporal.TemporalAccessor;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -31,83 +43,72 @@ import java.util.regex.Pattern;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class ItemUtils {
- private static final Logger LOGGER = LoggerFactory.getLogger(ItemUtils.class);
- public static final String EXTRA_ATTRIBUTES = "ExtraAttributes";
public static final String ID = "id";
public static final String UUID = "uuid";
private static final DateTimeFormatter OBTAINED_DATE_FORMATTER = DateTimeFormatter.ofPattern("MMMM d, yyyy").withZone(ZoneId.systemDefault()).localizedBy(Locale.ENGLISH);
- private static final SimpleDateFormat OLD_OBTAINED_DATE_FORMAT = new SimpleDateFormat("MM/dd/yy");
+ private static final DateTimeFormatter OLD_OBTAINED_DATE_FORMAT = DateTimeFormatter.ofPattern("M/d/yy h:m a").withZone(ZoneId.of("UTC")).localizedBy(Locale.ENGLISH);
public static final Pattern NOT_DURABILITY = Pattern.compile("[^0-9 /]");
public static final Predicate<String> FUEL_PREDICATE = line -> line.contains("Fuel: ");
-
- public static LiteralArgumentBuilder<FabricClientCommandSource> dumpHeldItemNbtCommand() {
- return literal("dumpHeldItemNbt").executes(context -> {
- context.getSource().sendFeedback(Text.literal("[Skyblocker Debug] Held Item Nbt: " + context.getSource().getPlayer().getMainHandStack().writeNbt(new NbtCompound())));
+ private static final Gson GSON = new Gson(); //GSON Instance with no config
+ private static final Codec<RegistryEntry<Item>> EMPTY_ALLOWING_ITEM_CODEC = Registries.ITEM.getEntryCodec();
+ public static final Codec<ItemStack> EMPTY_ALLOWING_ITEMSTACK_CODEC = Codec.lazyInitialized(() -> RecordCodecBuilder.create(instance -> instance.group(
+ EMPTY_ALLOWING_ITEM_CODEC.fieldOf("id").forGetter(ItemStack::getRegistryEntry),
+ Codec.INT.orElse(1).fieldOf("count").forGetter(ItemStack::getCount),
+ ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(ItemStack::getComponentChanges)
+ ).apply(instance, ItemStack::new)));
+
+ public static LiteralArgumentBuilder<FabricClientCommandSource> dumpHeldItemCommand() {
+ return literal("dumpHeldItem").executes(context -> {
+ context.getSource().sendFeedback(Text.literal("[Skyblocker Debug] Held Item: " + GSON.toJson(ItemStack.CODEC.encodeStart(JsonOps.INSTANCE, context.getSource().getPlayer().getMainHandStack()).getOrThrow())));
return Command.SINGLE_SUCCESS;
});
}
- /**
- * Gets the {@code ExtraAttributes} NBT tag from the item stack.
- *
- * @param stack the item stack to get the {@code ExtraAttributes} NBT tag from
- * @return an optional containing the {@code ExtraAttributes} NBT tag of the item stack
- */
- public static Optional<NbtCompound> getExtraAttributesOptional(@NotNull ItemStack stack) {
- return Optional.ofNullable(stack.getSubNbt(EXTRA_ATTRIBUTES));
- }
-
- /**
- * Gets the {@code ExtraAttributes} NBT tag from the item stack.
- *
- * @param stack the item stack to get the {@code ExtraAttributes} NBT tag from
- * @return the {@code ExtraAttributes} NBT tag of the item stack, or null if the item stack is null or does not have an {@code ExtraAttributes} NBT tag
- */
- @Nullable
- public static NbtCompound getExtraAttributes(@NotNull ItemStack stack) {
- return stack.getSubNbt(EXTRA_ATTRIBUTES);
+ @SuppressWarnings("deprecation")
+ public static NbtCompound getCustomData(@NotNull ItemStack stack) {
+ return stack.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).getNbt();
}
/**
- * Gets the internal name of the item stack from the {@code ExtraAttributes} NBT tag.
+ * Gets the Skyblock item id of the item stack.
*
* @param stack the item stack to get the internal name from
* @return an optional containing the internal name of the item stack
*/
- public static Optional<String> getItemIdOptional(@NotNull ItemStack stack) {
- return getExtraAttributesOptional(stack).map(extraAttributes -> extraAttributes.getString(ID));
+ public static Optional<String> getItemIdOptional(@NotNull ItemStack stack) {
+ NbtCompound customData = getCustomData(stack);
+ return customData.contains(ID) ? Optional.of(customData.getString(ID)) : Optional.empty();
}
/**
- * Gets the internal name of the item stack from the {@code ExtraAttributes} NBT tag.
+ * Gets the Skyblock item id of the item stack.
*
* @param stack the item stack to get the internal name from
* @return the internal name of the item stack, or an empty string if the item stack is null or does not have an internal name
*/
- public static String getItemId(@NotNull ItemStack stack) {
- NbtCompound extraAttributes = getExtraAttributes(stack);
- return extraAttributes != null ? extraAttributes.getString(ID) : "";
+ public static String getItemId(@NotNull ItemStack stack) {
+ return getCustomData(stack).getString(ID);
}
/**
- * Gets the UUID of the item stack from the {@code ExtraAttributes} NBT tag.
+ * Gets the UUID of the item stack.
*
* @param stack the item stack to get the UUID from
* @return an optional containing the UUID of the item stack
*/
- public static Optional<String> getItemUuidOptional(@NotNull ItemStack stack) {
- return getExtraAttributesOptional(stack).map(extraAttributes -> extraAttributes.getString(UUID));
+ public static Optional<String> getItemUuidOptional(@NotNull ItemStack stack) {
+ NbtCompound customData = getCustomData(stack);
+ return customData.contains(UUID) ? Optional.of(customData.getString(UUID)) : Optional.empty();
}
/**
- * Gets the UUID of the item stack from the {@code ExtraAttributes} NBT tag.
+ * Gets the UUID of the item stack.
*
* @param stack the item stack to get the UUID from
* @return the UUID of the item stack, or an empty string if the item stack is null or does not have a UUID
*/
- public static String getItemUuid(@NotNull ItemStack stack) {
- NbtCompound extraAttributes = getExtraAttributes(stack);
- return extraAttributes != null ? extraAttributes.getString(UUID) : "";
+ public static String getItemUuid(@NotNull ItemStack stack) {
+ return getCustomData(stack).getString(UUID);
}
/**
@@ -126,47 +127,41 @@ public class ItemUtils {
* @param stack the item under the pointer
* @return if the item have a "Timestamp" it will be shown formated on the tooltip
*/
- public static String getTimestamp(ItemStack stack) {
- NbtCompound ea = getExtraAttributes(stack);
-
- if (ea != null && ea.contains("timestamp", NbtElement.LONG_TYPE)) {
- Instant date = Instant.ofEpochMilli(ea.getLong("timestamp"));
+ public static String getTimestamp(ItemStack stack) {
+ NbtCompound customData = getCustomData(stack);
+ if (customData != null && customData.contains("timestamp", NbtElement.LONG_TYPE)) {
+ Instant date = Instant.ofEpochMilli(customData.getLong("timestamp"));
return OBTAINED_DATE_FORMATTER.format(date);
}
- if (ea != null && ea.contains("timestamp", NbtElement.STRING_TYPE)) {
- try {
- Instant date = OLD_OBTAINED_DATE_FORMAT.parse(ea.getString("timestamp")).toInstant();
-
- return OBTAINED_DATE_FORMATTER.format(date);
- } catch (ParseException e) {
- LOGGER.warn("[Skyblocker Item Utils] Encountered an unknown exception while parsing time stamp of item {} with extra attributes {}", stack, ea, e);
- }
+ if (customData != null && customData.contains("timestamp", NbtElement.STRING_TYPE)) {
+ TemporalAccessor date = OLD_OBTAINED_DATE_FORMAT.parse(customData.getString("timestamp"));
+ return OBTAINED_DATE_FORMATTER.format(date);
}
return "";
}
public static boolean hasCustomDurability(@NotNull ItemStack stack) {
- NbtCompound extraAttributes = getExtraAttributes(stack);
- return extraAttributes != null && (extraAttributes.contains("drill_fuel") || extraAttributes.getString(ID).equals("PICKONIMBUS"));
+ NbtCompound customData = getCustomData(stack);
+ return customData != null && (customData.contains("drill_fuel") || customData.getString(ID).equals("PICKONIMBUS"));
}
@Nullable
public static IntIntPair getDurability(@NotNull ItemStack stack) {
- NbtCompound extraAttributes = getExtraAttributes(stack);
- if (extraAttributes == null) return null;
+ NbtCompound customData = getCustomData(stack);
+ if (customData == null) return null;
// TODO Calculate drill durability based on the drill_fuel flag, fuel_tank flag, and hotm level
// TODO Cache the max durability and only update the current durability on inventory tick
- int pickonimbusDurability = extraAttributes.getInt("pickonimbus_durability");
+ int pickonimbusDurability = customData.getInt("pickonimbus_durability");
if (pickonimbusDurability > 0) {
return IntIntPair.of(pickonimbusDurability, 5000);
}
- String drillFuel = Formatting.strip(getNbtTooltip(stack, FUEL_PREDICATE));
+ String drillFuel = Formatting.strip(getLoreLineIf(stack, FUEL_PREDICATE));
if (drillFuel != null) {
String[] drillFuelStrings = NOT_DURABILITY.matcher(drillFuel).replaceAll("").trim().split("/");
return IntIntPair.of(Integer.parseInt(drillFuelStrings[0]), Integer.parseInt(drillFuelStrings[1]) * 1000);
@@ -176,8 +171,8 @@ public class ItemUtils {
}
@Nullable
- public static String getNbtTooltip(ItemStack item, Predicate<String> predicate) {
- for (Text line : getNbtTooltips(item)) {
+ public static String getLoreLineIf(ItemStack item, Predicate<String> predicate) {
+ for (Text line : getLore(item)) {
String string = line.getString();
if (predicate.test(string)) {
return string;
@@ -188,8 +183,8 @@ public class ItemUtils {
}
@Nullable
- public static Matcher getNbtTooltip(ItemStack item, Pattern pattern) {
- for (Text line : getNbtTooltips(item)) {
+ public static Matcher getLoreLineIfMatch(ItemStack item, Pattern pattern) {
+ for (Text line : getLore(item)) {
String string = line.getString();
Matcher matcher = pattern.matcher(string);
if (matcher.matches()) {
@@ -200,19 +195,32 @@ public class ItemUtils {
return null;
}
- public static List<Text> getNbtTooltips(ItemStack item) {
- NbtCompound displayNbt = item.getSubNbt("display");
- if (displayNbt == null || !displayNbt.contains("Lore", NbtElement.LIST_TYPE)) {
- return Collections.emptyList();
- }
+ public static List<Text> getLore(ItemStack item) {
+ return item.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).styledLines();
+ }
+
+ public static PropertyMap propertyMapWithTexture(String textureValue) {
+ return Codecs.GAME_PROFILE_PROPERTY_MAP.parse(JsonOps.INSTANCE, JsonParser.parseString("[{\"name\":\"textures\",\"value\":\"" + textureValue + "\"}]")).getOrThrow();
+ }
+
+ public static String getHeadTexture(ItemStack stack) {
+ if (!stack.isOf(Items.PLAYER_HEAD) || !stack.contains(DataComponentTypes.PROFILE)) return "";
+
+ ProfileComponent profile = stack.get(DataComponentTypes.PROFILE);
+ String texture = profile.properties().get("textures").stream()
+ .map(Property::value)
+ .findFirst()
+ .orElse("");
- return displayNbt.getList("Lore", NbtElement.STRING_TYPE).stream().map(NbtElement::asString).map(Text.Serialization::fromJson).filter(Objects::nonNull).map(text -> Texts.setStyleIfAbsent(text, ItemStackAccessor.getLORE_STYLE())).map(Text.class::cast).toList();
+ return texture;
}
public static ItemStack getSkyblockerStack() {
try {
- return ItemStack.fromNbt(StringNbtReader.parse("{id:\"minecraft:player_head\",Count:1,tag:{SkullOwner:{Id:[I;-300151517,-631415889,-1193921967,-1821784279],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}}}}"));
- } catch (CommandSyntaxException e) {
+ ItemStack stack = new ItemStack(Items.PLAYER_HEAD);
+ stack.set(DataComponentTypes.PROFILE, new ProfileComponent(Optional.of("SkyblockerStack"), Optional.of(java.util.UUID.randomUUID()), propertyMapWithTexture("e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=")));
+ return stack;
+ } catch (Exception e) {
throw new RuntimeException(e);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
index cda92273..f8716ca4 100644
--- a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
+++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
@@ -51,6 +51,10 @@ public class NEURepoManager {
);
}
+ public static boolean isLoading() {
+ return REPO_LOADING != null && !REPO_LOADING.isDone();
+ }
+
private static CompletableFuture<Boolean> loadRepository() {
return CompletableFuture.supplyAsync(() -> {
try {
@@ -78,7 +82,7 @@ public class NEURepoManager {
}
private static void deleteAndDownloadRepository(PlayerEntity player) {
- if (REPO_LOADING != null && !REPO_LOADING.isDone()) {
+ if (isLoading()) {
sendMessage(player, Constants.PREFIX.get().append(Text.translatable("skyblocker.updateRepository.loading")));
return;
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index bbee3ce1..dc13b61d 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -3,6 +3,7 @@ package de.hysky.skyblocker.utils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import de.hysky.skyblocker.events.SkyblockEvents;
+import de.hysky.skyblocker.mixins.accessors.MessageHandlerAccessor;
import de.hysky.skyblocker.skyblock.item.MuseumItemCache;
import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
@@ -25,6 +26,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -217,7 +219,6 @@ public class Utils {
}
if (sidebar.isEmpty() && !fabricLoader.isDevelopmentEnvironment()) return;
- String string = sidebar.toString();
if (fabricLoader.isDevelopmentEnvironment() || isConnectedToHypixel(client)) {
if (!isOnHypixel) {
@@ -466,4 +467,17 @@ public class Utils {
});
}
+
+ /**
+ * Used to avoid triggering things like chat rules or chat listeners infinitely, do not use otherwise.
+ *
+ * Bypasses MessageHandler#onGameMessage
+ */
+ public static void sendMessageToBypassEvents(Text message) {
+ MinecraftClient client = MinecraftClient.getInstance();
+
+ client.inGameHud.getChatHud().addMessage(message);
+ ((MessageHandlerAccessor) client.getMessageHandler()).invokeAddToChatLog(message, Instant.now());
+ client.getNarratorManager().narrateSystemMessage(message);
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
index bdff2d94..1f0caff5 100644
--- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
+++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
@@ -15,6 +15,7 @@ import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
@FunctionalInterface
public interface ChatMessageListener {
@@ -68,7 +69,7 @@ public interface ChatMessageListener {
if (!Utils.isOnSkyblock()) {
return true;
}
- ChatFilterResult result = EVENT.invoker().onMessage(message, message.getString());
+ ChatFilterResult result = EVENT.invoker().onMessage(message, Formatting.strip(message.getString()));
switch (result) {
case ACTION_BAR -> {
if (overlay) {
diff --git a/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java b/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java
new file mode 100644
index 00000000..3543a2f1
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java
@@ -0,0 +1,82 @@
+package de.hysky.skyblocker.utils.datafixer;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import com.mojang.brigadier.StringReader;
+import com.mojang.serialization.Dynamic;
+
+import net.minecraft.command.argument.ItemStringReader;
+import net.minecraft.command.argument.ItemStringReader.ItemResult;
+import net.minecraft.component.DataComponentType;
+import net.minecraft.datafixer.Schemas;
+import net.minecraft.datafixer.TypeReferences;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtElement;
+import net.minecraft.nbt.NbtOps;
+import net.minecraft.registry.DynamicRegistryManager;
+import net.minecraft.registry.Registries;
+import net.minecraft.registry.RegistryOps;
+import net.minecraft.util.Identifier;
+
+/**
+ * Contains a data fixer to convert legacy item NBT to the new components system, among other fixers related to the item components system.
+ *
+ * @see net.minecraft.datafixer.fix.ItemStackComponentizationFix
+ */
+public class ItemStackComponentizationFixer {
+ private static final int ITEM_NBT_DATA_VERSION = 3817;
+ private static final int ITEM_COMPONENTS_DATA_VERSION = 3825;
+ private static final DynamicRegistryManager REGISTRY_MANAGER = new DynamicRegistryManager.ImmutableImpl(List.of(Registries.ITEM, Registries.DATA_COMPONENT_TYPE));
+
+ public static ItemStack fixUpItem(NbtCompound nbt) {
+ Dynamic<NbtElement> dynamic = Schemas.getFixer().update(TypeReferences.ITEM_STACK, new Dynamic<>(NbtOps.INSTANCE, nbt), ITEM_NBT_DATA_VERSION, ITEM_COMPONENTS_DATA_VERSION);
+
+ return ItemStack.CODEC.parse(dynamic).getOrThrow();
+ }
+
+ /**
+ * Modified version of {@link net.minecraft.command.argument.ItemStackArgument#asString(net.minecraft.registry.RegistryWrapper.WrapperLookup)} to only care about changed components.
+ *
+ * @return The {@link ItemStack}'s components as a string which is in the format that the {@code /give} command accepts.
+ */
+ public static String componentsAsString(ItemStack stack) {
+ RegistryOps<NbtElement> nbtRegistryOps = REGISTRY_MANAGER.getOps(NbtOps.INSTANCE);
+
+ return Arrays.toString(stack.getComponentChanges().entrySet().stream().map(entry -> {
+ @SuppressWarnings("unchecked")
+ DataComponentType<Object> dataComponentType = (DataComponentType<Object>) entry.getKey();
+ Identifier componentId = Registries.DATA_COMPONENT_TYPE.getId(dataComponentType);
+ Optional<NbtElement> encodedComponent = dataComponentType.getCodec().encodeStart(nbtRegistryOps, entry.getValue().orElseThrow()).result();
+
+ if (componentId == null || encodedComponent.isEmpty()) {
+ return null;
+ }
+
+ return componentId + "=" + encodedComponent.orElseThrow();
+ }).filter(Objects::nonNull).toArray());
+ }
+
+ /**
+ * Constructs an {@link ItemStack} from an {@code itemId}, with item components in string format as returned by {@link #componentsAsString(ItemStack)}, and with a specified stack count.
+ *
+ * @return an {@link ItemStack} or {@link ItemStack#EMPTY} if there was an exception thrown.
+ */
+ public static ItemStack fromComponentsString(String itemId, int count, String componentsString) {
+ ItemStringReader reader = new ItemStringReader(REGISTRY_MANAGER);
+
+ try {
+ ItemResult result = reader.consume(new StringReader(itemId + componentsString));
+ ItemStack stack = new ItemStack(result.item(), count);
+
+ stack.applyComponentsFrom(result.components());
+
+ return stack;
+ } catch (Exception ignored) {}
+
+ return ItemStack.EMPTY;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/FrustumUtils.java b/src/main/java/de/hysky/skyblocker/utils/render/FrustumUtils.java
index 3fe79e43..d82b4497 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/FrustumUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/FrustumUtils.java
@@ -1,7 +1,7 @@
package de.hysky.skyblocker.utils.render;
-import de.hysky.skyblocker.mixin.accessor.FrustumInvoker;
-import de.hysky.skyblocker.mixin.accessor.WorldRendererAccessor;
+import de.hysky.skyblocker.mixins.accessors.FrustumInvoker;
+import de.hysky.skyblocker.mixins.accessors.WorldRendererAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Frustum;
import net.minecraft.util.math.Box;
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/MatrixHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/MatrixHelper.java
new file mode 100644
index 00000000..220dbf86
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/render/MatrixHelper.java
@@ -0,0 +1,30 @@
+package de.hysky.skyblocker.utils.render;
+
+import org.joml.Matrix4f;
+
+import net.minecraft.client.util.math.MatrixStack;
+
+/**
+ * Matrix helper methods
+ */
+public interface MatrixHelper {
+
+ /**
+ * Copies the {@code matrix} into a new {@link Matrix4f}. This is necessary otherwise
+ * any transformations applied will affect other uses of the same matrix.
+ */
+ static Matrix4f copyOf(Matrix4f matrix) {
+ return new Matrix4f(matrix);
+ }
+
+ /**
+ * Creates a blank {@link MatrixStack} and sets it's position matrix to the supplied
+ * {@code positionMatrix}.
+ */
+ static MatrixStack toStack(Matrix4f positionMatrix) {
+ MatrixStack matrices = new MatrixStack();
+ matrices.peek().getPositionMatrix().set(positionMatrix);
+
+ return matrices;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
index da179d0e..a6772fb2 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
@@ -3,8 +3,8 @@ package de.hysky.skyblocker.utils.render;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.logging.LogUtils;
import de.hysky.skyblocker.SkyblockerMod;
-import de.hysky.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
-import de.hysky.skyblocker.mixin.accessor.DrawContextInvoker;
+import de.hysky.skyblocker.mixins.accessors.BeaconBlockEntityRendererInvoker;
+import de.hysky.skyblocker.mixins.accessors.DrawContextInvoker;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.title.Title;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
@@ -26,6 +26,7 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
+
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector3f;
@@ -243,15 +244,13 @@ public class RenderHelper {
}
public static void renderQuad(WorldRenderContext context, Vec3d[] points, float[] colorComponents, float alpha, boolean throughWalls) {
+ Matrix4f positionMatrix = new Matrix4f();
Vec3d camera = context.camera().getPos();
- MatrixStack matrices = context.matrixStack();
- matrices.push();
- matrices.translate(-camera.x, -camera.y, -camera.z);
+ positionMatrix.translate((float) -camera.x, (float) -camera.y, (float) -camera.z);
Tessellator tessellator = RenderSystem.renderThreadTesselator();
BufferBuilder buffer = tessellator.getBuffer();
- Matrix4f positionMatrix = matrices.peek().getPositionMatrix();
RenderSystem.setShader(GameRenderer::getPositionColorProgram);
RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
@@ -268,8 +267,6 @@ public class RenderHelper {
RenderSystem.enableCull();
RenderSystem.depthFunc(GL11.GL_LEQUAL);
-
- matrices.pop();
}
public static void renderText(WorldRenderContext context, Text text, Vec3d pos, boolean throughWalls) {
@@ -290,19 +287,18 @@ public class RenderHelper {
* @param throughWalls whether the text should be able to be seen through walls or not.
*/
public static void renderText(WorldRenderContext context, OrderedText text, Vec3d pos, float scale, float yOffset, boolean throughWalls) {
- MatrixStack matrices = context.matrixStack();
- Vec3d camera = context.camera().getPos();
+ Matrix4f positionMatrix = new Matrix4f();
+ Camera camera = context.camera();
+ Vec3d cameraPos = camera.getPos();
TextRenderer textRenderer = client.textRenderer;
scale *= 0.025f;
- matrices.push();
- matrices.translate(pos.getX() - camera.getX(), pos.getY() - camera.getY(), pos.getZ() - camera.getZ());
- matrices.peek().getPositionMatrix().mul(RenderSystem.getModelViewMatrix());
- matrices.multiply(context.camera().getRotation());
- matrices.scale(-scale, -scale, scale);
+ positionMatrix
+ .translate((float) (pos.getX() - cameraPos.getX()), (float) (pos.getY() - cameraPos.getY()), (float) (pos.getZ() - cameraPos.getZ()))
+ .rotate(camera.getRotation())
+ .scale(-scale, -scale, scale);
- Matrix4f positionMatrix = matrices.peek().getPositionMatrix();
float xOffset = -textRenderer.getWidth(text) / 2f;
Tessellator tessellator = RenderSystem.renderThreadTesselator();
@@ -315,7 +311,6 @@ public class RenderHelper {
consumers.draw();
RenderSystem.depthFunc(GL11.GL_LEQUAL);
- matrices.pop();
}
/**
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java
index 4f648b8c..ef2e6bf9 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java
@@ -1,6 +1,6 @@
package de.hysky.skyblocker.utils.render.gui;
-import de.hysky.skyblocker.mixin.accessor.HandledScreenAccessor;
+import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.skyblock.auction.AuctionHouseScreenHandler;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java
index 80a1ba9d..e2e057b3 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java
@@ -1,11 +1,11 @@
package de.hysky.skyblocker.utils.render.gui;
import de.hysky.skyblocker.SkyblockerMod;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.item.ItemStack;
import java.util.List;
-import java.util.Map;
import java.util.regex.Pattern;
/**
@@ -34,9 +34,12 @@ public abstract class ContainerSolver {
SkyblockerMod.getInstance().containerSolverManager.markDirty();
}
- protected abstract List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots);
+ protected void onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) {
+ }
+
+ protected abstract List<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> slots);
- protected void trimEdges(Map<Integer, ItemStack> slots, int rows) {
+ protected void trimEdges(Int2ObjectMap<ItemStack> slots, int rows) {
fo