Handle books, among other things

This commit is contained in:
Nassim Jahnke 2024-03-06 18:52:23 +01:00
parent b4ee564aa2
commit 0961de898d
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
9 changed files with 333 additions and 105 deletions

View File

@ -35,6 +35,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.Bee;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
@ -73,7 +74,7 @@ public final class StructuredDataKey<T> {
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<PotionContents> POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE);
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
public static final StructuredDataKey<String[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", Type.STRING_ARRAY);
public static final StructuredDataKey<FilterableString[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", FilterableString.ARRAY_TYPE);
public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE);
public static final StructuredDataKey<ArmorTrim> TRIM = new StructuredDataKey<>("trim", ArmorTrim.TYPE);
public static final StructuredDataKey<CompoundTag> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Type.COMPOUND_TAG);

View File

@ -0,0 +1,71 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class Filterable<T> {
private final T raw;
private final T filtered;
protected Filterable(final T raw, @Nullable final T filtered) {
this.raw = raw;
this.filtered = filtered;
}
public T raw() {
return raw;
}
public T filtered() {
return filtered;
}
public abstract static class FilterableType<T, F extends Filterable<T>> extends Type<F> {
private final Type<T> elementType;
private final Type<T> optionalElementType;
protected FilterableType(final Type<T> elementType, final Type<T> optionalElementType) {
super(Filterable.class);
this.elementType = elementType;
this.optionalElementType = optionalElementType;
}
@Override
public F read(final ByteBuf buffer) throws Exception {
final T raw = elementType.read(buffer);
final T filtered = optionalElementType.read(buffer);
return create(raw, filtered);
}
@Override
public void write(final ByteBuf buffer, final F value) throws Exception {
elementType.write(buffer, value.raw());
optionalElementType.write(buffer, value.filtered());
}
protected abstract F create(T raw, T filtered);
}
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class FilterableComponent extends Filterable<Tag> {
public static final Type<FilterableComponent> TYPE = new FilterableType<Tag, FilterableComponent>(Type.TAG, Type.OPTIONAL_TAG) {
@Override
protected FilterableComponent create(final Tag raw, final Tag filtered) {
return new FilterableComponent(raw, filtered);
}
};
public static final Type<FilterableComponent[]> ARRAY_TYPE = new ArrayType<>(TYPE);
public FilterableComponent(final Tag raw, @Nullable final Tag filtered) {
super(raw, filtered);
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class FilterableString extends Filterable<String> {
public static final Type<FilterableString> TYPE = new FilterableType<String, FilterableString>(Type.STRING, Type.OPTIONAL_STRING) {
@Override
protected FilterableString create(final String raw, final String filtered) {
return new FilterableString(raw, filtered);
}
};
public static final Type<FilterableString[]> ARRAY_TYPE = new ArrayType<>(TYPE);
public FilterableString(final String raw, @Nullable final String filtered) {
super(raw, filtered);
}
}

View File

@ -30,31 +30,31 @@ public final class WrittenBook {
public static final Type<WrittenBook> TYPE = new Type<WrittenBook>(WrittenBook.class) {
@Override
public WrittenBook read(final ByteBuf buffer) throws Exception {
final String title = Type.STRING.read(buffer);
final FilterableString title = FilterableString.TYPE.read(buffer);
final String author = Type.STRING.read(buffer);
final int generation = Type.VAR_INT.readPrimitive(buffer);
final String[] pages = Type.STRING_ARRAY.read(buffer);
final FilterableComponent[] pages = FilterableComponent.ARRAY_TYPE.read(buffer);
final boolean resolved = buffer.readBoolean();
return new WrittenBook(title, author, generation, pages, resolved);
}
@Override
public void write(final ByteBuf buffer, final WrittenBook value) throws Exception {
Type.STRING.write(buffer, value.title);
FilterableString.TYPE.write(buffer, value.title);
Type.STRING.write(buffer, value.author);
Type.VAR_INT.writePrimitive(buffer, value.generation);
Type.STRING_ARRAY.write(buffer, value.pages);
FilterableComponent.ARRAY_TYPE.write(buffer, value.pages);
buffer.writeBoolean(value.resolved);
}
};
private final String title;
private final FilterableString title;
private final String author;
private final int generation;
private final String[] pages;
private final FilterableComponent[] pages;
private final boolean resolved;
public WrittenBook(final String title, final String author, final int generation, final String[] pages, final boolean resolved) {
public WrittenBook(final FilterableString title, final String author, final int generation, final FilterableComponent[] pages, final boolean resolved) {
this.title = title;
this.author = author;
this.generation = generation;
@ -62,7 +62,7 @@ public final class WrittenBook {
this.resolved = resolved;
}
public String title() {
public FilterableString title() {
return title;
}
@ -74,7 +74,7 @@ public final class WrittenBook {
return generation;
}
public String[] pages() {
public FilterableComponent[] pages() {
return pages;
}

View File

@ -147,7 +147,7 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
final CompoundTag tag = item.tag();
if (tag != null && item.identifier() == 1047) { // Written book
updatePages(tag, "pages");
updatePages(tag, "filtered_pages");
updatePages(tag, "filtered_pages"); // TODO This isn't a list
}
return super.handleItemToClient(item);
}

View File

@ -116,53 +116,22 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Types1_20_5.STRUCTURED_DATA.filler(this)
.add(StructuredDataKey.CUSTOM_DATA)
.add(StructuredDataKey.DAMAGE)
.add(StructuredDataKey.UNBREAKABLE)
.add(StructuredDataKey.CUSTOM_NAME)
.add(StructuredDataKey.LORE)
.add(StructuredDataKey.ENCHANTMENTS)
.add(StructuredDataKey.CAN_PLACE_ON)
.add(StructuredDataKey.CAN_BREAK)
.add(StructuredDataKey.ATTRIBUTE_MODIFIERS)
.add(StructuredDataKey.CUSTOM_MODEL_DATA)
.add(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP)
.add(StructuredDataKey.REPAIR_COST)
.add(StructuredDataKey.CREATIVE_SLOT_LOCK)
.add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE)
.add(StructuredDataKey.INTANGIBLE_PROJECTILE)
.add(StructuredDataKey.STORED_ENCHANTMENTS)
.add(StructuredDataKey.DYED_COLOR)
.add(StructuredDataKey.MAP_COLOR)
.add(StructuredDataKey.MAP_ID)
.add(StructuredDataKey.MAP_DECORATIONS)
.add(StructuredDataKey.MAP_POST_PROCESSING)
.add(StructuredDataKey.CHARGED_PROJECTILES)
.add(StructuredDataKey.BUNDLE_CONTENTS)
.add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS)
.add(StructuredDataKey.WRITABLE_BOOK_CONTENT)
.add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM)
.add(StructuredDataKey.DEBUG_STICK_STATE)
.add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA)
.add(StructuredDataKey.BLOCK_ENTITY_DATA)
.add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.RECIPES)
.add(StructuredDataKey.LODESTONE_TRACKER)
.add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS)
.add(StructuredDataKey.PROFILE)
.add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS)
.add(StructuredDataKey.BASE_COLOR)
.add(StructuredDataKey.POT_DECORATIONS)
.add(StructuredDataKey.CONTAINER)
.add(StructuredDataKey.BLOCK_STATE)
.add(StructuredDataKey.BEES)
.add(StructuredDataKey.LOCK)
.add(StructuredDataKey.CONTAINER_LOOT);
.add(StructuredDataKey.CUSTOM_DATA).add(StructuredDataKey.DAMAGE).add(StructuredDataKey.UNBREAKABLE)
.add(StructuredDataKey.CUSTOM_NAME).add(StructuredDataKey.LORE).add(StructuredDataKey.ENCHANTMENTS)
.add(StructuredDataKey.CAN_PLACE_ON).add(StructuredDataKey.CAN_BREAK).add(StructuredDataKey.ATTRIBUTE_MODIFIERS)
.add(StructuredDataKey.CUSTOM_MODEL_DATA).add(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP).add(StructuredDataKey.REPAIR_COST)
.add(StructuredDataKey.CREATIVE_SLOT_LOCK).add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE).add(StructuredDataKey.INTANGIBLE_PROJECTILE)
.add(StructuredDataKey.STORED_ENCHANTMENTS).add(StructuredDataKey.DYED_COLOR).add(StructuredDataKey.MAP_COLOR)
.add(StructuredDataKey.MAP_ID).add(StructuredDataKey.MAP_DECORATIONS).add(StructuredDataKey.MAP_POST_PROCESSING)
.add(StructuredDataKey.CHARGED_PROJECTILES).add(StructuredDataKey.BUNDLE_CONTENTS).add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS)
.add(StructuredDataKey.CONTAINER).add(StructuredDataKey.BLOCK_STATE).add(StructuredDataKey.BEES)
.add(StructuredDataKey.LOCK).add(StructuredDataKey.CONTAINER_LOOT);
tagRewriter.addTag(RegistryType.ITEM, "minecraft:dyeable", 853, 854, 855, 856, 1120);
}

View File

@ -35,6 +35,10 @@ import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
@ -62,6 +66,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<ClientboundPacket1_20_3, ServerboundPacket1_20_5, Protocol1_20_5To1_20_3> {
private static final GameProfile.Property[] EMPTY_PROPERTIES = new GameProfile.Property[0];
public BlockItemPacketRewriter1_20_5(final Protocol1_20_5To1_20_3 protocol) {
super(protocol, Type.ITEM1_20_2, Type.ITEM1_20_2_ARRAY, Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY);
}
@ -183,7 +189,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
if (item == null) return null;
super.handleItemToClient(item);
return toStructuredItem(item);
return toStructuredItem(item, true);
}
@Override
@ -203,7 +209,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
final CompoundTag tag = customData != null ? customData.value() : new CompoundTag();
final DataItem dataItem = new DataItem(item.identifier(), (byte) item.amount(), (short) 0, tag);
if (customData != null && tag.remove(tagMarker) != null) {
if (customData != null && tag.remove(nbtTagName()) != null) {
return dataItem;
}
@ -212,7 +218,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
return dataItem;
}
public Item toStructuredItem(final Item old) {
public Item toStructuredItem(final Item old, final boolean addMarker) {
final CompoundTag tag = old.tag();
final StructuredItem item = new StructuredItem(old.identifier(), (byte) old.amount(), new StructuredDataContainer());
final StructuredDataContainer data = item.structuredData();
@ -284,18 +290,29 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
//data.set(StructuredDataKey.TRIM, armorTrim);
}
final ListTag chargedProjectiles = tag.getListTag("ChargedProjectiles");
if (chargedProjectiles != null) {
final List<Item> items = new ArrayList<>();
for (final Tag chargedProjectile : chargedProjectiles) {
if (!(chargedProjectile instanceof CompoundTag)) {
continue;
}
items.add(itemFromTag((CompoundTag) chargedProjectile));
}
data.set(StructuredDataKey.CHARGED_PROJECTILES, items.toArray(new Item[0]));
final CompoundTag explosionTag = tag.getCompoundTag("Explosion");
if (explosionTag != null) {
final NumberTag shape = explosionTag.getNumberTag("Type");
final IntArrayTag colors = explosionTag.getIntArrayTag("Colors");
final IntArrayTag fadeColors = explosionTag.getIntArrayTag("FadeColors");
final NumberTag trail = explosionTag.getNumberTag("Trail");
final NumberTag flicker = explosionTag.getNumberTag("Flicker");
final FireworkExplosion explosion = new FireworkExplosion(
shape != null ? shape.asInt() : 0,
colors != null ? colors.getValue() : new int[0],
fadeColors != null ? fadeColors.getValue() : new int[0],
trail != null && trail.asBoolean(),
flicker != null && flicker.asBoolean()
);
data.set(StructuredDataKey.FIREWORK_EXPLOSION, explosion);
}
updateWritableBookPages(data, tag);
updateWrittenBookPages(data, tag);
updateItemList(data, tag, "ChargedProjectiles", StructuredDataKey.CHARGED_PROJECTILES);
updateItemList(data, tag, "Items", StructuredDataKey.BUNDLE_CONTENTS);
updateEnchantments(data, tag, "Enchantments", StructuredDataKey.ENCHANTMENTS, (hideFlagsValue & 0x01) == 0);
updateEnchantments(data, tag, "StoredEnchantments", StructuredDataKey.STORED_ENCHANTMENTS, (hideFlagsValue & 0x20) == 0);
@ -317,12 +334,8 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
// StructuredDataKey.CREATIVE_SLOT_LOCK
// StructuredDataKey.INTANGIBLE_PROJECTILE
// StructuredDataKey.DYED_COLOR
// StructuredDataKey.CHARGED_PROJECTILES
// StructuredDataKey.BUNDLE_CONTENTS
// StructuredDataKey.POTION_CONTENTS
// StructuredDataKey.SUSPICIOUS_STEW_EFFECTS
// StructuredDataKey.WRITABLE_BOOK_CONTENT
// StructuredDataKey.WRITTEN_BOOK_CONTENT
// StructuredDataKey.TRIM
// StructuredDataKey.DEBUG_STICK_STATE
// StructuredDataKey.BUCKET_ENTITY_DATA
@ -330,7 +343,6 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
// StructuredDataKey.INSTRUMENT
// StructuredDataKey.RECIPES
// StructuredDataKey.LODESTONE_TARGET
// StructuredDataKey.FIREWORK_EXPLOSION
// StructuredDataKey.FIREWORKS
// StructuredDataKey.NOTE_BLOCK_SOUND
// StructuredDataKey.BANNER_PATTERNS
@ -342,11 +354,97 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
// StructuredDataKey.CONTAINER_LOOT
// Add the original as custom data, to be re-used for creative clients as well
tag.putBoolean(nbtTagName(), true);
if (addMarker) {
tag.putBoolean(nbtTagName(), true);
}
data.set(StructuredDataKey.CUSTOM_DATA, tag);
return item;
}
private void updateWritableBookPages(final StructuredDataContainer data, final CompoundTag tag) {
final ListTag pagesTag = tag.getListTag("pages");
final CompoundTag filteredPagesTag = tag.getCompoundTag("filtered_pages");
if (pagesTag == null) {
return;
}
final List<FilterableString> pages = new ArrayList<>();
for (int i = 0; i < pagesTag.size(); i++) {
final Tag page = pagesTag.get(i);
if (!(page instanceof StringTag)) {
continue;
}
String filtered = null;
if (filteredPagesTag != null) {
final StringTag filteredPage = filteredPagesTag.getStringTag(String.valueOf(i));
if (filteredPage != null) {
filtered = filteredPage.getValue();
}
}
pages.add(new FilterableString(((StringTag) page).getValue(), filtered));
}
data.set(StructuredDataKey.WRITABLE_BOOK_CONTENT, pages.toArray(new FilterableString[0]));
}
private void updateWrittenBookPages(final StructuredDataContainer data, final CompoundTag tag) {
final ListTag pagesTag = tag.getListTag("pages");
final CompoundTag filteredPagesTag = tag.getCompoundTag("filtered_pages");
if (pagesTag == null) {
return;
}
final List<FilterableComponent> pages = new ArrayList<>();
for (int i = 0; i < pagesTag.size(); i++) {
final Tag page = pagesTag.get(i);
if (!(page instanceof StringTag)) {
continue;
}
Tag filtered = null;
if (filteredPagesTag != null) {
final StringTag filteredPage = filteredPagesTag.getStringTag(String.valueOf(i));
if (filteredPage != null) {
filtered = ComponentUtil.jsonStringToTag(filteredPage.getValue());
}
}
final Tag parsedPage = ComponentUtil.jsonStringToTag(((StringTag) page).getValue());
pages.add(new FilterableComponent(parsedPage, filtered));
}
final StringTag title = tag.getStringTag("title");
final StringTag filteredTitle = tag.getStringTag("filtered_title");
final StringTag author = tag.getStringTag("author");
final NumberTag generation = tag.getNumberTag("generation");
final NumberTag resolved = tag.getNumberTag("resolved");
final WrittenBook writtenBook = new WrittenBook(
new FilterableString(title != null ? title.getValue() : "", filteredTitle != null ? filteredTitle.getValue() : null),
author != null ? author.getValue() : "",
generation != null ? generation.asInt() : 0,
pages.toArray(new FilterableComponent[0]),
resolved != null && resolved.asBoolean()
);
data.set(StructuredDataKey.WRITTEN_BOOK_CONTENT, writtenBook);
}
private void updateItemList(final StructuredDataContainer data, final CompoundTag tag, final String key, final StructuredDataKey<Item[]> dataKey) {
final ListTag chargedProjectiles = tag.getListTag(key);
if (chargedProjectiles == null) {
return;
}
final List<Item> items = new ArrayList<>();
for (final Tag item : chargedProjectiles) {
if (!(item instanceof CompoundTag)) {
continue;
}
items.add(itemFromTag((CompoundTag) item));
}
data.set(dataKey, items.toArray(new Item[0]));
}
private Item itemFromTag(final CompoundTag item) {
final StringTag id = item.getStringTag("id");
final NumberTag count = item.getNumberTag("Count");
@ -388,49 +486,50 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
}
private void updateProfile(final StructuredDataContainer data, final Tag skullOwnerTag) {
final String name;
final List<GameProfile.Property> properties = new ArrayList<>(1);
UUID uuid = null;
if (skullOwnerTag instanceof StringTag) {
name = ((StringTag) skullOwnerTag).getValue();
final String name = ((StringTag) skullOwnerTag).getValue();
data.set(StructuredDataKey.PROFILE, new GameProfile(name, null, EMPTY_PROPERTIES));
} else if (skullOwnerTag instanceof CompoundTag) {
final CompoundTag skullOwner = (CompoundTag) skullOwnerTag;
final StringTag nameTag = skullOwner.getStringTag("Name");
name = nameTag != null ? nameTag.getValue() : "";
final String name = nameTag != null ? nameTag.getValue() : "";
final IntArrayTag idTag = skullOwner.getIntArrayTag("Id");
UUID uuid = null;
if (idTag != null) {
uuid = UUIDUtil.fromIntArray(idTag.getValue());
}
final CompoundTag propertiesTag = skullOwner.getCompoundTag("Properties");
if (propertiesTag != null) {
for (final Map.Entry<String, Tag> entry : propertiesTag.entrySet()) {
if (!(entry.getValue() instanceof ListTag)) {
continue;
}
for (final Tag propertyTag : (ListTag<?>) entry.getValue()) {
if (!(propertyTag instanceof CompoundTag)) {
continue;
}
final StringTag valueTag = ((CompoundTag) propertyTag).getStringTag("Value");
final StringTag signatureTag = ((CompoundTag) propertyTag).getStringTag("Signature");
final GameProfile.Property property = new GameProfile.Property(
entry.getKey(),
valueTag != null ? valueTag.getValue() : "",
signatureTag != null ? signatureTag.getValue() : null
);
properties.add(property);
}
}
updateProperties(propertiesTag, properties);
}
} else {
return;
data.set(StructuredDataKey.PROFILE, new GameProfile(name, uuid, properties.toArray(EMPTY_PROPERTIES)));
}
}
data.set(StructuredDataKey.PROFILE, new GameProfile(name, uuid, properties.toArray(new GameProfile.Property[0])));
private void updateProperties(final CompoundTag propertiesTag, final List<GameProfile.Property> properties) {
for (final Map.Entry<String, Tag> entry : propertiesTag.entrySet()) {
if (!(entry.getValue() instanceof ListTag)) {
continue;
}
for (final Tag propertyTag : (ListTag<?>) entry.getValue()) {
if (!(propertyTag instanceof CompoundTag)) {
continue;
}
final StringTag valueTag = ((CompoundTag) propertyTag).getStringTag("Value");
final StringTag signatureTag = ((CompoundTag) propertyTag).getStringTag("Signature");
final GameProfile.Property property = new GameProfile.Property(
entry.getKey(),
valueTag != null ? valueTag.getValue() : "",
signatureTag != null ? signatureTag.getValue() : null
);
properties.add(property);
}
}
}
private void updateMapDecorations(final StructuredDataContainer data, final ListTag<CompoundTag> decorationsTag) {

View File

@ -192,7 +192,10 @@ public final class EntityPacketRewriter1_20_5 extends EntityRewriter<Clientbound
protected void registerRewrites() {
filter().mapMetaType(typeId -> {
int id = typeId;
if (id >= Types1_20_5.META_TYPES.armadilloState.typeId()) {
if (typeId >= Types1_20_5.META_TYPES.armadilloState.typeId()) {
id++;
}
if (typeId >= Types1_20_5.META_TYPES.wolfVariantType.typeId()) {
id++;
}
return Types1_20_5.META_TYPES.byId(id);