mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2026-11-04 17:00:06 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f880adced2 | ||
|
|
fc07601f24 | ||
|
|
ecb241c187 | ||
|
|
46040b1f5d | ||
|
|
54daa11ce4 | ||
|
|
c556420870 | ||
|
|
84d928ebe7 | ||
|
|
fa6eab5cc3 | ||
|
|
94b26a903c | ||
|
|
c242456c30 | ||
|
|
8391e9d924 | ||
|
|
f5aac9b1ab | ||
|
|
a6850392e1 | ||
|
|
2b37178482 | ||
|
|
82199d9f39 | ||
|
|
c2d2c6d067 | ||
|
|
4066a7b5b6 | ||
|
|
4a7624fef4 | ||
|
|
e38b3f3824 | ||
|
|
4573035aab | ||
|
|
393a5ee973 | ||
|
|
080dc18165 | ||
|
|
6fd421d36e | ||
|
|
84bd1d0782 | ||
|
|
cff2303c62 | ||
|
|
f5733c2cb8 | ||
|
|
21fec0e263 | ||
|
|
093acc519e | ||
|
|
886be3161e | ||
|
|
dc7b708556 | ||
|
|
e82f28c1ac | ||
|
|
7c7239a70d | ||
|
|
3e3dad9e33 | ||
|
|
4871977681 | ||
|
|
0a56e57aec | ||
|
|
a6ff477b8a | ||
|
|
ddad0384f3 | ||
|
|
aabe47f8bc | ||
|
|
354a5f1b75 | ||
|
|
f58afd434d | ||
|
|
57d5652cd5 | ||
|
|
25b521dfcf | ||
|
|
ce655d0679 | ||
|
|
e4e8297a82 | ||
|
|
8357fd01aa | ||
|
|
12b420d3e7 | ||
|
|
db20bc0ae4 | ||
|
|
2a2afa3821 | ||
|
|
f0b2d9aafe | ||
|
|
cd427a2a39 | ||
|
|
75537d3f85 | ||
|
|
a88e2f3fb5 | ||
|
|
8a41e7add6 | ||
|
|
9c35228287 | ||
|
|
f9ec6b9d03 | ||
|
|
22d396d909 | ||
|
|
39b28e21ca | ||
|
|
0488cb7fbe | ||
|
|
ec4aa0637e | ||
|
|
ffc5584b1c | ||
|
|
45c6cfedb0 | ||
|
|
c150e50636 | ||
|
|
16e32a62e5 | ||
|
|
1d18f2e45e | ||
|
|
e46b38e58a | ||
|
|
033741d292 | ||
|
|
7a3ef1e0b7 | ||
|
|
5be41ed3e9 |
No files matched your search
@@ -19,7 +19,9 @@ dependencies {
|
||||
api(libs.vianbt) {
|
||||
exclude("it.unimi.dsi", "fastutil")
|
||||
}
|
||||
api(libs.gson)
|
||||
api(libs.gson) {
|
||||
exclude("com.google.errorprone", "error_prone_annotations")
|
||||
}
|
||||
implementation(rootProject.libs.text) {
|
||||
exclude("com.google.code.gson", "gson")
|
||||
exclude("com.viaversion", "nbt")
|
||||
|
||||
@@ -53,6 +53,14 @@ public interface FullMappings extends BiMappings {
|
||||
*/
|
||||
@Nullable String identifier(int id);
|
||||
|
||||
/**
|
||||
* Returns the unmapped string identifier for the given mapped identifier.
|
||||
*
|
||||
* @param mappedIdentifier mapped identifier
|
||||
* @return unmapped string identifier, or null if not found
|
||||
*/
|
||||
@Nullable String identifier(String mappedIdentifier);
|
||||
|
||||
/**
|
||||
* Returns the mapped string identifier for the given mapped id.
|
||||
*
|
||||
|
||||
@@ -83,6 +83,17 @@ public class FullMappingsBase implements FullMappings {
|
||||
return Key.namespaced(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String identifier(final String mappedIdentifier) {
|
||||
final int mappedId = mappedId(mappedIdentifier);
|
||||
if (mappedId == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int id = mappings.inverse().getNewId(mappedId);
|
||||
return id != -1 ? identifier(id) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mappedIdentifier(final int mappedId) {
|
||||
if (mappedId < 0 || mappedId >= mappedIdToString.length) {
|
||||
|
||||
@@ -126,10 +126,10 @@ public interface MappingData {
|
||||
|
||||
@Nullable Mappings getEnchantmentMappings();
|
||||
|
||||
@Nullable Mappings getAttributeMappings();
|
||||
|
||||
@Nullable Mappings getPaintingMappings();
|
||||
|
||||
@Nullable FullMappings getAttributeMappings();
|
||||
|
||||
@Nullable FullMappings getEntityMappings();
|
||||
|
||||
@Nullable FullMappings getArgumentTypeMappings();
|
||||
|
||||
@@ -43,10 +43,10 @@ public class MappingDataBase implements MappingData {
|
||||
protected FullMappings entityMappings;
|
||||
protected FullMappings recipeSerializerMappings;
|
||||
protected FullMappings itemDataSerializerMappings;
|
||||
protected FullMappings attributeMappings;
|
||||
protected ParticleMappings particleMappings;
|
||||
protected BiMappings itemMappings;
|
||||
protected BiMappings blockMappings;
|
||||
protected BiMappings attributeMappings;
|
||||
protected Mappings blockStateMappings;
|
||||
protected Mappings blockEntityMappings;
|
||||
protected Mappings soundMappings;
|
||||
@@ -76,8 +76,6 @@ public class MappingDataBase implements MappingData {
|
||||
menuMappings = loadMappings(data, "menus");
|
||||
enchantmentMappings = loadMappings(data, "enchantments");
|
||||
paintingMappings = loadMappings(data, "paintings");
|
||||
attributeMappings = loadBiMappings(data, "attributes");
|
||||
|
||||
|
||||
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
|
||||
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
|
||||
@@ -87,6 +85,7 @@ public class MappingDataBase implements MappingData {
|
||||
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
|
||||
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
|
||||
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
|
||||
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
|
||||
|
||||
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
|
||||
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
|
||||
@@ -272,7 +271,7 @@ public class MappingDataBase implements MappingData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Mappings getAttributeMappings() {
|
||||
public @Nullable FullMappings getAttributeMappings() {
|
||||
return attributeMappings;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public interface DebugHandler {
|
||||
|
||||
/**
|
||||
* Returns whether packets should be logged after being transformed.
|
||||
* Set to true by default.
|
||||
* Set to false by default.
|
||||
*
|
||||
* @return whether packets should be logged after being transformed
|
||||
*/
|
||||
|
||||
@@ -35,7 +35,7 @@ public interface Holder<T> {
|
||||
* @throws IllegalArgumentException if the id is negative
|
||||
*/
|
||||
static <T> Holder<T> of(final int id) {
|
||||
return new HolderImpl<>(id);
|
||||
return new IdHolder<>(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ public interface Holder<T> {
|
||||
* @return a new direct holder
|
||||
*/
|
||||
static <T> Holder<T> of(final T value) {
|
||||
return new HolderImpl<>(value);
|
||||
return new ValueHolder<>(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ public interface HolderSet {
|
||||
* @return a new holder set
|
||||
*/
|
||||
static HolderSet of(final String tagKey) {
|
||||
return new HolderSetImpl(tagKey);
|
||||
return new HolderSetImpl.Tag(tagKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ public interface HolderSet {
|
||||
* @return a new holder set
|
||||
*/
|
||||
static HolderSet of(final int[] ids) {
|
||||
return new HolderSetImpl(ids);
|
||||
return new HolderSetImpl.Ids(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,50 +22,63 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft;
|
||||
|
||||
import com.viaversion.viaversion.util.EitherImpl;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.Arrays;
|
||||
|
||||
final class HolderSetImpl extends EitherImpl<String, int[]> implements HolderSet {
|
||||
final class HolderSetImpl {
|
||||
|
||||
HolderSetImpl(final String tagKey) {
|
||||
super(tagKey, null);
|
||||
}
|
||||
record Tag(String tagKey) implements HolderSet {
|
||||
@Override
|
||||
public boolean hasTagKey() {
|
||||
return true;
|
||||
}
|
||||
|
||||
HolderSetImpl(final int[] ids) {
|
||||
super(null, ids);
|
||||
}
|
||||
@Override
|
||||
public int[] ids() {
|
||||
throw new IllegalArgumentException("This holder set has a tag key");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tagKey() {
|
||||
return left();
|
||||
}
|
||||
@Override
|
||||
public boolean hasIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTagKey() {
|
||||
return isLeft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] ids() {
|
||||
return right();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIds() {
|
||||
return isRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderSet rewrite(final Int2IntFunction idRewriter) {
|
||||
if (hasTagKey()) {
|
||||
@Override
|
||||
public HolderSet rewrite(final Int2IntFunction idRewriter) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
final int[] ids = ids();
|
||||
final int[] mappedIds = new int[ids.length];
|
||||
for (int i = 0; i < mappedIds.length; i++) {
|
||||
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
|
||||
record Ids(int[] ids) implements HolderSet {
|
||||
@Override
|
||||
public boolean hasTagKey() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tagKey() {
|
||||
throw new IllegalArgumentException("This holder set has direct ids");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolderSet rewrite(final Int2IntFunction idRewriter) {
|
||||
final int[] mappedIds = new int[ids.length];
|
||||
for (int i = 0; i < mappedIds.length; i++) {
|
||||
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
|
||||
}
|
||||
return new Ids(mappedIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Ids{" +
|
||||
"ids=" + Arrays.toString(ids) +
|
||||
'}';
|
||||
}
|
||||
return new HolderSetImpl(mappedIds);
|
||||
}
|
||||
}
|
||||
+5
-33
@@ -25,49 +25,29 @@ package com.viaversion.viaversion.api.minecraft;
|
||||
import com.google.common.base.Preconditions;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
final class HolderImpl<T> implements Holder<T> {
|
||||
record IdHolder<T>(int id) implements Holder<T> {
|
||||
|
||||
private final T value;
|
||||
private final int id;
|
||||
|
||||
HolderImpl(final int id) {
|
||||
IdHolder {
|
||||
Preconditions.checkArgument(id >= 0, "id cannot be negative");
|
||||
this.value = null;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
HolderImpl(final T value) {
|
||||
this.value = value;
|
||||
this.id = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
return id == -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasId() {
|
||||
return id != -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T value() {
|
||||
Preconditions.checkArgument(isDirect(), "Holder is not direct");
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id() {
|
||||
return id;
|
||||
throw new IllegalArgumentException("Holder is not direct");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
if (isDirect()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final int rewrittenId = rewriteFunction.applyAsInt(id);
|
||||
if (rewrittenId == id) {
|
||||
return this;
|
||||
@@ -77,12 +57,4 @@ final class HolderImpl<T> implements Holder<T> {
|
||||
}
|
||||
return Holder.of(rewrittenId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HolderImpl{" +
|
||||
"value=" + value +
|
||||
", id=" + id +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -36,4 +36,8 @@ public record RegistryEntry(String key, @Nullable Tag tag) {
|
||||
public RegistryEntry withKey(final String key) {
|
||||
return new RegistryEntry(key, tag != null ? tag.copy() : null);
|
||||
}
|
||||
|
||||
public RegistryEntry copy() {
|
||||
return new RegistryEntry(key, tag != null ? tag.copy() : null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
record ValueHolder<T>(T value) implements Holder<T> {
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasId() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -37,14 +37,14 @@ public class ChunkSectionImpl implements ChunkSection {
|
||||
public ChunkSectionImpl(final boolean holdsLight) {
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
this.light = ChunkSectionLightImpl.createWithBlockLight();
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
|
||||
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
|
||||
if (holdsLight) {
|
||||
this.light = new ChunkSectionLightImpl();
|
||||
this.light = ChunkSectionLightImpl.createWithBlockLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ public interface ChunkSectionLight {
|
||||
/**
|
||||
* Returns whether the section has sky light.
|
||||
*
|
||||
* @return true if skylight is present
|
||||
* @return true if sky light is present
|
||||
*/
|
||||
boolean hasSkyLight();
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface ChunkSectionLight {
|
||||
* Returns whether the section has block light.
|
||||
* This returns true unless specifically set to null.
|
||||
*
|
||||
* @return true if skylight is present
|
||||
* @return true if block light is present
|
||||
*/
|
||||
boolean hasBlockLight();
|
||||
|
||||
|
||||
+11
-3
@@ -30,9 +30,17 @@ public class ChunkSectionLightImpl implements ChunkSectionLight {
|
||||
private NibbleArray blockLight;
|
||||
private NibbleArray skyLight;
|
||||
|
||||
public ChunkSectionLightImpl() {
|
||||
// Block light is always written
|
||||
this.blockLight = new NibbleArray(ChunkSection.SIZE);
|
||||
protected ChunkSectionLightImpl() {
|
||||
}
|
||||
|
||||
public static ChunkSectionLight createWithBlockLight() {
|
||||
final ChunkSectionLightImpl light = new ChunkSectionLightImpl();
|
||||
light.blockLight = new NibbleArray(ChunkSection.SIZE);
|
||||
return light;
|
||||
}
|
||||
|
||||
public static ChunkSectionLight createEmpty() {
|
||||
return new ChunkSectionLightImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+32
-6
@@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
|
||||
@@ -34,13 +35,19 @@ import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
|
||||
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.Consumable1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
|
||||
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.Equippable;
|
||||
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.FoodProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
|
||||
@@ -48,11 +55,13 @@ import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.util.Unit;
|
||||
|
||||
public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
@@ -64,6 +73,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Unbreakable> UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE);
|
||||
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG);
|
||||
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
|
||||
public static final StructuredDataKey<String> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.STRING);
|
||||
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", Types.TAG_ARRAY);
|
||||
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE);
|
||||
@@ -78,10 +88,21 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Unit> CREATIVE_SLOT_LOCK = new StructuredDataKey<>("creative_slot_lock", Types.EMPTY);
|
||||
public static final StructuredDataKey<Boolean> ENCHANTMENT_GLINT_OVERRIDE = new StructuredDataKey<>("enchantment_glint_override", Types.BOOLEAN);
|
||||
public static final StructuredDataKey<Tag> INTANGIBLE_PROJECTILE = new StructuredDataKey<>("intangible_projectile", Types.TAG); // Doesn't actually hold data
|
||||
public static final StructuredDataKey<FoodProperties> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties.TYPE1_20_5);
|
||||
public static final StructuredDataKey<FoodProperties> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties.TYPE1_21);
|
||||
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_20_5);
|
||||
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_21);
|
||||
public static final StructuredDataKey<FoodProperties1_21_2> FOOD1_21_2 = new StructuredDataKey<>("food", FoodProperties1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_2 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Item> USE_REMAINDER = new StructuredDataKey<>("use_remainder", Types1_21_2.ITEM);
|
||||
public static final StructuredDataKey<UseCooldown> USE_COOLDOWN = new StructuredDataKey<>("use_cooldown", UseCooldown.TYPE);
|
||||
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY);
|
||||
public static final StructuredDataKey<DamageResistant> DAMAGE_RESISTANT = new StructuredDataKey<>("damage_resistant", DamageResistant.TYPE);
|
||||
public static final StructuredDataKey<ToolProperties> TOOL = new StructuredDataKey<>("tool", ToolProperties.TYPE);
|
||||
public static final StructuredDataKey<Integer> ENCHANTABLE = new StructuredDataKey<>("enchantable", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Equippable> EQUIPPABLE = new StructuredDataKey<>("equippable", Equippable.TYPE);
|
||||
public static final StructuredDataKey<HolderSet> REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET);
|
||||
public static final StructuredDataKey<Unit> GLIDER = new StructuredDataKey<>("glider", Types.EMPTY);
|
||||
public static final StructuredDataKey<String> TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.STRING);
|
||||
public static final StructuredDataKey<DeathProtection> DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE);
|
||||
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE);
|
||||
public static final StructuredDataKey<DyedColor> DYED_COLOR = new StructuredDataKey<>("dyed_color", DyedColor.TYPE);
|
||||
public static final StructuredDataKey<Integer> MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT);
|
||||
@@ -90,9 +111,12 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Integer> MAP_POST_PROCESSING = new StructuredDataKey<>("map_post_processing", Types.VAR_INT);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_20_5 = new StructuredDataKey<>("charged_projectiles", Types1_20_5.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21 = new StructuredDataKey<>("charged_projectiles", Types1_21.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21_2 = new StructuredDataKey<>("charged_projectiles", Types1_21_2.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_20_5 = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21 = new StructuredDataKey<>("bundle_contents", Types1_21.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<PotionContents> POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE);
|
||||
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21_2 = new StructuredDataKey<>("bundle_contents", Types1_21_2.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<PotionContents> POTION_CONTENTS1_20_5 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_20_5);
|
||||
public static final StructuredDataKey<PotionContents> POTION_CONTENTS1_21_2 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_21_2);
|
||||
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
|
||||
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);
|
||||
@@ -101,7 +125,8 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<CompoundTag> ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
|
||||
public static final StructuredDataKey<Holder<Instrument1_20_5>> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE);
|
||||
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT);
|
||||
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE);
|
||||
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG);
|
||||
@@ -115,6 +140,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_20_5 = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_21 = new StructuredDataKey<>("container", Types1_21.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<Item[]> CONTAINER1_21_2 = new StructuredDataKey<>("container", Types1_21_2.ITEM_ARRAY);
|
||||
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE);
|
||||
public static final StructuredDataKey<Bee[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
|
||||
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);
|
||||
|
||||
+314
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* 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.entities;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.util.EntityTypeUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public enum EntityTypes1_21_2 implements EntityType {
|
||||
|
||||
ENTITY(null, null),
|
||||
|
||||
AREA_EFFECT_CLOUD(ENTITY),
|
||||
END_CRYSTAL(ENTITY),
|
||||
EVOKER_FANGS(ENTITY),
|
||||
EXPERIENCE_ORB(ENTITY),
|
||||
EYE_OF_ENDER(ENTITY),
|
||||
FALLING_BLOCK(ENTITY),
|
||||
ITEM(ENTITY),
|
||||
TNT(ENTITY),
|
||||
OMINOUS_ITEM_SPAWNER(ENTITY),
|
||||
MARKER(ENTITY),
|
||||
LIGHTNING_BOLT(ENTITY),
|
||||
INTERACTION(ENTITY),
|
||||
|
||||
DISPLAY(ENTITY, null),
|
||||
BLOCK_DISPLAY(DISPLAY),
|
||||
ITEM_DISPLAY(DISPLAY),
|
||||
TEXT_DISPLAY(DISPLAY),
|
||||
|
||||
// Hanging entities
|
||||
HANGING_ENTITY(ENTITY, null),
|
||||
LEASH_KNOT(HANGING_ENTITY),
|
||||
PAINTING(HANGING_ENTITY),
|
||||
ITEM_FRAME(HANGING_ENTITY),
|
||||
GLOW_ITEM_FRAME(ITEM_FRAME),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE(ENTITY, null),
|
||||
ITEM_PROJECTILE(PROJECTILE, null),
|
||||
SNOWBALL(ITEM_PROJECTILE),
|
||||
ENDER_PEARL(ITEM_PROJECTILE),
|
||||
EGG(ITEM_PROJECTILE),
|
||||
POTION(ITEM_PROJECTILE),
|
||||
EXPERIENCE_BOTTLE(ITEM_PROJECTILE),
|
||||
FIREWORK_ROCKET(PROJECTILE),
|
||||
LLAMA_SPIT(PROJECTILE),
|
||||
SHULKER_BULLET(PROJECTILE),
|
||||
FISHING_BOBBER(PROJECTILE),
|
||||
WITHER_SKULL(PROJECTILE),
|
||||
DRAGON_FIREBALL(PROJECTILE), // Doesn't actually inherit fireball
|
||||
|
||||
ABSTRACT_ARROW(PROJECTILE, null),
|
||||
ARROW(ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(ABSTRACT_ARROW),
|
||||
TRIDENT(ABSTRACT_ARROW),
|
||||
|
||||
ABSTRACT_FIREBALL(ENTITY, null),
|
||||
FIREBALL(ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(ABSTRACT_FIREBALL),
|
||||
|
||||
ABSTRACT_WIND_CHARGE(PROJECTILE, null),
|
||||
WIND_CHARGE(ABSTRACT_WIND_CHARGE),
|
||||
BREEZE_WIND_CHARGE(ABSTRACT_WIND_CHARGE),
|
||||
|
||||
// Vehicles
|
||||
VEHICLE(ENTITY, null),
|
||||
|
||||
ABSTRACT_MINECART(VEHICLE, null),
|
||||
MINECART(ABSTRACT_MINECART),
|
||||
FURNACE_MINECART(ABSTRACT_MINECART),
|
||||
COMMAND_BLOCK_MINECART(ABSTRACT_MINECART),
|
||||
TNT_MINECART(ABSTRACT_MINECART),
|
||||
SPAWNER_MINECART(ABSTRACT_MINECART),
|
||||
|
||||
ABSTRACT_MINECART_CONTAINER(ABSTRACT_MINECART, null),
|
||||
CHEST_MINECART(ABSTRACT_MINECART_CONTAINER),
|
||||
HOPPER_MINECART(ABSTRACT_MINECART_CONTAINER),
|
||||
|
||||
ABSTRACT_BOAT(VEHICLE, null),
|
||||
ABSTRACT_CHEST_BOAT(ABSTRACT_BOAT, null),
|
||||
ACACIA_BOAT(ABSTRACT_BOAT),
|
||||
ACACIA_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
BAMBOO_CHEST_RAFT(ABSTRACT_CHEST_BOAT),
|
||||
BAMBOO_RAFT(ABSTRACT_BOAT),
|
||||
BIRCH_BOAT(ABSTRACT_BOAT),
|
||||
BIRCH_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
CHERRY_BOAT(ABSTRACT_BOAT),
|
||||
CHERRY_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
DARK_OAK_BOAT(ABSTRACT_BOAT),
|
||||
DARK_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
JUNGLE_BOAT(ABSTRACT_BOAT),
|
||||
JUNGLE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
MANGROVE_BOAT(ABSTRACT_BOAT),
|
||||
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
OAK_BOAT(ABSTRACT_BOAT),
|
||||
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
PALE_OAK_BOAT(ABSTRACT_BOAT),
|
||||
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
SPRUCE_BOAT(ABSTRACT_BOAT),
|
||||
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
|
||||
// Living entities as a larger subclass
|
||||
LIVING_ENTITY(ENTITY, null),
|
||||
ARMOR_STAND(LIVING_ENTITY),
|
||||
PLAYER(LIVING_ENTITY),
|
||||
|
||||
// Mobs as a larger subclass
|
||||
MOB(LIVING_ENTITY, null),
|
||||
ENDER_DRAGON(MOB),
|
||||
|
||||
SLIME(MOB),
|
||||
MAGMA_CUBE(SLIME),
|
||||
|
||||
// Ambient mobs
|
||||
AMBIENT_CREATURE(MOB, null),
|
||||
BAT(AMBIENT_CREATURE),
|
||||
|
||||
// Flying mobs
|
||||
FLYING_MOB(MOB, null),
|
||||
GHAST(FLYING_MOB),
|
||||
PHANTOM(FLYING_MOB),
|
||||
|
||||
// Pathfinder mobs and its subclasses
|
||||
PATHFINDER_MOB(MOB, null),
|
||||
ALLAY(PATHFINDER_MOB),
|
||||
|
||||
ABSTRACT_GOLEM(PATHFINDER_MOB, null),
|
||||
SNOW_GOLEM(ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(ABSTRACT_GOLEM),
|
||||
SHULKER(ABSTRACT_GOLEM),
|
||||
|
||||
// Ageable mobs and (tamable) animals
|
||||
ABSTRACT_AGEABLE(PATHFINDER_MOB, null),
|
||||
ABSTRACT_VILLAGER(ABSTRACT_AGEABLE, null),
|
||||
VILLAGER(ABSTRACT_VILLAGER),
|
||||
WANDERING_TRADER(ABSTRACT_VILLAGER),
|
||||
|
||||
ABSTRACT_ANIMAL(ABSTRACT_AGEABLE, null),
|
||||
AXOLOTL(ABSTRACT_ANIMAL),
|
||||
CHICKEN(ABSTRACT_ANIMAL),
|
||||
PANDA(ABSTRACT_ANIMAL),
|
||||
PIG(ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(ABSTRACT_ANIMAL),
|
||||
RABBIT(ABSTRACT_ANIMAL),
|
||||
SHEEP(ABSTRACT_ANIMAL),
|
||||
BEE(ABSTRACT_ANIMAL),
|
||||
TURTLE(ABSTRACT_ANIMAL),
|
||||
FOX(ABSTRACT_ANIMAL),
|
||||
FROG(ABSTRACT_ANIMAL),
|
||||
GOAT(ABSTRACT_ANIMAL),
|
||||
HOGLIN(ABSTRACT_ANIMAL),
|
||||
STRIDER(ABSTRACT_ANIMAL),
|
||||
SNIFFER(ABSTRACT_ANIMAL),
|
||||
ARMADILLO(ABSTRACT_ANIMAL),
|
||||
|
||||
COW(ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(COW),
|
||||
|
||||
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
|
||||
CAT(TAMABLE_ANIMAL),
|
||||
OCELOT(TAMABLE_ANIMAL),
|
||||
WOLF(TAMABLE_ANIMAL),
|
||||
PARROT(TAMABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_HORSE(ABSTRACT_ANIMAL, null),
|
||||
HORSE(ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(ABSTRACT_HORSE),
|
||||
CAMEL(ABSTRACT_HORSE),
|
||||
|
||||
ABSTRACT_CHESTED_HORSE(ABSTRACT_HORSE, null),
|
||||
DONKEY(ABSTRACT_CHESTED_HORSE),
|
||||
MULE(ABSTRACT_CHESTED_HORSE),
|
||||
LLAMA(ABSTRACT_CHESTED_HORSE),
|
||||
TRADER_LLAMA(LLAMA),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(PATHFINDER_MOB, null),
|
||||
BLAZE(ABSTRACT_MONSTER),
|
||||
CREEPER(ABSTRACT_MONSTER),
|
||||
ENDERMITE(ABSTRACT_MONSTER),
|
||||
ENDERMAN(ABSTRACT_MONSTER),
|
||||
GIANT(ABSTRACT_MONSTER),
|
||||
SILVERFISH(ABSTRACT_MONSTER),
|
||||
VEX(ABSTRACT_MONSTER),
|
||||
WITHER(ABSTRACT_MONSTER),
|
||||
BREEZE(ABSTRACT_MONSTER),
|
||||
ZOGLIN(ABSTRACT_MONSTER),
|
||||
WARDEN(ABSTRACT_MONSTER),
|
||||
CREAKING(ABSTRACT_MONSTER),
|
||||
CREAKING_TRANSIENT(ABSTRACT_MONSTER),
|
||||
|
||||
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
|
||||
SKELETON(ABSTRACT_SKELETON),
|
||||
STRAY(ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(ABSTRACT_SKELETON),
|
||||
BOGGED(ABSTRACT_SKELETON),
|
||||
|
||||
ZOMBIE(ABSTRACT_MONSTER),
|
||||
DROWNED(ZOMBIE),
|
||||
HUSK(ZOMBIE),
|
||||
ZOMBIFIED_PIGLIN(ZOMBIE),
|
||||
ZOMBIE_VILLAGER(ZOMBIE),
|
||||
|
||||
GUARDIAN(ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(GUARDIAN),
|
||||
|
||||
SPIDER(ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(SPIDER),
|
||||
|
||||
ABSTRACT_PIGLIN(ABSTRACT_MONSTER, null),
|
||||
PIGLIN(ABSTRACT_PIGLIN),
|
||||
PIGLIN_BRUTE(ABSTRACT_PIGLIN),
|
||||
|
||||
// Water mobs
|
||||
AGEABLE_WATER_CREATURE(ABSTRACT_AGEABLE, null),
|
||||
DOLPHIN(AGEABLE_WATER_CREATURE),
|
||||
|
||||
SQUID(AGEABLE_WATER_CREATURE),
|
||||
GLOW_SQUID(SQUID),
|
||||
|
||||
WATER_ANIMAL(PATHFINDER_MOB, null),
|
||||
ABSTRACT_FISH(WATER_ANIMAL, null),
|
||||
PUFFERFISH(ABSTRACT_FISH),
|
||||
TADPOLE(ABSTRACT_FISH),
|
||||
|
||||
ABSTRACT_SCHOOLING_FISH(ABSTRACT_FISH, null),
|
||||
COD(ABSTRACT_SCHOOLING_FISH),
|
||||
SALMON(ABSTRACT_SCHOOLING_FISH),
|
||||
TROPICAL_FISH(ABSTRACT_SCHOOLING_FISH),
|
||||
|
||||
// Raiders
|
||||
ABSTRACT_RAIDER(ABSTRACT_MONSTER, null),
|
||||
WITCH(ABSTRACT_RAIDER),
|
||||
RAVAGER(ABSTRACT_RAIDER),
|
||||
|
||||
ABSTRACT_ILLAGER(ABSTRACT_RAIDER, null),
|
||||
SPELLCASTER_ILLAGER(ABSTRACT_ILLAGER, null),
|
||||
VINDICATOR(ABSTRACT_ILLAGER),
|
||||
PILLAGER(ABSTRACT_ILLAGER),
|
||||
EVOKER(SPELLCASTER_ILLAGER),
|
||||
ILLUSIONER(SPELLCASTER_ILLAGER);
|
||||
|
||||
private static final EntityType[] TYPES = EntityTypeUtil.createSizedArray(values());
|
||||
private final EntityType parent;
|
||||
private final String identifier;
|
||||
private int id = -1;
|
||||
|
||||
EntityTypes1_21_2(final EntityType parent) {
|
||||
this.parent = parent;
|
||||
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
EntityTypes1_21_2(final EntityType parent, @Nullable final String identifier) {
|
||||
this.parent = parent;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
if (id == -1) {
|
||||
throw new IllegalStateException("Ids have not been initialized yet (type " + name() + ")");
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String identifier() {
|
||||
Preconditions.checkArgument(identifier != null, "Called identifier method on abstract type");
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstractType() {
|
||||
return identifier == null;
|
||||
}
|
||||
|
||||
public static EntityType getTypeFromId(final int typeId) {
|
||||
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
|
||||
}
|
||||
|
||||
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {
|
||||
EntityTypeUtil.initialize(values(), TYPES, protocol, (type, id) -> type.id = id);
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -26,10 +26,11 @@ import com.viaversion.viaversion.api.minecraft.PaintingVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.WolfVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
|
||||
public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
|
||||
@@ -40,7 +41,7 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType itemType = add(7, Types1_21.ITEM);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
|
||||
@@ -65,8 +66,9 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
|
||||
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
|
||||
|
||||
public EntityDataTypes1_21(final ParticleType particleType, final ArrayType<Particle> particlesType) {
|
||||
public EntityDataTypes1_21(final Type<Item> itemType, final ParticleType particleType, final ArrayType<Particle> particlesType) {
|
||||
super(31);
|
||||
this.itemType = add(7, itemType);
|
||||
this.particleType = add(17, particleType);
|
||||
this.particlesType = add(18, particlesType);
|
||||
}
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<SoundEvent> sound,
|
||||
boolean hasConsumeParticles, ConsumeEffect<?>[] consumeEffects) {
|
||||
|
||||
public static final Type<?>[] EFFECT_TYPES = {
|
||||
ApplyStatusEffects.TYPE,
|
||||
Types.HOLDER_SET, // remove effects
|
||||
Types.EMPTY, // clear all effects
|
||||
Types.FLOAT, // teleport randomly
|
||||
Types.SOUND_EVENT // play sound
|
||||
};
|
||||
|
||||
public static final Type<Consumable1_21_2> TYPE = new Type<>(Consumable1_21_2.class) {
|
||||
@Override
|
||||
public Consumable1_21_2 read(final ByteBuf buffer) {
|
||||
final float consumeSeconds = buffer.readFloat();
|
||||
final int animationType = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Holder<SoundEvent> sound = Types.SOUND_EVENT.read(buffer);
|
||||
final boolean hasConsumeParticles = buffer.readBoolean();
|
||||
final ConsumeEffect<?>[] consumeEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
|
||||
return new Consumable1_21_2(consumeSeconds, animationType, sound, hasConsumeParticles, consumeEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Consumable1_21_2 value) {
|
||||
buffer.writeFloat(value.consumeSeconds);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.animationType);
|
||||
Types.SOUND_EVENT.write(buffer, value.sound);
|
||||
buffer.writeBoolean(value.hasConsumeParticles);
|
||||
ConsumeEffect.ARRAY_TYPE.write(buffer, value.consumeEffects);
|
||||
}
|
||||
};
|
||||
|
||||
public record ConsumeEffect<T>(int id, Type<T> type, T value) {
|
||||
|
||||
public static final Type<ConsumeEffect<?>> TYPE = new Type<>(ConsumeEffect.class) {
|
||||
@Override
|
||||
public ConsumeEffect<?> read(final ByteBuf buffer) {
|
||||
// Oh no...
|
||||
final int effectType = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Type<?> type = EFFECT_TYPES[effectType];
|
||||
final Object value = type.read(buffer);
|
||||
return ConsumeEffect.of(effectType, type, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ConsumeEffect<?> value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.id);
|
||||
value.writeValue(buffer);
|
||||
}
|
||||
};
|
||||
public static final Type<ConsumeEffect<?>[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
|
||||
static <T> ConsumeEffect<T> of(final int id, final Type<T> type, final Object value) {
|
||||
//noinspection unchecked
|
||||
return new ConsumeEffect<>(id, type, (T) value);
|
||||
}
|
||||
|
||||
void writeValue(final ByteBuf buf) {
|
||||
this.type.write(buf, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
public record ApplyStatusEffects(PotionEffect[] effects, float probability) {
|
||||
|
||||
public static final Type<ApplyStatusEffects> TYPE = new Type<>(ApplyStatusEffects.class) {
|
||||
@Override
|
||||
public ApplyStatusEffects read(final ByteBuf buffer) {
|
||||
final PotionEffect[] effects = PotionEffect.ARRAY_TYPE.read(buffer);
|
||||
final float probability = buffer.readFloat();
|
||||
return new ApplyStatusEffects(effects, probability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final ApplyStatusEffects value) {
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.effects);
|
||||
buffer.writeFloat(value.probability);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+43
@@ -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.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record DamageResistant(String typesTagKey) {
|
||||
|
||||
public static final Type<DamageResistant> TYPE = new Type<>(DamageResistant.class) {
|
||||
@Override
|
||||
public DamageResistant read(final ByteBuf buffer) {
|
||||
final String typesTagKey = Types.STRING.read(buffer);
|
||||
return new DamageResistant(typesTagKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final DamageResistant value) {
|
||||
Types.STRING.write(buffer, value.typesTagKey());
|
||||
}
|
||||
};
|
||||
}
|
||||
+9
-12
@@ -22,26 +22,23 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2.ConsumeEffect;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record FoodEffect(PotionEffect effect, float probability) {
|
||||
public record DeathProtection(ConsumeEffect<?>[] deathEffects) {
|
||||
|
||||
public static final Type<FoodEffect> TYPE = new Type<>(FoodEffect.class) {
|
||||
public static final Type<DeathProtection> TYPE = new Type<>(DeathProtection.class) {
|
||||
@Override
|
||||
public FoodEffect read(final ByteBuf buffer) {
|
||||
final PotionEffect effect = PotionEffect.TYPE.read(buffer);
|
||||
final float probability = buffer.readFloat();
|
||||
return new FoodEffect(effect, probability);
|
||||
public DeathProtection read(final ByteBuf buffer) {
|
||||
final ConsumeEffect<?>[] deathEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
|
||||
return new DeathProtection(deathEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodEffect value) {
|
||||
PotionEffect.TYPE.write(buffer, value.effect);
|
||||
buffer.writeFloat(value.probability);
|
||||
public void write(final ByteBuf buffer, final DeathProtection value) {
|
||||
ConsumeEffect.ARRAY_TYPE.write(buffer, value.deathEffects);
|
||||
}
|
||||
};
|
||||
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Nullable String model,
|
||||
@Nullable String cameraOverlay, @Nullable HolderSet allowedEntities, boolean dispensable,
|
||||
boolean swappable, boolean damageOnHurt) {
|
||||
|
||||
public static final Type<Equippable> TYPE = new Type<>(Equippable.class) {
|
||||
@Override
|
||||
public Equippable read(final ByteBuf buffer) {
|
||||
final int equipmentSlot = Types.VAR_INT.readPrimitive(buffer);
|
||||
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
|
||||
final String model = Types.OPTIONAL_STRING.read(buffer);
|
||||
final String cameraOverlay = Types.OPTIONAL_STRING.read(buffer);
|
||||
final HolderSet allowedEntities = Types.HOLDER_SET.read(buffer);
|
||||
final boolean dispensable = buffer.readBoolean();
|
||||
final boolean swappable = buffer.readBoolean();
|
||||
final boolean damageOnHurt = buffer.readBoolean();
|
||||
return new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final Equippable value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.equipmentSlot());
|
||||
Types.SOUND_EVENT.write(buffer, value.soundEvent());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.model());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.cameraOverlay());
|
||||
Types.HOLDER_SET.write(buffer, value.allowedEntities());
|
||||
buffer.writeBoolean(value.dispensable());
|
||||
buffer.writeBoolean(value.swappable());
|
||||
buffer.writeBoolean(value.damageOnHurt());
|
||||
}
|
||||
};
|
||||
|
||||
public Equippable rewrite(final Int2IntFunction soundIdRewriter) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriter);
|
||||
return soundEvent == this.soundEvent ? this : new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
|
||||
}
|
||||
}
|
||||
+30
-10
@@ -25,25 +25,26 @@ package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record FoodProperties(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
|
||||
Item usingConvertsTo, FoodEffect[] possibleEffects) {
|
||||
public record FoodProperties1_20_5(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
|
||||
Item usingConvertsTo, FoodEffect[] possibleEffects) {
|
||||
|
||||
public static final Type<FoodProperties> TYPE1_20_5 = new Type<>(FoodProperties.class) {
|
||||
public static final Type<FoodProperties1_20_5> TYPE1_20_5 = new Type<>(FoodProperties1_20_5.class) {
|
||||
@Override
|
||||
public FoodProperties read(final ByteBuf buffer) {
|
||||
public FoodProperties1_20_5 read(final ByteBuf buffer) {
|
||||
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float saturationModifier = buffer.readFloat();
|
||||
final boolean canAlwaysEat = buffer.readBoolean();
|
||||
final float eatSeconds = buffer.readFloat();
|
||||
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer);
|
||||
return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, null, possibleEffects);
|
||||
return new FoodProperties1_20_5(nutrition, saturationModifier, canAlwaysEat, eatSeconds, null, possibleEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodProperties value) {
|
||||
public void write(final ByteBuf buffer, final FoodProperties1_20_5 value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
|
||||
buffer.writeFloat(value.saturationModifier);
|
||||
buffer.writeBoolean(value.canAlwaysEat);
|
||||
@@ -51,20 +52,20 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
|
||||
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
|
||||
}
|
||||
};
|
||||
public static final Type<FoodProperties> TYPE1_21 = new Type<FoodProperties>(FoodProperties.class) {
|
||||
public static final Type<FoodProperties1_20_5> TYPE1_21 = new Type<>(FoodProperties1_20_5.class) {
|
||||
@Override
|
||||
public FoodProperties read(final ByteBuf buffer) {
|
||||
public FoodProperties1_20_5 read(final ByteBuf buffer) {
|
||||
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float saturationModifier = buffer.readFloat();
|
||||
final boolean canAlwaysEat = buffer.readBoolean();
|
||||
final float eatSeconds = buffer.readFloat();
|
||||
final Item usingConvertsTo = Types1_21.OPTIONAL_ITEM.read(buffer);
|
||||
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer);
|
||||
return new FoodProperties(nutrition, saturationModifier, canAlwaysEat, eatSeconds, usingConvertsTo, possibleEffects);
|
||||
return new FoodProperties1_20_5(nutrition, saturationModifier, canAlwaysEat, eatSeconds, usingConvertsTo, possibleEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodProperties value) {
|
||||
public void write(final ByteBuf buffer, final FoodProperties1_20_5 value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
|
||||
buffer.writeFloat(value.saturationModifier);
|
||||
buffer.writeBoolean(value.canAlwaysEat);
|
||||
@@ -73,4 +74,23 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
|
||||
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects);
|
||||
}
|
||||
};
|
||||
|
||||
public record FoodEffect(PotionEffect effect, float probability) {
|
||||
|
||||
public static final Type<FoodEffect> TYPE = new Type<>(FoodEffect.class) {
|
||||
@Override
|
||||
public FoodEffect read(final ByteBuf buffer) {
|
||||
final PotionEffect effect = PotionEffect.TYPE.read(buffer);
|
||||
final float probability = buffer.readFloat();
|
||||
return new FoodEffect(effect, probability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodEffect value) {
|
||||
PotionEffect.TYPE.write(buffer, value.effect);
|
||||
buffer.writeFloat(value.probability);
|
||||
}
|
||||
};
|
||||
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record FoodProperties1_21_2(int nutrition, float saturationModifier, boolean canAlwaysEat) {
|
||||
|
||||
public static final Type<FoodProperties1_21_2> TYPE = new Type<>(FoodProperties1_21_2.class) {
|
||||
@Override
|
||||
public FoodProperties1_21_2 read(final ByteBuf buffer) {
|
||||
final int nutrition = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float saturationModifier = buffer.readFloat();
|
||||
final boolean canAlwaysEat = buffer.readBoolean();
|
||||
return new FoodProperties1_21_2(nutrition, saturationModifier, canAlwaysEat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final FoodProperties1_21_2 value) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.nutrition);
|
||||
buffer.writeFloat(value.saturationModifier);
|
||||
buffer.writeBoolean(value.canAlwaysEat);
|
||||
}
|
||||
};
|
||||
}
|
||||
+9
-9
@@ -29,27 +29,27 @@ import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record Instrument(Holder<SoundEvent> soundEvent, int useDuration, float range) {
|
||||
public record Instrument1_20_5(Holder<SoundEvent> soundEvent, int useDuration, float range) {
|
||||
|
||||
public static final HolderType<Instrument> TYPE = new HolderType<>() {
|
||||
public static final HolderType<Instrument1_20_5> TYPE = new HolderType<>() {
|
||||
@Override
|
||||
public Instrument readDirect(final ByteBuf buffer) {
|
||||
public Instrument1_20_5 readDirect(final ByteBuf buffer) {
|
||||
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
|
||||
final int useDuration = Types.VAR_INT.readPrimitive(buffer);
|
||||
final float range = buffer.readFloat();
|
||||
return new Instrument(soundEvent, useDuration, range);
|
||||
final float range = Types.FLOAT.readPrimitive(buffer);
|
||||
return new Instrument1_20_5(soundEvent, useDuration, range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final Instrument value) {
|
||||
public void writeDirect(final ByteBuf buffer, final Instrument1_20_5 value) {
|
||||
Types.SOUND_EVENT.write(buffer, value.soundEvent());
|
||||
Types.VAR_INT.writePrimitive(buffer, value.useDuration());
|
||||
buffer.writeFloat(value.range());
|
||||
Types.FLOAT.writePrimitive(buffer, value.range());
|
||||
}
|
||||
};
|
||||
|
||||
public Instrument rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
public Instrument1_20_5 rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
|
||||
return soundEvent == this.soundEvent ? this : new Instrument(soundEvent, useDuration, range);
|
||||
return soundEvent == this.soundEvent ? this : new Instrument1_20_5(soundEvent, useDuration, range);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
|
||||
public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration, float range, Tag description) {
|
||||
|
||||
public static final HolderType<Instrument1_21_2> TYPE = new HolderType<>() {
|
||||
@Override
|
||||
public Instrument1_21_2 readDirect(final ByteBuf buffer) {
|
||||
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
|
||||
final float useDuration = Types.FLOAT.readPrimitive(buffer);
|
||||
final float range = Types.FLOAT.readPrimitive(buffer);
|
||||
final Tag description = Types.TAG.read(buffer);
|
||||
return new Instrument1_21_2(soundEvent, useDuration, range, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final Instrument1_21_2 value) {
|
||||
Types.SOUND_EVENT.write(buffer, value.soundEvent());
|
||||
Types.FLOAT.writePrimitive(buffer, value.useDuration());
|
||||
Types.FLOAT.writePrimitive(buffer, value.range());
|
||||
Types.TAG.write(buffer, value.description());
|
||||
}
|
||||
};
|
||||
|
||||
public Instrument1_21_2 rewrite(final Int2IntFunction soundIdRewriteFunction) {
|
||||
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(soundIdRewriteFunction);
|
||||
return soundEvent == this.soundEvent ? this : new Instrument1_21_2(soundEvent, useDuration, range, description);
|
||||
}
|
||||
}
|
||||
+35
-3
@@ -27,15 +27,20 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects) {
|
||||
public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects,
|
||||
@Nullable String customName) {
|
||||
|
||||
public static final Type<PotionContents> TYPE = new Type<>(PotionContents.class) {
|
||||
public PotionContents(final @Nullable Integer potion, final @Nullable Integer customColor, final PotionEffect[] customEffects) {
|
||||
this(potion, customColor, customEffects, null);
|
||||
}
|
||||
|
||||
public static final Type<PotionContents> TYPE1_20_5 = new Type<>(PotionContents.class) {
|
||||
@Override
|
||||
public PotionContents read(final ByteBuf buffer) {
|
||||
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
|
||||
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
|
||||
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
|
||||
return new PotionContents(potion, customColor, customEffects);
|
||||
return new PotionContents(potion, customColor, customEffects, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,4 +58,31 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Type<PotionContents> TYPE1_21_2 = new Type<>(PotionContents.class) {
|
||||
@Override
|
||||
public PotionContents read(final ByteBuf buffer) {
|
||||
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
|
||||
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
|
||||
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
|
||||
final String customName = Types.OPTIONAL_STRING.read(buffer);
|
||||
return new PotionContents(potion, customColor, customEffects, customName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final PotionContents value) {
|
||||
buffer.writeBoolean(value.potion != null);
|
||||
if (value.potion != null) {
|
||||
Types.VAR_INT.writePrimitive(buffer, value.potion);
|
||||
}
|
||||
|
||||
buffer.writeBoolean(value.customColor != null);
|
||||
if (value.customColor != null) {
|
||||
buffer.writeInt(value.customColor);
|
||||
}
|
||||
|
||||
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
|
||||
Types.OPTIONAL_STRING.write(buffer, value.customName);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.function.Function;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record UseCooldown(float seconds, @Nullable String cooldownGroup) {
|
||||
|
||||
public static final Type<UseCooldown> TYPE = new Type<>(UseCooldown.class) {
|
||||
@Override
|
||||
public UseCooldown read(final ByteBuf buffer) {
|
||||
final float seconds = buffer.readFloat();
|
||||
final String cooldownGroup = Types.OPTIONAL_STRING.read(buffer);
|
||||
return new UseCooldown(seconds, cooldownGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final UseCooldown value) {
|
||||
buffer.writeFloat(value.seconds());
|
||||
Types.OPTIONAL_STRING.write(buffer, value.cooldownGroup());
|
||||
}
|
||||
};
|
||||
|
||||
public UseCooldown rewrite(final Function<String, String> idRewriter) {
|
||||
if (cooldownGroup == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final String mappedCooldownGroup = idRewriter.apply(cooldownGroup);
|
||||
return new UseCooldown(seconds, mappedCooldownGroup);
|
||||
}
|
||||
}
|
||||
@@ -198,6 +198,14 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
}
|
||||
}
|
||||
|
||||
public void registerFinishConfiguration(final CU packetType, final PacketHandler handler) {
|
||||
registerClientbound(packetType, wrapper -> {
|
||||
// TODO Temporary solution to handle the finish configuration packet already having changed our tracked protocol state in a previous handler
|
||||
wrapper.user().getProtocolInfo().setServerState(State.CONFIGURATION);
|
||||
handler.handle(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void loadMappingData() {
|
||||
getMappingData().load();
|
||||
|
||||
+17
-5
@@ -43,7 +43,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>();
|
||||
|
||||
public static final ProtocolVersion v1_7_2 = register(4, "1.7.2-1.7.5", new SubVersionRange("1.7", 2, 5));
|
||||
@Deprecated(forRemoval=true) public static final ProtocolVersion v1_7_1 = v1_7_2;
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final ProtocolVersion v1_7_1 = v1_7_2;
|
||||
public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new SubVersionRange("1.7", 6, 10));
|
||||
public static final ProtocolVersion v1_8 = register(47, "1.8.x", new SubVersionRange("1.8", 0, 9));
|
||||
public static final ProtocolVersion v1_9 = register(107, "1.9");
|
||||
@@ -85,8 +86,13 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4));
|
||||
public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6));
|
||||
public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1));
|
||||
public static final ProtocolVersion v1_21_2 = register(768, "1.21.2-1.21.3", new SubVersionRange("1.21", 2, 3));
|
||||
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
|
||||
|
||||
static {
|
||||
unknown.known = false;
|
||||
}
|
||||
|
||||
public static ProtocolVersion register(int version, String name) {
|
||||
return register(version, -1, name);
|
||||
}
|
||||
@@ -150,7 +156,11 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
return protocolVersion;
|
||||
}
|
||||
}
|
||||
return new ProtocolVersion(VersionType.SPECIAL, version, -1, "Unknown (" + version + ")", null);
|
||||
|
||||
// Will be made nullable instead in the future...
|
||||
final ProtocolVersion unknown = new ProtocolVersion(versionType, version, -1, "Unknown (" + version + ")", null);
|
||||
unknown.known = false;
|
||||
return unknown;
|
||||
}
|
||||
|
||||
public static @NonNull ProtocolVersion getProtocol(final int version) {
|
||||
@@ -201,6 +211,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
private final int snapshotVersion;
|
||||
private final String name;
|
||||
private final Set<String> includedVersions;
|
||||
@Deprecated // Remove when getProtocol is made nullable
|
||||
private boolean known = true;
|
||||
|
||||
/**
|
||||
* Constructs a new ProtocolVersion instance.
|
||||
@@ -285,12 +297,12 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the protocol is set. Should only be unknown for unregistered protocols returned by {@link #getProtocol(int)}.
|
||||
* Returns whether the protocol version is {@link #unknown}. For checking if the protocol version is registered, use {@link #isRegistered(VersionType, int)}
|
||||
*
|
||||
* @return true if the protocol is set
|
||||
* @return true if the protocol version is unknown
|
||||
*/
|
||||
public boolean isKnown() {
|
||||
return version != -1;
|
||||
return known;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package com.viaversion.viaversion.api.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
@@ -50,6 +51,8 @@ public interface ItemRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter<T
|
||||
@Nullable
|
||||
Item handleItemToServer(UserConnection connection, @Nullable Item item);
|
||||
|
||||
void rewriteParticle(UserConnection connection, Particle particle);
|
||||
|
||||
/**
|
||||
* Returns the item type of the current protocol.
|
||||
*
|
||||
|
||||
@@ -189,7 +189,9 @@ public final class Types {
|
||||
public static final Type<PlayerMessageSignature> OPTIONAL_PLAYER_MESSAGE_SIGNATURE = new PlayerMessageSignatureType.OptionalPlayerMessageSignatureType();
|
||||
public static final Type<PlayerMessageSignature[]> PLAYER_MESSAGE_SIGNATURE_ARRAY = new ArrayType<>(PLAYER_MESSAGE_SIGNATURE);
|
||||
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM = new BitSetType(6);
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM1_19_3 = new BitSetType(6);
|
||||
public static final BitSetType PROFILE_ACTIONS_ENUM1_21_2 = new BitSetType(7);
|
||||
|
||||
public static final ByteArrayType SIGNATURE_BYTES = new ByteArrayType(256);
|
||||
public static final BitSetType ACKNOWLEDGED_BIT_SET = new BitSetType(20);
|
||||
public static final ByteArrayType.OptionalByteArrayType OPTIONAL_SIGNATURE_BYTES = new ByteArrayType.OptionalByteArrayType(256);
|
||||
|
||||
@@ -36,11 +36,19 @@ public class IntType extends Type<Integer> implements TypeConverter<Integer> {
|
||||
return buffer.readInt();
|
||||
}
|
||||
|
||||
public int readPrimitive(ByteBuf buffer) {
|
||||
return buffer.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Integer object) {
|
||||
buffer.writeInt(object);
|
||||
}
|
||||
|
||||
public void writePrimitive(ByteBuf buffer, int object) {
|
||||
buffer.writeInt(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer from(Object o) {
|
||||
if (o instanceof Number number) {
|
||||
|
||||
+7
@@ -87,5 +87,12 @@ public class StructuredDataType extends Type<StructuredData<?>> {
|
||||
types[id] = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataFiller add(final StructuredDataKey<?>... keys) {
|
||||
for (final StructuredDataKey<?> key : keys) {
|
||||
add(key);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,10 @@ public class ParticleType extends DynamicType<Particle> {
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Blue 0-1
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4
|
||||
};
|
||||
public static final DataReader<Particle> DUST1_21_2 = (buf, particle) -> {
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // RGB
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4
|
||||
};
|
||||
public static final DataReader<Particle> DUST_TRANSITION = (buf, particle) -> {
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Red 0-1
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green 0-1
|
||||
@@ -86,6 +90,11 @@ public class ParticleType extends DynamicType<Particle> {
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Blue
|
||||
};
|
||||
public static final DataReader<Particle> DUST_TRANSITION1_21_2 = (buf, particle) -> {
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // From RGB
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // To RGB
|
||||
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4
|
||||
};
|
||||
public static final DataReader<Particle> VIBRATION = (buf, particle) -> {
|
||||
particle.add(Types.BLOCK_POSITION1_14, Types.BLOCK_POSITION1_14.read(buf)); // From block pos
|
||||
|
||||
@@ -136,7 +145,15 @@ public class ParticleType extends DynamicType<Particle> {
|
||||
public static final DataReader<Particle> SHRIEK = (buf, particle) -> {
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Delay
|
||||
};
|
||||
public static final DataReader<Particle> COLOR = (buf, particle) -> particle.add(Types.INT, buf.readInt());
|
||||
public static final DataReader<Particle> COLOR = (buf, particle) -> {
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf));
|
||||
};
|
||||
public static final DataReader<Particle> TRAIL = (buf, particle) -> {
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target X
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target Y
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target Z
|
||||
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // Color
|
||||
};
|
||||
|
||||
public static DataReader<Particle> item(Type<Item> item) {
|
||||
return (buf, particle) -> particle.add(item, item.read(buf));
|
||||
|
||||
@@ -50,7 +50,7 @@ public final class Types1_21 {
|
||||
|
||||
public static final ParticleType PARTICLE = new ParticleType();
|
||||
public static final ArrayType<Particle> PARTICLES = new ArrayType<>(PARTICLE);
|
||||
public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(PARTICLE, PARTICLES);
|
||||
public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(ITEM, PARTICLE, PARTICLES);
|
||||
public static final Type<EntityData> ENTITY_DATA = new EntityDataType(ENTITY_DATA_TYPES);
|
||||
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.type.types.version;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType;
|
||||
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.type.types.item.ItemCostType1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.item.ItemType1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.item.StructuredDataType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
|
||||
import java.util.List;
|
||||
|
||||
// Most of these are only safe to use after protocol loading
|
||||
public final class Types1_21_2 {
|
||||
|
||||
public static final StructuredDataType STRUCTURED_DATA = new StructuredDataType();
|
||||
public static final Type<StructuredData<?>[]> STRUCTURED_DATA_ARRAY = new ArrayType<>(STRUCTURED_DATA);
|
||||
public static final ItemType1_20_5 ITEM = new ItemType1_20_5(STRUCTURED_DATA);
|
||||
public static final Type<Item> OPTIONAL_ITEM = ITEM.new OptionalItemType(); // Optional as in boolean prefixed, not via the amount
|
||||
public static final Type<Item[]> ITEM_ARRAY = new ArrayType<>(ITEM);
|
||||
public static final Type<Item> ITEM_COST = new ItemCostType1_20_5(STRUCTURED_DATA_ARRAY);
|
||||
public static final Type<Item> OPTIONAL_ITEM_COST = new ItemCostType1_20_5.OptionalItemCostType(ITEM_COST);
|
||||
|
||||
public static final ParticleType PARTICLE = new ParticleType();
|
||||
public static final ArrayType<Particle> PARTICLES = new ArrayType<>(PARTICLE);
|
||||
public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(ITEM, PARTICLE, PARTICLES);
|
||||
public static final Type<EntityData> ENTITY_DATA = new EntityDataType(ENTITY_DATA_TYPES);
|
||||
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
|
||||
}
|
||||
@@ -76,6 +76,7 @@ import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.Protocol1_20_3To1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9;
|
||||
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.Protocol1_9_1To1_9_3;
|
||||
import com.viaversion.viaversion.protocols.v1_9_3to1_10.Protocol1_9_3To1_10;
|
||||
@@ -192,6 +193,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_20_3);
|
||||
|
||||
registerProtocol(new Protocol1_20_5To1_21(), ProtocolVersion.v1_21, ProtocolVersion.v1_20_5);
|
||||
registerProtocol(new Protocol1_21To1_21_2(), ProtocolVersion.v1_21_2, ProtocolVersion.v1_21);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-1
@@ -23,11 +23,14 @@ import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
|
||||
public enum ClientboundLoginPackets implements BaseClientboundPacket {
|
||||
LOGIN_DISCONNECT, // 0x00
|
||||
HELLO, // 0x01
|
||||
GAME_PROFILE, // 0x02
|
||||
LOGIN_FINISHED, // 0x02
|
||||
LOGIN_COMPRESSION, // 0x03
|
||||
CUSTOM_QUERY, // 0x04
|
||||
COOKIE_REQUEST; // 0x05
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final ClientboundLoginPackets GAME_PROFILE = LOGIN_FINISHED;
|
||||
|
||||
@Override
|
||||
public final int getId() {
|
||||
return ordinal();
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ public class ClientboundBaseProtocol1_7 extends AbstractProtocol<BaseClientbound
|
||||
});
|
||||
|
||||
// Track player name/uuid and setup connection + track state
|
||||
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
|
||||
registerClientbound(ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
|
||||
final ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
|
||||
if (info.serverProtocolVersion().olderThan(ProtocolVersion.v1_16)) {
|
||||
|
||||
+13
-10
@@ -19,11 +19,11 @@ package com.viaversion.viaversion.protocols.template;
|
||||
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
|
||||
|
||||
@@ -57,21 +57,24 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
|
||||
|
||||
// Registers item id changes
|
||||
// Other places using item ids are: Entity data, tags, statistics, effect
|
||||
// registerOpenWindow(ClientboundPackets1_21.OPEN_WINDOW); - If a new container type was added
|
||||
registerCooldown(ClientboundPackets1_21.COOLDOWN);
|
||||
registerSetContent1_17_1(ClientboundPackets1_21.CONTAINER_SET_CONTENT);
|
||||
registerSetSlot1_17_1(ClientboundPackets1_21.CONTAINER_SET_SLOT);
|
||||
// registerOpenScreen(ClientboundPackets1_21.OPEN_SCREEN); If a new container type was added; also remove from the component rewriter registration
|
||||
//protocol.registerClientbound(ClientboundPackets1_21_2.SET_CURSOR_ITEM, this::passthroughClientboundItem);
|
||||
registerCooldown1_21_2(ClientboundPackets1_21.COOLDOWN);
|
||||
registerSetContent1_21_2(ClientboundPackets1_21.CONTAINER_SET_CONTENT);
|
||||
registerSetSlot1_21_2(ClientboundPackets1_21.CONTAINER_SET_SLOT);
|
||||
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS);
|
||||
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT);
|
||||
registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK);
|
||||
registerContainerClick1_21_2(ServerboundPackets1_20_5.CONTAINER_CLICK);
|
||||
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS);
|
||||
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT);
|
||||
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
|
||||
registerExplosion(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
|
||||
registerExplosion1_21_2(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
|
||||
|
||||
new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES);
|
||||
final RecipeDisplayRewriter<ClientboundPacket1_21> recipeRewriter = new RecipeDisplayRewriter<>(protocol);
|
||||
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21.UPDATE_RECIPES);
|
||||
//recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21.RECIPE_BOOK_ADD);
|
||||
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21.PLACE_GHOST_RECIPE);
|
||||
// OR do this if serialization of recipes changed and override the relevant method
|
||||
// Add new serializers to RecipeRewriter, or extend the last one for changes
|
||||
// new RecipeRewriter1_20_3<ClientboundPacket1_21>(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES);
|
||||
// Add new serializers to RecipeDisplayRewriter, or extend the last one for changes
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.template;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
|
||||
public final class ComponentRewriter1_99 extends ComponentRewriter<ClientboundPacket1_21> {
|
||||
|
||||
public ComponentRewriter1_99(final Protocol1_99To_98 protocol) {
|
||||
super(protocol, ReadType.NBT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
|
||||
super.handleShowItem(connection, itemTag, componentsTag);
|
||||
if (componentsTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove or update data from componentsTag
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SerializerVersion inputSerializerVersion() {
|
||||
return SerializerVersion.V1_20_5;
|
||||
}
|
||||
}
|
||||
+34
-10
@@ -24,6 +24,7 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
|
||||
@@ -50,6 +51,7 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
|
||||
private final EntityPacketRewriter1_99 entityRewriter = new EntityPacketRewriter1_99(this);
|
||||
private final BlockItemPacketRewriter1_99 itemRewriter = new BlockItemPacketRewriter1_99(this);
|
||||
private final TagRewriter<ClientboundPacket1_21> tagRewriter = new TagRewriter<>(this);
|
||||
private final ComponentRewriter1_99 componentRewriter = new ComponentRewriter1_99(this);
|
||||
|
||||
public Protocol1_99To_98() {
|
||||
// Passing the class types into the super constructor is needed for automatic packet type id remapping, but can otherwise be omitted
|
||||
@@ -63,6 +65,20 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
|
||||
tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS);
|
||||
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
|
||||
|
||||
// If needed for item or component changes
|
||||
componentRewriter.registerOpenScreen(ClientboundPackets1_21.OPEN_SCREEN);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_ACTION_BAR_TEXT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_TITLE_TEXT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_SUBTITLE_TEXT);
|
||||
componentRewriter.registerBossEvent(ClientboundPackets1_21.BOSS_EVENT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISCONNECT);
|
||||
componentRewriter.registerTabList(ClientboundPackets1_21.TAB_LIST);
|
||||
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21.PLAYER_COMBAT_KILL);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SYSTEM_CHAT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISGUISED_CHAT);
|
||||
componentRewriter.registerPlayerInfoUpdate1_21_2(ClientboundPackets1_21.PLAYER_INFO_UPDATE);
|
||||
componentRewriter.registerPing();
|
||||
|
||||
final SoundRewriter<ClientboundPacket1_21> soundRewriter = new SoundRewriter<>(this);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY);
|
||||
@@ -90,16 +106,19 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
|
||||
// EntityTypes1_20_5.initialize(this);
|
||||
|
||||
// Uncomment if a new particle was added = ids shifted; requires a new Types_ class copied from the last
|
||||
/*Types1_21.PARTICLE.filler(this)
|
||||
.reader("block", ParticleType.Readers.BLOCK)
|
||||
.reader("block_marker", ParticleType.Readers.BLOCK)
|
||||
.reader("dust", ParticleType.Readers.DUST)
|
||||
.reader("falling_dust", ParticleType.Readers.BLOCK)
|
||||
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
|
||||
.reader("item", ParticleType.Readers.ITEM1_20_2)
|
||||
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
|
||||
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
|
||||
.reader("shriek", ParticleType.Readers.SHRIEK);*/
|
||||
/*Types1_21_2.PARTICLE.filler(this)
|
||||
.reader("block", ParticleType.Readers.BLOCK)
|
||||
.reader("block_marker", ParticleType.Readers.BLOCK)
|
||||
.reader("dust", ParticleType.Readers.DUST1_21_2)
|
||||
.reader("dust_pillar", ParticleType.Readers.BLOCK)
|
||||
.reader("falling_dust", ParticleType.Readers.BLOCK)
|
||||
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION1_21_2)
|
||||
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
|
||||
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
|
||||
.reader("shriek", ParticleType.Readers.SHRIEK)
|
||||
.reader("entity_effect", ParticleType.Readers.COLOR)
|
||||
.reader("trail", ParticleType.Readers.TRAIL)
|
||||
.reader("item", ParticleType.Readers.item(itemRewriter.mappedItemType()));*/
|
||||
|
||||
super.onMappingDataLoaded(); // Calls load methods on rewriters. Last in case the rewriters access the above filled data
|
||||
}
|
||||
@@ -132,6 +151,11 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
|
||||
return tagRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentRewriter getComponentRewriter() {
|
||||
return componentRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PacketTypesProvider<ClientboundPacket1_21, ClientboundPacket1_21, ServerboundPacket1_20_5, ServerboundPacket1_20_5> createPacketTypesProvider() {
|
||||
return new SimplePacketTypesProvider<>(
|
||||
|
||||
+2
-2
@@ -353,7 +353,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
|
||||
registerClientbound(ClientboundPackets1_12_1.PLACE_GHOST_RECIPE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE);
|
||||
map(Types.UNSIGNED_BYTE);
|
||||
handler(wrapper -> wrapper.write(Types.STRING, "viaversion:legacy/" + wrapper.read(Types.VAR_INT)));
|
||||
}
|
||||
});
|
||||
@@ -594,7 +594,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
|
||||
registerServerbound(ServerboundPackets1_13.PLACE_RECIPE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Window id
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
|
||||
handler(wrapper -> {
|
||||
String s = wrapper.read(Types.STRING);
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
|
||||
new StatisticsRewriter<>(this).register(ClientboundPackets1_15.AWARD_STATS);
|
||||
|
||||
// Login Success
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
|
||||
// Transform string to a uuid
|
||||
UUID uuid = UUID.fromString(wrapper.read(Types.STRING));
|
||||
wrapper.write(Types.UUID, uuid);
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
|
||||
cancelServerbound(ServerboundPackets1_19.CHAT_PREVIEW);
|
||||
|
||||
// Login changes
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, new PacketHandlers() {
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UUID); // UUID
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
|
||||
set.set(action == 1 ? action + 1 : action + 2);
|
||||
}
|
||||
|
||||
wrapper.write(Types.PROFILE_ACTIONS_ENUM, set);
|
||||
wrapper.write(Types.PROFILE_ACTIONS_ENUM1_19_3, set);
|
||||
final int entries = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
wrapper.passthrough(Types.UUID); // UUID
|
||||
|
||||
+1
-2
@@ -50,8 +50,7 @@ public class RecipeRewriter1_19_3<C extends ClientboundPacketType> extends Recip
|
||||
wrapper.passthrough(Types.STRING); // Group
|
||||
wrapper.passthrough(Types.VAR_INT); // Crafting book category
|
||||
handleIngredients(wrapper);
|
||||
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
|
||||
wrapper.write(mappedItemType(), result);
|
||||
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -268,7 +268,7 @@ public final class Protocol1_20_2To1_20_3 extends AbstractProtocol<ClientboundPa
|
||||
}
|
||||
});
|
||||
registerClientbound(ClientboundPackets1_20_2.PLAYER_INFO_UPDATE, wrapper -> {
|
||||
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM);
|
||||
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM1_19_3);
|
||||
final int entries = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
wrapper.passthrough(Types.UUID);
|
||||
|
||||
+1
-1
@@ -64,4 +64,4 @@ public class RecipeRewriter1_20_3<C extends ClientboundPacketType> extends Recip
|
||||
protected Type<Item[]> mappedItemArrayType() {
|
||||
return protocol.getItemRewriter().mappedItemArrayType();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -211,7 +211,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
|
||||
|
||||
new CommandRewriter1_19_4<>(this).registerDeclareCommands1_19(ClientboundPackets1_20_3.COMMANDS);
|
||||
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
|
||||
wrapper.passthrough(Types.UUID); // UUID
|
||||
wrapper.passthrough(Types.STRING); // Name
|
||||
|
||||
@@ -272,10 +272,10 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
|
||||
.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_PROJECTILES1_20_5).add(StructuredDataKey.BUNDLE_CONTENTS1_20_5).add(StructuredDataKey.POTION_CONTENTS)
|
||||
.add(StructuredDataKey.CHARGED_PROJECTILES1_20_5).add(StructuredDataKey.BUNDLE_CONTENTS1_20_5).add(StructuredDataKey.POTION_CONTENTS1_20_5)
|
||||
.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.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_20_5)
|
||||
.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)
|
||||
|
||||
+2
-1
@@ -18,8 +18,9 @@
|
||||
package com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
|
||||
|
||||
public enum ServerboundConfigurationPackets1_20_5 implements ServerboundPacket1_20_5 {
|
||||
public enum ServerboundConfigurationPackets1_20_5 implements ServerboundPacket1_20_5, ServerboundPacket1_21_2 {
|
||||
|
||||
CLIENT_INFORMATION, // 0x00
|
||||
COOKIE_RESPONSE, // 0x01
|
||||
|
||||
+8
-8
@@ -60,9 +60,9 @@ 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.Fireworks;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
|
||||
@@ -536,7 +536,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
if (instrument != null) {
|
||||
final int id = Instruments1_20_3.keyToId(instrument);
|
||||
if (id != -1) {
|
||||
data.set(StructuredDataKey.INSTRUMENT, Holder.of(id));
|
||||
data.set(StructuredDataKey.INSTRUMENT1_20_5, Holder.of(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,7 +628,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (item.identifier() == 814 || item.identifier() == 819 || item.identifier() == 824 || item.identifier() == 829 || item.identifier() == 834) { // swords
|
||||
// Make sword "eatable" to enable clientside instant blocking on 1.8. Consume time is set really high, so the eating animation doesn't play
|
||||
item.dataContainer().set(StructuredDataKey.FOOD1_20_5, new FoodProperties(0, 0F, true, 3600, null, new FoodEffect[0]));
|
||||
item.dataContainer().set(StructuredDataKey.FOOD1_20_5, new FoodProperties1_20_5(0, 0F, true, 3600, null, new FoodEffect[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -727,7 +727,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
soundEvent = Holder.of(instrument.getInt("sound_event"));
|
||||
}
|
||||
|
||||
data.set(StructuredDataKey.INSTRUMENT, Holder.of(new Instrument(soundEvent, useDuration, range)));
|
||||
data.set(StructuredDataKey.INSTRUMENT1_20_5, Holder.of(new Instrument1_20_5(soundEvent, useDuration, range)));
|
||||
}
|
||||
|
||||
private void restoreFoodFromBackup(final CompoundTag food, final StructuredDataContainer data) {
|
||||
@@ -756,7 +756,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
effect.getFloat("probability")
|
||||
));
|
||||
}
|
||||
data.set(StructuredDataKey.FOOD1_20_5, new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, null, possibleEffects.toArray(new FoodEffect[0])));
|
||||
data.set(StructuredDataKey.FOOD1_20_5, new FoodProperties1_20_5(nutrition, saturation, canAlwaysEat, eatSeconds, null, possibleEffects.toArray(new FoodEffect[0])));
|
||||
}
|
||||
|
||||
private void restoreToolFromBackup(final CompoundTag tool, final StructuredDataContainer data) {
|
||||
@@ -965,7 +965,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
}
|
||||
|
||||
if (potionId != null || customPotionColorTag != null || potionEffects != null) {
|
||||
data.set(StructuredDataKey.POTION_CONTENTS, new PotionContents(
|
||||
data.set(StructuredDataKey.POTION_CONTENTS1_20_5, new PotionContents(
|
||||
potionId,
|
||||
customPotionColorTag != null ? customPotionColorTag.asInt() : null,
|
||||
potionEffects != null ? potionEffects : new PotionEffect[0]
|
||||
|
||||
+8
-8
@@ -55,9 +55,9 @@ 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.Fireworks;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
|
||||
@@ -144,7 +144,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
|
||||
registerEmpty(StructuredDataKey.MAP_POST_PROCESSING);
|
||||
register(StructuredDataKey.CHARGED_PROJECTILES1_20_5, this::convertChargedProjectiles);
|
||||
register(StructuredDataKey.BUNDLE_CONTENTS1_20_5, this::convertBundleContents);
|
||||
register(StructuredDataKey.POTION_CONTENTS, this::convertPotionContents);
|
||||
register(StructuredDataKey.POTION_CONTENTS1_20_5, this::convertPotionContents);
|
||||
register(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, this::convertSuspiciousStewEffects);
|
||||
register(StructuredDataKey.WRITABLE_BOOK_CONTENT, this::convertWritableBookContent);
|
||||
register(StructuredDataKey.WRITTEN_BOOK_CONTENT, this::convertWrittenBookContent);
|
||||
@@ -153,7 +153,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
|
||||
register(StructuredDataKey.ENTITY_DATA, this::convertEntityData);
|
||||
register(StructuredDataKey.BUCKET_ENTITY_DATA, this::convertBucketEntityData);
|
||||
register(StructuredDataKey.BLOCK_ENTITY_DATA, this::convertBlockEntityData);
|
||||
register(StructuredDataKey.INSTRUMENT, this::convertInstrument);
|
||||
register(StructuredDataKey.INSTRUMENT1_20_5, this::convertInstrument);
|
||||
register(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, this::convertOminousBottleAmplifier);
|
||||
register(StructuredDataKey.RECIPES, this::convertRecipes);
|
||||
register(StructuredDataKey.LODESTONE_TRACKER, this::convertLodestoneTracker);
|
||||
@@ -502,7 +502,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
|
||||
return convertUnit();
|
||||
}
|
||||
|
||||
protected CompoundTag convertFood(final FoodProperties value) {
|
||||
protected CompoundTag convertFood(final FoodProperties1_20_5 value) {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.put("nutrition", convertNonNegativeInt(value.nutrition()));
|
||||
tag.putFloat("saturation", value.saturationModifier());
|
||||
@@ -745,12 +745,12 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
|
||||
return convertNbtWithId(value);
|
||||
}
|
||||
|
||||
protected Tag convertInstrument(final Holder<Instrument> value) {
|
||||
protected Tag convertInstrument(final Holder<Instrument1_20_5> value) {
|
||||
if (value.hasId()) {
|
||||
return new StringTag(Instruments1_20_3.idToKey(value.id()));
|
||||
}
|
||||
|
||||
final Instrument instrument = value.value();
|
||||
final Instrument1_20_5 instrument = value.value();
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
final Holder<SoundEvent> sound = instrument.soundEvent();
|
||||
if (sound.hasId()) {
|
||||
|
||||
+5
-5
@@ -44,8 +44,8 @@ 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.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.StatePropertyMatcher;
|
||||
@@ -278,12 +278,12 @@ public final class StructuredDataConverter {
|
||||
}
|
||||
profileTag.put("Properties", propertiesTag);
|
||||
});
|
||||
register(StructuredDataKey.INSTRUMENT, (data, tag) -> {
|
||||
register(StructuredDataKey.INSTRUMENT1_20_5, (data, tag) -> {
|
||||
// Can't do anything with direct values
|
||||
if (!data.hasId()) {
|
||||
if (backupInconvertibleData) {
|
||||
final CompoundTag backupTag = new CompoundTag();
|
||||
final Instrument instrument = data.value();
|
||||
final Instrument1_20_5 instrument = data.value();
|
||||
if (instrument.soundEvent().hasId()) {
|
||||
backupTag.putInt("sound_event", instrument.soundEvent().id());
|
||||
} else {
|
||||
@@ -398,7 +398,7 @@ public final class StructuredDataConverter {
|
||||
|
||||
enchantmentsTag.add(invalidEnchantment);
|
||||
});
|
||||
register(StructuredDataKey.POTION_CONTENTS, (data, tag) -> {
|
||||
register(StructuredDataKey.POTION_CONTENTS1_20_5, (data, tag) -> {
|
||||
if (data.potion() != null) {
|
||||
final String potion = Potions1_20_5.idToKey(data.potion()); // Include 1.20.5 names
|
||||
if (potion != null) {
|
||||
|
||||
+2
-2
@@ -201,10 +201,10 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
.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_PROJECTILES1_21).add(StructuredDataKey.BUNDLE_CONTENTS1_21).add(StructuredDataKey.POTION_CONTENTS)
|
||||
.add(StructuredDataKey.CHARGED_PROJECTILES1_21).add(StructuredDataKey.BUNDLE_CONTENTS1_21).add(StructuredDataKey.POTION_CONTENTS1_20_5)
|
||||
.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.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_20_5)
|
||||
.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)
|
||||
|
||||
+2
-1
@@ -18,8 +18,9 @@
|
||||
package com.viaversion.viaversion.protocols.v1_20_5to1_21.packet;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
|
||||
|
||||
public enum ClientboundConfigurationPackets1_21 implements ClientboundPacket1_21 {
|
||||
public enum ClientboundConfigurationPackets1_21 implements ClientboundPacket1_21, ClientboundPacket1_21_2 {
|
||||
|
||||
COOKIE_REQUEST, // 0x00
|
||||
CUSTOM_PAYLOAD, // 0x01
|
||||
|
||||
-5
@@ -60,9 +60,4 @@ public final class ComponentRewriter1_21 extends ComponentRewriter<ClientboundPa
|
||||
protected SerializerVersion inputSerializerVersion() {
|
||||
return SerializerVersion.V1_20_5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SerializerVersion outputSerializerVersion() {
|
||||
return SerializerVersion.V1_20_5;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -70,7 +70,7 @@ public final class EntityPacketRewriter1_21 extends EntityRewriter<ClientboundPa
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundConfigurationPackets1_20_5.FINISH_CONFIGURATION, wrapper -> {
|
||||
protocol.registerFinishConfiguration(ClientboundConfigurationPackets1_20_5.FINISH_CONFIGURATION, wrapper -> {
|
||||
// Add new registries
|
||||
final PacketWrapper paintingRegistryPacket = wrapper.create(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA);
|
||||
paintingRegistryPacket.write(Types.STRING, "minecraft:painting_variant");
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ public final class Protocol1_20To1_20_2 extends AbstractProtocol<ClientboundPack
|
||||
// We need to wait for it send the login ack before actually sending the play login,
|
||||
// hence packets are added to a queue. With the data from the login packet, we sent what is needed
|
||||
// during the configuration phase before finally transitioning to the play state with the client as well.
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
|
||||
wrapper.user().get(ConfigurationState.class).setBridgePhase(BridgePhase.PROFILE_SENT);
|
||||
wrapper.user().getProtocolInfo().setServerState(State.PLAY);
|
||||
});
|
||||
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.data.MappingDataBase;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.ComponentRewriter1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.EntityPacketRewriter1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.BundleStateTracker;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.PlayerPositionStorage;
|
||||
import com.viaversion.viaversion.rewriter.AttributeRewriter;
|
||||
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import java.util.BitSet;
|
||||
|
||||
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
|
||||
public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPacket1_21, ClientboundPacket1_21_2, ServerboundPacket1_20_5, ServerboundPacket1_21_2> {
|
||||
|
||||
public static final MappingData MAPPINGS = new MappingDataBase("1.21", "1.21.2");
|
||||
private final EntityPacketRewriter1_21_2 entityRewriter = new EntityPacketRewriter1_21_2(this);
|
||||
private final BlockItemPacketRewriter1_21_2 itemRewriter = new BlockItemPacketRewriter1_21_2(this);
|
||||
private final TagRewriter<ClientboundPacket1_21> tagRewriter = new TagRewriter<>(this);
|
||||
private final ComponentRewriter1_21_2 componentRewriter = new ComponentRewriter1_21_2(this);
|
||||
|
||||
public Protocol1_21To1_21_2() {
|
||||
super(ClientboundPacket1_21.class, ClientboundPacket1_21_2.class, ServerboundPacket1_20_5.class, ServerboundPacket1_21_2.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
super.registerPackets();
|
||||
|
||||
tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS);
|
||||
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
|
||||
|
||||
componentRewriter.registerOpenScreen(ClientboundPackets1_21.OPEN_SCREEN);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_ACTION_BAR_TEXT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_TITLE_TEXT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SET_SUBTITLE_TEXT);
|
||||
componentRewriter.registerBossEvent(ClientboundPackets1_21.BOSS_EVENT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISCONNECT);
|
||||
componentRewriter.registerTabList(ClientboundPackets1_21.TAB_LIST);
|
||||
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21.PLAYER_COMBAT_KILL);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.SYSTEM_CHAT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_21.DISGUISED_CHAT);
|
||||
componentRewriter.registerPing();
|
||||
|
||||
final SoundRewriter<ClientboundPacket1_21> soundRewriter = new SoundRewriter<>(this);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY);
|
||||
|
||||
new StatisticsRewriter<>(this).register(ClientboundPackets1_21.AWARD_STATS);
|
||||
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21.UPDATE_ATTRIBUTES);
|
||||
|
||||
registerServerbound(ServerboundPackets1_21_2.CLIENT_INFORMATION, this::clientInformation);
|
||||
registerServerbound(ServerboundConfigurationPackets1_20_5.CLIENT_INFORMATION, this::clientInformation);
|
||||
|
||||
cancelServerbound(ServerboundPackets1_21_2.BUNDLE_ITEM_SELECTED);
|
||||
cancelServerbound(ServerboundPackets1_21_2.CLIENT_TICK_END);
|
||||
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
|
||||
wrapper.passthrough(Types.UUID); // UUID
|
||||
wrapper.passthrough(Types.STRING); // Name
|
||||
|
||||
final int properties = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < properties; i++) {
|
||||
wrapper.passthrough(Types.STRING); // Name
|
||||
wrapper.passthrough(Types.STRING); // Value
|
||||
wrapper.passthrough(Types.OPTIONAL_STRING); // Signature
|
||||
}
|
||||
|
||||
wrapper.read(Types.BOOLEAN); // Strict error handling
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_21.SET_TIME, wrapper -> {
|
||||
wrapper.passthrough(Types.LONG); // Game time
|
||||
long dayTime = wrapper.read(Types.LONG);
|
||||
boolean doDaylightCycle = true;
|
||||
if (dayTime < 0) {
|
||||
dayTime = -dayTime;
|
||||
doDaylightCycle = false;
|
||||
}
|
||||
wrapper.write(Types.LONG, dayTime);
|
||||
wrapper.write(Types.BOOLEAN, doDaylightCycle);
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_21.PLAYER_INFO_UPDATE, wrapper -> {
|
||||
final BitSet actions = wrapper.passthroughAndMap(Types.PROFILE_ACTIONS_ENUM1_19_3, Types.PROFILE_ACTIONS_ENUM1_21_2);
|
||||
if (!actions.get(5)) { // Update display name
|
||||
return;
|
||||
}
|
||||
|
||||
final int entries = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
wrapper.passthrough(Types.UUID);
|
||||
if (actions.get(0)) {
|
||||
wrapper.passthrough(Types.STRING); // Player Name
|
||||
|
||||
final int properties = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int j = 0; j < properties; j++) {
|
||||
wrapper.passthrough(Types.STRING); // Name
|
||||
wrapper.passthrough(Types.STRING); // Value
|
||||
wrapper.passthrough(Types.OPTIONAL_STRING); // Signature
|
||||
}
|
||||
}
|
||||
if (actions.get(1) && wrapper.passthrough(Types.BOOLEAN)) {
|
||||
wrapper.passthrough(Types.UUID); // Session UUID
|
||||
wrapper.passthrough(Types.PROFILE_KEY);
|
||||
}
|
||||
if (actions.get(2)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Gamemode
|
||||
}
|
||||
if (actions.get(3)) {
|
||||
wrapper.passthrough(Types.BOOLEAN); // Listed
|
||||
}
|
||||
if (actions.get(4)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Latency
|
||||
}
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
}
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_21.BUNDLE_DELIMITER, wrapper -> wrapper.user().get(BundleStateTracker.class).toggleBundling());
|
||||
registerServerbound(ServerboundPackets1_21_2.PONG, wrapper -> {
|
||||
final int id = wrapper.passthrough(Types.INT); // id
|
||||
if (wrapper.user().get(PlayerPositionStorage.class).checkPong(id)) {
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clientInformation(final PacketWrapper wrapper) {
|
||||
wrapper.passthrough(Types.STRING); // Locale
|
||||
wrapper.passthrough(Types.BYTE); // View distance
|
||||
wrapper.passthrough(Types.VAR_INT); // Chat visibility
|
||||
wrapper.passthrough(Types.BOOLEAN); // Chat colors
|
||||
wrapper.passthrough(Types.UNSIGNED_BYTE); // Skin parts
|
||||
wrapper.passthrough(Types.VAR_INT); // Main hand
|
||||
wrapper.passthrough(Types.BOOLEAN); // Text filtering enabled
|
||||
wrapper.passthrough(Types.BOOLEAN); // Allow listing
|
||||
wrapper.read(Types.VAR_INT); // Particle status
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMappingDataLoaded() {
|
||||
EntityTypes1_21_2.initialize(this);
|
||||
Types1_21_2.PARTICLE.filler(this)
|
||||
.reader("block", ParticleType.Readers.BLOCK)
|
||||
.reader("block_marker", ParticleType.Readers.BLOCK)
|
||||
.reader("dust", ParticleType.Readers.DUST1_21_2)
|
||||
.reader("dust_pillar", ParticleType.Readers.BLOCK)
|
||||
.reader("falling_dust", ParticleType.Readers.BLOCK)
|
||||
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION1_21_2)
|
||||
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
|
||||
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
|
||||
.reader("shriek", ParticleType.Readers.SHRIEK)
|
||||
.reader("entity_effect", ParticleType.Readers.COLOR)
|
||||
.reader("trail", ParticleType.Readers.TRAIL)
|
||||
.reader("item", ParticleType.Readers.item(Types1_21_2.ITEM));
|
||||
Types1_21_2.STRUCTURED_DATA.filler(this).add(StructuredDataKey.CUSTOM_DATA, StructuredDataKey.MAX_STACK_SIZE, StructuredDataKey.MAX_DAMAGE,
|
||||
StructuredDataKey.UNBREAKABLE, StructuredDataKey.RARITY, StructuredDataKey.HIDE_TOOLTIP, StructuredDataKey.DAMAGE_RESISTANT,
|
||||
StructuredDataKey.CUSTOM_NAME, StructuredDataKey.LORE, StructuredDataKey.ENCHANTMENTS, StructuredDataKey.CAN_PLACE_ON,
|
||||
StructuredDataKey.CAN_BREAK, StructuredDataKey.CUSTOM_MODEL_DATA, StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP,
|
||||
StructuredDataKey.REPAIR_COST, StructuredDataKey.CREATIVE_SLOT_LOCK, StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE,
|
||||
StructuredDataKey.INTANGIBLE_PROJECTILE, StructuredDataKey.STORED_ENCHANTMENTS, StructuredDataKey.DYED_COLOR,
|
||||
StructuredDataKey.MAP_COLOR, StructuredDataKey.MAP_ID, StructuredDataKey.MAP_DECORATIONS, StructuredDataKey.MAP_POST_PROCESSING,
|
||||
StructuredDataKey.POTION_CONTENTS1_21_2, StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, StructuredDataKey.WRITABLE_BOOK_CONTENT,
|
||||
StructuredDataKey.WRITTEN_BOOK_CONTENT, StructuredDataKey.TRIM, StructuredDataKey.DEBUG_STICK_STATE, StructuredDataKey.ENTITY_DATA,
|
||||
StructuredDataKey.BUCKET_ENTITY_DATA, StructuredDataKey.BLOCK_ENTITY_DATA, StructuredDataKey.INSTRUMENT1_21_2,
|
||||
StructuredDataKey.RECIPES, StructuredDataKey.LODESTONE_TRACKER, StructuredDataKey.FIREWORK_EXPLOSION, StructuredDataKey.FIREWORKS,
|
||||
StructuredDataKey.PROFILE, StructuredDataKey.NOTE_BLOCK_SOUND, StructuredDataKey.BANNER_PATTERNS, StructuredDataKey.BASE_COLOR,
|
||||
StructuredDataKey.POT_DECORATIONS, StructuredDataKey.BLOCK_STATE, StructuredDataKey.BEES, StructuredDataKey.LOCK,
|
||||
StructuredDataKey.CONTAINER_LOOT, StructuredDataKey.TOOL, StructuredDataKey.ITEM_NAME, StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER,
|
||||
StructuredDataKey.FOOD1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE, StructuredDataKey.ATTRIBUTE_MODIFIERS1_21,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_2,
|
||||
StructuredDataKey.USE_COOLDOWN, StructuredDataKey.DAMAGE, StructuredDataKey.EQUIPPABLE, StructuredDataKey.ITEM_MODEL,
|
||||
StructuredDataKey.GLIDER, StructuredDataKey.TOOLTIP_STYLE, StructuredDataKey.DEATH_PROTECTION,
|
||||
// Volatile thanks to containing item
|
||||
StructuredDataKey.CHARGED_PROJECTILES1_21_2, StructuredDataKey.BUNDLE_CONTENTS1_21_2, StructuredDataKey.CONTAINER1_21_2, StructuredDataKey.USE_REMAINDER);
|
||||
super.onMappingDataLoaded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final UserConnection connection) {
|
||||
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_2.PLAYER));
|
||||
connection.put(new BundleStateTracker());
|
||||
connection.put(new PlayerPositionStorage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingData getMappingData() {
|
||||
return MAPPINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPacketRewriter1_21_2 getEntityRewriter() {
|
||||
return entityRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockItemPacketRewriter1_21_2 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagRewriter<ClientboundPacket1_21> getTagRewriter() {
|
||||
return tagRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentRewriter getComponentRewriter() {
|
||||
return componentRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PacketTypesProvider<ClientboundPacket1_21, ClientboundPacket1_21_2, ServerboundPacket1_20_5, ServerboundPacket1_21_2> createPacketTypesProvider() {
|
||||
return new SimplePacketTypesProvider<>(
|
||||
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class),
|
||||
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class),
|
||||
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class),
|
||||
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class)
|
||||
);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.packet;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
|
||||
public interface ClientboundPacket1_21_2 extends ClientboundPacketType {
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.packet;
|
||||
|
||||
public enum ClientboundPackets1_21_2 implements ClientboundPacket1_21_2 {
|
||||
|
||||
BUNDLE_DELIMITER, // 0x00
|
||||
ADD_ENTITY, // 0x01
|
||||
ADD_EXPERIENCE_ORB, // 0x02
|
||||
ANIMATE, // 0x03
|
||||
AWARD_STATS, // 0x04
|
||||
BLOCK_CHANGED_ACK, // 0x05
|
||||
BLOCK_DESTRUCTION, // 0x06
|
||||
BLOCK_ENTITY_DATA, // 0x07
|
||||
BLOCK_EVENT, // 0x08
|
||||
BLOCK_UPDATE, // 0x09
|
||||
BOSS_EVENT, // 0x0A
|
||||
CHANGE_DIFFICULTY, // 0x0B
|
||||
CHUNK_BATCH_FINISHED, // 0x0C
|
||||
CHUNK_BATCH_START, // 0x0D
|
||||
CHUNKS_BIOMES, // 0x0E
|
||||
CLEAR_TITLES, // 0x0F
|
||||
COMMAND_SUGGESTIONS, // 0x10
|
||||
COMMANDS, // 0x11
|
||||
CONTAINER_CLOSE, // 0x12
|
||||
CONTAINER_SET_CONTENT, // 0x13
|
||||
CONTAINER_SET_DATA, // 0x14
|
||||
CONTAINER_SET_SLOT, // 0x15
|
||||
COOKIE_REQUEST, // 0x16
|
||||
COOLDOWN, // 0x17
|
||||
CUSTOM_CHAT_COMPLETIONS, // 0x18
|
||||
CUSTOM_PAYLOAD, // 0x19
|
||||
DAMAGE_EVENT, // 0x1A
|
||||
DEBUG_SAMPLE, // 0x1B
|
||||
DELETE_CHAT, // 0x1C
|
||||
DISCONNECT, // 0x1D
|
||||
DISGUISED_CHAT, // 0x1E
|
||||
ENTITY_EVENT, // 0x1F
|
||||
ENTITY_POSITION_SYNC, // 0x20
|
||||
EXPLODE, // 0x21
|
||||
FORGET_LEVEL_CHUNK, // 0x22
|
||||
GAME_EVENT, // 0x23
|
||||
HORSE_SCREEN_OPEN, // 0x24
|
||||
HURT_ANIMATION, // 0x25
|
||||
INITIALIZE_BORDER, // 0x26
|
||||
KEEP_ALIVE, // 0x27
|
||||
LEVEL_CHUNK_WITH_LIGHT, // 0x28
|
||||
LEVEL_EVENT, // 0x29
|
||||
LEVEL_PARTICLES, // 0x2A
|
||||
LIGHT_UPDATE, // 0x2B
|
||||
LOGIN, // 0x2C
|
||||
MAP_ITEM_DATA, // 0x2D
|
||||
MERCHANT_OFFERS, // 0x2E
|
||||
MOVE_ENTITY_POS, // 0x2F
|
||||
MOVE_ENTITY_POS_ROT, // 0x30
|
||||
MOVE_MINECART_ALONG_TRACK, // 0x31
|
||||
MOVE_ENTITY_ROT, // 0x32
|
||||
MOVE_VEHICLE, // 0x33
|
||||
OPEN_BOOK, // 0x34
|
||||
OPEN_SCREEN, // 0x35
|
||||
OPEN_SIGN_EDITOR, // 0x36
|
||||
PING, // 0x37
|
||||
PONG_RESPONSE, // 0x38
|
||||
PLACE_GHOST_RECIPE, // 0x39
|
||||
PLAYER_ABILITIES, // 0x3A
|
||||
PLAYER_CHAT, // 0x3B
|
||||
PLAYER_COMBAT_END, // 0x3C
|
||||
PLAYER_COMBAT_ENTER, // 0x3D
|
||||
PLAYER_COMBAT_KILL, // 0x3E
|
||||
PLAYER_INFO_REMOVE, // 0x3F
|
||||
PLAYER_INFO_UPDATE, // 0x40
|
||||
PLAYER_LOOK_AT, // 0x41
|
||||
PLAYER_POSITION, // 0x42
|
||||
PLAYER_ROTATION, // 0x43
|
||||
RECIPE_BOOK_ADD, // 0x44
|
||||
RECIPE_BOOK_REMOVE, // 0x45
|
||||
RECIPE_BOOK_SETTINGS, // 0x46
|
||||
REMOVE_ENTITIES, // 0x47
|
||||
REMOVE_MOB_EFFECT, // 0x48
|
||||
RESET_SCORE, // 0x49
|
||||
RESOURCE_PACK_POP, // 0x4A
|
||||
RESOURCE_PACK_PUSH, // 0x4B
|
||||
RESPAWN, // 0x4C
|
||||
ROTATE_HEAD, // 0x4D
|
||||
SECTION_BLOCKS_UPDATE, // 0x4E
|
||||
SELECT_ADVANCEMENTS_TAB, // 0x4F
|
||||
SERVER_DATA, // 0x50
|
||||
SET_ACTION_BAR_TEXT, // 0x51
|
||||
SET_BORDER_CENTER, // 0x52
|
||||
SET_BORDER_LERP_SIZE, // 0x53
|
||||
SET_BORDER_SIZE, // 0x54
|
||||
SET_BORDER_WARNING_DELAY, // 0x55
|
||||
SET_BORDER_WARNING_DISTANCE, // 0x56
|
||||
SET_CAMERA, // 0x57
|
||||
SET_CHUNK_CACHE_CENTER, // 0x58
|
||||
SET_CHUNK_CACHE_RADIUS, // 0x59
|
||||
SET_CURSOR_ITEM, // 0x5A
|
||||
SET_DEFAULT_SPAWN_POSITION, // 0x5B
|
||||
SET_DISPLAY_OBJECTIVE, // 0x5C
|
||||
SET_ENTITY_DATA, // 0x5D
|
||||
SET_ENTITY_LINK, // 0x5E
|
||||
SET_ENTITY_MOTION, // 0x5F
|
||||
SET_EQUIPMENT, // 0x60
|
||||
SET_EXPERIENCE, // 0x61
|
||||
SET_HEALTH, // 0x62
|
||||
SET_HELD_SLOT, // 0x63
|
||||
SET_OBJECTIVE, // 0x64
|
||||
SET_PASSENGERS, // 0x65
|
||||
SET_PLAYER_INVENTORY, // 0x66
|
||||
SET_PLAYER_TEAM, // 0x67
|
||||
SET_SCORE, // 0x68
|
||||
SET_SIMULATION_DISTANCE, // 0x69
|
||||
SET_SUBTITLE_TEXT, // 0x6A
|
||||
SET_TIME, // 0x6B
|
||||
SET_TITLE_TEXT, // 0x6C
|
||||
SET_TITLES_ANIMATION, // 0x6D
|
||||
SOUND_ENTITY, // 0x6E
|
||||
SOUND, // 0x6F
|
||||
START_CONFIGURATION, // 0x70
|
||||
STOP_SOUND, // 0x71
|
||||
STORE_COOKIE, // 0x72
|
||||
SYSTEM_CHAT, // 0x73
|
||||
TAB_LIST, // 0x74
|
||||
TAG_QUERY, // 0x75
|
||||
TAKE_ITEM_ENTITY, // 0x76
|
||||
TELEPORT_ENTITY, // 0x77
|
||||
TICKING_STATE, // 0x78
|
||||
TICKING_STEP, // 0x79
|
||||
TRANSFER, // 0x7A
|
||||
UPDATE_ADVANCEMENTS, // 0x7B
|
||||
UPDATE_ATTRIBUTES, // 0x7C
|
||||
UPDATE_MOB_EFFECT, // 0x7D
|
||||
UPDATE_RECIPES, // 0x7E
|
||||
UPDATE_TAGS, // 0x7F
|
||||
PROJECTILE_POWER, // 0x80
|
||||
CUSTOM_REPORT_DETAILS, // 0x81
|
||||
SERVER_LINKS; // 0x82
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.packet;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
|
||||
public interface ServerboundPacket1_21_2 extends ServerboundPacketType {
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.packet;
|
||||
|
||||
public enum ServerboundPackets1_21_2 implements ServerboundPacket1_21_2 {
|
||||
|
||||
ACCEPT_TELEPORTATION, // 0x00
|
||||
BLOCK_ENTITY_TAG_QUERY, // 0x01
|
||||
BUNDLE_ITEM_SELECTED, // 0x02
|
||||
CHANGE_DIFFICULTY, // 0x03
|
||||
CHAT_ACK, // 0x04
|
||||
CHAT_COMMAND, // 0x05
|
||||
CHAT_COMMAND_SIGNED, // 0x06
|
||||
CHAT, // 0x07
|
||||
CHAT_SESSION_UPDATE, // 0x08
|
||||
CHUNK_BATCH_RECEIVED, // 0x09
|
||||
CLIENT_COMMAND, // 0x0A
|
||||
CLIENT_TICK_END, // 0x0B
|
||||
CLIENT_INFORMATION, // 0x0C
|
||||
COMMAND_SUGGESTION, // 0x0D
|
||||
CONFIGURATION_ACKNOWLEDGED, // 0x0E
|
||||
CONTAINER_BUTTON_CLICK, // 0x0F
|
||||
CONTAINER_CLICK, // 0x10
|
||||
CONTAINER_CLOSE, // 0x11
|
||||
CONTAINER_SLOT_STATE_CHANGED, // 0x12
|
||||
COOKIE_RESPONSE, // 0x13
|
||||
CUSTOM_PAYLOAD, // 0x14
|
||||
DEBUG_SAMPLE_SUBSCRIPTION, // 0x15
|
||||
EDIT_BOOK, // 0x16
|
||||
ENTITY_TAG_QUERY, // 0x17
|
||||
INTERACT, // 0x18
|
||||
JIGSAW_GENERATE, // 0x19
|
||||
KEEP_ALIVE, // 0x1A
|
||||
LOCK_DIFFICULTY, // 0x1B
|
||||
MOVE_PLAYER_POS, // 0x1C
|
||||
MOVE_PLAYER_POS_ROT, // 0x1D
|
||||
MOVE_PLAYER_ROT, // 0x1E
|
||||
MOVE_PLAYER_STATUS_ONLY, // 0x1F
|
||||
MOVE_VEHICLE, // 0x20
|
||||
PADDLE_BOAT, // 0x21
|
||||
PICK_ITEM, // 0x22
|
||||
PING_REQUEST, // 0x23
|
||||
PLACE_RECIPE, // 0x24
|
||||
PLAYER_ABILITIES, // 0x25
|
||||
PLAYER_ACTION, // 0x26
|
||||
PLAYER_COMMAND, // 0x27
|
||||
PLAYER_INPUT, // 0x28
|
||||
PONG, // 0x29
|
||||
RECIPE_BOOK_CHANGE_SETTINGS, // 0x2A
|
||||
RECIPE_BOOK_SEEN_RECIPE, // 0x2B
|
||||
RENAME_ITEM, // 0x2C
|
||||
RESOURCE_PACK, // 0x2D
|
||||
SEEN_ADVANCEMENTS, // 0x2E
|
||||
SELECT_TRADE, // 0x2F
|
||||
SET_BEACON, // 0x30
|
||||
SET_CARRIED_ITEM, // 0x31
|
||||
SET_COMMAND_BLOCK, // 0x32
|
||||
SET_COMMAND_MINECART, // 0x33
|
||||
SET_CREATIVE_MODE_SLOT, // 0x34
|
||||
SET_JIGSAW_BLOCK, // 0x35
|
||||
SET_STRUCTURE_BLOCK, // 0x36
|
||||
SIGN_UPDATE, // 0x37
|
||||
SWING, // 0x38
|
||||
TELEPORT_TO_ENTITY, // 0x39
|
||||
USE_ITEM_ON, // 0x3A
|
||||
USE_ITEM; // 0x3B
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
+500
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import com.viaversion.viaversion.util.Unit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<ClientboundPacket1_21, ServerboundPacket1_21_2, Protocol1_21To1_21_2> {
|
||||
|
||||
private static final int RECIPE_NOTIFICATION_FLAG = 1 << 0;
|
||||
private static final int RECIPE_HIGHLIGHT_FLAG = 1 << 1;
|
||||
private static final int RECIPE_INIT = 0;
|
||||
private static final int RECIPE_ADD = 1;
|
||||
private static final int RECIPE_REMOVE = 2;
|
||||
|
||||
public BlockItemPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) {
|
||||
super(protocol,
|
||||
Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_21_2.ITEM, Types1_21_2.ITEM_ARRAY,
|
||||
Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_21_2.ITEM_COST, Types1_21_2.OPTIONAL_ITEM_COST,
|
||||
Types1_21.PARTICLE, Types1_21_2.PARTICLE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
final BlockRewriter<ClientboundPacket1_21> blockRewriter = BlockRewriter.for1_20_2(protocol);
|
||||
blockRewriter.registerBlockEvent(ClientboundPackets1_21.BLOCK_EVENT);
|
||||
blockRewriter.registerBlockUpdate(ClientboundPackets1_21.BLOCK_UPDATE);
|
||||
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE);
|
||||
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21.LEVEL_EVENT, 2001);
|
||||
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new);
|
||||
blockRewriter.registerBlockEntityData(ClientboundPackets1_21.BLOCK_ENTITY_DATA);
|
||||
|
||||
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS);
|
||||
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT);
|
||||
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS);
|
||||
registerSetCreativeModeSlot(ServerboundPackets1_21_2.SET_CREATIVE_MODE_SLOT);
|
||||
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.COOLDOWN, wrapper -> {
|
||||
final MappingData mappingData = protocol.getMappingData();
|
||||
final int itemId = wrapper.read(Types.VAR_INT);
|
||||
final int mappedItemId = mappingData.getNewItemId(itemId);
|
||||
wrapper.write(Types.STRING, mappingData.getFullItemMappings().mappedIdentifier(mappedItemId));
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_CONTENT, wrapper -> {
|
||||
updateContainerId(wrapper);
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
final Item[] items = wrapper.read(itemArrayType());
|
||||
wrapper.write(mappedItemArrayType(), items);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
passthroughClientboundItem(wrapper);
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_SLOT, wrapper -> {
|
||||
updateContainerId(wrapper);
|
||||
final int containerId = wrapper.get(Types.VAR_INT, 0);
|
||||
if (containerId == -1) { // cursor item
|
||||
wrapper.setPacketType(ClientboundPackets1_21_2.SET_CURSOR_ITEM);
|
||||
wrapper.resetReader();
|
||||
wrapper.read(Types.VAR_INT); // container id
|
||||
wrapper.read(Types.VAR_INT); // State id
|
||||
wrapper.read(Types.SHORT); // Slot id
|
||||
} else if (containerId == -2) { // cursor item
|
||||
wrapper.setPacketType(ClientboundPackets1_21_2.SET_PLAYER_INVENTORY);
|
||||
wrapper.resetReader();
|
||||
wrapper.read(Types.VAR_INT); // container id
|
||||
wrapper.read(Types.VAR_INT); // State id
|
||||
wrapper.write(Types.VAR_INT, (int) wrapper.read(Types.SHORT)); // Slot id
|
||||
} else {
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
wrapper.passthrough(Types.SHORT); // Slot id
|
||||
}
|
||||
passthroughClientboundItem(wrapper);
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_CLOSE, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_DATA, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.HORSE_SCREEN_OPEN, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.SET_CARRIED_ITEM, ClientboundPackets1_21_2.SET_HELD_SLOT);
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLOSE, this::updateContainerIdServerbound);
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLICK, wrapper -> {
|
||||
updateContainerIdServerbound(wrapper);
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
wrapper.passthrough(Types.BYTE); // Button
|
||||
wrapper.passthrough(Types.VAR_INT); // Mode
|
||||
final int length = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
passthroughServerboundItem(wrapper);
|
||||
}
|
||||
passthroughServerboundItem(wrapper);
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_21.PLACE_GHOST_RECIPE, wrapper -> {
|
||||
this.updateContainerId(wrapper);
|
||||
|
||||
final String recipeKey = wrapper.read(Types.STRING);
|
||||
final RecipeRewriter1_21_2.Recipe recipe = wrapper.user().get(RecipeRewriter1_21_2.class).recipe(recipeKey);
|
||||
if (recipe == null) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.write(Types.VAR_INT, recipe.recipeDisplayId());
|
||||
recipe.writeRecipeDisplay(wrapper);
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.PLACE_RECIPE, wrapper -> {
|
||||
this.updateContainerIdServerbound(wrapper);
|
||||
convertServerboundRecipeDisplayId(wrapper);
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.RECIPE_BOOK_SEEN_RECIPE, this::convertServerboundRecipeDisplayId);
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.USE_ITEM_ON, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Hand
|
||||
wrapper.passthrough(Types.BLOCK_POSITION1_14); // Block position
|
||||
wrapper.passthrough(Types.VAR_INT); // Direction
|
||||
wrapper.passthrough(Types.FLOAT); // X
|
||||
wrapper.passthrough(Types.FLOAT); // Y
|
||||
wrapper.passthrough(Types.FLOAT); // Z
|
||||
wrapper.passthrough(Types.BOOLEAN); // Inside
|
||||
wrapper.read(Types.BOOLEAN); // World border hit
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.EXPLODE, wrapper -> {
|
||||
final int centerX = (int) Math.floor(wrapper.passthrough(Types.DOUBLE)); // Center X
|
||||
final int centerY = (int) Math.floor(wrapper.passthrough(Types.DOUBLE)); // Center Y
|
||||
final int centerZ = (int) Math.floor(wrapper.passthrough(Types.DOUBLE)); // Center Z
|
||||
|
||||
final float power = wrapper.read(Types.FLOAT); // Power
|
||||
final List<BlockPosition> affectedBlocks = new ArrayList<>();
|
||||
final int blocks = wrapper.read(Types.VAR_INT);
|
||||
for (int i = 0; i < blocks; i++) {
|
||||
final int x = centerX + wrapper.read(Types.BYTE); // Relative X
|
||||
final int y = centerY + wrapper.read(Types.BYTE); // Relative Y
|
||||
final int z = centerZ + wrapper.read(Types.BYTE); // Relative Z
|
||||
affectedBlocks.add(new BlockPosition(x, y, z));
|
||||
}
|
||||
|
||||
final float knockbackX = wrapper.read(Types.FLOAT);
|
||||
final float knockbackY = wrapper.read(Types.FLOAT);
|
||||
final float knockbackZ = wrapper.read(Types.FLOAT);
|
||||
if (knockbackX != 0 || knockbackY != 0 || knockbackZ != 0) {
|
||||
wrapper.write(Types.BOOLEAN, true);
|
||||
wrapper.write(Types.DOUBLE, (double) knockbackX);
|
||||
wrapper.write(Types.DOUBLE, (double) knockbackY);
|
||||
wrapper.write(Types.DOUBLE, (double) knockbackZ);
|
||||
} else {
|
||||
wrapper.write(Types.BOOLEAN, false);
|
||||
}
|
||||
|
||||
final int blockInteractionMode = wrapper.read(Types.VAR_INT);
|
||||
if (blockInteractionMode == 1 || blockInteractionMode == 2) {
|
||||
for (final BlockPosition affectedBlock : affectedBlocks) {
|
||||
final PacketWrapper blockUpdate = PacketWrapper.create(ClientboundPackets1_21_2.BLOCK_UPDATE, wrapper.user());
|
||||
blockUpdate.write(Types.BLOCK_POSITION1_14, affectedBlock); // position
|
||||
blockUpdate.write(Types.VAR_INT, 0); // block state
|
||||
blockUpdate.send(Protocol1_21To1_21_2.class);
|
||||
}
|
||||
}
|
||||
|
||||
final Particle smallExplosionParticle = wrapper.read(Types1_21.PARTICLE);
|
||||
final Particle largeExplosionParticle = wrapper.read(Types1_21.PARTICLE);
|
||||
if (power >= 2.0F && blockInteractionMode != 0) {
|
||||
rewriteParticle(wrapper.user(), largeExplosionParticle);
|
||||
wrapper.write(Types1_21_2.PARTICLE, largeExplosionParticle);
|
||||
} else {
|
||||
rewriteParticle(wrapper.user(), smallExplosionParticle);
|
||||
wrapper.write(Types1_21_2.PARTICLE, smallExplosionParticle);
|
||||
}
|
||||
|
||||
new SoundRewriter<>(protocol).soundHolderHandler().handle(wrapper);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.UPDATE_RECIPES, wrapper -> {
|
||||
final FullMappings recipeSerializerMappings = protocol.getMappingData().getRecipeSerializerMappings();
|
||||
final RecipeRewriter1_21_2 rewriter = new RecipeRewriter1_21_2(protocol);
|
||||
wrapper.user().put(rewriter);
|
||||
|
||||
final int size = wrapper.read(Types.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
final String recipeIdentifier = wrapper.read(Types.STRING);
|
||||
final int serializerTypeId = wrapper.read(Types.VAR_INT);
|
||||
final String serializerTypeIdentifier = recipeSerializerMappings.identifier(serializerTypeId);
|
||||
rewriter.setCurrentRecipeIdentifier(recipeIdentifier);
|
||||
rewriter.handleRecipeType(wrapper, serializerTypeIdentifier);
|
||||
}
|
||||
rewriter.finalizeRecipes();
|
||||
|
||||
// These are used for client predictions, such smithing or furnace inputs.
|
||||
// Other recipes will be written in RECIPE/RECIPE_BOOK_ADD
|
||||
rewriter.writeUpdateRecipeInputs(wrapper);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.RECIPE, ClientboundPackets1_21_2.RECIPE_BOOK_ADD, wrapper -> {
|
||||
final int state = wrapper.passthrough(Types.VAR_INT);
|
||||
|
||||
// Pairs of open + filtering for: Crafting, furnace, blast furnace, smoker
|
||||
final PacketWrapper settingsPacket = wrapper.create(ClientboundPackets1_21_2.RECIPE_BOOK_SETTINGS);
|
||||
for (int i = 0; i < 4 * 2; i++) {
|
||||
settingsPacket.write(Types.BOOLEAN, wrapper.read(Types.BOOLEAN));
|
||||
}
|
||||
settingsPacket.send(Protocol1_21To1_21_2.class);
|
||||
|
||||
// Read recipe keys from the packet
|
||||
final String[] recipes = wrapper.read(Types.STRING_ARRAY);
|
||||
Set<String> toHighlight = Set.of();
|
||||
if (state == RECIPE_INIT) {
|
||||
final String[] highlightRecipes = wrapper.read(Types.STRING_ARRAY);
|
||||
toHighlight = Set.of(highlightRecipes);
|
||||
}
|
||||
|
||||
final RecipeRewriter1_21_2 recipeRewriter = wrapper.user().get(RecipeRewriter1_21_2.class);
|
||||
if (recipeRewriter == null) {
|
||||
protocol.getLogger().severe("Recipes not yet sent for recipe add packet");
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.clearPacket();
|
||||
|
||||
if (state == RECIPE_REMOVE) {
|
||||
wrapper.setPacketType(ClientboundPackets1_21_2.RECIPE_BOOK_REMOVE);
|
||||
|
||||
final int[] ids = new int[recipes.length];
|
||||
for (int i = 0; i < recipes.length; i++) {
|
||||
final String recipeKey = recipes[i];
|
||||
final RecipeRewriter1_21_2.Recipe recipe = recipeRewriter.recipe(recipeKey);
|
||||
if (recipe == null) {
|
||||
protocol.getLogger().severe("Recipe not found for key " + recipeKey);
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
ids[i] = recipe.index();
|
||||
}
|
||||
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, ids);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add or init recipes
|
||||
int size = recipes.length;
|
||||
wrapper.write(Types.VAR_INT, size);
|
||||
for (final String recipeKey : recipes) {
|
||||
final RecipeRewriter1_21_2.Recipe recipe = recipeRewriter.recipe(recipeKey);
|
||||
if (recipe == null) {
|
||||
// Stonecutting and smithing recipes, or bad data
|
||||
size--;
|
||||
continue;
|
||||
}
|
||||
|
||||
wrapper.write(Types.VAR_INT, recipe.index()); // Display ID, just an arbitrary index as determined by the server
|
||||
|
||||
wrapper.write(Types.VAR_INT, recipe.recipeDisplayId());
|
||||
recipe.writeRecipeDisplay(wrapper);
|
||||
|
||||
wrapper.write(Types.OPTIONAL_VAR_INT, recipe.group() != -1 ? recipe.group() : null);
|
||||
wrapper.write(Types.VAR_INT, recipe.category());
|
||||
|
||||
final Item[][] ingredients = recipe.ingredients();
|
||||
if (ingredients != null) {
|
||||
wrapper.write(Types.BOOLEAN, true);
|
||||
|
||||
// Why are some of these empty? Who knows, but they can't be
|
||||
final List<HolderSet> filteredIngredients = Arrays.stream(ingredients).filter(ingredient -> ingredient.length > 0).map(recipeRewriter::toHolderSet).toList();
|
||||
wrapper.write(Types.VAR_INT, filteredIngredients.size());
|
||||
for (final HolderSet ingredient : filteredIngredients) {
|
||||
wrapper.write(Types.HOLDER_SET, ingredient);
|
||||
}
|
||||
} else {
|
||||
wrapper.write(Types.BOOLEAN, false);
|
||||
}
|
||||
|
||||
byte flags = 0;
|
||||
if (state == RECIPE_ADD) {
|
||||
if (recipe.showNotification()) {
|
||||
flags |= RECIPE_NOTIFICATION_FLAG;
|
||||
}
|
||||
flags |= RECIPE_HIGHLIGHT_FLAG;
|
||||
} else if (toHighlight.contains(recipeKey)) {
|
||||
flags |= RECIPE_HIGHLIGHT_FLAG;
|
||||
}
|
||||
wrapper.write(Types.BYTE, flags);
|
||||
}
|
||||
|
||||
// Update final size
|
||||
wrapper.set(Types.VAR_INT, 0, size);
|
||||
|
||||
wrapper.write(Types.BOOLEAN, state == RECIPE_INIT); // Replace
|
||||
});
|
||||
}
|
||||
|
||||
private void convertServerboundRecipeDisplayId(final PacketWrapper wrapper) {
|
||||
final int recipeDisplayId = wrapper.read(Types.VAR_INT);
|
||||
final RecipeRewriter1_21_2.Recipe recipe = wrapper.user().get(RecipeRewriter1_21_2.class).recipe(recipeDisplayId);
|
||||
if (recipe == null) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.write(Types.STRING, recipe.identifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rewriteParticle(final UserConnection connection, final Particle particle) {
|
||||
super.rewriteParticle(connection, particle);
|
||||
|
||||
final String identifier = protocol.getMappingData().getParticleMappings().mappedIdentifier(particle.id());
|
||||
if (identifier.equals("minecraft:dust_color_transition")) {
|
||||
floatsToARGB(particle, 0);
|
||||
floatsToARGB(particle, 1);
|
||||
} else if (identifier.equals("minecraft:dust")) {
|
||||
floatsToARGB(particle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void floatsToARGB(final Particle particle, final int fromIndex) {
|
||||
final Particle.ParticleData<Float> r = particle.removeArgument(fromIndex);
|
||||
final Particle.ParticleData<Float> g = particle.removeArgument(fromIndex);
|
||||
final Particle.ParticleData<Float> b = particle.removeArgument(fromIndex);
|
||||
final int rgb = 255 << 24 | (int) (r.getValue() * 255) << 16 | (int) (g.getValue() * 255) << 8 | (int) (b.getValue() * 255);
|
||||
particle.add(fromIndex, Types.INT, rgb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item handleItemToClient(final UserConnection connection, final Item item) {
|
||||
super.handleItemToClient(connection, item);
|
||||
updateItemData(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item handleItemToServer(final UserConnection connection, final Item item) {
|
||||
super.handleItemToServer(connection, item);
|
||||
downgradeItemData(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
private void updateContainerId(final PacketWrapper wrapper) {
|
||||
// Container id handling was always a bit whack with most reading them as unsigned bytes, some as bytes, some already as var ints.
|
||||
// In VV they're generally read as unsigned bytes to not have to look the type up every time, but we need to make sure they're
|
||||
// properly converted to ints when used
|
||||
final short containerId = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
final int intId = (byte) containerId;
|
||||
wrapper.write(Types.VAR_INT, intId);
|
||||
}
|
||||
|
||||
private void updateContainerIdServerbound(final PacketWrapper wrapper) {
|
||||
final int containerId = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.UNSIGNED_BYTE, (short) containerId);
|
||||
}
|
||||
|
||||
public static void updateItemData(final Item item) {
|
||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||
dataContainer.replace(StructuredDataKey.INSTRUMENT1_20_5, StructuredDataKey.INSTRUMENT1_21_2, instrument -> {
|
||||
if (instrument.hasId()) {
|
||||
return Holder.of(instrument.id());
|
||||
}
|
||||
final Instrument1_20_5 value = instrument.value();
|
||||
return Holder.of(new Instrument1_21_2(value.soundEvent(), value.useDuration() / 20F, value.range(), new StringTag("")));
|
||||
});
|
||||
dataContainer.replace(StructuredDataKey.FOOD1_21, StructuredDataKey.FOOD1_21_2, food -> {
|
||||
final Holder<SoundEvent> sound = Holder.of(new SoundEvent("minecraft:entity.generic.eat", null));
|
||||
final Consumable1_21_2.ConsumeEffect<?>[] consumeEffects = new Consumable1_21_2.ConsumeEffect[food.possibleEffects().length];
|
||||
for (int i = 0; i < consumeEffects.length; i++) {
|
||||
final FoodProperties1_20_5.FoodEffect effect = food.possibleEffects()[i];
|
||||
final Consumable1_21_2.ApplyStatusEffects applyStatusEffects = new Consumable1_21_2.ApplyStatusEffects(new PotionEffect[]{effect.effect()}, effect.probability());
|
||||
consumeEffects[i] = new Consumable1_21_2.ConsumeEffect<>(0 /* add status effect */, Consumable1_21_2.ApplyStatusEffects.TYPE, applyStatusEffects);
|
||||
}
|
||||
dataContainer.set(StructuredDataKey.CONSUMABLE1_21_2, new Consumable1_21_2(food.eatSeconds(), 1 /* eat */, sound, true, consumeEffects));
|
||||
if (food.usingConvertsTo() != null) {
|
||||
dataContainer.set(StructuredDataKey.USE_REMAINDER, food.usingConvertsTo());
|
||||
}
|
||||
return new FoodProperties1_21_2(food.nutrition(), food.saturationModifier(), food.canAlwaysEat());
|
||||
});
|
||||
dataContainer.replaceKey(StructuredDataKey.CONTAINER1_21, StructuredDataKey.CONTAINER1_21_2);
|
||||
dataContainer.replaceKey(StructuredDataKey.CHARGED_PROJECTILES1_21, StructuredDataKey.CHARGED_PROJECTILES1_21_2);
|
||||
dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21, StructuredDataKey.BUNDLE_CONTENTS1_21_2);
|
||||
dataContainer.replaceKey(StructuredDataKey.POTION_CONTENTS1_20_5, StructuredDataKey.POTION_CONTENTS1_21_2);
|
||||
dataContainer.replace(StructuredDataKey.FIRE_RESISTANT, StructuredDataKey.DAMAGE_RESISTANT, fireResistant -> new DamageResistant("minecraft:is_fire"));
|
||||
dataContainer.replace(StructuredDataKey.LOCK, lock -> {
|
||||
final CompoundTag predicateTag = new CompoundTag();
|
||||
final CompoundTag itemComponentsTag = new CompoundTag();
|
||||
predicateTag.put("components", itemComponentsTag);
|
||||
itemComponentsTag.put("custom_name", lock);
|
||||
return predicateTag;
|
||||
});
|
||||
}
|
||||
|
||||
public static void downgradeItemData(final Item item) {
|
||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||
dataContainer.replace(StructuredDataKey.LOCK, StructuredDataKey.LOCK, lock -> {
|
||||
final CompoundTag predicateTag = (CompoundTag) lock;
|
||||
final CompoundTag itemComponentsTag = predicateTag.getCompoundTag("components");
|
||||
if (itemComponentsTag != null) {
|
||||
return TagUtil.getNamespacedStringTag(itemComponentsTag, "custom_name");
|
||||
}
|
||||
return null;
|
||||
});
|
||||
dataContainer.replace(StructuredDataKey.INSTRUMENT1_21_2, StructuredDataKey.INSTRUMENT1_20_5, instrument -> {
|
||||
if (instrument.hasId()) {
|
||||
return Holder.of(instrument.id());
|
||||
}
|
||||
final Instrument1_21_2 value = instrument.value();
|
||||
return Holder.of(new Instrument1_20_5(value.soundEvent(), (int) (value.useDuration() * 20), value.range()));
|
||||
});
|
||||
dataContainer.replace(StructuredDataKey.FOOD1_21_2, StructuredDataKey.FOOD1_21, food -> {
|
||||
final Consumable1_21_2 consumableData = dataContainer.get(StructuredDataKey.CONSUMABLE1_21_2);
|
||||
final Item useRemainderData = dataContainer.get(StructuredDataKey.USE_REMAINDER);
|
||||
final float eatSeconds = consumableData != null ? consumableData.consumeSeconds() : 1.6F;
|
||||
final List<FoodProperties1_20_5.FoodEffect> foodEffects = new ArrayList<>();
|
||||
if (consumableData != null) {
|
||||
for (Consumable1_21_2.ConsumeEffect<?> consumeEffect : consumableData.consumeEffects()) {
|
||||
if (consumeEffect.value() instanceof Consumable1_21_2.ApplyStatusEffects applyStatusEffects) {
|
||||
for (PotionEffect effect : applyStatusEffects.effects()) {
|
||||
foodEffects.add(new FoodProperties1_20_5.FoodEffect(effect, applyStatusEffects.probability()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FoodProperties1_20_5(food.nutrition(), food.saturationModifier(), food.canAlwaysEat(), eatSeconds, useRemainderData, foodEffects.toArray(new FoodProperties1_20_5.FoodEffect[0]));
|
||||
});
|
||||
dataContainer.replaceKey(StructuredDataKey.CONTAINER1_21_2, StructuredDataKey.CONTAINER1_21);
|
||||
dataContainer.replaceKey(StructuredDataKey.CHARGED_PROJECTILES1_21_2, StructuredDataKey.CHARGED_PROJECTILES1_21);
|
||||
dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21_2, StructuredDataKey.BUNDLE_CONTENTS1_21);
|
||||
dataContainer.replaceKey(StructuredDataKey.POTION_CONTENTS1_21_2, StructuredDataKey.POTION_CONTENTS1_20_5);
|
||||
dataContainer.replace(StructuredDataKey.DAMAGE_RESISTANT, StructuredDataKey.FIRE_RESISTANT, damageResistant -> {
|
||||
if (Key.stripMinecraftNamespace(damageResistant.typesTagKey()).equals("is_fire")) {
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
dataContainer.remove(StructuredDataKey.REPAIRABLE);
|
||||
dataContainer.remove(StructuredDataKey.ENCHANTABLE);
|
||||
dataContainer.remove(StructuredDataKey.CONSUMABLE1_21_2);
|
||||
dataContainer.remove(StructuredDataKey.USE_REMAINDER);
|
||||
dataContainer.remove(StructuredDataKey.USE_COOLDOWN);
|
||||
dataContainer.remove(StructuredDataKey.ITEM_MODEL);
|
||||
dataContainer.remove(StructuredDataKey.EQUIPPABLE);
|
||||
dataContainer.remove(StructuredDataKey.GLIDER);
|
||||
dataContainer.remove(StructuredDataKey.TOOLTIP_STYLE);
|
||||
dataContainer.remove(StructuredDataKey.DEATH_PROTECTION);
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import java.util.Iterator;
|
||||
|
||||
public final class ComponentRewriter1_21_2 extends ComponentRewriter<ClientboundPacket1_21> {
|
||||
|
||||
public ComponentRewriter1_21_2(final Protocol1_21To1_21_2 protocol) {
|
||||
super(protocol, ReadType.NBT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
|
||||
super.handleShowItem(connection, itemTag, componentsTag);
|
||||
if (componentsTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
convertAttributes(componentsTag, protocol.getMappingData().getAttributeMappings());
|
||||
|
||||
final CompoundTag instrument = TagUtil.getNamespacedCompoundTag(componentsTag, "instrument");
|
||||
if (instrument != null) {
|
||||
instrument.putString("description", "");
|
||||
}
|
||||
|
||||
final CompoundTag food = TagUtil.getNamespacedCompoundTag(componentsTag, "food");
|
||||
if (food != null) {
|
||||
final CompoundTag convertsTo = food.getCompoundTag("using_converts_to");
|
||||
if (convertsTo != null) {
|
||||
food.remove("using_converts_to");
|
||||
componentsTag.put("minecraft:use_remainder", convertsTo);
|
||||
}
|
||||
food.remove("eat_seconds");
|
||||
food.remove("effects");
|
||||
}
|
||||
|
||||
TagUtil.removeNamespaced(componentsTag, "fire_resistant");
|
||||
TagUtil.removeNamespaced(componentsTag, "lock");
|
||||
}
|
||||
|
||||
public static void convertAttributes(final CompoundTag componentsTag, final FullMappings mappings) {
|
||||
final CompoundTag attributeModifiers = TagUtil.getNamespacedCompoundTag(componentsTag, "attribute_modifiers");
|
||||
if (attributeModifiers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> modifiers = attributeModifiers.getListTag("modifiers", CompoundTag.class);
|
||||
final Iterator<CompoundTag> iterator = modifiers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final CompoundTag modifier = iterator.next();
|
||||
final StringTag attribute = modifier.getStringTag("type");
|
||||
final String mappedAttribute = mappings.mappedIdentifier(attribute.getValue());
|
||||
if (mappedAttribute != null) {
|
||||
attribute.setValue(mappedAttribute);
|
||||
} else {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SerializerVersion inputSerializerVersion() {
|
||||
return SerializerVersion.V1_20_5;
|
||||
}
|
||||
|
||||
// Only cosmetic changes in the 1.21.2 serializer
|
||||
}
|
||||
+353
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.BundleStateTracker;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ClientVehicleStorage;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.PlayerPositionStorage;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public final class EntityPacketRewriter1_21_2 extends EntityRewriter<ClientboundPacket1_21, Protocol1_21To1_21_2> {
|
||||
|
||||
private static final String[] GOAT_HORN_INSTRUMENTS = {
|
||||
"ponder_goat_horn",
|
||||
"sing_goat_horn",
|
||||
"seek_goat_horn",
|
||||
"feel_goat_horn",
|
||||
"admire_goat_horn",
|
||||
"call_goat_horn",
|
||||
"yearn_goat_horn",
|
||||
"dream_goat_horn"
|
||||
};
|
||||
private static final float IMPULSE = 0.98F;
|
||||
|
||||
public EntityPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
registerTrackerWithData1_19(ClientboundPackets1_21.ADD_ENTITY, EntityTypes1_21_2.FALLING_BLOCK);
|
||||
registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA, Types1_21.ENTITY_DATA_LIST, Types1_21_2.ENTITY_DATA_LIST);
|
||||
registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES);
|
||||
|
||||
protocol.registerFinishConfiguration(ClientboundConfigurationPackets1_21.FINISH_CONFIGURATION, wrapper -> {
|
||||
final PacketWrapper instrumentsPacket = wrapper.create(ClientboundConfigurationPackets1_21.REGISTRY_DATA);
|
||||
instrumentsPacket.write(Types.STRING, "minecraft:instrument");
|
||||
final RegistryEntry[] entries = new RegistryEntry[GOAT_HORN_INSTRUMENTS.length];
|
||||
for (int i = 0; i < GOAT_HORN_INSTRUMENTS.length; i++) {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.putString("sound_event", "item.goat_horn.sound." + i);
|
||||
tag.putFloat("use_duration", 7);
|
||||
tag.putInt("range", 256);
|
||||
tag.putString("description", "");
|
||||
entries[i] = new RegistryEntry(GOAT_HORN_INSTRUMENTS[i], tag);
|
||||
}
|
||||
instrumentsPacket.write(Types.REGISTRY_ENTRY_ARRAY, entries);
|
||||
instrumentsPacket.send(Protocol1_21To1_21_2.class);
|
||||
});
|
||||
|
||||
final RegistryDataRewriter registryDataRewriter = registryDataRewriter();
|
||||
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Entity id
|
||||
map(Types.BOOLEAN); // Hardcore
|
||||
map(Types.STRING_ARRAY); // World List
|
||||
map(Types.VAR_INT); // Max players
|
||||
map(Types.VAR_INT); // View distance
|
||||
map(Types.VAR_INT); // Simulation distance
|
||||
map(Types.BOOLEAN); // Reduced debug info
|
||||
map(Types.BOOLEAN); // Show death screen
|
||||
map(Types.BOOLEAN); // Limited crafting
|
||||
map(Types.VAR_INT); // Dimension id
|
||||
map(Types.STRING); // World
|
||||
map(Types.LONG); // Seed
|
||||
map(Types.BYTE); // Gamemode
|
||||
map(Types.BYTE); // Previous gamemode
|
||||
map(Types.BOOLEAN); // Debug
|
||||
map(Types.BOOLEAN); // Flat
|
||||
map(Types.OPTIONAL_GLOBAL_POSITION); // Last death location
|
||||
map(Types.VAR_INT); // Portal cooldown
|
||||
handler(worldDataTrackerHandlerByKey1_20_5(3));
|
||||
handler(playerTrackerHandler());
|
||||
create(Types.VAR_INT, 64); // Sea level, was hardcoded at 64 before
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.RESPAWN, wrapper -> {
|
||||
final int dimensionId = wrapper.passthrough(Types.VAR_INT);
|
||||
final String world = wrapper.passthrough(Types.STRING);
|
||||
wrapper.passthrough(Types.LONG); // Seed
|
||||
wrapper.passthrough(Types.BYTE); // Gamemode
|
||||
wrapper.passthrough(Types.BYTE); // Previous gamemode
|
||||
wrapper.passthrough(Types.BOOLEAN); // Debug
|
||||
wrapper.passthrough(Types.BOOLEAN); // Flat
|
||||
wrapper.passthrough(Types.OPTIONAL_GLOBAL_POSITION); // Last death location
|
||||
wrapper.passthrough(Types.VAR_INT); // Portal cooldown
|
||||
|
||||
wrapper.write(Types.VAR_INT, 64); // Sea level
|
||||
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
|
||||
|
||||
wrapper.user().remove(ClientVehicleStorage.class);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.PLAYER_POSITION, wrapper -> {
|
||||
wrapper.write(Types.VAR_INT, 0); // Teleport id, set at the end
|
||||
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement X
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement Y
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement Z
|
||||
|
||||
wrapper.passthrough(Types.FLOAT); // Y rot
|
||||
wrapper.passthrough(Types.FLOAT); // X rot
|
||||
|
||||
int relativeArguments = wrapper.read(Types.BYTE) & 0b00011111;
|
||||
if ((relativeArguments & (1 << 0)) != 0) { // relative X
|
||||
relativeArguments |= 1 << 5; // relative delta movement X
|
||||
}
|
||||
if ((relativeArguments & (1 << 1)) != 0) { // relative Y
|
||||
relativeArguments |= 1 << 6; // relative delta movement Y
|
||||
}
|
||||
if ((relativeArguments & (1 << 2)) != 0) { // relative Z
|
||||
relativeArguments |= 1 << 7; // relative delta movement Z
|
||||
}
|
||||
wrapper.write(Types.INT, relativeArguments);
|
||||
|
||||
final int teleportId = wrapper.read(Types.VAR_INT);
|
||||
wrapper.set(Types.VAR_INT, 0, teleportId);
|
||||
|
||||
// Accept teleportation and player position were swapped.
|
||||
// Send a ping first to then capture and send the player position the accept teleportation
|
||||
final boolean isBundling = wrapper.user().get(BundleStateTracker.class).isBundling();
|
||||
if (!isBundling) {
|
||||
final PacketWrapper bundleStart = wrapper.create(ClientboundPackets1_21_2.BUNDLE_DELIMITER);
|
||||
bundleStart.send(Protocol1_21To1_21_2.class);
|
||||
}
|
||||
|
||||
final int pingId = ThreadLocalRandom.current().nextInt();
|
||||
wrapper.user().get(PlayerPositionStorage.class).addPendingPong(pingId);
|
||||
final PacketWrapper ping = wrapper.create(ClientboundPackets1_21_2.PING);
|
||||
ping.write(Types.INT, pingId); // id
|
||||
ping.send(Protocol1_21To1_21_2.class);
|
||||
wrapper.send(Protocol1_21To1_21_2.class);
|
||||
wrapper.cancel();
|
||||
|
||||
if (!isBundling) {
|
||||
final PacketWrapper bundleEnd = wrapper.create(ClientboundPackets1_21_2.BUNDLE_DELIMITER);
|
||||
bundleEnd.send(Protocol1_21To1_21_2.class);
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.SET_PASSENGERS, wrapper -> {
|
||||
final int vehicleId = wrapper.passthrough(Types.VAR_INT);
|
||||
final int[] passengerIds = wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE);
|
||||
final ClientVehicleStorage storage = wrapper.user().get(ClientVehicleStorage.class);
|
||||
if (storage != null && vehicleId == storage.vehicleId()) {
|
||||
wrapper.user().remove(ClientVehicleStorage.class);
|
||||
}
|
||||
|
||||
final int clientEntityId = tracker(wrapper.user()).clientEntityId();
|
||||
for (final int passenger : passengerIds) {
|
||||
if (passenger == clientEntityId) {
|
||||
wrapper.user().put(new ClientVehicleStorage(vehicleId));
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
protocol.appendClientbound(ClientboundPackets1_21.REMOVE_ENTITIES, wrapper -> {
|
||||
final ClientVehicleStorage vehicleStorage = wrapper.user().get(ClientVehicleStorage.class);
|
||||
if (vehicleStorage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int[] entityIds = wrapper.get(Types.VAR_INT_ARRAY_PRIMITIVE, 0);
|
||||
for (final int entityId : entityIds) {
|
||||
if (entityId == vehicleStorage.vehicleId()) {
|
||||
wrapper.user().remove(ClientVehicleStorage.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.PLAYER_INPUT, wrapper -> {
|
||||
// Previously only used while in a vehicle, now always sent
|
||||
// Filter them appropriately
|
||||
if (!wrapper.user().has(ClientVehicleStorage.class)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
final byte flags = wrapper.read(Types.BYTE);
|
||||
final boolean left = (flags & 1 << 2) != 0;
|
||||
final boolean right = (flags & 1 << 3) != 0;
|
||||
wrapper.write(Types.FLOAT, left ? IMPULSE : (right ? -IMPULSE : 0F));
|
||||
|
||||
final boolean forward = (flags & 1 << 0) != 0;
|
||||
final boolean backward = (flags & 1 << 1) != 0;
|
||||
wrapper.write(Types.FLOAT, forward ? IMPULSE : (backward ? -IMPULSE : 0F));
|
||||
|
||||
byte updatedFlags = 0;
|
||||
if ((flags & 1 << 4) != 0) {
|
||||
updatedFlags |= 1;
|
||||
}
|
||||
if ((flags & 1 << 5) != 0) {
|
||||
updatedFlags |= 2;
|
||||
}
|
||||
wrapper.write(Types.BYTE, updatedFlags);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.TELEPORT_ENTITY, ClientboundPackets1_21_2.ENTITY_POSITION_SYNC, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Entity ID
|
||||
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
|
||||
// Unused...
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement X
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement Y
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement Z
|
||||
|
||||
// Unpack y and x rot
|
||||
final byte yaw = wrapper.read(Types.BYTE);
|
||||
final byte pitch = wrapper.read(Types.BYTE);
|
||||
wrapper.write(Types.FLOAT, yaw * 360F / 256F);
|
||||
wrapper.write(Types.FLOAT, pitch * 360F / 256F);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS, wrapper -> {
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
readOnGround(wrapper);
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS_ROT, wrapper -> {
|
||||
final double x = wrapper.passthrough(Types.DOUBLE); // X
|
||||
final double y = wrapper.passthrough(Types.DOUBLE); // Y
|
||||
final double z = wrapper.passthrough(Types.DOUBLE); // Z
|
||||
final float yaw = wrapper.passthrough(Types.FLOAT); // Yaw
|
||||
final float pitch = wrapper.passthrough(Types.FLOAT); // Pitch
|
||||
readOnGround(wrapper);
|
||||
|
||||
final PlayerPositionStorage playerPositionStorage = wrapper.user().get(PlayerPositionStorage.class);
|
||||
if (playerPositionStorage.checkCaptureNextPlayerPositionPacket()) {
|
||||
// Capture this packet and send it after accept teleportation
|
||||
final boolean onGround = wrapper.get(Types.BOOLEAN, 0);
|
||||
playerPositionStorage.setPlayerPosition(new PlayerPositionStorage.PlayerPosition(x, y, z, yaw, pitch, onGround));
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_ROT, wrapper -> {
|
||||
wrapper.passthrough(Types.FLOAT); // Yaw
|
||||
wrapper.passthrough(Types.FLOAT); // Pitch
|
||||
readOnGround(wrapper);
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, this::readOnGround);
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.ACCEPT_TELEPORTATION, wrapper -> {
|
||||
final PlayerPositionStorage playerPositionStorage = wrapper.user().get(PlayerPositionStorage.class);
|
||||
if (playerPositionStorage.checkHasPlayerPosition()) {
|
||||
// Send move player after accept teleportation
|
||||
wrapper.sendToServer(Protocol1_21To1_21_2.class);
|
||||
wrapper.cancel();
|
||||
playerPositionStorage.sendMovePlayerPosRot(wrapper.user());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private RegistryDataRewriter registryDataRewriter() {
|
||||
final CompoundTag enderpearlData = new CompoundTag();
|
||||
enderpearlData.putString("scaling", "when_caused_by_living_non_player");
|
||||
enderpearlData.putString("message_id", "fall");
|
||||
enderpearlData.putFloat("exhaustion", 0.0F);
|
||||
|
||||
final CompoundTag maceSmashData = new CompoundTag();
|
||||
maceSmashData.putString("scaling", "when_caused_by_living_non_player");
|
||||
maceSmashData.putString("message_id", "mace_smash");
|
||||
maceSmashData.putFloat("exhaustion", 0.1F);
|
||||
|
||||
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
|
||||
registryDataRewriter.addEntries(
|
||||
"damage_type",
|
||||
new RegistryEntry("minecraft:ender_pearl", enderpearlData),
|
||||
new RegistryEntry("minecraft:mace_smash", maceSmashData)
|
||||
);
|
||||
registryDataRewriter.addEnchantmentEffectRewriter("damage_item", tag -> tag.putString("type", "change_item_damage"));
|
||||
return registryDataRewriter;
|
||||
}
|
||||
|
||||
private void readOnGround(final PacketWrapper wrapper) {
|
||||
final short data = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
wrapper.write(Types.BOOLEAN, (data & 1) != 0); // On ground, ignoring horizontal collision data
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
filter().mapDataType(Types1_21_2.ENTITY_DATA_TYPES::byId);
|
||||
|
||||
registerEntityDataTypeHandler(
|
||||
Types1_21_2.ENTITY_DATA_TYPES.itemType,
|
||||
Types1_21_2.ENTITY_DATA_TYPES.blockStateType,
|
||||
Types1_21_2.ENTITY_DATA_TYPES.optionalBlockStateType,
|
||||
Types1_21_2.ENTITY_DATA_TYPES.particleType,
|
||||
Types1_21_2.ENTITY_DATA_TYPES.particlesType,
|
||||
Types1_21_2.ENTITY_DATA_TYPES.componentType,
|
||||
Types1_21_2.ENTITY_DATA_TYPES.optionalComponentType
|
||||
);
|
||||
registerBlockStateHandler(EntityTypes1_21_2.ABSTRACT_MINECART, 11);
|
||||
|
||||
filter().type(EntityTypes1_21_2.ABSTRACT_BOAT).removeIndex(11); // Goodbye boat type
|
||||
|
||||
filter().type(EntityTypes1_21_2.SALMON).addIndex(17); // Data type
|
||||
filter().type(EntityTypes1_21_2.AGEABLE_WATER_CREATURE).addIndex(16); // Baby
|
||||
|
||||
filter().type(EntityTypes1_21_2.ABSTRACT_ARROW).addIndex(10); // In ground
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType typeFromId(final int type) {
|
||||
return EntityTypes1_21_2.getTypeFromId(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMappingDataLoaded() {
|
||||
mapTypes();
|
||||
}
|
||||
}
|
||||
+346
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
// Use directly as a connection storage. Slightly weird, but easiest and closed off from other packages
|
||||
final class RecipeRewriter1_21_2 extends RecipeRewriter1_20_3<ClientboundPacket1_21> implements StorableObject {
|
||||
|
||||
private static final int[] EMPTY_ARRAY = new int[0];
|
||||
private final List<StoneCutterRecipe> stoneCutterRecipes = new ArrayList<>();
|
||||
private final Object2IntMap<String> recipeGroups = new Object2IntOpenHashMap<>();
|
||||
private final Map<String, Recipe> recipesByKey = new HashMap<>();
|
||||
private final Map<String, IntSet> recipeInputs = new Object2ObjectArrayMap<>();
|
||||
private final List<Recipe> recipes = new ArrayList<>();
|
||||
private String currentRecipeIdentifier;
|
||||
|
||||
public void setCurrentRecipeIdentifier(final String recipeIdentifier) {
|
||||
this.currentRecipeIdentifier = Key.stripMinecraftNamespace(recipeIdentifier);
|
||||
}
|
||||
|
||||
RecipeRewriter1_21_2(final Protocol<ClientboundPacket1_21, ?, ?, ?> protocol) {
|
||||
super(protocol);
|
||||
recipeGroups.defaultReturnValue(-1);
|
||||
|
||||
recipeHandlers.put("smelting", wrapper -> handleSmelting("furnace_input", wrapper));
|
||||
recipeHandlers.put("blasting", wrapper -> handleSmelting("blast_furnace_input", wrapper));
|
||||
recipeHandlers.put("smoking", wrapper -> handleSmelting("smoker_input", wrapper));
|
||||
recipeHandlers.put("campfire_cooking", wrapper -> handleSmelting("campfire_input", wrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSimpleRecipe(final PacketWrapper wrapper) {
|
||||
final int category = wrapper.read(Types.VAR_INT);
|
||||
// Special recipes aren't sent to the client
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStonecutting(final PacketWrapper wrapper) {
|
||||
final int group = readRecipeGroup(wrapper);
|
||||
final Item[] ingredient = readIngredient(wrapper);
|
||||
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
|
||||
|
||||
final StoneCutterRecipe recipe = new StoneCutterRecipe(currentRecipeIdentifier, group, ingredient, result);
|
||||
stoneCutterRecipes.add(recipe); // Sent separately in update_recipes
|
||||
}
|
||||
|
||||
private void addRecipe(final Recipe recipe) {
|
||||
recipes.add(recipe);
|
||||
recipesByKey.put(currentRecipeIdentifier, recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSmithingTransform(final PacketWrapper wrapper) {
|
||||
readRecipeInputs("smithing_template", wrapper);
|
||||
readRecipeInputs("smithing_base", wrapper);
|
||||
readRecipeInputs("smithing_addition", wrapper);
|
||||
wrapper.read(itemType()); // Result
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSmithingTrim(final PacketWrapper wrapper) {
|
||||
readRecipeInputs("smithing_template", wrapper);
|
||||
readRecipeInputs("smithing_base", wrapper);
|
||||
readRecipeInputs("smithing_addition", wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCraftingShaped(final PacketWrapper wrapper) {
|
||||
final int group = readRecipeGroup(wrapper);
|
||||
final int category = wrapper.read(Types.VAR_INT);
|
||||
final int width = wrapper.read(Types.VAR_INT);
|
||||
final int height = wrapper.read(Types.VAR_INT);
|
||||
final int ingredientsSize = width * height;
|
||||
final Item[][] ingredients = new Item[ingredientsSize][];
|
||||
for (int i = 0; i < ingredientsSize; i++) {
|
||||
ingredients[i] = readIngredient(wrapper);
|
||||
}
|
||||
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
|
||||
final boolean showNotification = wrapper.read(Types.BOOLEAN);
|
||||
|
||||
final ShapedRecipe recipe = new ShapedRecipe(recipesByKey.size(), currentRecipeIdentifier, group, category, width, height, ingredients, result, showNotification);
|
||||
addRecipe(recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCraftingShapeless(final PacketWrapper wrapper) {
|
||||
final int group = readRecipeGroup(wrapper);
|
||||
final int category = wrapper.read(Types.VAR_INT);
|
||||
final int ingredientsSize = wrapper.read(Types.VAR_INT);
|
||||
final Item[][] ingredients = new Item[ingredientsSize][];
|
||||
for (int i = 0; i < ingredientsSize; i++) {
|
||||
ingredients[i] = readIngredient(wrapper);
|
||||
}
|
||||
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
|
||||
|
||||
final ShapelessRecipe recipe = new ShapelessRecipe(recipesByKey.size(), currentRecipeIdentifier, group, category, ingredients, result);
|
||||
addRecipe(recipe);
|
||||
}
|
||||
|
||||
public void handleSmelting(final String key, final PacketWrapper wrapper) {
|
||||
final int group = readRecipeGroup(wrapper);
|
||||
final int category = wrapper.read(Types.VAR_INT);
|
||||
final Item[] ingredient = readRecipeInputs(key, wrapper);
|
||||
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
|
||||
final float experience = wrapper.read(Types.FLOAT);
|
||||
final int cookingTime = wrapper.read(Types.VAR_INT);
|
||||
|
||||
final FurnaceRecipe recipe = new FurnaceRecipe(recipesByKey.size(), currentRecipeIdentifier, group, category, ingredient, result, cookingTime, experience);
|
||||
addRecipe(recipe);
|
||||
}
|
||||
|
||||
private int readRecipeGroup(final PacketWrapper wrapper) {
|
||||
final String recipeGroup = Key.stripMinecraftNamespace(wrapper.read(Types.STRING));
|
||||
if (recipeGroup.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recipeGroups.containsKey(recipeGroup)) {
|
||||
return recipeGroups.getInt(recipeGroup);
|
||||
}
|
||||
|
||||
final int size = recipeGroups.size();
|
||||
recipeGroups.put(recipeGroup, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
private Item[] readIngredient(final PacketWrapper wrapper) {
|
||||
final Item[] items = wrapper.read(itemArrayType());
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
final Item item = items[i];
|
||||
items[i] = rewrite(wrapper.user(), item);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public HolderSet toHolderSet(final Item[] ingredient) {
|
||||
// Ingredients are no longer full items, already store them as just holder sets
|
||||
final int[] ids = new int[ingredient.length];
|
||||
for (int i = 0; i < ingredient.length; i++) {
|
||||
ids[i] = ingredient[i].identifier();
|
||||
}
|
||||
return HolderSet.of(ids);
|
||||
}
|
||||
|
||||
public @Nullable Recipe recipe(final String key) {
|
||||
return recipesByKey.get(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public @Nullable Recipe recipe(final int displayId) {
|
||||
return displayId >= 0 && displayId < recipes.size() ? recipes.get(displayId) : null;
|
||||
}
|
||||
|
||||
public void finalizeRecipes() {
|
||||
// Need to be sorted alphabetically
|
||||
stoneCutterRecipes.sort(Comparator.comparing(recipe -> recipe.identifier));
|
||||
}
|
||||
|
||||
public void writeUpdateRecipeInputs(final PacketWrapper wrapper) {
|
||||
// Smithing and smelting inputs
|
||||
wrapper.write(Types.VAR_INT, recipeInputs.size());
|
||||
for (final Map.Entry<String, IntSet> entry : recipeInputs.entrySet()) {
|
||||
wrapper.write(Types.STRING, entry.getKey());
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, entry.getValue().toArray(EMPTY_ARRAY));
|
||||
}
|
||||
|
||||
// Stonecutter recipes
|
||||
wrapper.write(Types.VAR_INT, stoneCutterRecipes.size());
|
||||
for (final StoneCutterRecipe recipe : stoneCutterRecipes) {
|
||||
final HolderSet ingredient = toHolderSet(recipe.ingredient());
|
||||
wrapper.write(Types.HOLDER_SET, ingredient);
|
||||
writeItemDisplay(wrapper, recipe.result());
|
||||
}
|
||||
}
|
||||
|
||||
private Item[] readRecipeInputs(final String key, final PacketWrapper wrapper) {
|
||||
// Collect inputs for new UPDATE_RECIPE
|
||||
final Item[] ingredient = readIngredient(wrapper);
|
||||
final IntSet ids = recipeInputs.computeIfAbsent(key, $ -> new IntOpenHashSet(ingredient.length));
|
||||
for (final Item item : ingredient) {
|
||||
ids.add(item.identifier());
|
||||
}
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
interface Recipe {
|
||||
int SLOT_DISPLAY_EMPTY = 0;
|
||||
int SLOT_DISPLAY_ANY_FUEL = 1;
|
||||
int SLOT_DISPLAY_ITEM = 3;
|
||||
int SLOT_DISPLAY_COMPOSITE = 7;
|
||||
|
||||
int index();
|
||||
|
||||
String identifier();
|
||||
|
||||
int recipeDisplayId();
|
||||
|
||||
default Item @Nullable [][] ingredients() {
|
||||
final Item[] ingredient = ingredient();
|
||||
return ingredient == null ? null : new Item[][]{ingredient};
|
||||
}
|
||||
|
||||
default Item @Nullable [] ingredient() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default int group() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
default boolean showNotification() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int category();
|
||||
|
||||
void writeRecipeDisplay(PacketWrapper wrapper);
|
||||
}
|
||||
|
||||
record ShapelessRecipe(int index, String identifier, int group, int category, Item[][] ingredients,
|
||||
Item result) implements Recipe {
|
||||
@Override
|
||||
public int recipeDisplayId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRecipeDisplay(final PacketWrapper wrapper) {
|
||||
writeIngredientsDisplay(wrapper, ingredients);
|
||||
writeItemDisplay(wrapper, result);
|
||||
writeCraftingStationDisplay(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
record ShapedRecipe(int index, String identifier, int group, int category, int width, int height,
|
||||
Item[][] ingredients, Item result, boolean showNotification) implements Recipe {
|
||||
@Override
|
||||
public int recipeDisplayId() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRecipeDisplay(final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.VAR_INT, width);
|
||||
wrapper.write(Types.VAR_INT, height);
|
||||
writeIngredientsDisplay(wrapper, ingredients);
|
||||
writeItemDisplay(wrapper, result);
|
||||
writeCraftingStationDisplay(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
record FurnaceRecipe(int index, String identifier, int group, int category, Item[] ingredient,
|
||||
Item result, int duration, float experience) implements Recipe {
|
||||
@Override
|
||||
public int recipeDisplayId() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRecipeDisplay(final PacketWrapper wrapper) {
|
||||
writeIngredientDisplay(wrapper, ingredient);
|
||||
wrapper.write(Types.VAR_INT, SLOT_DISPLAY_ANY_FUEL); // Fuel
|
||||
writeItemDisplay(wrapper, result);
|
||||
writeCraftingStationDisplay(wrapper);
|
||||
wrapper.write(Types.VAR_INT, duration);
|
||||
wrapper.write(Types.FLOAT, experience);
|
||||
}
|
||||
}
|
||||
|
||||
record StoneCutterRecipe(String identifier, int group, Item[] ingredient, Item result) {
|
||||
|
||||
public int recipeDisplayId() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public void writeRecipeDisplay(final PacketWrapper wrapper) {
|
||||
writeIngredientDisplay(wrapper, ingredient);
|
||||
writeItemDisplay(wrapper, result);
|
||||
writeCraftingStationDisplay(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeIngredientsDisplay(final PacketWrapper wrapper, final Item[][] ingredients) {
|
||||
wrapper.write(Types.VAR_INT, ingredients.length);
|
||||
for (final Item[] ingredient : ingredients) {
|
||||
writeIngredientDisplay(wrapper, ingredient);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeIngredientDisplay(final PacketWrapper wrapper, final Item[] ingredient) {
|
||||
if (ingredient.length == 0) {
|
||||
wrapper.write(Types.VAR_INT, Recipe.SLOT_DISPLAY_EMPTY);
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.write(Types.VAR_INT, Recipe.SLOT_DISPLAY_COMPOSITE);
|
||||
wrapper.write(Types.VAR_INT, ingredient.length);
|
||||
for (final Item item : ingredient) {
|
||||
writeItemDisplay(wrapper, item);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeItemDisplay(final PacketWrapper wrapper, final Item item) {
|
||||
wrapper.write(Types.VAR_INT, Recipe.SLOT_DISPLAY_ITEM);
|
||||
wrapper.write(Types1_21_2.ITEM, item.copy());
|
||||
}
|
||||
|
||||
private static void writeCraftingStationDisplay(final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.VAR_INT, Recipe.SLOT_DISPLAY_EMPTY);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
|
||||
public class BundleStateTracker implements StorableObject {
|
||||
|
||||
private boolean bundling;
|
||||
|
||||
public boolean isBundling() {
|
||||
return this.bundling;
|
||||
}
|
||||
|
||||
public void toggleBundling() {
|
||||
this.bundling = !this.bundling;
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
|
||||
public record ClientVehicleStorage(int vehicleId) implements StorableObject {
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
|
||||
public class PlayerPositionStorage implements StorableObject {
|
||||
|
||||
private final IntSet pendingPongs = new IntOpenHashSet();
|
||||
private boolean captureNextPlayerPositionPacket;
|
||||
private PlayerPosition playerPosition;
|
||||
|
||||
public void addPendingPong(final int id) {
|
||||
if (!this.pendingPongs.add(id)) {
|
||||
throw new IllegalStateException("Pong already pending for id " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkPong(final int id) {
|
||||
if (this.pendingPongs.remove(id)) {
|
||||
this.reset(); // Ensure we don't have any leftover state
|
||||
this.captureNextPlayerPositionPacket = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkCaptureNextPlayerPositionPacket() {
|
||||
if (this.captureNextPlayerPositionPacket) {
|
||||
this.captureNextPlayerPositionPacket = false;
|
||||
return true;
|
||||
} else { // Packet order was wrong
|
||||
this.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerPosition(final PlayerPosition playerPosition) {
|
||||
this.playerPosition = playerPosition;
|
||||
}
|
||||
|
||||
public boolean checkHasPlayerPosition() {
|
||||
if (this.playerPosition != null) {
|
||||
return true;
|
||||
} else { // Packet order was wrong (ACCEPT_TELEPORTATION before MOVE_PLAYER_POS_ROT packet)
|
||||
this.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMovePlayerPosRot(final UserConnection user) {
|
||||
final PacketWrapper movePlayerPosRot = PacketWrapper.create(ServerboundPackets1_20_5.MOVE_PLAYER_POS_ROT, user);
|
||||
movePlayerPosRot.write(Types.DOUBLE, this.playerPosition.x); // X
|
||||
movePlayerPosRot.write(Types.DOUBLE, this.playerPosition.y); // Y
|
||||
movePlayerPosRot.write(Types.DOUBLE, this.playerPosition.z); // Z
|
||||
movePlayerPosRot.write(Types.FLOAT, this.playerPosition.yaw); // Yaw
|
||||
movePlayerPosRot.write(Types.FLOAT, this.playerPosition.pitch); // Pitch
|
||||
movePlayerPosRot.write(Types.BOOLEAN, this.playerPosition.onGround); // On Ground
|
||||
movePlayerPosRot.sendToServer(Protocol1_21To1_21_2.class);
|
||||
this.reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
this.captureNextPlayerPositionPacket = false;
|
||||
this.playerPosition = null;
|
||||
}
|
||||
|
||||
public record PlayerPosition(double x, double y, double z, float yaw, float pitch, boolean onGround) {
|
||||
}
|
||||
|
||||
}
|
||||
+4
-5
@@ -36,7 +36,6 @@ import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ServerboundPacke
|
||||
import com.viaversion.viaversion.protocols.v1_9_3to1_10.rewriter.ItemPacketRewriter1_10;
|
||||
import com.viaversion.viaversion.protocols.v1_9_3to1_10.storage.ResourcePackTracker;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class Protocol1_9_3To1_10 extends AbstractProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
|
||||
|
||||
@@ -49,12 +48,12 @@ public class Protocol1_9_3To1_10 extends AbstractProtocol<ClientboundPackets1_9_
|
||||
public static final ValueTransformer<List<EntityData>, List<EntityData>> TRANSFORM_ENTITY_DATA = new ValueTransformer<>(Types1_9.ENTITY_DATA_LIST) {
|
||||
@Override
|
||||
public List<EntityData> transform(PacketWrapper wrapper, List<EntityData> inputValue) {
|
||||
List<EntityData> dataList = new CopyOnWriteArrayList<>(inputValue);
|
||||
for (EntityData data : dataList) {
|
||||
if (data.id() >= 5)
|
||||
for (EntityData data : inputValue) {
|
||||
if (data.id() >= 5) {
|
||||
data.setId(data.id() + 1);
|
||||
}
|
||||
}
|
||||
return dataList;
|
||||
return inputValue;
|
||||
}
|
||||
};
|
||||
private final ItemPacketRewriter1_10 itemRewriter = new ItemPacketRewriter1_10(this);
|
||||
|
||||
@@ -142,10 +142,11 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
|
||||
|
||||
public void registerPlayerInfoUpdate1_20_3(final C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM);
|
||||
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM1_19_3);
|
||||
if (!actions.get(5)) { // Update display name
|
||||
return;
|
||||
}
|
||||
|
||||
final int entries = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
wrapper.passthrough(Types.UUID);
|
||||
@@ -177,6 +178,49 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
|
||||
});
|
||||
}
|
||||
|
||||
public void registerPlayerInfoUpdate1_21_2(final C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM1_21_2);
|
||||
if (!actions.get(5)) { // Update display name
|
||||
return;
|
||||
}
|
||||
|
||||
final int entries = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
wrapper.passthrough(Types.UUID);
|
||||
if (actions.get(0)) {
|
||||
wrapper.passthrough(Types.STRING); // Player Name
|
||||
|
||||
final int properties = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int j = 0; j < properties; j++) {
|
||||
wrapper.passthrough(Types.STRING); // Name
|
||||
wrapper.passthrough(Types.STRING); // Value
|
||||
wrapper.passthrough(Types.OPTIONAL_STRING); // Signature
|
||||
}
|
||||
}
|
||||
if (actions.get(1) && wrapper.passthrough(Types.BOOLEAN)) {
|
||||
wrapper.passthrough(Types.UUID); // Session UUID
|
||||
wrapper.passthrough(Types.PROFILE_KEY);
|
||||
}
|
||||
if (actions.get(2)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Gamemode
|
||||
}
|
||||
if (actions.get(3)) {
|
||||
wrapper.passthrough(Types.BOOLEAN); // Listed
|
||||
}
|
||||
if (actions.get(4)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Latency
|
||||
}
|
||||
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
|
||||
if (actions.get(6)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // List order
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerPlayerCombatKill(final C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
@@ -359,6 +403,10 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
|
||||
final CompoundTag componentsTag = contentsTag.getCompoundTag("components");
|
||||
handleShowItem(connection, contentsTag, componentsTag);
|
||||
if (componentsTag != null) {
|
||||
final CompoundTag useRemainder = TagUtil.getNamespacedCompoundTag(componentsTag, "use_remainder");
|
||||
if (useRemainder != null) {
|
||||
handleShowItem(connection, useRemainder);
|
||||
}
|
||||
handleContainerContents(connection, componentsTag);
|
||||
if (inputSerializerVersion() != null) {
|
||||
handleWrittenBookContents(connection, componentsTag);
|
||||
@@ -370,6 +418,10 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
|
||||
}
|
||||
}
|
||||
|
||||
protected final void handleShowItem(final UserConnection connection, final CompoundTag itemTag) {
|
||||
handleShowItem(connection, itemTag, itemTag.getCompoundTag("components"));
|
||||
}
|
||||
|
||||
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, @Nullable final CompoundTag componentsTag) {
|
||||
final StringTag idTag = itemTag.getStringTag("id");
|
||||
final String mappedId = protocol.getMappingData().getFullItemMappings().mappedIdentifier(idTag.getValue());
|
||||
@@ -385,8 +437,7 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
|
||||
}
|
||||
|
||||
for (final CompoundTag entryTag : container) {
|
||||
final CompoundTag itemTag = entryTag.getCompoundTag("item");
|
||||
handleShowItem(connection, itemTag, itemTag.getCompoundTag("components"));
|
||||
handleShowItem(connection, entryTag.getCompoundTag("item"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,16 +486,16 @@ public class ComponentRewriter<C extends ClientboundPacketType> implements com.v
|
||||
}
|
||||
}
|
||||
|
||||
protected SerializerVersion inputSerializerVersion() {
|
||||
protected @Nullable SerializerVersion inputSerializerVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected SerializerVersion outputSerializerVersion() {
|
||||
return null;
|
||||
protected @Nullable SerializerVersion outputSerializerVersion() {
|
||||
return inputSerializerVersion(); // Only matters if the nbt serializer changed
|
||||
}
|
||||
|
||||
private void convertLegacyContents(final CompoundTag hoverEvent) {
|
||||
if (inputSerializerVersion() == null || outputSerializerVersion() == null) {
|
||||
if (inputSerializerVersion() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,12 +35,10 @@ import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
@@ -235,8 +233,10 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
rewriteParticle(event.user(), particle);
|
||||
}
|
||||
} else if (type == componentType || type == optionalComponentType) {
|
||||
final Tag component = data.value();
|
||||
protocol.getComponentRewriter().processTag(event.user(), component);
|
||||
if (protocol.getComponentRewriter() != null) {
|
||||
final Tag component = data.value();
|
||||
protocol.getComponentRewriter().processTag(event.user(), component);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -589,21 +589,17 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
}
|
||||
|
||||
public void rewriteParticle(UserConnection connection, Particle particle) {
|
||||
if (protocol.getItemRewriter() != null) {
|
||||
protocol.getItemRewriter().rewriteParticle(connection, particle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Dupe parts of the logic if no item rewriter is available
|
||||
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
|
||||
int id = particle.id();
|
||||
if (mappings.isBlockParticle(id)) {
|
||||
Particle.ParticleData<Integer> data = particle.getArgument(0);
|
||||
data.setValue(protocol.getMappingData().getNewBlockStateId(data.getValue()));
|
||||
} else if (mappings.isItemParticle(id) && protocol.getItemRewriter() != null) {
|
||||
Particle.ParticleData<Item> data = particle.getArgument(0);
|
||||
ItemRewriter<?> itemRewriter = protocol.getItemRewriter();
|
||||
Item item = itemRewriter.handleItemToClient(connection, data.getValue());
|
||||
if (itemRewriter.mappedItemType() != null && itemRewriter.itemType() != itemRewriter.mappedItemType()) {
|
||||
// Replace the type
|
||||
particle.set(0, itemRewriter.mappedItemType(), item);
|
||||
} else {
|
||||
data.setValue(item);
|
||||
}
|
||||
}
|
||||
|
||||
particle.setId(protocol.getMappingData().getNewParticleId(id));
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.viaversion.viaversion.rewriter;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.Mappings;
|
||||
import com.viaversion.viaversion.api.data.ParticleMappings;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
@@ -105,30 +106,30 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
}
|
||||
|
||||
public void registerSetContent1_17_1(C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.VAR_INT); // State id
|
||||
handler(wrapper -> {
|
||||
Item[] items = wrapper.passthroughAndMap(itemArrayType, mappedItemArrayType);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
registerSetContent1_17_1(packetType, Types.UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
handleClientboundItem(wrapper);
|
||||
});
|
||||
public void registerSetContent1_21_2(C packetType) {
|
||||
registerSetContent1_17_1(packetType, Types.VAR_INT);
|
||||
}
|
||||
|
||||
private void registerSetContent1_17_1(C packetType, Type<? extends Number> containerIdType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(containerIdType); // Container id
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
Item[] items = wrapper.passthroughAndMap(itemArrayType, mappedItemArrayType);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
|
||||
passthroughClientboundItem(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
public void registerOpenScreen(C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Container id
|
||||
handler(wrapper -> handleMenuType(wrapper));
|
||||
}
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Container id
|
||||
handleMenuType(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,22 +148,27 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.UNSIGNED_BYTE); // Container id
|
||||
map(Types.SHORT); // Slot id
|
||||
handler(wrapper -> handleClientboundItem(wrapper));
|
||||
handler(wrapper -> passthroughClientboundItem(wrapper));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerSetSlot1_17_1(C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.VAR_INT); // State id
|
||||
map(Types.SHORT); // Slot id
|
||||
handler(wrapper -> handleClientboundItem(wrapper));
|
||||
}
|
||||
registerSetSlot1_17_1(packetType, Types.UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
public void registerSetSlot1_21_2(C packetType) {
|
||||
registerSetSlot1_17_1(packetType, Types.VAR_INT);
|
||||
}
|
||||
|
||||
private void registerSetSlot1_17_1(C packetType, Type<? extends Number> containerIdType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(containerIdType); // Container id
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
wrapper.passthrough(Types.SHORT); // Slot id
|
||||
passthroughClientboundItem(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,7 +179,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity ID
|
||||
map(Types.VAR_INT); // Slot ID
|
||||
handler(wrapper -> handleClientboundItem(wrapper));
|
||||
handler(wrapper -> passthroughClientboundItem(wrapper));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -190,7 +196,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
do {
|
||||
slot = wrapper.passthrough(Types.BYTE);
|
||||
// & 0x7F into an extra variable if slot is needed
|
||||
handleClientboundItem(wrapper);
|
||||
passthroughClientboundItem(wrapper);
|
||||
} while (slot < 0);
|
||||
});
|
||||
}
|
||||
@@ -202,7 +208,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.SHORT); // 0 - Slot
|
||||
handler(wrapper -> handleServerboundItem(wrapper));
|
||||
handler(wrapper -> passthroughServerboundItem(wrapper));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -211,38 +217,41 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
protocol.registerServerbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // 0 - Window ID
|
||||
map(Types.UNSIGNED_BYTE); // 0 - Container ID
|
||||
map(Types.SHORT); // 1 - Slot
|
||||
map(Types.BYTE); // 2 - Button
|
||||
map(Types.SHORT); // 3 - Action number
|
||||
map(Types.VAR_INT); // 4 - Mode
|
||||
handler(wrapper -> handleServerboundItem(wrapper));
|
||||
handler(wrapper -> passthroughServerboundItem(wrapper));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerContainerClick1_17_1(S packetType) {
|
||||
protocol.registerServerbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window Id
|
||||
map(Types.VAR_INT); // State id
|
||||
map(Types.SHORT); // Slot
|
||||
map(Types.BYTE); // Button
|
||||
map(Types.VAR_INT); // Mode
|
||||
registerContainerClick1_17_1(packetType, Types.UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
handler(wrapper -> {
|
||||
// Affected items
|
||||
int length = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
handleServerboundItem(wrapper);
|
||||
}
|
||||
public void registerContainerClick1_21_2(S packetType) {
|
||||
registerContainerClick1_17_1(packetType, Types.VAR_INT);
|
||||
}
|
||||
|
||||
// Carried item
|
||||
handleServerboundItem(wrapper);
|
||||
});
|
||||
public void registerContainerClick1_17_1(S packetType, Type<? extends Number> containerIdType) {
|
||||
protocol.registerServerbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(containerIdType); // Container id
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
wrapper.passthrough(Types.BYTE); // Button
|
||||
wrapper.passthrough(Types.VAR_INT); // Mode
|
||||
|
||||
// Affected items
|
||||
final int length = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
passthroughServerboundItem(wrapper);
|
||||
}
|
||||
|
||||
// Carried item
|
||||
passthroughServerboundItem(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -253,6 +262,15 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
});
|
||||
}
|
||||
|
||||
public void registerCooldown1_21_2(C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
String itemIdentifier = wrapper.read(Types.OPTIONAL_STRING);
|
||||
if (itemIdentifier != null) {
|
||||
itemIdentifier = mappedIdentifier(protocol.getMappingData().getFullItemMappings(), itemIdentifier);
|
||||
}
|
||||
wrapper.write(Types.OPTIONAL_STRING, itemIdentifier);
|
||||
});
|
||||
}
|
||||
|
||||
public void registerCustomPayloadTradeList(C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@@ -274,11 +292,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
|
||||
final int size = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
for (int i = 0; i < size; i++) {
|
||||
handleClientboundItem(wrapper); // Input Item
|
||||
handleClientboundItem(wrapper); // Output Item
|
||||
passthroughClientboundItem(wrapper); // Input Item
|
||||
passthroughClientboundItem(wrapper); // Output Item
|
||||
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
handleClientboundItem(wrapper); // Second Item
|
||||
passthroughClientboundItem(wrapper); // Second Item
|
||||
}
|
||||
|
||||
wrapper.passthrough(Types.BOOLEAN); // Trade disabled
|
||||
@@ -294,11 +312,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
wrapper.passthrough(Types.VAR_INT);
|
||||
int size = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
for (int i = 0; i < size; i++) {
|
||||
handleClientboundItem(wrapper); // Input
|
||||
handleClientboundItem(wrapper); // Output
|
||||
passthroughClientboundItem(wrapper); // Input
|
||||
passthroughClientboundItem(wrapper); // Output
|
||||
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) { // Has second item
|
||||
handleClientboundItem(wrapper); // Second item
|
||||
passthroughClientboundItem(wrapper); // Second item
|
||||
}
|
||||
|
||||
wrapper.passthrough(Types.BOOLEAN); // Trade disabled
|
||||
@@ -319,9 +337,9 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
wrapper.passthrough(Types.VAR_INT); // Container id
|
||||
int size = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
handleClientboundItem(wrapper); // Input
|
||||
handleClientboundItem(wrapper); // Output
|
||||
handleClientboundItem(wrapper); // Second item
|
||||
passthroughClientboundItem(wrapper); // Input
|
||||
passthroughClientboundItem(wrapper); // Output
|
||||
passthroughClientboundItem(wrapper); // Second item
|
||||
|
||||
wrapper.passthrough(Types.BOOLEAN); // Trade disabled
|
||||
wrapper.passthrough(Types.INT); // Number of tools uses
|
||||
@@ -344,7 +362,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
final Item input = wrapper.read(itemCostType);
|
||||
wrapper.write(mappedItemCostType, handleItemToClient(wrapper.user(), input));
|
||||
|
||||
handleClientboundItem(wrapper); // Result
|
||||
passthroughClientboundItem(wrapper); // Result
|
||||
|
||||
Item secondInput = wrapper.read(optionalItemCostType);
|
||||
if (secondInput != null) {
|
||||
@@ -382,7 +400,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
componentRewriter.processText(wrapper.user(), description);
|
||||
}
|
||||
|
||||
handleClientboundItem(wrapper); // Icon
|
||||
passthroughClientboundItem(wrapper); // Icon
|
||||
wrapper.passthrough(Types.VAR_INT); // Frame type
|
||||
int flags = wrapper.passthrough(Types.INT); // Flags
|
||||
if ((flags & 1) != 0) {
|
||||
@@ -420,7 +438,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
componentRewriter.processTag(wrapper.user(), description);
|
||||
}
|
||||
|
||||
handleClientboundItem(wrapper); // Icon
|
||||
passthroughClientboundItem(wrapper); // Icon
|
||||
wrapper.passthrough(Types.VAR_INT); // Frame type
|
||||
int flags = wrapper.passthrough(Types.INT); // Flags
|
||||
if ((flags & 1) != 0) {
|
||||
@@ -549,6 +567,24 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
});
|
||||
}
|
||||
|
||||
public void registerExplosion1_21_2(C packetType) {
|
||||
final SoundRewriter<C> soundRewriter = new SoundRewriter<>(protocol);
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
wrapper.passthrough(Types.DOUBLE); // Knockback X
|
||||
wrapper.passthrough(Types.DOUBLE); // Knockback Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Knockback Z
|
||||
|
||||
final Particle explosionParticle = wrapper.read(particleType);
|
||||
wrapper.write(mappedParticleType, explosionParticle);
|
||||
rewriteParticle(wrapper.user(), explosionParticle);
|
||||
|
||||
soundRewriter.soundHolderHandler().handle(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
public PacketHandler levelParticlesHandler() {
|
||||
return levelParticlesHandler(Types.INT);
|
||||
}
|
||||
@@ -565,7 +601,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
int data = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(data));
|
||||
} else if (mappings.isItemParticle(id)) {
|
||||
handleClientboundItem(wrapper);
|
||||
passthroughClientboundItem(wrapper);
|
||||
}
|
||||
|
||||
int mappedId = protocol.getMappingData().getNewParticleId(id);
|
||||
@@ -575,17 +611,18 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
};
|
||||
}
|
||||
|
||||
private void handleClientboundItem(final PacketWrapper wrapper) {
|
||||
protected void passthroughClientboundItem(final PacketWrapper wrapper) {
|
||||
final Item item = handleItemToClient(wrapper.user(), wrapper.read(itemType));
|
||||
wrapper.write(mappedItemType, item);
|
||||
}
|
||||
|
||||
private void handleServerboundItem(final PacketWrapper wrapper) {
|
||||
protected void passthroughServerboundItem(final PacketWrapper wrapper) {
|
||||
final Item item = handleItemToServer(wrapper.user(), wrapper.read(mappedItemType));
|
||||
wrapper.write(itemType, item);
|
||||
}
|
||||
|
||||
protected void rewriteParticle(UserConnection connection, Particle particle) {
|
||||
@Override
|
||||
public void rewriteParticle(UserConnection connection, Particle particle) {
|
||||
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
|
||||
int id = particle.id();
|
||||
if (mappings.isBlockParticle(id)) {
|
||||
@@ -605,6 +642,21 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
particle.setId(protocol.getMappingData().getNewParticleId(id));
|
||||
}
|
||||
|
||||
protected @Nullable String mappedIdentifier(final FullMappings mappings, final String identifier) {
|
||||
// Check if the original exists before mapping
|
||||
if (mappings.id(identifier) == -1) {
|
||||
return identifier;
|
||||
}
|
||||
return mappings.mappedIdentifier(identifier);
|
||||
}
|
||||
|
||||
protected @Nullable String unmappedIdentifier(final FullMappings mappings, final String mappedIdentifier) {
|
||||
if (mappings.mappedId(mappedIdentifier) == -1) {
|
||||
return mappedIdentifier;
|
||||
}
|
||||
return mappings.identifier(mappedIdentifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<Item> itemType() {
|
||||
return itemType;
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
|
||||
// Base for 1.21.2 and onwards
|
||||
public class RecipeDisplayRewriter<C extends ClientboundPacketType> {
|
||||
protected final Protocol<C, ?, ?, ?> protocol;
|
||||
|
||||
public RecipeDisplayRewriter(final Protocol<C, ?, ?, ?> protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void registerUpdateRecipes(final C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
final int size = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.passthrough(Types.STRING); // Recipe group
|
||||
rewriteItemIds(wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE));
|
||||
}
|
||||
|
||||
final int stonecutterRecipesSize = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < stonecutterRecipesSize; i++) {
|
||||
handleIngredient(wrapper);
|
||||
handleSlotDisplay(wrapper);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerRecipeBookAdd(final C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
final int size = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Display ID
|
||||
handleRecipeDisplay(wrapper);
|
||||
wrapper.passthrough(Types.OPTIONAL_VAR_INT); // Group
|
||||
wrapper.passthrough(Types.VAR_INT); // Category
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
final int ingredientsSize = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int j = 0; j < ingredientsSize; j++) {
|
||||
handleIngredient(wrapper); // Items
|
||||
}
|
||||
}
|
||||
wrapper.passthrough(Types.BYTE); // Flags
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerPlaceGhostRecipe(final C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Container ID
|
||||
handleRecipeDisplay(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
protected void handleShapeless(final PacketWrapper wrapper) {
|
||||
handleSlotDisplayList(wrapper); // Ingredients
|
||||
handleSlotDisplay(wrapper); // Result
|
||||
handleSlotDisplay(wrapper); // Crafting station
|
||||
}
|
||||
|
||||
protected void handleShaped(final PacketWrapper wrapper) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Width
|
||||
wrapper.passthrough(Types.VAR_INT); // Height
|
||||
handleSlotDisplayList(wrapper); // Ingredients
|
||||
handleSlotDisplay(wrapper); // Result
|
||||
handleSlotDisplay(wrapper); // Crafting station
|
||||
}
|
||||
|
||||
protected void handleFurnace(final PacketWrapper wrapper) {
|
||||
handleSlotDisplay(wrapper); // Ingredient
|
||||
handleSlotDisplay(wrapper); // Fuel
|
||||
handleSlotDisplay(wrapper); // Result
|
||||
handleSlotDisplay(wrapper); // Crafting station
|
||||
}
|
||||
|
||||
protected void handleStoneCutter(final PacketWrapper wrapper) {
|
||||
handleSlotDisplay(wrapper); // Input
|
||||
handleSlotDisplay(wrapper); // Result
|
||||
handleSlotDisplay(wrapper); // Crafting station
|
||||
}
|
||||
|
||||
protected void handleSmithing(final PacketWrapper wrapper) {
|
||||
handleSlotDisplay(wrapper); // Template
|
||||
handleSlotDisplay(wrapper); // Base
|
||||
handleSlotDisplay(wrapper); // Addition
|
||||
handleSlotDisplay(wrapper); // Result
|
||||
handleSlotDisplay(wrapper); // Crafting station
|
||||
}
|
||||
|
||||
protected void handleRecipeDisplay(final PacketWrapper wrapper) {
|
||||
final int type = wrapper.passthrough(Types.VAR_INT);
|
||||
switch (type) {
|
||||
case 0 -> handleShapeless(wrapper);
|
||||
case 1 -> handleShaped(wrapper);
|
||||
case 2 -> handleFurnace(wrapper);
|
||||
case 3 -> handleStoneCutter(wrapper);
|
||||
case 4 -> handleSmithing(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleSlotDisplay(final PacketWrapper wrapper) {
|
||||
// empty and any_fuel are empty
|
||||
final int type = wrapper.passthrough(Types.VAR_INT);
|
||||
switch (type) {
|
||||
case 2 -> handleItemId(wrapper); // Item type
|
||||
case 3 -> handleItem(wrapper); // Item
|
||||
case 4 -> wrapper.passthrough(Types.STRING); // Tag key
|
||||
case 5 -> handleSmithingTrimSlotDisplay(wrapper); // Smithing trim
|
||||
case 6 -> handleWithRemainderSlotDisplay(wrapper); // With remainder
|
||||
case 7 -> handleSlotDisplayList(wrapper); // Composite
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleSlotDisplayList(final PacketWrapper wrapper) {
|
||||
final int size = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
handleSlotDisplay(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleSmithingTrimSlotDisplay(final PacketWrapper wrapper) {
|
||||
handleSlotDisplay(wrapper); // Base
|
||||
handleSlotDisplay(wrapper); // Material
|
||||
handleSlotDisplay(wrapper); // Pattern
|
||||
}
|
||||
|
||||
protected void handleWithRemainderSlotDisplay(final PacketWrapper wrapper) {
|
||||
handleSlotDisplay(wrapper); // Input
|
||||
handleSlotDisplay(wrapper); // Remainder
|
||||
}
|
||||
|
||||
protected void handleIngredient(final PacketWrapper wrapper) {
|
||||
final HolderSet items = wrapper.passthrough(Types.HOLDER_SET);
|
||||
if (items.hasTagKey()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int[] ids = items.ids();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
ids[i] = rewriteItemId(ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleItemId(final PacketWrapper wrapper) {
|
||||
final int id = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.write(Types.VAR_INT, rewriteItemId(id));
|
||||
}
|
||||
|
||||
protected void handleItem(final PacketWrapper wrapper) {
|
||||
final ItemRewriter<?> itemRewriter = protocol.getItemRewriter();
|
||||
final Item item = wrapper.read(itemRewriter.itemType());
|
||||
itemRewriter.handleItemToClient(wrapper.user(), item);
|
||||
wrapper.write(itemRewriter.mappedItemType(), item);
|
||||
}
|
||||
|
||||
protected int rewriteItemId(final int id) {
|
||||
if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) {
|
||||
return protocol.getMappingData().getItemMappings().getNewIdOrDefault(id, id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void rewriteItemIds(final int[] ids) {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
final int id = ids[i];
|
||||
ids[i] = rewriteItemId(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package com.viaversion.viaversion.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
@@ -29,6 +30,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
// Base up to and including 1.21.1
|
||||
public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
|
||||
protected final Protocol<C, ?, ?, ?> protocol;
|
||||
@@ -80,13 +82,22 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
|
||||
public void register1_20_5(C packetType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
int size = wrapper.passthrough(Types.VAR_INT);
|
||||
final int size = wrapper.passthrough(Types.VAR_INT);
|
||||
int newSize = size;
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.passthrough(Types.STRING); // Recipe Identifier
|
||||
final String recipeIdentifier = wrapper.read(Types.STRING);
|
||||
|
||||
final int typeId = wrapper.passthrough(Types.VAR_INT);
|
||||
final String type = protocol.getMappingData().getRecipeSerializerMappings().identifier(typeId);
|
||||
handleRecipeType(wrapper, type);
|
||||
final FullMappings recipeSerializerMappings = protocol.getMappingData().getRecipeSerializerMappings();
|
||||
final int typeId = wrapper.read(Types.VAR_INT);
|
||||
final int mappedId = recipeSerializerMappings.getNewId(typeId);
|
||||
if (mappedId != -1) {
|
||||
wrapper.write(Types.STRING, recipeIdentifier);
|
||||
wrapper.write(Types.VAR_INT, mappedId);
|
||||
} else {
|
||||
wrapper.set(Types.VAR_INT, 0, --newSize);
|
||||
}
|
||||
|
||||
handleRecipeType(wrapper, Key.stripMinecraftNamespace(recipeSerializerMappings.identifier(typeId))); // Use the original
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -150,6 +161,13 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
handleIngredient(wrapper); // Additions
|
||||
}
|
||||
|
||||
protected int rewrite(final int itemId) {
|
||||
if (protocol.getMappingData() != null && protocol.getItemRewriter() != null) {
|
||||
return protocol.getMappingData().getNewItemId(itemId);
|
||||
}
|
||||
return itemId;
|
||||
}
|
||||
|
||||
protected @Nullable Item rewrite(UserConnection connection, @Nullable Item item) {
|
||||
if (protocol.getItemRewriter() != null) {
|
||||
return protocol.getItemRewriter().handleItemToClient(connection, item);
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.entity.DimensionData;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.DimensionDataImpl;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class RegistryDataRewriter {
|
||||
private final Map<String, Consumer<CompoundTag>> enchantmentEffectRewriters = new Object2ObjectArrayMap<>();
|
||||
private final Map<String, List<RegistryEntry>> toAdd = new Object2ObjectArrayMap<>();
|
||||
private final Protocol<?, ?, ?, ?> protocol;
|
||||
|
||||
public RegistryDataRewriter(Protocol<?, ?, ?, ?> protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void handle(final PacketWrapper wrapper) {
|
||||
final String registryKey = wrapper.passthrough(Types.STRING);
|
||||
RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY);
|
||||
entries = handle(wrapper.user(), registryKey, entries);
|
||||
wrapper.write(Types.REGISTRY_ENTRY_ARRAY, entries);
|
||||
}
|
||||
|
||||
public RegistryEntry[] handle(final UserConnection connection, String key, RegistryEntry[] entries) {
|
||||
key = Key.stripMinecraftNamespace(key);
|
||||
if (key.equals("enchantment")) {
|
||||
updateEnchantments(entries);
|
||||
}
|
||||
|
||||
final List<RegistryEntry> toAdd = this.toAdd.get(key);
|
||||
if (toAdd != null) {
|
||||
final int length = entries.length;
|
||||
final int toAddLength = toAdd.size();
|
||||
entries = Arrays.copyOf(entries, length + toAddLength);
|
||||
for (int i = 0; i < toAddLength; i++) {
|
||||
entries[length + i] = toAdd.get(i).copy();
|
||||
}
|
||||
}
|
||||
|
||||
trackDimensionAndBiomes(connection, key, entries);
|
||||
return entries;
|
||||
}
|
||||
|
||||
public void addEntries(final String registryKey, final RegistryEntry... entries) {
|
||||
toAdd.computeIfAbsent(Key.stripMinecraftNamespace(registryKey), $ -> new ArrayList<>()).addAll(List.of(entries));
|
||||
}
|
||||
|
||||
public void addEnchantmentEffectRewriter(final String key, final Consumer<CompoundTag> rewriter) {
|
||||
enchantmentEffectRewriters.put(Key.stripMinecraftNamespace(key), rewriter);
|
||||
}
|
||||
|
||||
public void trackDimensionAndBiomes(final UserConnection connection, final String registryKey, final RegistryEntry[] entries) {
|
||||
if (registryKey.equals("worldgen/biome")) {
|
||||
protocol.getEntityRewriter().tracker(connection).setBiomesSent(entries.length);
|
||||
} else if (registryKey.equals("dimension_type")) {
|
||||
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(entries.length);
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
final RegistryEntry entry = entries[i];
|
||||
final String key = Key.stripMinecraftNamespace(entry.key());
|
||||
final DimensionData dimensionData = entry.tag() != null
|
||||
? new DimensionDataImpl(i, (CompoundTag) entry.tag())
|
||||
: DimensionDataImpl.withDefaultsFor(key, i);
|
||||
dimensionDataMap.put(key, dimensionData);
|
||||
}
|
||||
protocol.getEntityRewriter().tracker(connection).setDimensions(dimensionDataMap);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateEnchantments(final RegistryEntry[] entries) {
|
||||
for (final RegistryEntry entry : entries) {
|
||||
if (entry.tag() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final CompoundTag effects = ((CompoundTag) entry.tag()).getCompoundTag("effects");
|
||||
if (effects == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go through all effects, almost all of them may contain an "effect" element
|
||||
for (final Map.Entry<String, Tag> effectEntry : effects.entrySet()) {
|
||||
if (effectEntry.getValue() instanceof final CompoundTag compoundTag) {
|
||||
updateNestedEffect(compoundTag);
|
||||
} else if (effectEntry.getValue() instanceof final ListTag<?> listTag && listTag.getElementType() == CompoundTag.class) {
|
||||
for (final Tag tag : listTag) {
|
||||
updateNestedEffect((CompoundTag) tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateAttributesFields(effects);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNestedEffect(final CompoundTag effectsTag) {
|
||||
final CompoundTag effect = effectsTag.getCompoundTag("effect");
|
||||
if (effect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
runEffectRewriters(effect);
|
||||
|
||||
final ListTag<CompoundTag> innerEffects = effect.getListTag("effects", CompoundTag.class);
|
||||
if (innerEffects == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CompoundTag innerEffect : innerEffects) {
|
||||
runEffectRewriters(innerEffect);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttributesFields(final CompoundTag effects) {
|
||||
if (!hasAttributeMappings()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> attributesList = TagUtil.getNamespacedCompoundTagList(effects, "attributes");
|
||||
if (attributesList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CompoundTag attributeData : attributesList) {
|
||||
updateAttributeField(attributeData);
|
||||
}
|
||||
}
|
||||
|
||||
private void runEffectRewriters(final CompoundTag effectTag) {
|
||||
String effect = effectTag.getString("type");
|
||||
if (effect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
effect = Key.stripMinecraftNamespace(effect);
|
||||
updateAttributeField(effectTag);
|
||||
|
||||
final Consumer<CompoundTag> rewriter = enchantmentEffectRewriters.get(effect);
|
||||
if (rewriter != null) {
|
||||
rewriter.accept(effectTag);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttributeField(final CompoundTag attributeData) {
|
||||
final StringTag attributeTag = attributeData.getStringTag("attribute");
|
||||
if (attributeTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
|
||||
final String attribute = Key.stripMinecraftNamespace(attributeTag.getValue());
|
||||
String mappedAttribute = mappings.mappedIdentifier(attribute);
|
||||
if (mappedAttribute == null) {
|
||||
mappedAttribute = mappings.mappedIdentifier(0); // Dummy
|
||||
}
|
||||
attributeTag.setValue(mappedAttribute);
|
||||
}
|
||||
|
||||
private boolean hasAttributeMappings() {
|
||||
return protocol.getMappingData() != null && protocol.getMappingData().getAttributeMappings() != null;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class StructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
||||
@@ -118,6 +119,11 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
||||
final Int2IntFunction itemIdRewriter = clientbound ? mappingData::getNewItemId : mappingData::getOldItemId;
|
||||
container.replace(StructuredDataKey.TRIM, value -> value.rewrite(itemIdRewriter));
|
||||
container.replace(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(itemIdRewriter));
|
||||
container.replace(StructuredDataKey.REPAIRABLE, value -> value.rewrite(itemIdRewriter));
|
||||
}
|
||||
if (mappingData.getFullItemMappings() != null) {
|
||||
final Function<String, String> itemIdRewriter = clientbound ? id -> mappedIdentifier(mappingData.getFullItemMappings(), id) : id -> unmappedIdentifier(mappingData.getFullItemMappings(), id);
|
||||
container.replace(StructuredDataKey.USE_COOLDOWN, value -> value.rewrite(itemIdRewriter));
|
||||
}
|
||||
if (mappingData.getBlockMappings() != null) {
|
||||
final Int2IntFunction blockIdRewriter = clientbound ? mappingData::getNewBlockId : mappingData::getOldBlockId;
|
||||
@@ -127,7 +133,8 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
||||
}
|
||||
if (mappingData.getSoundMappings() != null) {
|
||||
final Int2IntFunction soundIdRewriter = clientbound ? mappingData::getNewSoundId : mappingData::getOldSoundId;
|
||||
container.replace(StructuredDataKey.INSTRUMENT, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value);
|
||||
container.replace(StructuredDataKey.INSTRUMENT1_20_5, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value);
|
||||
container.replace(StructuredDataKey.INSTRUMENT1_21_2, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value);
|
||||
container.replace(StructuredDataKey.JUKEBOX_PLAYABLE, value -> value.rewrite(soundIdRewriter));
|
||||
}
|
||||
if (clientbound && protocol.getComponentRewriter() != null) {
|
||||
|
||||
@@ -162,7 +162,7 @@ public class TagRewriter<C extends ClientboundPacketType> implements com.viavers
|
||||
|
||||
wrapper.write(Types.STRING, registryKey);
|
||||
|
||||
final RegistryType type = RegistryType.getByKey(registryKey);
|
||||
final RegistryType type = RegistryType.getByKey(strippedKey);
|
||||
if (type != null) {
|
||||
handle(wrapper, type);
|
||||
readTypes.add(type);
|
||||
|
||||
@@ -60,7 +60,9 @@ public final class ComponentUtil {
|
||||
final ATextComponent component = SerializerVersion.V1_20_3.toComponent(tag);
|
||||
return component != null ? SerializerVersion.V1_19_4.toJson(component) : null;
|
||||
} catch (final Exception e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting tag: " + tag, e);
|
||||
if (!Via.getConfig().isSuppressConversionWarnings()) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting tag: " + tag, e);
|
||||
}
|
||||
return plainToJson("<error>");
|
||||
}
|
||||
}
|
||||
@@ -74,7 +76,9 @@ public final class ComponentUtil {
|
||||
final ATextComponent component = SerializerVersion.V1_19_4.toComponent(element);
|
||||
return trimStrings(SerializerVersion.V1_20_3.toTag(component));
|
||||
} catch (final Exception e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting component: " + element, e);
|
||||
if (!Via.getConfig().isSuppressConversionWarnings()) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting component: " + element, e);
|
||||
}
|
||||
return new StringTag("<error>");
|
||||
}
|
||||
}
|
||||
@@ -101,7 +105,9 @@ public final class ComponentUtil {
|
||||
final ATextComponent component = SerializerVersion.V1_20_5.toComponent(tag);
|
||||
return component != null ? SerializerVersion.V1_20_3.toString(component) : null;
|
||||
} catch (final Exception e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting tag: " + tag, e);
|
||||
if (!Via.getConfig().isSuppressConversionWarnings()) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting tag: " + tag, e);
|
||||
}
|
||||
return plainToJson("<error>").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import net.lenni0451.mcstructs.snbt.SNbtSerializer;
|
||||
import net.lenni0451.mcstructs.snbt.exceptions.SNbtDeserializeException;
|
||||
import net.lenni0451.mcstructs.snbt.exceptions.SNbtSerializeException;
|
||||
@@ -26,6 +27,13 @@ import net.lenni0451.mcstructs.text.ATextComponent;
|
||||
import net.lenni0451.mcstructs.text.serializer.TextComponentCodec;
|
||||
import net.lenni0451.mcstructs.text.serializer.TextComponentSerializer;
|
||||
|
||||
/**
|
||||
* Wrapper enum to unify text component and string nbt serialization functions across different versions.
|
||||
* Only contains versions which have actual changes we handle.
|
||||
*
|
||||
* @see ComponentUtil
|
||||
* @see ComponentRewriter
|
||||
*/
|
||||
public enum SerializerVersion {
|
||||
V1_6(TextComponentSerializer.V1_6, null),
|
||||
V1_7(TextComponentSerializer.V1_7, SNbtSerializer.V1_7),
|
||||
@@ -115,4 +123,4 @@ public enum SerializerVersion {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.util;
|
||||
|
||||
import com.google.common.collect.ForwardingSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public class SetWrapper<E> extends ForwardingSet<E> {
|
||||
|
||||
private final Set<E> set;
|
||||
private final Consumer<E> addListener;
|
||||
|
||||
public SetWrapper(Set<E> set, Consumer<E> addListener) {
|
||||
this.set = set;
|
||||
this.addListener = addListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(@NonNull E element) {
|
||||
addListener.accept(element);
|
||||
|
||||
return super.add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> collection) {
|
||||
for (E element : collection) {
|
||||
addListener.accept(element);
|
||||
}
|
||||
|
||||
return super.addAll(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<E> delegate() {
|
||||
return originalSet();
|
||||
}
|
||||
|
||||
public Set<E> originalSet() {
|
||||
return this.set;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.util;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@@ -69,6 +70,11 @@ public final class TagUtil {
|
||||
return listTag != null ? listTag : tag.getListTag(Key.stripMinecraftNamespace(key), CompoundTag.class);
|
||||
}
|
||||
|
||||
public static @Nullable StringTag getNamespacedStringTag(final CompoundTag tag, final String key) {
|
||||
final StringTag stringTag = tag.getStringTag(Key.namespaced(key));
|
||||
return stringTag != null ? stringTag : tag.getStringTag(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public static Tag handleDeep(final Tag tag, final TagUpdater consumer) {
|
||||
return handleDeep(null, tag, consumer);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ block-disconnect-msg: "You are using an unsupported Minecraft version!"
|
||||
# (We don't suggest using reload either, use a plugin manager)
|
||||
# You can customize the message we kick people with if you use ProtocolLib here.
|
||||
reload-disconnect-msg: "Server reload, please rejoin!"
|
||||
# We warn when there's an error converting item and block data over versions, should we suppress these? (Only suggested if spamming)
|
||||
# We warn when there's an error converting item/block or component/nbt data over versions, should we suppress these? (Only suggested if spamming)
|
||||
suppress-conversion-warnings: false
|
||||
#
|
||||
#----------------------------------------------------------#
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
-3
@@ -1,9 +1,9 @@
|
||||
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
|
||||
projectVersion=5.0.4
|
||||
projectVersion=5.1.0
|
||||
|
||||
# Smile emoji
|
||||
mcVersions=1.21.1,1.21,1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
|
||||
mcVersionRange=1.8-1.21.1
|
||||
mcVersions=1.21.3,1.21.2,1.21.1,1.21,1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
|
||||
mcVersionRange=1.8-1.21.3
|
||||
velocityVersion=3.3
|
||||
|
||||
# Gradle properties
|
||||
|
||||
@@ -4,7 +4,7 @@ metadata.format.version = "1.1"
|
||||
|
||||
gson = "2.11.0"
|
||||
fastutil = "8.5.14"
|
||||
vianbt = "5.0.0"
|
||||
vianbt = "5.0.1"
|
||||
mcstructs = "5-2.5.4-SNAPSHOT"
|
||||
|
||||
# Common provided
|
||||
|
||||
Reference in new issue
Block a user