aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/utils/ItemUtils.java')
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java168
1 files changed, 88 insertions, 80 deletions
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);
}
}