Skip to content

Instantly share code, notes, and snippets.

@lolo45654
Last active August 30, 2024 21:19
Show Gist options
  • Select an option

  • Save lolo45654/6aa2306ae10b14e1de92969255a25972 to your computer and use it in GitHub Desktop.

Select an option

Save lolo45654/6aa2306ae10b14e1de92969255a25972 to your computer and use it in GitHub Desktop.
legacy nbt for itemstack argument
package me.loloed.gist.mixin;
import com.mojang.serialization.DynamicOps;
import net.minecraft.command.argument.ItemStringReader;
import net.minecraft.nbt.NbtElement;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ItemStringReader.class)
public interface ItemStringReaderAccessor {
@Accessor
DynamicOps<NbtElement> getNbtOps();
}
package me.loloed.gist.mixin;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import net.minecraft.SharedConstants;
import net.minecraft.command.argument.ItemStringReader;
import net.minecraft.component.ComponentType;
import net.minecraft.datafixer.Schemas;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.StringNbtReader;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(targets = "net.minecraft.command.argument.ItemStringReader.Reader")
public class ItemStringReaderMixin {
@Shadow @Final private StringReader reader;
@Shadow @Final private ItemStringReader.Callbacks callbacks;
@Shadow @Final
ItemStringReader field_48970;
@Unique
private Identifier id;
@Inject(method = "readItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/command/argument/ItemStringReader$Callbacks;onItem(Lnet/minecraft/registry/entry/RegistryEntry;)V"), locals = LocalCapture.CAPTURE_FAILHARD)
public void onReadItem(CallbackInfo ci, int i, Identifier identifier) {
this.id = identifier;
}
@SuppressWarnings("unchecked")
@Inject(method = "read", at = @At("RETURN"))
public void readSNBT(CallbackInfo ci) throws CommandSyntaxException {
if (!reader.canRead() || reader.peek() != '{') return;
NbtCompound tagNbt = new StringNbtReader(this.reader).parseCompound();
NbtCompound rootNbt = new NbtCompound();
rootNbt.put("tag", tagNbt);
rootNbt.putString("id", id.toString());
rootNbt.putByte("Count", (byte) 1);
NbtCompound updatedNbt = (NbtCompound) Schemas.getFixer().update(TypeReferences.ITEM_STACK, new Dynamic<>(NbtOps.INSTANCE, rootNbt), 3700, SharedConstants.getGameVersion().getSaveVersion().getId()).getValue();
NbtCompound componentsNbt = updatedNbt.getCompound("components");
for (String key : componentsNbt.getKeys()) {
ComponentType<Object> type = (ComponentType<Object>) Registries.DATA_COMPONENT_TYPE.get(Identifier.of(key));
if (type == null) continue;
NbtElement elementNbt = componentsNbt.get(key);
DataResult<?> elementData = type.getCodecOrThrow().parse(((ItemStringReaderAccessor) this.field_48970).getNbtOps(), elementNbt);
Object element = elementData.getOrThrow();
callbacks.onComponentAdded(type, element);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment