3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-12-28 09:00:09 +01:00

Merge branch 'master' into component-rewriter-work

# Conflicts:
#	common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/ComponentRewriter1_20_5.java
Dieser Commit ist enthalten in:
FlorianMichael 2024-12-14 22:19:29 +01:00
Commit 13fa72435c
213 geänderte Dateien mit 8661 neuen und 2060 gelöschten Zeilen

1
.github/FUNDING.yml vendored
Datei anzeigen

@ -1,2 +1,3 @@
github: kennytv github: kennytv
patreon: kennytv patreon: kennytv
custom: ['https://florianmichael.de/donate']

Datei anzeigen

@ -21,10 +21,11 @@ body:
- type: textarea - type: textarea
attributes: attributes:
label: Console Error label: Server/Client Error
description: | description: |
If you encounter warnings/errors in your console, **paste them with https://mclo.gs/ and put the paste link here**. If you encounter warnings/errors in your console, **paste them with https://mclo.gs/ and put the paste link here**.
If the error is small/less than 10 lines, you may put it directly into this field. If the error is small/less than 10 lines, you may put it directly into this field.
**Important**: If you are kicked for `Network Protocol Error` or an encoder/decoder exception, please click the `Open Report Directory` button on your client and paste the newest disconnect file contents.
value: | value: |
``` ```
Put the mclo.gs link or text here. Put the mclo.gs link or text here.
@ -51,7 +52,7 @@ body:
List the steps on how we can reproduce the issue. Make sure we can easily understand what you mean with each step. List the steps on how we can reproduce the issue. Make sure we can easily understand what you mean with each step.
placeholder: | placeholder: |
Example: Example:
1. Login with a 1.13.2 client 1. Login with a 1.21.3 client
2. Place a sign 2. Place a sign
3. The sign text is displayed wrong 3. The sign text is displayed wrong
validations: validations:

3
.gitignore vendored
Datei anzeigen

@ -110,3 +110,6 @@ nb-configuration.xml
### MacOS ### ### MacOS ###
.DS_Store .DS_Store
### Run Folder (ViaProxy) ###
common/run/

Datei anzeigen

@ -20,6 +20,13 @@ Supported Versions:
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/ **User Docs:** https://docs.viaversion.com/display/VIAVERSION/
Snapshot support
--------
**ViaVersion will only be released a few days *after* a Minecraft update** unless the protocol changes of the update were trivial. If you want early-access, usually days or even weeks before the final release, you can subscribe to either:
- [GitHub Sponsors](https://github.com/sponsors/kennytv/sponsorships?sponsor=kennytv&tier_id=385613&preview=false) (preferred option. Use the `/verify` command on this Discord after), or alternatively
- [Patreon](https://www.patreon.com/kennytv/membership) (see the highest tier and make sure to link Patreon to your Discord account under Settings->Connections)
This also includes access to a private repository with the code, which will be pushed to the public repository after the given delay on a Minecraft update.
Releases/Dev Builds Releases/Dev Builds
-------- --------
You can find official releases in the following places: You can find official releases in the following places:
@ -91,8 +98,7 @@ Resources
- **[Via Mappings Generator](https://github.com/ViaVersion/Mappings)** - **[Via Mappings Generator](https://github.com/ViaVersion/Mappings)**
- **[Mojang mappings](https://minecraft.wiki/w/Obfuscation_map)** (Thank you, Mojang, very cool) - **[Mojang mappings](https://minecraft.wiki/w/Obfuscation_map)** (Thank you, Mojang, very cool)
- **[wiki.vg](https://wiki.vg)** (Used for historic information regarding packet structure, we also contribute back) - Previously: **[Burger](https://github.com/Pokechu22/Burger)** (see [PAaaS](https://github.com/Matsv/Paaas)) and **wiki.vg**
- **[Burger](https://github.com/Pokechu22/Burger)** (See [PAaaS](https://github.com/Matsv/Paaas))
License License
-------- --------

Datei anzeigen

@ -19,7 +19,9 @@ dependencies {
api(libs.vianbt) { api(libs.vianbt) {
exclude("it.unimi.dsi", "fastutil") exclude("it.unimi.dsi", "fastutil")
} }
api(libs.gson) api(libs.gson) {
exclude("com.google.errorprone", "error_prone_annotations")
}
implementation(rootProject.libs.text) { implementation(rootProject.libs.text) {
exclude("com.google.code.gson", "gson") exclude("com.google.code.gson", "gson")
exclude("com.viaversion", "nbt") exclude("com.viaversion", "nbt")

Datei anzeigen

@ -53,6 +53,14 @@ public interface FullMappings extends BiMappings {
*/ */
@Nullable String identifier(int id); @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. * Returns the mapped string identifier for the given mapped id.
* *

Datei anzeigen

@ -84,7 +84,18 @@ public class FullMappingsBase implements FullMappings {
} }
@Override @Override
public String mappedIdentifier(final int mappedId) { 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 @Nullable String mappedIdentifier(final int mappedId) {
if (mappedId < 0 || mappedId >= mappedIdToString.length) { if (mappedId < 0 || mappedId >= mappedIdToString.length) {
return null; return null;
} }

Datei anzeigen

@ -35,56 +35,82 @@ public interface MappingData {
void load(); void load();
/** /**
* Returns the mapped block state id, or -1 if unmapped. * Returns the mapped block state id, or 0 if unmapped.
* *
* @param id unmapped block state id * @param id unmapped block state id
* @return mapped block state id, or -1 if unmapped * @return mapped block state id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold block state mappings * @throws NullPointerException if this mappingdata does not hold block state mappings
*/ */
int getNewBlockStateId(int id); int getNewBlockStateId(int id);
/** /**
* Returns the mapped block id, or -1 if unmapped. * Returns the mapped block id, or 0 if unmapped.
* *
* @param id unmapped block id * @param id unmapped block id
* @return mapped block id, or -1 if unmapped * @return mapped block id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold block mappings * @throws NullPointerException if this mappingdata does not hold block mappings
*/ */
int getNewBlockId(int id); int getNewBlockId(int id);
/**
* Returns the backwards mapped block id, or 1 if unmapped.
*
* @param id mapped block id
* @return backwards mapped block id, or 1 if unmapped
*/
int getOldBlockId(int id); int getOldBlockId(int id);
/** /**
* Returns the mapped item id, or -1 if unmapped. * Returns the mapped item id, or 0 if unmapped.
* *
* @param id unmapped item id * @param id unmapped item id
* @return mapped item id, or -1 if unmapped * @return mapped item id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold item mappings * @throws NullPointerException if this mappingdata does not hold item mappings
*/ */
int getNewItemId(int id); int getNewItemId(int id);
/** /**
* Returns the backwards mapped item id, or -1 if unmapped. * Returns the backwards mapped item id, or 1 if unmapped.
* *
* @param id mapped item id * @param id mapped item id
* @return backwards mapped item id, or -1 if unmapped * @return backwards mapped item id, or 1 if unmapped
* @throws NullPointerException if this mappingdata does not hold item mappings * @throws NullPointerException if this mappingdata does not hold item mappings
*/ */
int getOldItemId(int id); int getOldItemId(int id);
/** /**
* Returns the mapped particle id, or -1 if unmapped. * Returns the mapped particle id, or 0 if unmapped.
* *
* @param id unmapped particle id * @param id unmapped particle id
* @return mapped particle id, or -1 if unmapped * @return mapped particle id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold particle mappings * @throws NullPointerException if this mappingdata does not hold particle mappings
*/ */
int getNewParticleId(int id); int getNewParticleId(int id);
/**
* Returns the mapped attribute id, or 0 if unmapped.
*
* @param id unmapped attribute id
* @return mapped attribute id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold attribute mappings
*/
int getNewAttributeId(int id); int getNewAttributeId(int id);
/**
* Returns the mapped sound id, or 0 if unmapped.
*
* @param id unmapped sound id
* @return mapped sound id, or 0 if unmapped
* @throws NullPointerException if this mappingdata does not hold sound mappings
*/
int getNewSoundId(int id); int getNewSoundId(int id);
/**
* Returns the backwards mapped sound id, or 1 if unmapped.
*
* @param i mapped sound id
* @return backwards mapped sound id, or 1 if unmapped
*/
int getOldSoundId(int i); int getOldSoundId(int i);
/** /**
@ -126,10 +152,10 @@ public interface MappingData {
@Nullable Mappings getEnchantmentMappings(); @Nullable Mappings getEnchantmentMappings();
@Nullable Mappings getAttributeMappings();
@Nullable Mappings getPaintingMappings(); @Nullable Mappings getPaintingMappings();
@Nullable FullMappings getAttributeMappings();
@Nullable FullMappings getEntityMappings(); @Nullable FullMappings getEntityMappings();
@Nullable FullMappings getArgumentTypeMappings(); @Nullable FullMappings getArgumentTypeMappings();

Datei anzeigen

@ -43,10 +43,10 @@ public class MappingDataBase implements MappingData {
protected FullMappings entityMappings; protected FullMappings entityMappings;
protected FullMappings recipeSerializerMappings; protected FullMappings recipeSerializerMappings;
protected FullMappings itemDataSerializerMappings; protected FullMappings itemDataSerializerMappings;
protected FullMappings attributeMappings;
protected ParticleMappings particleMappings; protected ParticleMappings particleMappings;
protected BiMappings itemMappings; protected BiMappings itemMappings;
protected BiMappings blockMappings; protected BiMappings blockMappings;
protected BiMappings attributeMappings;
protected Mappings blockStateMappings; protected Mappings blockStateMappings;
protected Mappings blockEntityMappings; protected Mappings blockEntityMappings;
protected Mappings soundMappings; protected Mappings soundMappings;
@ -76,8 +76,6 @@ public class MappingDataBase implements MappingData {
menuMappings = loadMappings(data, "menus"); menuMappings = loadMappings(data, "menus");
enchantmentMappings = loadMappings(data, "enchantments"); enchantmentMappings = loadMappings(data, "enchantments");
paintingMappings = loadMappings(data, "paintings"); paintingMappings = loadMappings(data, "paintings");
attributeMappings = loadBiMappings(data, "attributes");
final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt"); final CompoundTag unmappedIdentifierData = readUnmappedIdentifiersFile("identifiers-" + unmappedVersion + ".nbt");
final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt"); final CompoundTag mappedIdentifierData = readMappedIdentifiersFile("identifiers-" + mappedVersion + ".nbt");
@ -87,6 +85,7 @@ public class MappingDataBase implements MappingData {
argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes"); argumentTypeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "argumenttypes");
recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers"); recipeSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "recipe_serializers");
itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type"); itemDataSerializerMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "data_component_type");
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles"); final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles"); final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
@ -180,7 +179,7 @@ public class MappingDataBase implements MappingData {
@Override @Override
public int getOldBlockId(final int id) { public int getOldBlockId(final int id) {
return blockMappings.getNewIdOrDefault(id, 1); return blockMappings.inverse().getNewIdOrDefault(id, 1);
} }
@Override @Override
@ -272,7 +271,7 @@ public class MappingDataBase implements MappingData {
} }
@Override @Override
public @Nullable Mappings getAttributeMappings() { public @Nullable FullMappings getAttributeMappings() {
return attributeMappings; return attributeMappings;
} }

Datei anzeigen

@ -36,6 +36,7 @@ public class ParticleMappings extends FullMappingsBase {
addBlockParticle("falling_dust"); addBlockParticle("falling_dust");
addBlockParticle("block_marker"); addBlockParticle("block_marker");
addBlockParticle("dust_pillar"); addBlockParticle("dust_pillar");
addBlockParticle("block_crumble");
addItemParticle("item"); addItemParticle("item");
} }

Datei anzeigen

@ -78,7 +78,7 @@ public interface DebugHandler {
/** /**
* Returns whether packets should be logged after being transformed. * 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 * @return whether packets should be logged after being transformed
*/ */

Datei anzeigen

@ -37,6 +37,13 @@ public class BlockPosition {
return new BlockPosition(x + face.modX(), y + face.modY(), z + face.modZ()); return new BlockPosition(x + face.modX(), y + face.modY(), z + face.modZ());
} }
public double distanceFromCenterSquared(final double x, final double y, final double z) {
final double dx = this.x + 0.5 - x;
final double dy = this.y + 0.5 - y;
final double dz = this.z + 0.5 - z;
return dx * dx + dy * dy + dz * dz;
}
public int x() { public int x() {
return x; return x;
} }

Datei anzeigen

@ -66,6 +66,17 @@ public final class ChunkPosition {
return (long) chunkX & 0xffffffffL | ((long) chunkZ & 0xffffffffL) << 32; return (long) chunkX & 0xffffffffL | ((long) chunkZ & 0xffffffffL) << 32;
} }
/**
* Returns a long key for the given block coordinates.
*
* @param x the block X coordinate
* @param z the block Z coordinate
* @return the chunk key
*/
public static long chunkKeyForBlock(final int x, final int z) {
return chunkKey(x >> 4, z >> 4);
}
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) return true; if (this == o) return true;

Datei anzeigen

@ -35,7 +35,7 @@ public interface Holder<T> {
* @throws IllegalArgumentException if the id is negative * @throws IllegalArgumentException if the id is negative
*/ */
static <T> Holder<T> of(final int id) { 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 * @return a new direct holder
*/ */
static <T> Holder<T> of(final T value) { static <T> Holder<T> of(final T value) {
return new HolderImpl<>(value); return new ValueHolder<>(value);
} }
/** /**

Datei anzeigen

@ -36,7 +36,7 @@ public interface HolderSet {
* @return a new holder set * @return a new holder set
*/ */
static HolderSet of(final String tagKey) { 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 * @return a new holder set
*/ */
static HolderSet of(final int[] ids) { static HolderSet of(final int[] ids) {
return new HolderSetImpl(ids); return new HolderSetImpl.Ids(ids);
} }
/** /**

Datei anzeigen

@ -22,50 +22,63 @@
*/ */
package com.viaversion.viaversion.api.minecraft; package com.viaversion.viaversion.api.minecraft;
import com.viaversion.viaversion.util.EitherImpl;
import it.unimi.dsi.fastutil.ints.Int2IntFunction; 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);
}
HolderSetImpl(final int[] ids) {
super(null, ids);
}
@Override
public String tagKey() {
return left();
}
record Tag(String tagKey) implements HolderSet {
@Override @Override
public boolean hasTagKey() { public boolean hasTagKey() {
return isLeft(); return true;
} }
@Override @Override
public int[] ids() { public int[] ids() {
return right(); throw new IllegalArgumentException("This holder set has a tag key");
} }
@Override @Override
public boolean hasIds() { public boolean hasIds() {
return isRight(); return false;
} }
@Override @Override
public HolderSet rewrite(final Int2IntFunction idRewriter) { public HolderSet rewrite(final Int2IntFunction idRewriter) {
if (hasTagKey()) {
return this; return this;
} }
}
final int[] ids = ids(); 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]; final int[] mappedIds = new int[ids.length];
for (int i = 0; i < mappedIds.length; i++) { for (int i = 0; i < mappedIds.length; i++) {
mappedIds[i] = idRewriter.applyAsInt(ids[i]); mappedIds[i] = idRewriter.applyAsInt(ids[i]);
} }
return new HolderSetImpl(mappedIds); return new Ids(mappedIds);
}
@Override
public String toString() {
return "Ids{" +
"ids=" + Arrays.toString(ids) +
'}';
}
} }
} }

Datei anzeigen

@ -25,49 +25,29 @@ package com.viaversion.viaversion.api.minecraft;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2IntFunction; 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; IdHolder {
private final int id;
HolderImpl(final int id) {
Preconditions.checkArgument(id >= 0, "id cannot be negative"); 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 @Override
public boolean isDirect() { public boolean isDirect() {
return id == -1; return false;
} }
@Override @Override
public boolean hasId() { public boolean hasId() {
return id != -1; return true;
} }
@Override @Override
public T value() { public T value() {
Preconditions.checkArgument(isDirect(), "Holder is not direct"); throw new IllegalArgumentException("Holder is not direct");
return value;
}
@Override
public int id() {
return id;
} }
@Override @Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) { public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
if (isDirect()) {
return this;
}
final int rewrittenId = rewriteFunction.applyAsInt(id); final int rewrittenId = rewriteFunction.applyAsInt(id);
if (rewrittenId == id) { if (rewrittenId == id) {
return this; return this;
@ -77,12 +57,4 @@ final class HolderImpl<T> implements Holder<T> {
} }
return Holder.of(rewrittenId); return Holder.of(rewrittenId);
} }
@Override
public String toString() {
return "HolderImpl{" +
"value=" + value +
", id=" + id +
'}';
}
} }

Datei anzeigen

@ -22,13 +22,19 @@
*/ */
package com.viaversion.viaversion.api.minecraft; package com.viaversion.viaversion.api.minecraft;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType; import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record PaintingVariant(int width, int height, String assetId) { public record PaintingVariant(int width, int height, String assetId, @Nullable Tag title, @Nullable Tag author) {
public static HolderType<PaintingVariant> TYPE = new HolderType<>() { public PaintingVariant(final int width, final int height, final String assetId) {
this(width, height, assetId, null, null);
}
public static HolderType<PaintingVariant> TYPE1_21 = new HolderType<>() {
@Override @Override
public PaintingVariant readDirect(final ByteBuf buffer) { public PaintingVariant readDirect(final ByteBuf buffer) {
final int width = Types.VAR_INT.readPrimitive(buffer); final int width = Types.VAR_INT.readPrimitive(buffer);
@ -44,4 +50,24 @@ public record PaintingVariant(int width, int height, String assetId) {
Types.STRING.write(buffer, variant.assetId()); Types.STRING.write(buffer, variant.assetId());
} }
}; };
public static HolderType<PaintingVariant> TYPE1_21_2 = new HolderType<>() {
@Override
public PaintingVariant readDirect(final ByteBuf buffer) {
final int width = Types.VAR_INT.readPrimitive(buffer);
final int height = Types.VAR_INT.readPrimitive(buffer);
final String assetId = Types.STRING.read(buffer);
final Tag title = Types.OPTIONAL_TAG.read(buffer);
final Tag author = Types.OPTIONAL_TAG.read(buffer);
return new PaintingVariant(width, height, assetId, title, author);
}
@Override
public void writeDirect(final ByteBuf buffer, final PaintingVariant variant) {
Types.VAR_INT.writePrimitive(buffer, variant.width());
Types.VAR_INT.writePrimitive(buffer, variant.height());
Types.STRING.write(buffer, variant.assetId());
Types.OPTIONAL_TAG.write(buffer, variant.title());
Types.OPTIONAL_TAG.write(buffer, variant.author());
}
};
} }

Datei anzeigen

@ -36,4 +36,8 @@ public record RegistryEntry(String key, @Nullable Tag tag) {
public RegistryEntry withKey(final String key) { public RegistryEntry withKey(final String key) {
return new RegistryEntry(key, tag != null ? tag.copy() : null); return new RegistryEntry(key, tag != null ? tag.copy() : null);
} }
public RegistryEntry copy() {
return new RegistryEntry(key, tag != null ? tag.copy() : null);
}
} }

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -37,14 +37,14 @@ public class ChunkSectionImpl implements ChunkSection {
public ChunkSectionImpl(final boolean holdsLight) { public ChunkSectionImpl(final boolean holdsLight) {
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE)); addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
if (holdsLight) { if (holdsLight) {
this.light = new ChunkSectionLightImpl(); this.light = ChunkSectionLightImpl.createWithBlockLight();
} }
} }
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) { public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength)); addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
if (holdsLight) { if (holdsLight) {
this.light = new ChunkSectionLightImpl(); this.light = ChunkSectionLightImpl.createWithBlockLight();
} }
} }

Datei anzeigen

@ -35,7 +35,7 @@ public interface ChunkSectionLight {
/** /**
* Returns whether the section has sky light. * Returns whether the section has sky light.
* *
* @return true if skylight is present * @return true if sky light is present
*/ */
boolean hasSkyLight(); boolean hasSkyLight();
@ -43,7 +43,7 @@ public interface ChunkSectionLight {
* Returns whether the section has block light. * Returns whether the section has block light.
* This returns true unless specifically set to null. * This returns true unless specifically set to null.
* *
* @return true if skylight is present * @return true if block light is present
*/ */
boolean hasBlockLight(); boolean hasBlockLight();

Datei anzeigen

@ -30,9 +30,17 @@ public class ChunkSectionLightImpl implements ChunkSectionLight {
private NibbleArray blockLight; private NibbleArray blockLight;
private NibbleArray skyLight; private NibbleArray skyLight;
public ChunkSectionLightImpl() { protected ChunkSectionLightImpl() {
// Block light is always written }
this.blockLight = new NibbleArray(ChunkSection.SIZE);
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 @Override

Datei anzeigen

@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag; import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.GameProfile; import com.viaversion.viaversion.api.minecraft.GameProfile;
import com.viaversion.viaversion.api.minecraft.Holder; 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.Item;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate; import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim; import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
@ -34,13 +35,20 @@ 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.BannerPatternLayer;
import com.viaversion.viaversion.api.minecraft.item.data.Bee; 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.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.CustomModelData1_21_4;
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.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; 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.FilterableString;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion; 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.Fireworks;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties; import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument; 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.JukeboxPlayable;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker; 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.PotDecorations;
@ -48,11 +56,15 @@ 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.SuspiciousStewEffect;
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties; 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.Unbreakable;
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook; import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5; 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;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.api.type.types.version.Types1_21_4;
import com.viaversion.viaversion.util.Unit; import com.viaversion.viaversion.util.Unit;
public record StructuredDataKey<T>(String identifier, Type<T> type) { public record StructuredDataKey<T>(String identifier, Type<T> type) {
@ -64,24 +76,38 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Unbreakable> UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.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> 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<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", Types.TAG_ARRAY); public static final StructuredDataKey<String> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.STRING);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TAG, 256));
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT); public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE); public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE);
public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON = new StructuredDataKey<>("can_place_on", AdventureModePredicate.TYPE); public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON = new StructuredDataKey<>("can_place_on", AdventureModePredicate.TYPE);
public static final StructuredDataKey<AdventureModePredicate> CAN_BREAK = new StructuredDataKey<>("can_break", AdventureModePredicate.TYPE); public static final StructuredDataKey<AdventureModePredicate> CAN_BREAK = new StructuredDataKey<>("can_break", AdventureModePredicate.TYPE);
public static final StructuredDataKey<AttributeModifiers1_20_5> ATTRIBUTE_MODIFIERS1_20_5 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_20_5.TYPE); public static final StructuredDataKey<AttributeModifiers1_20_5> ATTRIBUTE_MODIFIERS1_20_5 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_20_5.TYPE);
public static final StructuredDataKey<AttributeModifiers1_21> ATTRIBUTE_MODIFIERS1_21 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_21.TYPE); public static final StructuredDataKey<AttributeModifiers1_21> ATTRIBUTE_MODIFIERS1_21 = new StructuredDataKey<>("attribute_modifiers", AttributeModifiers1_21.TYPE);
public static final StructuredDataKey<Integer> CUSTOM_MODEL_DATA = new StructuredDataKey<>("custom_model_data", Types.VAR_INT); public static final StructuredDataKey<Integer> CUSTOM_MODEL_DATA1_20_5 = new StructuredDataKey<>("custom_model_data", Types.VAR_INT);
public static final StructuredDataKey<CustomModelData1_21_4> CUSTOM_MODEL_DATA1_21_4 = new StructuredDataKey<>("custom_model_data", CustomModelData1_21_4.TYPE);
public static final StructuredDataKey<Unit> HIDE_ADDITIONAL_TOOLTIP = new StructuredDataKey<>("hide_additional_tooltip", Types.EMPTY); public static final StructuredDataKey<Unit> HIDE_ADDITIONAL_TOOLTIP = new StructuredDataKey<>("hide_additional_tooltip", Types.EMPTY);
public static final StructuredDataKey<Unit> HIDE_TOOLTIP = new StructuredDataKey<>("hide_tooltip", Types.EMPTY); public static final StructuredDataKey<Unit> HIDE_TOOLTIP = new StructuredDataKey<>("hide_tooltip", Types.EMPTY);
public static final StructuredDataKey<Integer> REPAIR_COST = new StructuredDataKey<>("repair_cost", Types.VAR_INT); public static final StructuredDataKey<Integer> REPAIR_COST = new StructuredDataKey<>("repair_cost", Types.VAR_INT);
public static final StructuredDataKey<Unit> CREATIVE_SLOT_LOCK = new StructuredDataKey<>("creative_slot_lock", Types.EMPTY); 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<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<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<FoodProperties1_20_5> FOOD1_20_5 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_20_5);
public static final StructuredDataKey<FoodProperties> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties.TYPE1_21); 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_REMAINDER1_21_2 = new StructuredDataKey<>("use_remainder", Types1_21_2.ITEM);
public static final StructuredDataKey<Item> USE_REMAINDER1_21_4 = new StructuredDataKey<>("use_remainder", Types1_21_4.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<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<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<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<DyedColor> DYED_COLOR = new StructuredDataKey<>("dyed_color", DyedColor.TYPE);
public static final StructuredDataKey<Integer> MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT); public static final StructuredDataKey<Integer> MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT);
@ -90,18 +116,26 @@ 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<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_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 = 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[]> CHARGED_PROJECTILES1_21_4 = new StructuredDataKey<>("charged_projectiles", Types1_21_4.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_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<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<Item[]> BUNDLE_CONTENTS1_21_4 = new StructuredDataKey<>("bundle_contents", Types1_21_4.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<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<FilterableString[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", FilterableString.ARRAY_TYPE);
public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE); public static final StructuredDataKey<WrittenBook> WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE);
public static final StructuredDataKey<ArmorTrim> TRIM = new StructuredDataKey<>("trim", ArmorTrim.TYPE); public static final StructuredDataKey<ArmorTrim> TRIM1_20_5 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_20_5);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_2 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_2);
public static final StructuredDataKey<ArmorTrim> TRIM1_21_4 = new StructuredDataKey<>("trim", ArmorTrim.TYPE1_21_4);
public static final StructuredDataKey<CompoundTag> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Types.COMPOUND_TAG); public static final StructuredDataKey<CompoundTag> DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG); 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> 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<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<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<JukeboxPlayable> JUKEBOX_PLAYABLE = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE);
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG); public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG);
@ -115,6 +149,8 @@ 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<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_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 = new StructuredDataKey<>("container", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CONTAINER1_21_2 = new StructuredDataKey<>("container", new ArrayType<>(Types1_21_2.ITEM, 256));
public static final StructuredDataKey<Item[]> CONTAINER1_21_4 = new StructuredDataKey<>("container", Types1_21_4.ITEM_ARRAY);
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE); 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<Bee[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG); public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);

Datei anzeigen

@ -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(CREAKING),
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);
}
}

Datei anzeigen

@ -0,0 +1,313 @@
/*
* 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_4 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),
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_4(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_4(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);
}
}

Datei anzeigen

@ -26,10 +26,11 @@ import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.Particle; import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.WolfVariant; import com.viaversion.viaversion.api.minecraft.WolfVariant;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType; 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;
import com.viaversion.viaversion.api.type.types.ArrayType; import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.misc.ParticleType; 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 { 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 stringType = add(4, Types.STRING);
public final EntityDataType componentType = add(5, Types.TAG); public final EntityDataType componentType = add(5, Types.TAG);
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_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 booleanType = add(8, Types.BOOLEAN);
public final EntityDataType rotationsType = add(9, Types.ROTATIONS); public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14); public final EntityDataType blockPositionType = add(10, Types.BLOCK_POSITION1_14);
@ -59,14 +60,15 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE); public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE);
public final EntityDataType frogVariantType = add(24, Types.VAR_INT); public final EntityDataType frogVariantType = add(24, Types.VAR_INT);
public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION); public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION);
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE); public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE1_21);
public final EntityDataType snifferState = add(27, Types.VAR_INT); public final EntityDataType snifferState = add(27, Types.VAR_INT);
public final EntityDataType armadilloState = add(28, Types.VAR_INT); public final EntityDataType armadilloState = add(28, Types.VAR_INT);
public final EntityDataType vector3FType = add(29, Types.VECTOR3F); public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
public final EntityDataType quaternionType = add(30, Types.QUATERNION); 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); super(31);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType); this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType); this.particlesType = add(18, particlesType);
} }

Datei anzeigen

@ -0,0 +1,74 @@
/*
* 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.entitydata.types;
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.misc.ParticleType;
public final class EntityDataTypes1_21_2 extends AbstractEntityDataTypes {
public final EntityDataType byteType = add(0, Types.BYTE);
public final EntityDataType varIntType = add(1, Types.VAR_INT);
public final EntityDataType longType = add(2, Types.VAR_LONG);
public final EntityDataType floatType = add(3, Types.FLOAT);
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;
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);
public final EntityDataType optionalBlockPositionType = add(11, Types.OPTIONAL_POSITION_1_14);
public final EntityDataType directionType = add(12, Types.VAR_INT);
public final EntityDataType optionalUUIDType = add(13, Types.OPTIONAL_UUID);
public final EntityDataType blockStateType = add(14, Types.VAR_INT);
public final EntityDataType optionalBlockStateType = add(15, Types.VAR_INT);
public final EntityDataType compoundTagType = add(16, Types.COMPOUND_TAG);
public final EntityDataType particleType;
public final EntityDataType particlesType;
public final EntityDataType villagerDatatType = add(19, Types.VILLAGER_DATA);
public final EntityDataType optionalVarIntType = add(20, Types.OPTIONAL_VAR_INT);
public final EntityDataType poseType = add(21, Types.VAR_INT);
public final EntityDataType catVariantType = add(22, Types.VAR_INT);
public final EntityDataType wolfVariantType = add(23, WolfVariant.TYPE);
public final EntityDataType frogVariantType = add(24, Types.VAR_INT);
public final EntityDataType optionalGlobalPosition = add(25, Types.OPTIONAL_GLOBAL_POSITION);
public final EntityDataType paintingVariantType = add(26, PaintingVariant.TYPE1_21_2);
public final EntityDataType snifferState = add(27, Types.VAR_INT);
public final EntityDataType armadilloState = add(28, Types.VAR_INT);
public final EntityDataType vector3FType = add(29, Types.VECTOR3F);
public final EntityDataType quaternionType = add(30, Types.QUATERNION);
public EntityDataTypes1_21_2(final Type<Item> itemType, final ParticleType particleType, final Type<Particle[]> particlesType) {
super(31);
this.itemType = add(7, itemType);
this.particleType = add(17, particleType);
this.particlesType = add(18, particlesType);
}
}

Datei anzeigen

@ -29,10 +29,10 @@ import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern, boolean showInTooltip) { public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPattern> pattern, boolean showInTooltip) {
public static final Type<ArmorTrim> TYPE = new Type<>(ArmorTrim.class) { public static final Type<ArmorTrim> TYPE1_20_5 = new Type<>(ArmorTrim.class) {
@Override @Override
public ArmorTrim read(final ByteBuf buffer) { public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE.read(buffer); final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_20_5.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer); final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer);
final boolean showInTooltip = buffer.readBoolean(); final boolean showInTooltip = buffer.readBoolean();
return new ArmorTrim(material, pattern, showInTooltip); return new ArmorTrim(material, pattern, showInTooltip);
@ -40,7 +40,39 @@ public record ArmorTrim(Holder<ArmorTrimMaterial> material, Holder<ArmorTrimPatt
@Override @Override
public void write(final ByteBuf buffer, final ArmorTrim value) { public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE.write(buffer, value.material); ArmorTrimMaterial.TYPE1_20_5.write(buffer, value.material);
ArmorTrimPattern.TYPE.write(buffer, value.pattern);
buffer.writeBoolean(value.showInTooltip);
}
};
public static final Type<ArmorTrim> TYPE1_21_2 = new Type<>(ArmorTrim.class) {
@Override
public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_2.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer);
final boolean showInTooltip = buffer.readBoolean();
return new ArmorTrim(material, pattern, showInTooltip);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE1_21_2.write(buffer, value.material);
ArmorTrimPattern.TYPE.write(buffer, value.pattern);
buffer.writeBoolean(value.showInTooltip);
}
};
public static final Type<ArmorTrim> TYPE1_21_4 = new Type<>(ArmorTrim.class) {
@Override
public ArmorTrim read(final ByteBuf buffer) {
final Holder<ArmorTrimMaterial> material = ArmorTrimMaterial.TYPE1_21_4.read(buffer);
final Holder<ArmorTrimPattern> pattern = ArmorTrimPattern.TYPE.read(buffer);
final boolean showInTooltip = buffer.readBoolean();
return new ArmorTrim(material, pattern, showInTooltip);
}
@Override
public void write(final ByteBuf buffer, final ArmorTrim value) {
ArmorTrimMaterial.TYPE1_21_4.write(buffer, value.material);
ArmorTrimPattern.TYPE.write(buffer, value.pattern); ArmorTrimPattern.TYPE.write(buffer, value.pattern);
buffer.writeBoolean(value.showInTooltip); buffer.writeBoolean(value.showInTooltip);
} }

Datei anzeigen

@ -27,13 +27,19 @@ import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType; import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction; import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import java.util.Map;
public record ArmorTrimMaterial(String assetName, int itemId, float itemModelIndex, public record ArmorTrimMaterial(String assetName, int itemId, float itemModelIndex,
Int2ObjectMap<String> overrideArmorMaterials, Tag description) { Map<String, String> overrideArmorMaterials, Tag description) {
public static final HolderType<ArmorTrimMaterial> TYPE = new HolderType<>() { public ArmorTrimMaterial(final String assetName, final int itemId, final Map<String, String> overrideArmorMaterials, final Tag description) {
this(assetName, itemId, 0F, overrideArmorMaterials, description);
}
public static final HolderType<ArmorTrimMaterial> TYPE1_20_5 = new HolderType<>() {
// The override key is an int, but given we don't use it at all and that creating a new type is annoying,
// we'll just store it in the string map:tm:
@Override @Override
public ArmorTrimMaterial readDirect(final ByteBuf buffer) { public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer); final String assetName = Types.STRING.read(buffer);
@ -41,10 +47,45 @@ public record ArmorTrimMaterial(String assetName, int itemId, float itemModelInd
final float itemModelIndex = buffer.readFloat(); final float itemModelIndex = buffer.readFloat();
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer); final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Int2ObjectMap<String> overrideArmorMaterials = new Int2ObjectOpenHashMap<>(overrideArmorMaterialsSize); final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>(overrideArmorMaterialsSize);
for (int i = 0; i < overrideArmorMaterialsSize; i++) { for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final int key = Types.VAR_INT.readPrimitive(buffer); final int key = Types.VAR_INT.readPrimitive(buffer);
final String value = Types.STRING.read(buffer); final String value = Types.STRING.read(buffer);
overrideArmorMaterials.put(Integer.toString(key), value);
}
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial(assetName, item, itemModelIndex, overrideArmorMaterials, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
Types.STRING.write(buffer, value.assetName());
Types.VAR_INT.writePrimitive(buffer, value.itemId());
buffer.writeFloat(value.itemModelIndex());
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
for (final Map.Entry<String, String> entry : value.overrideArmorMaterials().entrySet()) {
Types.VAR_INT.writePrimitive(buffer, Integer.parseInt(entry.getKey()));
Types.STRING.write(buffer, entry.getValue());
}
Types.TAG.write(buffer, value.description());
}
};
public static final HolderType<ArmorTrimMaterial> TYPE1_21_2 = new HolderType<>() {
@Override
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer);
final int item = Types.VAR_INT.readPrimitive(buffer);
final float itemModelIndex = buffer.readFloat();
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>(overrideArmorMaterialsSize);
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final String key = Types.STRING.read(buffer);
final String value = Types.STRING.read(buffer);
overrideArmorMaterials.put(key, value); overrideArmorMaterials.put(key, value);
} }
@ -59,8 +100,41 @@ public record ArmorTrimMaterial(String assetName, int itemId, float itemModelInd
buffer.writeFloat(value.itemModelIndex()); buffer.writeFloat(value.itemModelIndex());
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size()); Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
for (final Int2ObjectMap.Entry<String> entry : value.overrideArmorMaterials().int2ObjectEntrySet()) { for (final Map.Entry<String, String> entry : value.overrideArmorMaterials().entrySet()) {
Types.VAR_INT.writePrimitive(buffer, entry.getIntKey()); Types.STRING.write(buffer, entry.getKey());
Types.STRING.write(buffer, entry.getValue());
}
Types.TAG.write(buffer, value.description());
}
};
public static final HolderType<ArmorTrimMaterial> TYPE1_21_4 = new HolderType<>() {
@Override
public ArmorTrimMaterial readDirect(final ByteBuf buffer) {
final String assetName = Types.STRING.read(buffer);
final int item = Types.VAR_INT.readPrimitive(buffer);
final int overrideArmorMaterialsSize = Types.VAR_INT.readPrimitive(buffer);
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>(overrideArmorMaterialsSize);
for (int i = 0; i < overrideArmorMaterialsSize; i++) {
final String key = Types.STRING.read(buffer);
final String value = Types.STRING.read(buffer);
overrideArmorMaterials.put(key, value);
}
final Tag description = Types.TAG.read(buffer);
return new ArmorTrimMaterial(assetName, item, overrideArmorMaterials, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) {
Types.STRING.write(buffer, value.assetName());
Types.VAR_INT.writePrimitive(buffer, value.itemId());
Types.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size());
for (final Map.Entry<String, String> entry : value.overrideArmorMaterials().entrySet()) {
Types.STRING.write(buffer, entry.getKey());
Types.STRING.write(buffer, entry.getValue()); Types.STRING.write(buffer, entry.getValue());
} }

Datei anzeigen

@ -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);
}
};
}
}

Datei anzeigen

@ -0,0 +1,49 @@
/*
* 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 CustomModelData1_21_4(float[] floats, boolean[] booleans, String[] strings, int[] colors) {
public static final Type<CustomModelData1_21_4> TYPE = new Type<>(CustomModelData1_21_4.class) {
@Override
public CustomModelData1_21_4 read(final ByteBuf buffer) {
final float[] floats = Types.FLOAT_ARRAY_PRIMITIVE.read(buffer);
final boolean[] booleans = Types.BOOLEAN_ARRAY_PRIMITIVE.read(buffer);
final String[] strings = Types.STRING_ARRAY.read(buffer);
final int[] colors = Types.INT_ARRAY_PRIMITIVE.read(buffer);
return new CustomModelData1_21_4(floats, booleans, strings, colors);
}
@Override
public void write(final ByteBuf buffer, final CustomModelData1_21_4 value) {
Types.FLOAT_ARRAY_PRIMITIVE.write(buffer, value.floats());
Types.BOOLEAN_ARRAY_PRIMITIVE.write(buffer, value.booleans());
Types.STRING_ARRAY.write(buffer, value.strings());
Types.INT_ARRAY_PRIMITIVE.write(buffer, value.colors());
}
};
}

Datei anzeigen

@ -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());
}
};
}

Datei anzeigen

@ -22,26 +22,23 @@
*/ */
package com.viaversion.viaversion.api.minecraft.item.data; 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.Type;
import com.viaversion.viaversion.api.type.types.ArrayType; import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf; 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 @Override
public FoodEffect read(final ByteBuf buffer) { public DeathProtection read(final ByteBuf buffer) {
final PotionEffect effect = PotionEffect.TYPE.read(buffer); final ConsumeEffect<?>[] deathEffects = ConsumeEffect.ARRAY_TYPE.read(buffer);
final float probability = buffer.readFloat(); return new DeathProtection(deathEffects);
return new FoodEffect(effect, probability);
} }
@Override @Override
public void write(final ByteBuf buffer, final FoodEffect value) { public void write(final ByteBuf buffer, final DeathProtection value) {
PotionEffect.TYPE.write(buffer, value.effect); ConsumeEffect.ARRAY_TYPE.write(buffer, value.deathEffects);
buffer.writeFloat(value.probability);
} }
}; };
public static final Type<FoodEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
} }

Datei anzeigen

@ -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.OPTIONAL_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.OPTIONAL_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);
}
}

Datei anzeigen

@ -25,25 +25,27 @@ package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types; 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 com.viaversion.viaversion.api.type.types.version.Types1_21;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record FoodProperties(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds, public record FoodProperties1_20_5(int nutrition, float saturationModifier, boolean canAlwaysEat, float eatSeconds,
Item usingConvertsTo, FoodEffect[] possibleEffects) { @Nullable 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 @Override
public FoodProperties read(final ByteBuf buffer) { public FoodProperties1_20_5 read(final ByteBuf buffer) {
final int nutrition = Types.VAR_INT.readPrimitive(buffer); final int nutrition = Types.VAR_INT.readPrimitive(buffer);
final float saturationModifier = buffer.readFloat(); final float saturationModifier = buffer.readFloat();
final boolean canAlwaysEat = buffer.readBoolean(); final boolean canAlwaysEat = buffer.readBoolean();
final float eatSeconds = buffer.readFloat(); final float eatSeconds = buffer.readFloat();
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.read(buffer); 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 @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); Types.VAR_INT.writePrimitive(buffer, value.nutrition);
buffer.writeFloat(value.saturationModifier); buffer.writeFloat(value.saturationModifier);
buffer.writeBoolean(value.canAlwaysEat); buffer.writeBoolean(value.canAlwaysEat);
@ -51,20 +53,20 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects); 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 @Override
public FoodProperties read(final ByteBuf buffer) { public FoodProperties1_20_5 read(final ByteBuf buffer) {
final int nutrition = Types.VAR_INT.readPrimitive(buffer); final int nutrition = Types.VAR_INT.readPrimitive(buffer);
final float saturationModifier = buffer.readFloat(); final float saturationModifier = buffer.readFloat();
final boolean canAlwaysEat = buffer.readBoolean(); final boolean canAlwaysEat = buffer.readBoolean();
final float eatSeconds = buffer.readFloat(); final float eatSeconds = buffer.readFloat();
final Item usingConvertsTo = Types1_21.OPTIONAL_ITEM.read(buffer); final Item usingConvertsTo = Types1_21.OPTIONAL_ITEM.read(buffer);
final FoodEffect[] possibleEffects = FoodEffect.ARRAY_TYPE.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 @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); Types.VAR_INT.writePrimitive(buffer, value.nutrition);
buffer.writeFloat(value.saturationModifier); buffer.writeFloat(value.saturationModifier);
buffer.writeBoolean(value.canAlwaysEat); buffer.writeBoolean(value.canAlwaysEat);
@ -73,4 +75,23 @@ public record FoodProperties(int nutrition, float saturationModifier, boolean ca
FoodEffect.ARRAY_TYPE.write(buffer, value.possibleEffects); 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);
}
} }

Datei anzeigen

@ -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);
}
};
}

Datei anzeigen

@ -29,27 +29,27 @@ import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction; 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 @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 Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final int useDuration = Types.VAR_INT.readPrimitive(buffer); final int useDuration = Types.VAR_INT.readPrimitive(buffer);
final float range = buffer.readFloat(); final float range = Types.FLOAT.readPrimitive(buffer);
return new Instrument(soundEvent, useDuration, range); return new Instrument1_20_5(soundEvent, useDuration, range);
} }
@Override @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.SOUND_EVENT.write(buffer, value.soundEvent());
Types.VAR_INT.writePrimitive(buffer, value.useDuration()); 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); 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);
} }
} }

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -27,15 +27,20 @@ import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable; 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 @Override
public PotionContents read(final ByteBuf buffer) { public PotionContents read(final ByteBuf buffer) {
final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null; final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null;
final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null; final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null;
final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer); final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer);
return new PotionContents(potion, customColor, customEffects); return new PotionContents(potion, customColor, customEffects, null);
} }
@Override @Override
@ -53,4 +58,31 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects); 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);
}
};
} }

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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 @Override
public final void loadMappingData() { public final void loadMappingData() {
getMappingData().load(); getMappingData().load();

Datei anzeigen

@ -36,6 +36,7 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.rewriter.ComponentRewriter; import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.rewriter.EntityRewriter; import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter; import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.rewriter.ParticleRewriter;
import com.viaversion.viaversion.api.rewriter.TagRewriter; import com.viaversion.viaversion.api.rewriter.TagRewriter;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException; import com.viaversion.viaversion.exception.CancelException;
@ -374,6 +375,15 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
return null; return null;
} }
/**
* Returns the protocol's particle rewriter if present.
*
* @return particle rewriter
*/
default @Nullable ParticleRewriter getParticleRewriter() {
return null;
}
/** /**
* Returns the protocol's tag rewriter if present. * Returns the protocol's tag rewriter if present.
* *

Datei anzeigen

@ -43,7 +43,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>(); 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)); 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_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_8 = register(47, "1.8.x", new SubVersionRange("1.8", 0, 9));
public static final ProtocolVersion v1_9 = register(107, "1.9"); public static final ProtocolVersion v1_9 = register(107, "1.9");
@ -85,8 +86,14 @@ 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_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_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 = 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 v1_21_4 = register(769, "1.21.4");
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null); 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) { public static ProtocolVersion register(int version, String name) {
return register(version, -1, name); return register(version, -1, name);
} }
@ -150,7 +157,11 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
return 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) { public static @NonNull ProtocolVersion getProtocol(final int version) {
@ -201,6 +212,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
private final int snapshotVersion; private final int snapshotVersion;
private final String name; private final String name;
private final Set<String> includedVersions; private final Set<String> includedVersions;
@Deprecated // Remove when getProtocol is made nullable
private boolean known = true;
/** /**
* Constructs a new ProtocolVersion instance. * Constructs a new ProtocolVersion instance.
@ -285,12 +298,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() { public boolean isKnown() {
return version != -1; return known;
} }
/** /**

Datei anzeigen

@ -58,6 +58,14 @@ public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter
*/ */
int newEntityId(int id); int newEntityId(int id);
/**
* Returns the mapped entity (or the same if it has not changed).
*
* @param identifier unmapped entity identifier
* @return mapped entity identifier
*/
String mappedEntityIdentifier(String identifier);
/** /**
* Handles and transforms entity data of an entity. * Handles and transforms entity data of an entity.
* *

Datei anzeigen

@ -0,0 +1,27 @@
/*
* 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.api.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
public interface ParticleRewriter {
void rewriteParticle(UserConnection connection, Particle particle);
}

Datei anzeigen

@ -45,12 +45,14 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.ChunkPosition; import com.viaversion.viaversion.api.minecraft.ChunkPosition;
import com.viaversion.viaversion.api.type.types.ArrayType; import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.BitSetType; import com.viaversion.viaversion.api.type.types.BitSetType;
import com.viaversion.viaversion.api.type.types.BooleanArrayType;
import com.viaversion.viaversion.api.type.types.BooleanType; import com.viaversion.viaversion.api.type.types.BooleanType;
import com.viaversion.viaversion.api.type.types.ByteArrayType; import com.viaversion.viaversion.api.type.types.ByteArrayType;
import com.viaversion.viaversion.api.type.types.ByteType; import com.viaversion.viaversion.api.type.types.ByteType;
import com.viaversion.viaversion.api.type.types.ComponentType; import com.viaversion.viaversion.api.type.types.ComponentType;
import com.viaversion.viaversion.api.type.types.DoubleType; import com.viaversion.viaversion.api.type.types.DoubleType;
import com.viaversion.viaversion.api.type.types.EmptyType; import com.viaversion.viaversion.api.type.types.EmptyType;
import com.viaversion.viaversion.api.type.types.FloatArrayType;
import com.viaversion.viaversion.api.type.types.FloatType; import com.viaversion.viaversion.api.type.types.FloatType;
import com.viaversion.viaversion.api.type.types.IntArrayType; import com.viaversion.viaversion.api.type.types.IntArrayType;
import com.viaversion.viaversion.api.type.types.IntType; import com.viaversion.viaversion.api.type.types.IntType;
@ -115,14 +117,17 @@ public final class Types {
public static final Type<byte[]> OPTIONAL_BYTE_ARRAY_PRIMITIVE = new ByteArrayType.OptionalByteArrayType(); public static final Type<byte[]> OPTIONAL_BYTE_ARRAY_PRIMITIVE = new ByteArrayType.OptionalByteArrayType();
public static final Type<byte[]> SHORT_BYTE_ARRAY = new ShortByteArrayType(); public static final Type<byte[]> SHORT_BYTE_ARRAY = new ShortByteArrayType();
public static final Type<byte[]> REMAINING_BYTES = new RemainingBytesType(); public static final Type<byte[]> REMAINING_BYTES = new RemainingBytesType();
public static final Type<int[]> INT_ARRAY_PRIMITIVE = new IntArrayType();
public static final ShortType SHORT = new ShortType(); public static final ShortType SHORT = new ShortType();
public static final UnsignedShortType UNSIGNED_SHORT = new UnsignedShortType(); public static final UnsignedShortType UNSIGNED_SHORT = new UnsignedShortType();
public static final IntType INT = new IntType(); public static final IntType INT = new IntType();
public static final Type<int[]> INT_ARRAY_PRIMITIVE = new IntArrayType();
public static final FloatType FLOAT = new FloatType(); public static final FloatType FLOAT = new FloatType();
public static final FloatType.OptionalFloatType OPTIONAL_FLOAT = new FloatType.OptionalFloatType(); public static final FloatType.OptionalFloatType OPTIONAL_FLOAT = new FloatType.OptionalFloatType();
public static final Type<float[]> FLOAT_ARRAY_PRIMITIVE = new FloatArrayType();
public static final DoubleType DOUBLE = new DoubleType(); public static final DoubleType DOUBLE = new DoubleType();
public static final LongType LONG = new LongType(); public static final LongType LONG = new LongType();
@ -130,6 +135,7 @@ public final class Types {
public static final BooleanType BOOLEAN = new BooleanType(); public static final BooleanType BOOLEAN = new BooleanType();
public static final BooleanType.OptionalBooleanType OPTIONAL_BOOLEAN = new BooleanType.OptionalBooleanType(); public static final BooleanType.OptionalBooleanType OPTIONAL_BOOLEAN = new BooleanType.OptionalBooleanType();
public static final Type<boolean[]> BOOLEAN_ARRAY_PRIMITIVE = new BooleanArrayType();
/* Other Types */ /* Other Types */
public static final Type<JsonElement> COMPONENT = new ComponentType(); public static final Type<JsonElement> COMPONENT = new ComponentType();
@ -149,6 +155,8 @@ public final class Types {
public static final VarLongType VAR_LONG = new VarLongType(); public static final VarLongType VAR_LONG = new VarLongType();
/* MC Types */ /* MC Types */
public static final Type<byte[]> SERVERBOUND_CUSTOM_PAYLOAD_DATA = new RemainingBytesType(Short.MAX_VALUE);
public static final Type<BlockPosition> BLOCK_POSITION1_8 = new BlockPositionType1_8(); public static final Type<BlockPosition> BLOCK_POSITION1_8 = new BlockPositionType1_8();
public static final Type<BlockPosition> OPTIONAL_POSITION1_8 = new BlockPositionType1_8.OptionalBlockPositionType(); public static final Type<BlockPosition> OPTIONAL_POSITION1_8 = new BlockPositionType1_8.OptionalBlockPositionType();
public static final Type<BlockPosition> BLOCK_POSITION1_14 = new BlockPositionType1_14(); public static final Type<BlockPosition> BLOCK_POSITION1_14 = new BlockPositionType1_14();
@ -189,7 +197,10 @@ public final class Types {
public static final Type<PlayerMessageSignature> OPTIONAL_PLAYER_MESSAGE_SIGNATURE = new PlayerMessageSignatureType.OptionalPlayerMessageSignatureType(); 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 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 BitSetType PROFILE_ACTIONS_ENUM1_21_4 = new BitSetType(8);
public static final ByteArrayType SIGNATURE_BYTES = new ByteArrayType(256); public static final ByteArrayType SIGNATURE_BYTES = new ByteArrayType(256);
public static final BitSetType ACKNOWLEDGED_BIT_SET = new BitSetType(20); public static final BitSetType ACKNOWLEDGED_BIT_SET = new BitSetType(20);
public static final ByteArrayType.OptionalByteArrayType OPTIONAL_SIGNATURE_BYTES = new ByteArrayType.OptionalByteArrayType(256); public static final ByteArrayType.OptionalByteArrayType OPTIONAL_SIGNATURE_BYTES = new ByteArrayType.OptionalByteArrayType(256);

Datei anzeigen

@ -26,13 +26,22 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class ArrayType<T> extends Type<T[]> { public class ArrayType<T> extends Type<T[]> {
private final Type<T> elementType; private final Type<T> elementType;
private final int maxLength;
public ArrayType(Type<T> type) { public ArrayType(Type<T> type) {
this(type, -1);
}
public ArrayType(Type<T> type, int maxLength) {
//noinspection unchecked
super(type.getTypeName() + " Array", (Class<T[]>) getArrayClass(type.getOutputClass())); super(type.getTypeName() + " Array", (Class<T[]>) getArrayClass(type.getOutputClass()));
this.elementType = type; this.elementType = type;
this.maxLength = maxLength;
} }
public static Class<?> getArrayClass(Class<?> componentType) { public static Class<?> getArrayClass(Class<?> componentType) {
@ -43,16 +52,40 @@ public class ArrayType<T> extends Type<T[]> {
@Override @Override
public T[] read(ByteBuf buffer) { public T[] read(ByteBuf buffer) {
int amount = Types.VAR_INT.readPrimitive(buffer); int amount = Types.VAR_INT.readPrimitive(buffer);
T[] array = (T[]) Array.newInstance(elementType.getOutputClass(), amount); if (maxLength != -1 && amount > maxLength) {
throw new IllegalArgumentException("Array length " + amount + " is longer than maximum " + maxLength);
}
for (int i = 0; i < amount; i++) { return amount < Short.MAX_VALUE ? readArray(buffer, amount) : readList(buffer, amount);
}
private T[] readArray(ByteBuf buffer, int length) {
T[] array = createArray(length);
for (int i = 0; i < length; i++) {
array[i] = elementType.read(buffer); array[i] = elementType.read(buffer);
} }
return array; return array;
} }
private T[] readList(ByteBuf buffer, int length) {
List<T> list = new ArrayList<>();
for (int i = 0; i < length; i++) {
list.add(elementType.read(buffer));
}
return list.toArray(createArray(0));
}
private T[] createArray(int length) {
//noinspection unchecked
return (T[]) Array.newInstance(elementType.getOutputClass(), length);
}
@Override @Override
public void write(ByteBuf buffer, T[] object) { public void write(ByteBuf buffer, T[] object) {
if (maxLength != -1 && object.length > maxLength) {
throw new IllegalArgumentException("Array length " + object.length + " is longer than maximum " + maxLength);
}
Types.VAR_INT.writePrimitive(buffer, object.length); Types.VAR_INT.writePrimitive(buffer, object.length);
for (T o : object) { for (T o : object) {
elementType.write(buffer, o); elementType.write(buffer, o);

Datei anzeigen

@ -0,0 +1,67 @@
/*
* 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;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
// Ok...
public class BooleanArrayType extends Type<boolean[]> {
private final int length;
public BooleanArrayType(final int length) {
super(boolean[].class);
this.length = length;
}
public BooleanArrayType() {
super(boolean[].class);
this.length = -1;
}
@Override
public void write(final ByteBuf buffer, final boolean[] object) {
if (this.length != -1) {
Preconditions.checkArgument(length == object.length, "Length does not match expected length");
} else {
Types.VAR_INT.writePrimitive(buffer, object.length);
}
for (final boolean b : object) {
buffer.writeBoolean(b);
}
}
@Override
public boolean[] read(final ByteBuf buffer) {
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
final boolean[] array = new boolean[length];
for (int i = 0; i < length; i++) {
array[i] = buffer.readBoolean();
}
return array;
}
}

Datei anzeigen

@ -0,0 +1,66 @@
/*
* 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;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public class FloatArrayType extends Type<float[]> {
private final int length;
public FloatArrayType(final int length) {
super(float[].class);
this.length = length;
}
public FloatArrayType() {
super(float[].class);
this.length = -1;
}
@Override
public void write(final ByteBuf buffer, final float[] object) {
if (this.length != -1) {
Preconditions.checkArgument(length == object.length, "Length does not match expected length");
} else {
Types.VAR_INT.writePrimitive(buffer, object.length);
}
for (final float f : object) {
buffer.writeFloat(f);
}
}
@Override
public float[] read(final ByteBuf buffer) {
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
final float[] array = new float[length];
for (int i = 0; i < length; i++) {
array[i] = buffer.readFloat();
}
return array;
}
}

Datei anzeigen

@ -36,11 +36,19 @@ public class IntType extends Type<Integer> implements TypeConverter<Integer> {
return buffer.readInt(); return buffer.readInt();
} }
public int readPrimitive(ByteBuf buffer) {
return buffer.readInt();
}
@Override @Override
public void write(ByteBuf buffer, Integer object) { public void write(ByteBuf buffer, Integer object) {
buffer.writeInt(object); buffer.writeInt(object);
} }
public void writePrimitive(ByteBuf buffer, int object) {
buffer.writeInt(object);
}
@Override @Override
public Integer from(Object o) { public Integer from(Object o) {
if (o instanceof Number number) { if (o instanceof Number number) {

Datei anzeigen

@ -26,19 +26,35 @@ import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
public class RemainingBytesType extends Type<byte[]> { public class RemainingBytesType extends Type<byte[]> {
private final int maxLength;
public RemainingBytesType() { public RemainingBytesType() {
this(-1);
}
public RemainingBytesType(final int maxLength) {
super(byte[].class); super(byte[].class);
this.maxLength = maxLength;
} }
@Override @Override
public byte[] read(ByteBuf buffer) { public byte[] read(final ByteBuf buffer) {
byte[] array = new byte[buffer.readableBytes()]; final int bytes = buffer.readableBytes();
if (maxLength != -1 && bytes > maxLength) {
throw new RuntimeException("Remaining bytes cannot be longer than " + maxLength + " (got " + bytes + ")");
}
final byte[] array = new byte[bytes];
buffer.readBytes(array); buffer.readBytes(array);
return array; return array;
} }
@Override @Override
public void write(ByteBuf buffer, byte[] object) { public void write(final ByteBuf buffer, final byte[] object) {
if (maxLength != -1 && object.length > maxLength) {
throw new RuntimeException("Remaining bytes cannot be longer than " + maxLength + " (got " + object.length + ")");
}
buffer.writeBytes(object); buffer.writeBytes(object);
} }
} }

Datei anzeigen

@ -32,6 +32,15 @@ public class VarIntType extends Type<Integer> implements TypeConverter<Integer>
private static final int VALUE_BITS = 0x7F; private static final int VALUE_BITS = 0x7F;
private static final int MULTI_BYTE_BITS = ~VALUE_BITS; private static final int MULTI_BYTE_BITS = ~VALUE_BITS;
private static final int MAX_BYTES = 5; private static final int MAX_BYTES = 5;
private static final int[] VAR_INT_LENGTHS = new int[65];
static {
// Copied from Velocity https://github.com/PaperMC/Velocity/blob/08a42b3723633ea5eb6b96c0bb42180f3c2b07eb/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java#L166
for (int i = 0; i <= 32; ++i) {
VAR_INT_LENGTHS[i] = (int) Math.ceil((31d - (i - 1)) / 7d);
}
VAR_INT_LENGTHS[32] = 1; // Special case for the number 0.
}
public VarIntType() { public VarIntType() {
super("VarInt", Integer.class); super("VarInt", Integer.class);
@ -88,4 +97,8 @@ public class VarIntType extends Type<Integer> implements TypeConverter<Integer>
} }
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public static int varIntLength(final int value) {
return VAR_INT_LENGTHS[Integer.numberOfLeadingZeros(value)];
}
} }

Datei anzeigen

@ -22,6 +22,7 @@
*/ */
package com.viaversion.viaversion.api.type.types.chunk; package com.viaversion.viaversion.api.type.types.chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
@ -54,4 +55,14 @@ public final class ChunkSectionType1_18 extends Type<ChunkSection> {
blockPaletteType.write(buffer, section.palette(PaletteType.BLOCKS)); blockPaletteType.write(buffer, section.palette(PaletteType.BLOCKS));
biomePaletteType.write(buffer, section.palette(PaletteType.BIOMES)); biomePaletteType.write(buffer, section.palette(PaletteType.BIOMES));
} }
public int serializedSize(final Chunk chunk) {
int length = 0;
for (final ChunkSection section : chunk.getSections()) {
length += Short.BYTES
+ blockPaletteType.serializedSize(section.palette(PaletteType.BLOCKS))
+ biomePaletteType.serializedSize(section.palette(PaletteType.BIOMES));
}
return length;
}
} }

Datei anzeigen

@ -52,15 +52,11 @@ public final class ChunkType1_18 extends Type<Chunk> {
final CompoundTag heightMap = Types.NAMED_COMPOUND_TAG.read(buffer); final CompoundTag heightMap = Types.NAMED_COMPOUND_TAG.read(buffer);
// Read sections // Read sections
final ByteBuf sectionsBuf = buffer.readBytes(Types.VAR_INT.readPrimitive(buffer)); final ByteBuf sectionsBuf = buffer.readSlice(Types.VAR_INT.readPrimitive(buffer));
final ChunkSection[] sections = new ChunkSection[ySectionCount]; final ChunkSection[] sections = new ChunkSection[ySectionCount];
try {
for (int i = 0; i < ySectionCount; i++) { for (int i = 0; i < ySectionCount; i++) {
sections[i] = sectionType.read(sectionsBuf); sections[i] = sectionType.read(sectionsBuf);
} }
} finally {
sectionsBuf.release();
}
final int blockEntitiesLength = Types.VAR_INT.readPrimitive(buffer); final int blockEntitiesLength = Types.VAR_INT.readPrimitive(buffer);
final List<BlockEntity> blockEntities = new ArrayList<>(blockEntitiesLength); final List<BlockEntity> blockEntities = new ArrayList<>(blockEntitiesLength);
@ -78,16 +74,9 @@ public final class ChunkType1_18 extends Type<Chunk> {
Types.NAMED_COMPOUND_TAG.write(buffer, chunk.getHeightMap()); Types.NAMED_COMPOUND_TAG.write(buffer, chunk.getHeightMap());
final ByteBuf sectionBuffer = buffer.alloc().buffer(); Types.VAR_INT.writePrimitive(buffer, sectionType.serializedSize(chunk));
try {
for (final ChunkSection section : chunk.getSections()) { for (final ChunkSection section : chunk.getSections()) {
sectionType.write(sectionBuffer, section); sectionType.write(buffer, section);
}
sectionBuffer.readerIndex(0);
Types.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
buffer.writeBytes(sectionBuffer);
} finally {
sectionBuffer.release(); // release buffer
} }
Types.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size()); Types.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size());

Datei anzeigen

@ -52,15 +52,11 @@ public final class ChunkType1_20_2 extends Type<Chunk> {
final CompoundTag heightMap = Types.COMPOUND_TAG.read(buffer); final CompoundTag heightMap = Types.COMPOUND_TAG.read(buffer);
// Read sections // Read sections
final ByteBuf sectionsBuf = buffer.readBytes(Types.VAR_INT.readPrimitive(buffer)); final ByteBuf sectionsBuf = buffer.readSlice(Types.VAR_INT.readPrimitive(buffer));
final ChunkSection[] sections = new ChunkSection[ySectionCount]; final ChunkSection[] sections = new ChunkSection[ySectionCount];
try {
for (int i = 0; i < ySectionCount; i++) { for (int i = 0; i < ySectionCount; i++) {
sections[i] = sectionType.read(sectionsBuf); sections[i] = sectionType.read(sectionsBuf);
} }
} finally {
sectionsBuf.release();
}
final int blockEntitiesLength = Types.VAR_INT.readPrimitive(buffer); final int blockEntitiesLength = Types.VAR_INT.readPrimitive(buffer);
final List<BlockEntity> blockEntities = new ArrayList<>(blockEntitiesLength); final List<BlockEntity> blockEntities = new ArrayList<>(blockEntitiesLength);
@ -78,16 +74,9 @@ public final class ChunkType1_20_2 extends Type<Chunk> {
Types.COMPOUND_TAG.write(buffer, chunk.getHeightMap()); Types.COMPOUND_TAG.write(buffer, chunk.getHeightMap());
final ByteBuf sectionBuffer = buffer.alloc().buffer(); Types.VAR_INT.writePrimitive(buffer, sectionType.serializedSize(chunk));
try {
for (final ChunkSection section : chunk.getSections()) { for (final ChunkSection section : chunk.getSections()) {
sectionType.write(sectionBuffer, section); sectionType.write(buffer, section);
}
sectionBuffer.readerIndex(0);
Types.VAR_INT.writePrimitive(buffer, sectionBuffer.readableBytes());
buffer.writeBytes(sectionBuffer);
} finally {
sectionBuffer.release(); // release buffer
} }
Types.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size()); Types.VAR_INT.writePrimitive(buffer, chunk.blockEntities().size());

Datei anzeigen

@ -27,6 +27,7 @@ import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.VarIntType;
import com.viaversion.viaversion.util.CompactArrayUtil; import com.viaversion.viaversion.util.CompactArrayUtil;
import com.viaversion.viaversion.util.MathUtil; import com.viaversion.viaversion.util.MathUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@ -94,13 +95,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
return; return;
} }
// 1, 2, and 3 bit linear block palettes can't be read by the client final int bitsPerValue = bitsPerValue(size);
final int min = type == PaletteType.BLOCKS ? 4 : 1;
int bitsPerValue = Math.max(min, MathUtil.ceilLog2(size));
if (bitsPerValue > type.highestBitsPerValue()) {
bitsPerValue = globalPaletteBits;
}
buffer.writeByte(bitsPerValue); buffer.writeByte(bitsPerValue);
if (bitsPerValue != globalPaletteBits) { if (bitsPerValue != globalPaletteBits) {
@ -113,4 +108,39 @@ public final class PaletteType1_18 extends Type<DataPalette> {
Types.LONG_ARRAY_PRIMITIVE.write(buffer, CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt)); Types.LONG_ARRAY_PRIMITIVE.write(buffer, CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt));
} }
private int bitsPerValue(final int size) {
// 1, 2, and 3 bit linear block palettes can't be read by the client
final int min = type == PaletteType.BLOCKS ? 4 : 1;
int bitsPerValue = Math.max(min, MathUtil.ceilLog2(size));
if (bitsPerValue > type.highestBitsPerValue()) {
bitsPerValue = globalPaletteBits;
}
return bitsPerValue;
}
public int serializedSize(final DataPalette palette) {
// This is a bit of extra work, but worth it to avoid otherwise having to allocate and write to an extra buffer.
// On top of saving memory, it provides small but measurable speedup compared to writing to a separate buffer and then back
final int size = palette.size();
final int bitsPerValue = bitsPerValue(size);
int serializedTypesSize = 0;
int serializedValuesSize = 1; // At least one byte for 0 length
if (size == 1) {
serializedTypesSize = VarIntType.varIntLength(palette.idByIndex(0));
} else {
if (bitsPerValue != globalPaletteBits) {
serializedTypesSize = VarIntType.varIntLength(size);
for (int i = 0; i < size; i++) {
serializedTypesSize += VarIntType.varIntLength(palette.idByIndex(i));
}
}
final int valuesPerLong = 64 / bitsPerValue;
final int values = (type.size() + valuesPerLong - 1) / valuesPerLong;
serializedValuesSize = VarIntType.varIntLength(values) + (Long.BYTES * values);
}
return Byte.BYTES + serializedTypesSize + serializedValuesSize;
}
} }

Datei anzeigen

@ -63,7 +63,7 @@ public class ItemType1_20_5 extends Type<Item> {
return new Reference2ObjectOpenHashMap<>(); return new Reference2ObjectOpenHashMap<>();
} }
final Map<StructuredDataKey<?>, StructuredData<?>> map = new Reference2ObjectOpenHashMap<>(); final Map<StructuredDataKey<?>, StructuredData<?>> map = new Reference2ObjectOpenHashMap<>(Math.min(valuesSize + markersSize, 128));
for (int i = 0; i < valuesSize; i++) { for (int i = 0; i < valuesSize; i++) {
final StructuredData<?> value = dataType.read(buffer); final StructuredData<?> value = dataType.read(buffer);
final StructuredDataKey<?> key = dataType.key(value.id()); final StructuredDataKey<?> key = dataType.key(value.id());

Datei anzeigen

@ -87,5 +87,12 @@ public class StructuredDataType extends Type<StructuredData<?>> {
types[id] = key; types[id] = key;
return this; return this;
} }
public DataFiller add(final StructuredDataKey<?>... keys) {
for (final StructuredDataKey<?> key : keys) {
add(key);
}
return this;
}
} }
} }

Datei anzeigen

@ -29,7 +29,6 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@ -77,6 +76,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)); // Blue 0-1
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Scale 0.01-4 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) -> { 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)); // Red 0-1
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green 0-1 particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green 0-1
@ -86,6 +89,11 @@ public class ParticleType extends DynamicType<Particle> {
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Blue 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) -> { public static final DataReader<Particle> VIBRATION = (buf, particle) -> {
particle.add(Types.BLOCK_POSITION1_14, Types.BLOCK_POSITION1_14.read(buf)); // From block pos particle.add(Types.BLOCK_POSITION1_14, Types.BLOCK_POSITION1_14.read(buf)); // From block pos
@ -136,7 +144,22 @@ public class ParticleType extends DynamicType<Particle> {
public static final DataReader<Particle> SHRIEK = (buf, particle) -> { public static final DataReader<Particle> SHRIEK = (buf, particle) -> {
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Delay 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> TRAIL1_21_2 = (buf, particle) -> {
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target X
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target Y
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target Z
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // Color
};
public static final DataReader<Particle> TRAIL1_21_4 = (buf, particle) -> {
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target X
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target Y
particle.add(Types.DOUBLE, Types.DOUBLE.readPrimitive(buf)); // Target Z
particle.add(Types.INT, Types.INT.readPrimitive(buf)); // Color
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Duration
};
public static DataReader<Particle> item(Type<Item> item) { public static DataReader<Particle> item(Type<Item> item) {
return (buf, particle) -> particle.add(item, item.read(buf)); return (buf, particle) -> particle.add(item, item.read(buf));

Datei anzeigen

@ -50,7 +50,7 @@ public final class Types1_21 {
public static final ParticleType PARTICLE = new ParticleType(); public static final ParticleType PARTICLE = new ParticleType();
public static final ArrayType<Particle> PARTICLES = new ArrayType<>(PARTICLE); 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<EntityData> ENTITY_DATA = new EntityDataType(ENTITY_DATA_TYPES);
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA); public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
} }

Datei anzeigen

@ -0,0 +1,55 @@
/*
* 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_2;
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[]> 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 Type<Particle[]> PARTICLES = new ArrayType<>(PARTICLE);
public static final EntityDataTypes1_21_2 ENTITY_DATA_TYPES = new EntityDataTypes1_21_2(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);
}

Datei anzeigen

@ -0,0 +1,55 @@
/*
* 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_4 {
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[]> 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);
}

Datei anzeigen

@ -22,11 +22,14 @@
*/ */
package com.viaversion.viaversion.exception; package com.viaversion.viaversion.exception;
import java.util.HashMap; import com.viaversion.viaversion.api.Via;
import java.util.Map; import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public class InformativeException extends RuntimeException { public class InformativeException extends RuntimeException {
private final Map<String, Object> info = new HashMap<>(); private static final int MAX_MESSAGE_LENGTH = 5_000;
private final List<DataEntry> dataEntries = new ArrayList<>();
private boolean shouldBePrinted = true; private boolean shouldBePrinted = true;
private int sources; private int sources;
@ -34,8 +37,8 @@ public class InformativeException extends RuntimeException {
super(cause); super(cause);
} }
public InformativeException set(String key, Object value) { public InformativeException set(String key, @Nullable Object value) {
info.put(key, value); dataEntries.add(new DataEntry(key, value));
return this; return this;
} }
@ -57,15 +60,22 @@ public class InformativeException extends RuntimeException {
@Override @Override
public String getMessage() { public String getMessage() {
StringBuilder builder = new StringBuilder("Please report this on the Via support Discord or open an issue on the relevant GitHub repository\n"); final StringBuilder builder = new StringBuilder("Please report this on the Via support Discord or open an issue on the relevant GitHub repository\n");
boolean first = true; boolean first = true;
for (Map.Entry<String, Object> entry : info.entrySet()) { for (final DataEntry entry : dataEntries) {
if (!first) { if (!first) {
builder.append(", "); builder.append(", ");
} } else {
builder.append(entry.getKey()).append(": ").append(entry.getValue());
first = false; first = false;
} }
builder.append(entry.name()).append(": ");
String s = String.valueOf(entry.value());
if (!Via.getManager().isDebug() && s.length() > 10 && builder.length() + s.length() > MAX_MESSAGE_LENGTH) {
s = s.substring(0, MAX_MESSAGE_LENGTH - builder.length()) + "...";
}
builder.append(s.replaceAll("\\s", ""));
}
return builder.toString(); return builder.toString();
} }
@ -74,4 +84,7 @@ public class InformativeException extends RuntimeException {
// Don't record this stack // Don't record this stack
return this; return this;
} }
private record DataEntry(String name, @Nullable Object value) {
}
} }

Datei anzeigen

@ -0,0 +1,28 @@
/*
* 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;
public final class Limit {
public static int max(final int value, final int max) {
if (value > max) {
throw new IllegalArgumentException("Value " + value + " is higher than the maximum " + max);
}
return value;
}
}

Datei anzeigen

@ -1,7 +1,6 @@
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.jvm.toolchain.JavaLanguageVersion
import java.io.ByteArrayOutputStream
fun Project.latestCommitHash(): String { fun Project.latestCommitHash(): String {
return runGitCommand(listOf("rev-parse", "--short", "HEAD")) return runGitCommand(listOf("rev-parse", "--short", "HEAD"))
@ -16,12 +15,9 @@ fun Project.branchName(): String {
} }
fun Project.runGitCommand(args: List<String>): String { fun Project.runGitCommand(args: List<String>): String {
val byteOut = ByteArrayOutputStream() return providers.exec {
exec {
commandLine = listOf("git") + args commandLine = listOf("git") + args
standardOutput = byteOut }.standardOutput.asBytes.get().toString(Charsets.UTF_8).trim()
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
} }
fun JavaPluginExtension.javaTarget(version: Int) { fun JavaPluginExtension.javaTarget(version: Int) {

Datei anzeigen

@ -1,5 +1,6 @@
plugins { plugins {
`java-library` `java-library`
`jvm-test-suite`
} }
tasks { tasks {

Datei anzeigen

@ -16,10 +16,10 @@ val main = setOf(
projects.viaversionBukkit, projects.viaversionBukkit,
projects.viaversionVelocity, projects.viaversionVelocity,
projects.viaversionFabric projects.viaversionFabric
).map { it.dependencyProject } ).map { it.path }
subprojects { subprojects {
when (this) { when (path) {
in main -> plugins.apply("via.shadow-conventions") in main -> plugins.apply("via.shadow-conventions")
else -> plugins.apply("via.base-conventions") else -> plugins.apply("via.base-conventions")
} }

Datei anzeigen

@ -33,6 +33,7 @@ import com.viaversion.viaversion.bukkit.platform.BukkitViaInjector;
import com.viaversion.viaversion.bukkit.platform.BukkitViaLoader; import com.viaversion.viaversion.bukkit.platform.BukkitViaLoader;
import com.viaversion.viaversion.bukkit.platform.BukkitViaTask; import com.viaversion.viaversion.bukkit.platform.BukkitViaTask;
import com.viaversion.viaversion.bukkit.platform.BukkitViaTaskTask; import com.viaversion.viaversion.bukkit.platform.BukkitViaTaskTask;
import com.viaversion.viaversion.bukkit.platform.FoliaViaTask;
import com.viaversion.viaversion.bukkit.platform.PaperViaInjector; import com.viaversion.viaversion.bukkit.platform.PaperViaInjector;
import com.viaversion.viaversion.dump.PluginInfo; import com.viaversion.viaversion.dump.PluginInfo;
import com.viaversion.viaversion.unsupported.UnsupportedPlugin; import com.viaversion.viaversion.unsupported.UnsupportedPlugin;
@ -46,6 +47,7 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -55,6 +57,8 @@ import org.bukkit.plugin.java.JavaPlugin;
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> { public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
private static final boolean FOLIA = PaperViaInjector.hasClass("io.papermc.paper.threadedregions.RegionizedServer"); private static final boolean FOLIA = PaperViaInjector.hasClass("io.papermc.paper.threadedregions.RegionizedServer");
private static final Runnable DUMMY_RUNNABLE = () -> {
};
private static ViaVersionPlugin instance; private static ViaVersionPlugin instance;
private final BukkitCommandHandler commandHandler = new BukkitCommandHandler(); private final BukkitCommandHandler commandHandler = new BukkitCommandHandler();
private final BukkitViaConfig conf; private final BukkitViaConfig conf;
@ -171,11 +175,36 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
@Override @Override
public PlatformTask runSync(Runnable runnable, long delay) { public PlatformTask runSync(Runnable runnable, long delay) {
if (FOLIA) {
// Set the delayed tick to at least 1, as Folia requires this.
return new FoliaViaTask(getServer().getGlobalRegionScheduler().runDelayed(this, (e) -> runnable.run(), delay <= 0L ? 1L : delay));
}
return new BukkitViaTask(getServer().getScheduler().runTaskLater(this, runnable, delay)); return new BukkitViaTask(getServer().getScheduler().runTaskLater(this, runnable, delay));
} }
public PlatformTask<?> runSyncAt(Runnable runnable, Block block) {
if (FOLIA) {
return new FoliaViaTask(getServer().getRegionScheduler().run(this, block.getLocation(), (e) -> runnable.run()));
}
return runSync(runnable);
}
public PlatformTask<?> runSyncFor(Runnable runnable, Player player) {
if (FOLIA) {
return new FoliaViaTask(player.getScheduler().run(this, (e) -> runnable.run(), DUMMY_RUNNABLE));
}
return runSync(() -> {
if (player.isOnline()) {
runnable.run();
}
});
}
@Override @Override
public PlatformTask runRepeatingSync(Runnable runnable, long period) { public PlatformTask runRepeatingSync(Runnable runnable, long period) {
if (FOLIA) {
return new FoliaViaTask(getServer().getGlobalRegionScheduler().runAtFixedRate(this, (e) -> runnable.run(), 1, period));
}
return new BukkitViaTask(getServer().getScheduler().runTaskTimer(this, runnable, 0, period)); return new BukkitViaTask(getServer().getScheduler().runTaskTimer(this, runnable, 0, period));
} }

Datei anzeigen

@ -22,6 +22,7 @@ import com.viaversion.viaversion.bukkit.util.NMSUtil;
import com.viaversion.viaversion.exception.CancelCodecException; import com.viaversion.viaversion.exception.CancelCodecException;
import com.viaversion.viaversion.exception.CancelDecoderException; import com.viaversion.viaversion.exception.CancelDecoderException;
import com.viaversion.viaversion.exception.InformativeException; import com.viaversion.viaversion.exception.InformativeException;
import com.viaversion.viaversion.util.ByteBufUtil;
import com.viaversion.viaversion.util.PipelineUtil; import com.viaversion.viaversion.util.PipelineUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
@ -39,7 +40,7 @@ public final class BukkitDecodeHandler extends MessageToMessageDecoder<ByteBuf>
} }
@Override @Override
protected void decode(final ChannelHandlerContext ctx, final ByteBuf bytebuf, final List<Object> out) throws Exception { protected void decode(final ChannelHandlerContext ctx, final ByteBuf bytebuf, final List<Object> out) {
if (!connection.checkServerboundPacket()) { if (!connection.checkServerboundPacket()) {
throw CancelDecoderException.generate(null); throw CancelDecoderException.generate(null);
} }
@ -48,7 +49,7 @@ public final class BukkitDecodeHandler extends MessageToMessageDecoder<ByteBuf>
return; return;
} }
final ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf); final ByteBuf transformedBuf = ByteBufUtil.copy(ctx.alloc(), bytebuf);
try { try {
connection.transformIncoming(transformedBuf, CancelDecoderException::generate); connection.transformIncoming(transformedBuf, CancelDecoderException::generate);
out.add(transformedBuf.retain()); out.add(transformedBuf.retain());

Datei anzeigen

@ -22,6 +22,7 @@ import com.viaversion.viaversion.bukkit.util.NMSUtil;
import com.viaversion.viaversion.exception.CancelCodecException; import com.viaversion.viaversion.exception.CancelCodecException;
import com.viaversion.viaversion.exception.CancelEncoderException; import com.viaversion.viaversion.exception.CancelEncoderException;
import com.viaversion.viaversion.exception.InformativeException; import com.viaversion.viaversion.exception.InformativeException;
import com.viaversion.viaversion.util.ByteBufUtil;
import com.viaversion.viaversion.util.PipelineUtil; import com.viaversion.viaversion.util.PipelineUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
@ -52,7 +53,7 @@ public final class BukkitEncodeHandler extends MessageToMessageEncoder<ByteBuf>
return; return;
} }
final ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf); final ByteBuf transformedBuf = ByteBufUtil.copy(ctx.alloc(), bytebuf);
try { try {
final boolean needsCompression = !handledCompression && handleCompressionOrder(ctx, transformedBuf); final boolean needsCompression = !handledCompression && handleCompressionOrder(ctx, transformedBuf);
connection.transformClientbound(transformedBuf, CancelEncoderException::generate); connection.transformClientbound(transformedBuf, CancelEncoderException::generate);

Datei anzeigen

@ -0,0 +1,72 @@
/*
* 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.bukkit.listeners.v1_20_5to1_21;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.storage.EfficiencyAttributeStorage;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
public class LegacyChangeItemListener extends PlayerChangeItemListener {
public LegacyChangeItemListener(final ViaVersionPlugin plugin) {
super(plugin);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockDamageEvent(final BlockDamageEvent event) {
final Player player = event.getPlayer();
final ItemStack item = event.getItemInHand();
sendAttributeUpdate(player, item, Slot.HAND);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryClose(final InventoryCloseEvent event) {
if (event.getPlayer() instanceof Player player &&
(event.getInventory().getType() == InventoryType.CRAFTING ||
event.getInventory().getType() == InventoryType.PLAYER)) {
sendArmorUpdate(player);
}
}
private void sendArmorUpdate(final Player player) {
final UserConnection connection = getUserConnection(player);
final EfficiencyAttributeStorage storage = getEfficiencyStorage(connection);
if (storage == null) {
return;
}
final PlayerInventory inventory = player.getInventory();
final ItemStack helmet = inventory.getHelmet();
final ItemStack leggings = swiftSneak != null ? inventory.getLeggings() : null;
final ItemStack boots = depthStrider != null ? inventory.getBoots() : null;
storage.setEnchants(player.getEntityId(), connection, storage.activeEnchants()
.aquaAffinity(helmet != null ? helmet.getEnchantmentLevel(aquaAffinity) : 0)
.swiftSneak(leggings != null ? leggings.getEnchantmentLevel(swiftSneak) : 0)
.depthStrider(boots != null ? boots.getEnchantmentLevel(depthStrider) : 0));
}
}

Datei anzeigen

@ -18,7 +18,6 @@
package com.viaversion.viaversion.bukkit.listeners.v1_20_5to1_21; package com.viaversion.viaversion.bukkit.listeners.v1_20_5to1_21;
import com.viaversion.viaversion.ViaVersionPlugin; import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.bukkit.listeners.ViaBukkitListener; import com.viaversion.viaversion.bukkit.listeners.ViaBukkitListener;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
@ -38,11 +37,11 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class PlayerChangeItemListener extends ViaBukkitListener { public class PlayerChangeItemListener extends ViaBukkitListener {
// Use legacy function and names here to support all versions // Use legacy function and names here to support all versions
private final Enchantment efficiency = getByName("efficiency", "DIG_SPEED"); protected final Enchantment efficiency = getByName("efficiency", "DIG_SPEED");
private final Enchantment aquaAffinity = getByName("aqua_affinity", "WATER_WORKER"); protected final Enchantment aquaAffinity = getByName("aqua_affinity", "WATER_WORKER");
private final Enchantment depthStrider = getByName("depth_strider", "DEPTH_STRIDER"); protected final Enchantment depthStrider = getByName("depth_strider", "DEPTH_STRIDER");
private final Enchantment soulSpeed = getByName("soul_speed", "SOUL_SPEED"); protected final Enchantment soulSpeed = getByName("soul_speed", "SOUL_SPEED");
private final Enchantment swiftSneak = getByName("swift_sneak", "SWIFT_SNEAK"); protected final Enchantment swiftSneak = getByName("swift_sneak", "SWIFT_SNEAK");
public PlayerChangeItemListener(final ViaVersionPlugin plugin) { public PlayerChangeItemListener(final ViaVersionPlugin plugin) {
super(plugin, Protocol1_20_5To1_21.class); super(plugin, Protocol1_20_5To1_21.class);
@ -55,35 +54,26 @@ public class PlayerChangeItemListener extends ViaBukkitListener {
sendAttributeUpdate(player, item, Slot.HAND); sendAttributeUpdate(player, item, Slot.HAND);
} }
protected EfficiencyAttributeStorage getEfficiencyStorage(final UserConnection connection) {
return connection != null ? connection.get(EfficiencyAttributeStorage.class) : null;
}
void sendAttributeUpdate(final Player player, @Nullable final ItemStack item, final Slot slot) { void sendAttributeUpdate(final Player player, @Nullable final ItemStack item, final Slot slot) {
final UserConnection connection = Via.getAPI().getConnection(player.getUniqueId()); final UserConnection connection = getUserConnection(player);
if (connection == null || !isOnPipe(player)) { final EfficiencyAttributeStorage storage = getEfficiencyStorage(connection);
return; if (storage == null) return;
}
final EfficiencyAttributeStorage storage = connection.get(EfficiencyAttributeStorage.class); EfficiencyAttributeStorage.ActiveEnchants enchants = storage.activeEnchants();
if (storage == null) { enchants = switch (slot) {
return; case HAND -> enchants.efficiency(item != null ? item.getEnchantmentLevel(efficiency) : 0);
} case HELMET -> enchants.aquaAffinity(item != null ? item.getEnchantmentLevel(aquaAffinity) : 0);
case LEGGINGS -> enchants.swiftSneak(item != null && swiftSneak != null ? item.getEnchantmentLevel(swiftSneak) : 0);
final EfficiencyAttributeStorage.ActiveEnchants activeEnchants = storage.activeEnchants(); case BOOTS -> enchants.depthStrider(item != null && depthStrider != null ? item.getEnchantmentLevel(depthStrider) : 0);
int efficiencyLevel = activeEnchants.efficiency().level();
int aquaAffinityLevel = activeEnchants.aquaAffinity().level();
int soulSpeedLevel = activeEnchants.soulSpeed().level();
int swiftSneakLevel = activeEnchants.swiftSneak().level();
int depthStriderLevel = activeEnchants.depthStrider().level();
switch (slot) {
case HAND -> efficiencyLevel = item != null ? item.getEnchantmentLevel(efficiency) : 0;
case HELMET -> aquaAffinityLevel = item != null ? item.getEnchantmentLevel(aquaAffinity) : 0;
case LEGGINGS -> swiftSneakLevel = item != null && swiftSneak != null ? item.getEnchantmentLevel(swiftSneak) : 0;
case BOOTS -> {
depthStriderLevel = item != null && depthStrider != null ? item.getEnchantmentLevel(depthStrider) : 0;
// TODO This needs continuous ticking for the supporting block as a conditional effect // TODO This needs continuous ticking for the supporting block as a conditional effect
// and is even more prone to desync from high ping than the other attributes // and is even more prone to desync from high ping than the other attributes
//soulSpeedLevel = item != null && soulSpeed != null ? item.getEnchantmentLevel(soulSpeed) : 0; //soulSpeedLevel = item != null && soulSpeed != null ? item.getEnchantmentLevel(soulSpeed) : 0;
} };
} storage.setEnchants(player.getEntityId(), connection, enchants);
storage.setEnchants(player.getEntityId(), connection, efficiencyLevel, soulSpeedLevel, swiftSneakLevel, aquaAffinityLevel, depthStriderLevel);
} }
enum Slot { enum Slot {

Datei anzeigen

@ -26,23 +26,25 @@ import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.bukkit.listeners.UpdateListener; import com.viaversion.viaversion.bukkit.listeners.UpdateListener;
import com.viaversion.viaversion.bukkit.listeners.multiversion.PlayerSneakListener; import com.viaversion.viaversion.bukkit.listeners.multiversion.PlayerSneakListener;
import com.viaversion.viaversion.bukkit.listeners.v1_14_4to1_15.EntityToggleGlideListener; import com.viaversion.viaversion.bukkit.listeners.v1_14_4to1_15.EntityToggleGlideListener;
import com.viaversion.viaversion.bukkit.listeners.v1_19_3to1_19_4.ArmorToggleListener;
import com.viaversion.viaversion.bukkit.listeners.v1_18_2to1_19.BlockBreakListener; import com.viaversion.viaversion.bukkit.listeners.v1_18_2to1_19.BlockBreakListener;
import com.viaversion.viaversion.bukkit.listeners.v1_19_3to1_19_4.ArmorToggleListener;
import com.viaversion.viaversion.bukkit.listeners.v1_20_5to1_21.LegacyChangeItemListener;
import com.viaversion.viaversion.bukkit.listeners.v1_20_5to1_21.PaperPlayerChangeItemListener;
import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.ArmorListener; import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.ArmorListener;
import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.BlockListener; import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.BlockListener;
import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.DeathListener; import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.DeathListener;
import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.HandItemCache; import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.HandItemCache;
import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.PaperPatch; import com.viaversion.viaversion.bukkit.listeners.v1_8to1_9.PaperPatch;
import com.viaversion.viaversion.bukkit.listeners.v1_20_5to1_21.PaperPlayerChangeItemListener;
import com.viaversion.viaversion.bukkit.listeners.v1_20_5to1_21.PlayerChangeItemListener;
import com.viaversion.viaversion.bukkit.providers.BukkitAckSequenceProvider; import com.viaversion.viaversion.bukkit.providers.BukkitAckSequenceProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitBlockConnectionProvider; import com.viaversion.viaversion.bukkit.providers.BukkitBlockConnectionProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitInventoryQuickMoveProvider; import com.viaversion.viaversion.bukkit.providers.BukkitInventoryQuickMoveProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitPickItemProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitViaMovementTransmitter; import com.viaversion.viaversion.bukkit.providers.BukkitViaMovementTransmitter;
import com.viaversion.viaversion.protocols.v1_11_1to1_12.provider.InventoryQuickMoveProvider; import com.viaversion.viaversion.protocols.v1_11_1to1_12.provider.InventoryQuickMoveProvider;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.blockconnections.ConnectionData; import com.viaversion.viaversion.protocols.v1_12_2to1_13.blockconnections.ConnectionData;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.blockconnections.providers.BlockConnectionProvider; import com.viaversion.viaversion.protocols.v1_12_2to1_13.blockconnections.providers.BlockConnectionProvider;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.provider.AckSequenceProvider; import com.viaversion.viaversion.protocols.v1_18_2to1_19.provider.AckSequenceProvider;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.provider.PickItemProvider;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider; import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.MovementTransmitterProvider; import com.viaversion.viaversion.protocols.v1_8to1_9.provider.MovementTransmitterProvider;
import java.util.HashSet; import java.util.HashSet;
@ -184,7 +186,12 @@ public class BukkitViaLoader implements ViaPlatformLoader {
if (PaperViaInjector.hasClass("io.papermc.paper.event.player.PlayerInventorySlotChangeEvent")) { if (PaperViaInjector.hasClass("io.papermc.paper.event.player.PlayerInventorySlotChangeEvent")) {
new PaperPlayerChangeItemListener(plugin).register(); new PaperPlayerChangeItemListener(plugin).register();
} else { } else {
new PlayerChangeItemListener(plugin).register(); new LegacyChangeItemListener(plugin).register();
}
}
if (serverProtocolVersion.olderThan(ProtocolVersion.v1_21_4)) {
if (PaperViaInjector.hasMethod(Material.class, "isItem")) {
Via.getManager().getProviders().use(PickItemProvider.class, new BukkitPickItemProvider(plugin));
} }
} }
} }

Datei anzeigen

@ -0,0 +1,28 @@
/*
* 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.bukkit.platform;
import com.viaversion.viaversion.api.platform.PlatformTask;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
public record FoliaViaTask(ScheduledTask task) implements PlatformTask<ScheduledTask> {
@Override
public void cancel() {
task.cancel();
}
}

Datei anzeigen

@ -65,12 +65,7 @@ public final class PaperViaInjector {
} }
private static boolean hasServerProtocolMethod() { private static boolean hasServerProtocolMethod() {
try { return hasMethod("org.bukkit.UnsafeValues", "getProtocolVersion");
Class.forName("org.bukkit.UnsafeValues").getDeclaredMethod("getProtocolVersion");
return true;
} catch (final ClassNotFoundException | NoSuchMethodException e) {
return false;
}
} }
private static boolean hasPaperInjectionMethod() { private static boolean hasPaperInjectionMethod() {
@ -78,12 +73,7 @@ public final class PaperViaInjector {
} }
private static boolean hasIsStoppingMethod() { private static boolean hasIsStoppingMethod() {
try { return hasMethod(Bukkit.class, "isStopping");
Bukkit.class.getDeclaredMethod("isStopping");
return true;
} catch (final NoSuchMethodException e) {
return false;
}
} }
private static boolean hasPacketLimiter() { private static boolean hasPacketLimiter() {
@ -98,4 +88,22 @@ public final class PaperViaInjector {
return false; return false;
} }
} }
public static boolean hasMethod(final String className, final String method) {
try {
Class.forName(className).getDeclaredMethod(method);
return true;
} catch (final ClassNotFoundException | NoSuchMethodException e) {
return false;
}
}
public static boolean hasMethod(final Class<?> clazz, final String method, final Class<?>... params) {
try {
clazz.getDeclaredMethod(method, params);
return true;
} catch (final NoSuchMethodException e) {
return false;
}
}
} }

Datei anzeigen

@ -84,7 +84,6 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
updateTask = new BukkitInventoryUpdateTask(this, uuid); updateTask = new BukkitInventoryUpdateTask(this, uuid);
updateTasks.put(uuid, updateTask); updateTasks.put(uuid, updateTask);
} }
// http://wiki.vg/index.php?title=Protocol&oldid=13223#Click_Window
updateTask.addItem(windowId, slotId, actionId); updateTask.addItem(windowId, slotId, actionId);
if (!registered && Via.getPlatform().isPluginEnabled()) { if (!registered && Via.getPlatform().isPluginEnabled()) {
Via.getPlatform().runSync(updateTask); Via.getPlatform().runSync(updateTask);

Datei anzeigen

@ -0,0 +1,184 @@
/*
* 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.bukkit.providers;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.bukkit.platform.PaperViaInjector;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.provider.PickItemProvider;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class BukkitPickItemProvider extends PickItemProvider {
private static final boolean HAS_PLACEMENT_MATERIAL_METHOD = PaperViaInjector.hasMethod("org.bukkit.block.data.BlockData", "getPlacementMaterial");
private static final boolean HAS_SPAWN_EGG_METHOD = PaperViaInjector.hasMethod(ItemFactory.class, "getSpawnEgg", EntityType.class);
private static final double BLOCK_RANGE = 4.5 + 1;
private static final double BLOCK_RANGE_SQUARED = BLOCK_RANGE * BLOCK_RANGE;
private static final double ENTITY_RANGE = 3 + 3;
private final ViaVersionPlugin plugin;
public BukkitPickItemProvider(final ViaVersionPlugin plugin) {
this.plugin = plugin;
}
@Override
public void pickItemFromBlock(final UserConnection connection, final BlockPosition blockPosition, final boolean includeData) {
final UUID uuid = connection.getProtocolInfo().getUuid();
final Player player = plugin.getServer().getPlayer(uuid);
if (player == null) {
return;
}
plugin.runSyncFor(() -> {
final Location playerLocation = player.getLocation();
if (blockPosition.distanceFromCenterSquared(playerLocation.getX(), playerLocation.getY(), playerLocation.getZ()) > BLOCK_RANGE_SQUARED) {
return;
}
final Block block = player.getWorld().getBlockAt(blockPosition.x(), blockPosition.y(), blockPosition.z());
if (block.getType() == Material.AIR) {
return;
}
final ItemStack item = blockToItem(block, includeData && player.getGameMode() == GameMode.CREATIVE);
if (item != null) {
pickItem(player, item);
}
}, player);
}
private @Nullable ItemStack blockToItem(final Block block, final boolean includeData) {
if (HAS_PLACEMENT_MATERIAL_METHOD) {
final ItemStack item = new ItemStack(block.getBlockData().getPlacementMaterial(), 1);
if (includeData && item.getItemMeta() instanceof final BlockStateMeta blockStateMeta) {
blockStateMeta.setBlockState(block.getState());
item.setItemMeta(blockStateMeta);
}
return item;
} else if (block.getType().isItem()) {
return new ItemStack(block.getType(), 1);
}
return null;
}
@Override
public void pickItemFromEntity(final UserConnection connection, final int entityId, final boolean includeData) {
if (!HAS_SPAWN_EGG_METHOD) {
return;
}
final UUID uuid = connection.getProtocolInfo().getUuid();
final Player player = plugin.getServer().getPlayer(uuid);
if (player == null) {
return;
}
plugin.runSyncFor(() -> {
final Entity entity = player.getWorld().getNearbyEntities(player.getLocation(), ENTITY_RANGE, ENTITY_RANGE, ENTITY_RANGE).stream()
.filter(e -> e.getEntityId() == entityId)
.findAny()
.orElse(null);
if (entity == null) {
return;
}
final Material spawnEggType = Bukkit.getItemFactory().getSpawnEgg(entity.getType());
if (spawnEggType != null) {
pickItem(player, new ItemStack(spawnEggType, 1));
}
}, player);
}
private void pickItem(final Player player, final ItemStack item) {
// Find matching item
final PlayerInventory inventory = player.getInventory();
final ItemStack[] contents = inventory.getStorageContents();
int sourceSlot = -1;
for (int i = 0; i < contents.length; i++) {
final ItemStack content = contents[i];
if (content == null || !content.isSimilar(item)) {
continue;
}
sourceSlot = i;
break;
}
if (sourceSlot != -1) {
moveToHotbar(inventory, sourceSlot, contents);
} else if (player.getGameMode() == GameMode.CREATIVE) {
spawnItem(item, inventory, contents);
}
}
private void spawnItem(final ItemStack item, final PlayerInventory inventory, final ItemStack[] contents) {
final int targetSlot = findEmptyHotbarSlot(inventory, inventory.getHeldItemSlot());
inventory.setHeldItemSlot(targetSlot);
final ItemStack heldItem = inventory.getItem(targetSlot);
int emptySlot = targetSlot;
if (heldItem != null && heldItem.getType() != Material.AIR) {
// Swap to the first free slot in the inventory, else add it to the current hotbar slot
for (int i = 0; i < contents.length; i++) {
if (contents[i] == null || contents[i].getType() == Material.AIR) {
emptySlot = i;
break;
}
}
}
inventory.setItem(emptySlot, heldItem);
inventory.setItemInMainHand(item);
}
private void moveToHotbar(final PlayerInventory inventory, final int sourceSlot, final ItemStack[] contents) {
if (sourceSlot < 9) {
inventory.setHeldItemSlot(sourceSlot);
return;
}
final int heldSlot = inventory.getHeldItemSlot();
final int targetSlot = findEmptyHotbarSlot(inventory, heldSlot);
inventory.setHeldItemSlot(targetSlot);
final ItemStack heldItem = inventory.getItem(targetSlot);
inventory.setItemInMainHand(contents[sourceSlot]);
inventory.setItem(sourceSlot, heldItem);
}
private int findEmptyHotbarSlot(final PlayerInventory inventory, final int heldSlot) {
for (int i = 0; i < 9; i++) {
final ItemStack item = inventory.getItem(i);
if (item == null || item.getType() == Material.AIR) {
return i;
}
}
return heldSlot;
}
}

Datei anzeigen

@ -18,3 +18,32 @@ java {
tasks.named<Jar>("sourcesJar") { tasks.named<Jar>("sourcesJar") {
from(project(":viaversion-api").sourceSets.main.get().allSource) from(project(":viaversion-api").sourceSets.main.get().allSource)
} }
// Task to quickly test/debug code changes using https://github.com/ViaVersion/ViaProxy
// For further instructions see the ViaProxy repository README
tasks.register<JavaExec>("runViaProxy") {
dependsOn(tasks.shadowJar)
val viaProxyConfiguration = configurations.create("viaProxy")
viaProxyConfiguration.dependencies.add(dependencies.create(rootProject.libs.viaProxy.get().copy().setTransitive(false)))
mainClass.set("net.raphimc.viaproxy.ViaProxy")
classpath = viaProxyConfiguration
workingDir = file("run")
jvmArgs = listOf("-DskipUpdateCheck")
if (System.getProperty("viaproxy.gui.autoStart") != null) {
jvmArgs("-Dviaproxy.gui.autoStart")
}
doFirst {
val jarsDir = file("$workingDir/jars")
jarsDir.mkdirs()
file("$jarsDir/${project.name}.jar").writeBytes(tasks.shadowJar.get().archiveFile.get().asFile.readBytes())
}
doLast {
file("$workingDir/jars/${project.name}.jar").delete()
file("$workingDir/logs").deleteRecursively()
}
}

Datei anzeigen

@ -48,7 +48,10 @@ public abstract class ViaListener {
* @return True if on pipe * @return True if on pipe
*/ */
protected boolean isOnPipe(UUID uuid) { protected boolean isOnPipe(UUID uuid) {
UserConnection userConnection = getUserConnection(uuid); return isOnPipe(getUserConnection(uuid));
}
protected boolean isOnPipe(UserConnection userConnection) {
return userConnection != null && return userConnection != null &&
(requiredPipeline == null || userConnection.getProtocolInfo().getPipeline().contains(requiredPipeline)); (requiredPipeline == null || userConnection.getProtocolInfo().getPipeline().contains(requiredPipeline));
} }

Datei anzeigen

@ -244,9 +244,12 @@ public class ViaManagerImpl implements ViaManager {
} }
if (version < 17) { if (version < 17) {
platform.getLogger().warning("You are running an outdated Java version, please update it to at least Java 17 (your version is " + javaVersion + ")."); platform.getLogger().warning("You are running an outdated Java version, please update it to at least Java 21 (your version is " + javaVersion + ").");
platform.getLogger().warning("ViaVersion no longer officially supports this version of Java, only offering unsupported compatibility builds."); platform.getLogger().warning("ViaVersion no longer officially supports this version of Java, only offering unsupported compatibility builds.");
platform.getLogger().warning("See https://github.com/ViaVersion/ViaVersion/releases/tag/5.0.0 for more information."); platform.getLogger().warning("See https://github.com/ViaVersion/ViaVersion/releases/tag/5.0.0 for more information.");
} else if (version < 21) {
platform.getLogger().warning("Please update your Java runtime to at least Java 21 (your version is " + javaVersion + ").");
platform.getLogger().warning("At some point in the future, ViaVersion will no longer be compatible with this version of Java.");
} }
} }

Datei anzeigen

@ -30,7 +30,7 @@ public class DumpSubCmd implements ViaSubCommand {
@Override @Override
public String description() { public String description() {
return "Dump information about your server, this is helpful if you report bugs."; return "Dump information about your platform implementation, this is helpful if you report bugs.";
} }
@Override @Override

Datei anzeigen

@ -35,7 +35,7 @@ public class ReloadSubCmd implements ViaSubCommand {
@Override @Override
public boolean execute(ViaCommandSender sender, String[] args) { public boolean execute(ViaCommandSender sender, String[] args) {
Via.getManager().getConfigurationProvider().reloadConfigs(); Via.getManager().getConfigurationProvider().reloadConfigs();
sendMessage(sender, "&6Configuration successfully reloaded! Some features may need a restart."); sendMessage(sender, "&6Configuration successfully reloaded! Some config options may require a restart to take effect.");
return true; return true;
} }
} }

Datei anzeigen

@ -164,7 +164,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
handleInvalidItemCount = getBoolean("handle-invalid-item-count", false); handleInvalidItemCount = getBoolean("handle-invalid-item-count", false);
cancelBlockSounds = getBoolean("cancel-block-sounds", true); cancelBlockSounds = getBoolean("cancel-block-sounds", true);
hideScoreboardNumbers = getBoolean("hide-scoreboard-numbers", false); hideScoreboardNumbers = getBoolean("hide-scoreboard-numbers", false);
fix1_21PlacementRotation = getBoolean("fix-1_21-placement-rotation", false); fix1_21PlacementRotation = getBoolean("fix-1_21-placement-rotation", true);
} }
private BlockedProtocolVersions loadBlockedProtocolVersions() { private BlockedProtocolVersions loadBlockedProtocolVersions() {
@ -554,6 +554,6 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
@Override @Override
public boolean fix1_21PlacementRotation() { public boolean fix1_21PlacementRotation() {
return false && fix1_21PlacementRotation; // TODO Can't always set onGround to true return fix1_21PlacementRotation;
} }
} }

Datei anzeigen

@ -29,8 +29,8 @@ import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.Direction; import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketTracker; import com.viaversion.viaversion.api.protocol.packet.PacketTracker;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.VarIntType;
import com.viaversion.viaversion.exception.CancelException; import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.exception.InformativeException; import com.viaversion.viaversion.exception.InformativeException;
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl; import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
@ -55,6 +55,7 @@ import java.util.function.Function;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class UserConnectionImpl implements UserConnection { public class UserConnectionImpl implements UserConnection {
private static final int PASSTHROUGH_DATA_BYTES = Long.BYTES * 2 + 2;
private static final AtomicLong IDS = new AtomicLong(); private static final AtomicLong IDS = new AtomicLong();
private final long id = IDS.incrementAndGet(); private final long id = IDS.incrementAndGet();
private final Map<Class<?>, StorableObject> storedObjects = new ConcurrentHashMap<>(); private final Map<Class<?>, StorableObject> storedObjects = new ConcurrentHashMap<>();
@ -244,7 +245,8 @@ public class UserConnectionImpl implements UserConnection {
} }
private void sendRawPacketToServerServerSide(final ByteBuf packet, final boolean currentThread) { private void sendRawPacketToServerServerSide(final ByteBuf packet, final boolean currentThread) {
final ByteBuf buf = packet.alloc().buffer(); final int initialCapacity = active ? packet.readableBytes() + PASSTHROUGH_DATA_BYTES : packet.readableBytes();
final ByteBuf buf = packet.alloc().buffer(initialCapacity);
try { try {
// We'll use passing through because there are some encoder wrappers // We'll use passing through because there are some encoder wrappers
ChannelHandlerContext context = PipelineUtil ChannelHandlerContext context = PipelineUtil
@ -333,7 +335,7 @@ public class UserConnectionImpl implements UserConnection {
return; return;
} }
int id = Types.VAR_INT.readPrimitive(buf); final int id = Types.VAR_INT.readPrimitive(buf);
if (id == PacketWrapper.PASSTHROUGH_ID) { if (id == PacketWrapper.PASSTHROUGH_ID) {
if (!passthroughTokens.remove(Types.UUID.read(buf))) { if (!passthroughTokens.remove(Types.UUID.read(buf))) {
throw new IllegalArgumentException("Invalid token"); throw new IllegalArgumentException("Invalid token");
@ -341,20 +343,47 @@ public class UserConnectionImpl implements UserConnection {
return; return;
} }
PacketWrapper wrapper = new PacketWrapperImpl(id, buf, this); final int valuesReaderIndex = buf.readerIndex();
State state = protocolInfo.getState(direction); final PacketWrapperImpl wrapper = new PacketWrapperImpl(id, buf, this);
try { try {
protocolInfo.getPipeline().transform(direction, state, wrapper); protocolInfo.getPipeline().transform(direction, protocolInfo.getState(direction), wrapper);
} catch (CancelException ex) { } catch (final CancelException ex) {
throw cancelSupplier.apply(ex); throw cancelSupplier.apply(ex);
} }
ByteBuf transformed = buf.alloc().buffer(); writeToBuffer(wrapper, buf, id, valuesReaderIndex);
}
private void writeToBuffer(final PacketWrapperImpl wrapper, final ByteBuf buf, final int originalId, final int originalReaderIndex) {
final int remainingBytes = buf.readableBytes();
if (buf.readerIndex() == originalReaderIndex && wrapper.areStoredPacketValuesEmpty()) {
if (wrapper.getId() == originalId) {
// No changes needed; just set the reader and writer indexes and we're done
buf.setIndex(0, originalReaderIndex + remainingBytes);
return;
}
if (VarIntType.varIntLength(wrapper.getId()) == VarIntType.varIntLength(originalId)) {
// If the var int encoded length is the same, simply replace the id at the head
buf.setIndex(0, 0);
Types.VAR_INT.writePrimitive(buf, wrapper.getId());
buf.writerIndex(originalReaderIndex + remainingBytes);
return;
}
}
// Instead of allocating a possible unnecessarily large buffer to write the wrapper contents to,
// only allocate the remaining bytes and write the rest to the original buf's head directly.
final ByteBuf remainingBuf = buf.alloc().buffer(remainingBytes, remainingBytes);
try { try {
wrapper.writeToBuffer(transformed); // Copy before modifying the buffer
buf.clear().writeBytes(transformed); remainingBuf.writeBytes(buf, remainingBytes);
// Reset indexes, write wrapper contents, then the unread bytes
buf.setIndex(0, 0);
wrapper.writeProcessedValues(buf);
buf.writeBytes(remainingBuf);
} finally { } finally {
transformed.release(); remainingBuf.release();
} }
} }

Datei anzeigen

@ -76,6 +76,8 @@ 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_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_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_20to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.Protocol1_21_2To1_21_4;
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_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_1to1_9_3.Protocol1_9_1To1_9_3;
import com.viaversion.viaversion.protocols.v1_9_3to1_10.Protocol1_9_3To1_10; import com.viaversion.viaversion.protocols.v1_9_3to1_10.Protocol1_9_3To1_10;
@ -192,6 +194,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_20_3); 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_20_5To1_21(), ProtocolVersion.v1_21, ProtocolVersion.v1_20_5);
registerProtocol(new Protocol1_21To1_21_2(), ProtocolVersion.v1_21_2, ProtocolVersion.v1_21);
registerProtocol(new Protocol1_21_2To1_21_4(), ProtocolVersion.v1_21_4, ProtocolVersion.v1_21_2);
} }
@Override @Override

Datei anzeigen

@ -222,6 +222,18 @@ public class PacketWrapperImpl implements PacketWrapper {
@Override @Override
public void writeToBuffer(ByteBuf buffer) throws InformativeException { public void writeToBuffer(ByteBuf buffer) throws InformativeException {
writeProcessedValues(buffer);
if (inputBuffer != null) {
buffer.writeBytes(inputBuffer);
}
}
public boolean areStoredPacketValuesEmpty() {
// Check for read/added packet values, not the input buffer
return packetValues.isEmpty() && readableObjects.isEmpty();
}
public void writeProcessedValues(ByteBuf buffer) throws InformativeException {
if (id != -1) { if (id != -1) {
Types.VAR_INT.writePrimitive(buffer, id); Types.VAR_INT.writePrimitive(buffer, id);
} }
@ -238,16 +250,15 @@ public class PacketWrapperImpl implements PacketWrapper {
throw createInformativeException(e, packetValue.type(), i); throw createInformativeException(e, packetValue.type(), i);
} }
} }
writeRemaining(buffer);
} }
private InformativeException createInformativeException(final Exception cause, final Type<?> type, final int index) { private InformativeException createInformativeException(final Exception cause, final Type<?> type, final int index) {
return new InformativeException(cause) return new InformativeException(cause)
.set("Packet Type", this.packetType)
.set("Index", index) .set("Index", index)
.set("Type", type.getTypeName()) .set("Type", type.getTypeName())
.set("Packet ID", this.id) .set("Data", this.packetValues)
.set("Packet Type", this.packetType) .set("Packet ID", this.id);
.set("Data", this.packetValues);
} }
@Override @Override
@ -264,12 +275,6 @@ public class PacketWrapperImpl implements PacketWrapper {
packetValues.clear(); packetValues.clear();
} }
private void writeRemaining(ByteBuf output) {
if (inputBuffer != null) {
output.writeBytes(inputBuffer);
}
}
@Override @Override
public void send(Class<? extends Protocol> protocol, boolean skipCurrentPipeline) throws InformativeException { public void send(Class<? extends Protocol> protocol, boolean skipCurrentPipeline) throws InformativeException {
send0(protocol, skipCurrentPipeline, true); send0(protocol, skipCurrentPipeline, true);
@ -320,7 +325,7 @@ public class PacketWrapperImpl implements PacketWrapper {
final ProtocolInfo protocolInfo = user().getProtocolInfo(); final ProtocolInfo protocolInfo = user().getProtocolInfo();
final List<Protocol> protocols = protocolInfo.getPipeline().pipes(protocolClass, skipCurrentPipeline, direction); final List<Protocol> protocols = protocolInfo.getPipeline().pipes(protocolClass, skipCurrentPipeline, direction);
apply(direction, protocolInfo.getState(direction), protocols); apply(direction, protocolInfo.getState(direction), protocols);
final ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer(); final ByteBuf output = allocateOutputBuffer();
try { try {
writeToBuffer(output); writeToBuffer(output);
return output.retain(); return output.retain();
@ -354,7 +359,7 @@ public class PacketWrapperImpl implements PacketWrapper {
return cancelledFuture(); return cancelledFuture();
} }
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer(); ByteBuf output = allocateOutputBuffer();
try { try {
writeToBuffer(output); writeToBuffer(output);
return user().sendRawPacketFuture(output.retain()); return user().sendRawPacketFuture(output.retain());
@ -373,7 +378,7 @@ public class PacketWrapperImpl implements PacketWrapper {
return; return;
} }
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer(); ByteBuf output = allocateOutputBuffer();
try { try {
writeToBuffer(output); writeToBuffer(output);
if (currentThread) { if (currentThread) {
@ -386,6 +391,14 @@ public class PacketWrapperImpl implements PacketWrapper {
} }
} }
private ByteBuf allocateOutputBuffer() {
if (inputBuffer == null) {
return user().getChannel().alloc().buffer();
}
// May have already been partially or fully read
return inputBuffer.alloc().buffer(Math.max(inputBuffer.readableBytes(), 256));
}
private ChannelFuture cancelledFuture() { private ChannelFuture cancelledFuture() {
return user().getChannel().newFailedFuture(new RuntimeException("Tried to send cancelled packet")); return user().getChannel().newFailedFuture(new RuntimeException("Tried to send cancelled packet"));
} }
@ -454,7 +467,7 @@ public class PacketWrapperImpl implements PacketWrapper {
return; return;
} }
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer(); ByteBuf output = allocateOutputBuffer();
try { try {
writeToBuffer(output); writeToBuffer(output);
if (currentThread) { if (currentThread) {

Datei anzeigen

@ -23,11 +23,14 @@ import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
public enum ClientboundLoginPackets implements BaseClientboundPacket { public enum ClientboundLoginPackets implements BaseClientboundPacket {
LOGIN_DISCONNECT, // 0x00 LOGIN_DISCONNECT, // 0x00
HELLO, // 0x01 HELLO, // 0x01
GAME_PROFILE, // 0x02 LOGIN_FINISHED, // 0x02
LOGIN_COMPRESSION, // 0x03 LOGIN_COMPRESSION, // 0x03
CUSTOM_QUERY, // 0x04 CUSTOM_QUERY, // 0x04
COOKIE_REQUEST; // 0x05 COOKIE_REQUEST; // 0x05
@Deprecated(forRemoval = true)
public static final ClientboundLoginPackets GAME_PROFILE = LOGIN_FINISHED;
@Override @Override
public final int getId() { public final int getId() {
return ordinal(); return ordinal();

Datei anzeigen

@ -128,7 +128,7 @@ public class ClientboundBaseProtocol1_7 extends AbstractProtocol<BaseClientbound
}); });
// Track player name/uuid and setup connection + track state // 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(); final ProtocolInfo info = wrapper.user().getProtocolInfo();
if (info.serverProtocolVersion().olderThan(ProtocolVersion.v1_16)) { if (info.serverProtocolVersion().olderThan(ProtocolVersion.v1_16)) {

Datei anzeigen

@ -18,27 +18,26 @@
package com.viaversion.viaversion.protocols.template; package com.viaversion.viaversion.protocols.template;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; 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_4;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPacket1_21_4;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5; import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPackets1_21_4;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter; import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
// To replace if needed: // To replace if needed:
// ChunkType1_20_2 // ChunkType1_20_2
// RecipeRewriter1_20_3 // RecipeDisplayRewriter
// Types1_21, Types1_OLD // Types1_21_4, Types1_OLD
final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<ClientboundPacket1_21, ServerboundPacket1_20_5, Protocol1_99To_98> { final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<ClientboundPacket1_21_2, ServerboundPacket1_21_4, Protocol1_99To_98> {
public BlockItemPacketRewriter1_99(final Protocol1_99To_98 protocol) { public BlockItemPacketRewriter1_99(final Protocol1_99To_98 protocol) {
super(protocol, Types1_21.ITEM, Types1_21.ITEM_ARRAY); super(protocol, Types1_21_4.ITEM, Types1_21_4.ITEM_ARRAY);
/*super(protocol, /*super(protocol,
Types1_OLD.ITEM, Types1_OLD.ITEM_ARRAY, Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_OLD.ITEM, Types1_OLD.ITEM_ARRAY, Types1_21_4.ITEM, Types1_21_4.ITEM_ARRAY,
Types1_OLD.ITEM_COST, Types1_OLD.OPTIONAL_ITEM_COST, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_OLD.ITEM_COST, Types1_OLD.OPTIONAL_ITEM_COST, Types1_21_4.ITEM_COST, Types1_21_4.OPTIONAL_ITEM_COST
Types1_OLD.PARTICLE, Types1_21.PARTICLE
);*/ );*/
} }
@ -47,31 +46,33 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
// Register block and block state id changes // Register block and block state id changes
// Other places using block state id mappings: Spawn particle, entity data, entity spawn (falling blocks) // Other places using block state id mappings: Spawn particle, entity data, entity spawn (falling blocks)
// Tags and statistics use block (!) ids // Tags and statistics use block (!) ids
final BlockRewriter<ClientboundPacket1_21> blockRewriter = BlockRewriter.for1_20_2(protocol); final BlockRewriter<ClientboundPacket1_21_2> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_21.BLOCK_EVENT); blockRewriter.registerBlockEvent(ClientboundPackets1_21_2.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_21.BLOCK_UPDATE); blockRewriter.registerBlockUpdate(ClientboundPackets1_21_2.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE); blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21.LEVEL_EVENT, 2001); blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_2.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new); blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21.BLOCK_ENTITY_DATA); blockRewriter.registerBlockEntityData(ClientboundPackets1_21_2.BLOCK_ENTITY_DATA);
// Registers item id changes // Registers item id changes
// Other places using item ids are: Entity data, tags, statistics, effect // Other places using item ids are: Entity data, tags, statistics, effect
// registerOpenWindow(ClientboundPackets1_21.OPEN_WINDOW); - If a new container type was added // registerOpenScreen(ClientboundPackets1_21_2.OPEN_SCREEN); If a new container type was added; also remove from the component rewriter registration
registerCooldown(ClientboundPackets1_21.COOLDOWN); protocol.registerClientbound(ClientboundPackets1_21_2.SET_CURSOR_ITEM, this::passthroughClientboundItem);
registerSetContent1_17_1(ClientboundPackets1_21.CONTAINER_SET_CONTENT); registerSetPlayerInventory(ClientboundPackets1_21_2.SET_PLAYER_INVENTORY);
registerSetSlot1_17_1(ClientboundPackets1_21.CONTAINER_SET_SLOT); registerCooldown1_21_2(ClientboundPackets1_21_2.COOLDOWN);
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS); registerSetContent1_21_2(ClientboundPackets1_21_2.CONTAINER_SET_CONTENT);
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT); registerSetSlot1_21_2(ClientboundPackets1_21_2.CONTAINER_SET_SLOT);
registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK); registerAdvancements1_20_3(ClientboundPackets1_21_2.UPDATE_ADVANCEMENTS);
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS); registerSetEquipment(ClientboundPackets1_21_2.SET_EQUIPMENT);
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT); registerMerchantOffers1_20_5(ClientboundPackets1_21_2.MERCHANT_OFFERS);
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES); registerContainerClick1_21_2(ServerboundPackets1_21_4.CONTAINER_CLICK);
registerExplosion(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles registerSetCreativeModeSlot(ServerboundPackets1_21_4.SET_CREATIVE_MODE_SLOT);
new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES); final RecipeDisplayRewriter<ClientboundPacket1_21_2> recipeRewriter = new RecipeDisplayRewriter<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21_2.UPDATE_RECIPES);
recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21_2.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21_2.PLACE_GHOST_RECIPE);
// OR do this if serialization of recipes changed and override the relevant method // 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 // Add new serializers to RecipeDisplayRewriter, or extend the last one for changes
// new RecipeRewriter1_20_3<ClientboundPacket1_21>(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES);
} }
} }

Datei anzeigen

@ -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_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.util.SerializerVersion;
final class ComponentRewriter1_99 extends ComponentRewriter<ClientboundPacket1_21_2> {
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_21_4;
}
}

Datei anzeigen

@ -17,22 +17,20 @@
*/ */
package com.viaversion.viaversion.protocols.template; package com.viaversion.viaversion.protocols.template;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_4;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types; 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_4;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; 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_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.EntityRewriter; import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
// Replace if needed // Replace if needed
// Types1_OLD // Types1_OLD
// Types1_21 // Types1_21_4
final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_21, Protocol1_99To_98> { final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_21_2, Protocol1_99To_98> {
public EntityPacketRewriter1_99(final Protocol1_99To_98 protocol) { public EntityPacketRewriter1_99(final Protocol1_99To_98 protocol) {
super(protocol); super(protocol);
@ -41,36 +39,32 @@ final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_2
@Override @Override
public void registerPackets() { public void registerPackets() {
// Tracks entities, applies entity data rewrites registered below, untracks entities // Tracks entities, applies entity data rewrites registered below, untracks entities
registerTrackerWithData1_19(ClientboundPackets1_21.ADD_ENTITY, EntityTypes1_20_5.FALLING_BLOCK); registerTrackerWithData1_19(ClientboundPackets1_21_2.ADD_ENTITY, EntityTypes1_21_4.FALLING_BLOCK);
registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA, /*Types1_OLD_ENTITY_DATA_LIST, */Types1_21.ENTITY_DATA_LIST); // Specify old and new entity data list if changed registerSetEntityData(ClientboundPackets1_21_2.SET_ENTITY_DATA, /*Types1_OLD_ENTITY_DATA_LIST, */Types1_21_4.ENTITY_DATA_LIST); // Specify old and new entity data list if changed
registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES); registerRemoveEntities(ClientboundPackets1_21_2.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> { final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING)); protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
final RegistryEntry[] entries = wrapper.passthrough(Types.REGISTRY_ENTRY_ARRAY);
handleRegistryData1_20_5(wrapper.user(), registryKey, entries); // Caches dimensions to access data like height later and tracks the amount of biomes sent for chunk data protocol.registerClientbound(ClientboundPackets1_21_2.LOGIN, wrapper -> {
final int entityId = wrapper.passthrough(Types.INT); // Entity id
wrapper.passthrough(Types.BOOLEAN); // Hardcore
wrapper.passthrough(Types.STRING_ARRAY); // World List
wrapper.passthrough(Types.VAR_INT); // Max players
wrapper.passthrough(Types.VAR_INT); // View distance
wrapper.passthrough(Types.VAR_INT); // Simulation distance
wrapper.passthrough(Types.BOOLEAN); // Reduced debug info
wrapper.passthrough(Types.BOOLEAN); // Show death screen
wrapper.passthrough(Types.BOOLEAN); // Limited crafting
final int dimensionId = wrapper.passthrough(Types.VAR_INT);
final String world = wrapper.passthrough(Types.STRING);
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
trackPlayer(wrapper.user(), entityId);
}); });
protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() { protocol.registerClientbound(ClientboundPackets1_21_2.RESPAWN, wrapper -> {
@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
handler(worldDataTrackerHandlerByKey1_20_5(3)); // Tracks world height and name for chunk data and entity (un)tracking
handler(playerTrackerHandler());
}
});
protocol.registerClientbound(ClientboundPackets1_21.RESPAWN, wrapper -> {
final int dimensionId = wrapper.passthrough(Types.VAR_INT); final int dimensionId = wrapper.passthrough(Types.VAR_INT);
final String world = wrapper.passthrough(Types.STRING); final String world = wrapper.passthrough(Types.STRING);
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world); // Tracks world height and name for chunk data and entity (un)tracking trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world); // Tracks world height and name for chunk data and entity (un)tracking
@ -85,20 +79,20 @@ final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_2
if (id >= SomeAddedIndex) { if (id >= SomeAddedIndex) {
id++; id++;
} }
return Types1_21.ENTITY_DATA_TYPES.byId(id); return Types1_21_4.ENTITY_DATA_TYPES.byId(id);
});*/ });*/
// Registers registry type id changes // Registers registry type id changes
registerEntityDataTypeHandler( registerEntityDataTypeHandler(
Types1_21.ENTITY_DATA_TYPES.itemType, Types1_21_4.ENTITY_DATA_TYPES.itemType,
Types1_21.ENTITY_DATA_TYPES.blockStateType, Types1_21_4.ENTITY_DATA_TYPES.blockStateType,
Types1_21.ENTITY_DATA_TYPES.optionalBlockStateType, Types1_21_4.ENTITY_DATA_TYPES.optionalBlockStateType,
Types1_21.ENTITY_DATA_TYPES.particleType, Types1_21_4.ENTITY_DATA_TYPES.particleType,
Types1_21.ENTITY_DATA_TYPES.particlesType, Types1_21_4.ENTITY_DATA_TYPES.particlesType,
Types1_21.ENTITY_DATA_TYPES.componentType, Types1_21_4.ENTITY_DATA_TYPES.componentType,
Types1_21.ENTITY_DATA_TYPES.optionalComponentType Types1_21_4.ENTITY_DATA_TYPES.optionalComponentType
); );
registerBlockStateHandler(EntityTypes1_20_5.ABSTRACT_MINECART, 11); registerBlockStateHandler(EntityTypes1_21_4.ABSTRACT_MINECART, 11);
} }
@Override @Override
@ -109,6 +103,6 @@ final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_2
@Override @Override
public EntityType typeFromId(final int type) { public EntityType typeFromId(final int type) {
return EntityTypes1_20_5.getTypeFromId(type); return EntityTypes1_21_4.getTypeFromId(type);
} }
} }

Datei anzeigen

@ -20,18 +20,21 @@ package com.viaversion.viaversion.protocols.template;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase; import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_4;
import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.type.types.version.Types1_21_4;
import com.viaversion.viaversion.data.entity.EntityTrackerBase; 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.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.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPacket1_21_4;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPackets1_21_4;
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.rewriter.AttributeRewriter; import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter; import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.rewriter.TagRewriter;
@ -40,35 +43,56 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
// Placeholders to replace (in the entire package): // Placeholders to replace (in the entire package):
// Protocol1_99To_98, EntityPacketRewriter1_99, BlockItemPacketRewriter1_99 - move the latter two to a rewriter package // Protocol1_99To_98, EntityPacketRewriter1_99, BlockItemPacketRewriter1_99 - move the latter two to a rewriter package
// ClientboundPacket1_21 // ClientboundPacket1_21_2
// ServerboundPacket1_20_5 // ServerboundPacket1_21_4
// EntityTypes1_20_5 (MAPPED type) // EntityTypes1_21_4 (MAPPED type)
// Types1_21_4.PARTICLE
// 1.99, 1.98 // 1.99, 1.98
final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, ClientboundPacket1_21, ServerboundPacket1_20_5, ServerboundPacket1_20_5> { final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21_2, ClientboundPacket1_21_2, ServerboundPacket1_21_4, ServerboundPacket1_21_4> {
public static final MappingData MAPPINGS = new MappingDataBase("1.98", "1.99"); public static final MappingData MAPPINGS = new MappingDataBase("1.98", "1.99");
private final EntityPacketRewriter1_99 entityRewriter = new EntityPacketRewriter1_99(this); private final EntityPacketRewriter1_99 entityRewriter = new EntityPacketRewriter1_99(this);
private final BlockItemPacketRewriter1_99 itemRewriter = new BlockItemPacketRewriter1_99(this); private final BlockItemPacketRewriter1_99 itemRewriter = new BlockItemPacketRewriter1_99(this);
private final TagRewriter<ClientboundPacket1_21> tagRewriter = new TagRewriter<>(this); private final ParticleRewriter<ClientboundPacket1_21_2> particleRewriter = new ParticleRewriter<>(this, /*Types1_OLD.PARTICLE,*/ Types1_21_4.PARTICLE);
private final TagRewriter<ClientboundPacket1_21_2> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter<ClientboundPacket1_21_2> componentRewriter = new ComponentRewriter1_99(this);
public Protocol1_99To_98() { 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 // Passing the class types into the super constructor is needed for automatic packet type id remapping, but can otherwise be omitted
super(ClientboundPacket1_21.class, ClientboundPacket1_21.class, ServerboundPacket1_20_5.class, ServerboundPacket1_20_5.class); super(ClientboundPacket1_21_2.class, ClientboundPacket1_21_2.class, ServerboundPacket1_21_4.class, ServerboundPacket1_21_4.class);
} }
@Override @Override
protected void registerPackets() { protected void registerPackets() {
super.registerPackets(); super.registerPackets();
tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS); tagRewriter.registerGeneric(ClientboundPackets1_21_2.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS); tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
final SoundRewriter<ClientboundPacket1_21> soundRewriter = new SoundRewriter<>(this); // If needed for item or component changes
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND); componentRewriter.registerOpenScreen(ClientboundPackets1_21_2.OPEN_SCREEN);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY); componentRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_ACTION_BAR_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_TITLE_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_SUBTITLE_TEXT);
componentRewriter.registerBossEvent(ClientboundPackets1_21_2.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_21_2.TAB_LIST);
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_2.PLAYER_COMBAT_KILL);
componentRewriter.registerComponentPacket(ClientboundPackets1_21_2.SYSTEM_CHAT);
componentRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISGUISED_CHAT);
componentRewriter.registerPlayerInfoUpdate1_21_4(ClientboundPackets1_21_2.PLAYER_INFO_UPDATE);
componentRewriter.registerPing();
new StatisticsRewriter<>(this).register(ClientboundPackets1_21.AWARD_STATS); // If needed for any particle, item, or block changes. Extend ParticleRewriter for particle serializer changes
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21.UPDATE_ATTRIBUTES); particleRewriter.registerLevelParticles1_20_5(ClientboundPackets1_21_2.LEVEL_PARTICLES);
particleRewriter.registerExplode1_21_2(ClientboundPackets1_21_2.EXPLODE); // Rewrites the included sound and particles
final SoundRewriter<ClientboundPacket1_21_2> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_2.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_2.SOUND_ENTITY);
new StatisticsRewriter<>(this).register(ClientboundPackets1_21_2.AWARD_STATS);
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21_2.UPDATE_ATTRIBUTES);
// Uncomment if an existing type changed serialization format. Mappings for argument type keys can also be defined in mapping files // Uncomment if an existing type changed serialization format. Mappings for argument type keys can also be defined in mapping files
/*new CommandRewriter1_19_4<>(this) { /*new CommandRewriter1_19_4<>(this) {
@ -81,25 +105,29 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
super.handleArgument(wrapper, argumentType); super.handleArgument(wrapper, argumentType);
} }
} }
}.registerDeclareCommands1_19(ClientboundPackets1_21.COMMANDS);*/ }.registerDeclareCommands1_19(ClientboundPackets1_21_2.COMMANDS);*/
} }
@Override @Override
protected void onMappingDataLoaded() { protected void onMappingDataLoaded() {
// Uncomment this if the entity types enum has been newly added specifically for this Protocol // Uncomment this if the entity types enum has been newly added specifically for this Protocol
// EntityTypes1_20_5.initialize(this); // EntityTypes1_21_4.initialize(this);
// Uncomment if a new particle was added = ids shifted; requires a new Types_ class copied from the last // Uncomment if a new particle was added = ids shifted; requires a new Types_ class copied from the last
/*Types1_21.PARTICLE.filler(this) /*Types1_21_4.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK) .reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK) .reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST) .reader("dust_pillar", ParticleType.Readers.BLOCK)
.reader("falling_dust", ParticleType.Readers.BLOCK) .reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION) .reader("block_crumble", ParticleType.Readers.BLOCK)
.reader("item", ParticleType.Readers.ITEM1_20_2) .reader("dust", ParticleType.Readers.DUST1_21_2)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION1_21_2)
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3) .reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE) .reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);*/ .reader("shriek", ParticleType.Readers.SHRIEK)
.reader("entity_effect", ParticleType.Readers.COLOR)
.reader("trail", ParticleType.Readers.TRAIL1_21_4)
.reader("item", ParticleType.Readers.item(itemRewriter.mappedItemType()));*/
super.onMappingDataLoaded(); // Calls load methods on rewriters. Last in case the rewriters access the above filled data super.onMappingDataLoaded(); // Calls load methods on rewriters. Last in case the rewriters access the above filled data
} }
@ -107,7 +135,7 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
@Override @Override
public void init(final UserConnection connection) { public void init(final UserConnection connection) {
// Register the entity tracker - used for entity id/entity data rewriting AND for tracking world data sent to the client (then used for chunk data rewriting) // Register the entity tracker - used for entity id/entity data rewriting AND for tracking world data sent to the client (then used for chunk data rewriting)
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_20_5.PLAYER)); addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_4.PLAYER));
} }
// Overriding these four methods is important as they are relied on various rewriter classes // Overriding these four methods is important as they are relied on various rewriter classes
@ -128,17 +156,27 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
} }
@Override @Override
public TagRewriter<ClientboundPacket1_21> getTagRewriter() { public ParticleRewriter<ClientboundPacket1_21_2> getParticleRewriter() {
return particleRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21_2> getTagRewriter() {
return tagRewriter; return tagRewriter;
} }
@Override @Override
protected PacketTypesProvider<ClientboundPacket1_21, ClientboundPacket1_21, ServerboundPacket1_20_5, ServerboundPacket1_20_5> createPacketTypesProvider() { public ComponentRewriter<ClientboundPacket1_21_2> getComponentRewriter() {
return componentRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_21_2, ClientboundPacket1_21_2, ServerboundPacket1_21_4, ServerboundPacket1_21_4> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>( return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class), packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class),
packetTypeMap(mappedClientboundPacketType, 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(mappedServerboundPacketType, ServerboundPackets1_21_4.class, ServerboundConfigurationPackets1_20_5.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class) packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_4.class, ServerboundConfigurationPackets1_20_5.class)
); );
} }
} }

Datei anzeigen

@ -132,13 +132,13 @@ public class Protocol1_10To1_11 extends AbstractProtocol<ClientboundPackets1_9_3
if (effectID == 2002) { if (effectID == 2002) {
int data = packetWrapper.get(Types.INT, 1); int data = packetWrapper.get(Types.INT, 1);
boolean isInstant = false; boolean isInstant = false;
Pair<Integer, Boolean> newData = PotionColorMappings1_11.getNewData(data); PotionColorMappings1_11.PotionData newData = PotionColorMappings1_11.getNewData(data);
if (newData == null) { if (newData == null) {
getLogger().warning("Received unknown potion data: " + data); getLogger().warning("Received unknown potion data: " + data);
data = 0; data = 0;
} else { } else {
data = newData.key(); data = newData.data();
isInstant = newData.value(); isInstant = newData.instant();
} }
if (isInstant) { if (isInstant) {
packetWrapper.set(Types.INT, 0, 2007); packetWrapper.set(Types.INT, 0, 2007);

Datei anzeigen

@ -17,14 +17,13 @@
*/ */
package com.viaversion.viaversion.protocols.v1_10to1_11.data; package com.viaversion.viaversion.protocols.v1_10to1_11.data;
import com.viaversion.viaversion.util.Pair;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class PotionColorMappings1_11 { public class PotionColorMappings1_11 {
//<oldData> to <newData, isInstant> mapping private static final Int2ObjectMap<PotionData> POTIONS = new Int2ObjectOpenHashMap<>(37);
private static final Int2ObjectMap<Pair<Integer, Boolean>> POTIONS = new Int2ObjectOpenHashMap<>(37);
static { static {
addRewrite(0, 3694022, false); addRewrite(0, 3694022, false);
@ -66,12 +65,14 @@ public class PotionColorMappings1_11 {
addRewrite(36, 3381504, false); addRewrite(36, 3381504, false);
} }
public static Pair<Integer, Boolean> getNewData(int oldData) { public static @Nullable PotionData getNewData(int oldData) {
return POTIONS.get(oldData); return POTIONS.get(oldData);
} }
private static void addRewrite(int oldData, int newData, boolean isInstant) { private static void addRewrite(int oldData, int newData, boolean isInstant) {
POTIONS.put(oldData, new Pair<>(newData, isInstant)); POTIONS.put(oldData, new PotionData(newData, isInstant));
} }
public record PotionData(int data, boolean instant) {
}
} }

Datei anzeigen

@ -24,9 +24,9 @@ import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11.EntityType;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_9; import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_9;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
@ -37,6 +37,7 @@ import com.viaversion.viaversion.protocols.v1_10to1_11.data.EntityMappings1_11;
import com.viaversion.viaversion.protocols.v1_10to1_11.storage.EntityTracker1_11; import com.viaversion.viaversion.protocols.v1_10to1_11.storage.EntityTracker1_11;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ClientboundPackets1_9_3; import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ClientboundPackets1_9_3;
import com.viaversion.viaversion.rewriter.EntityRewriter; import com.viaversion.viaversion.rewriter.EntityRewriter;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.logging.Level; import java.util.logging.Level;
@ -91,13 +92,27 @@ public class EntityPacketRewriter1_11 extends EntityRewriter<ClientboundPackets1
map(Types.INT); // 8 - Data map(Types.INT); // 8 - Data
// Track Entity // Track Entity
handler(objectTrackerHandler());
handler(wrapper -> { handler(wrapper -> {
byte type = wrapper.get(Types.BYTE, 0); byte type = wrapper.get(Types.BYTE, 0);
if (type == EntityTypes1_10.ObjectType.FISHIHNG_HOOK.getId()) { if (type == EntityTypes1_10.ObjectType.FISHIHNG_HOOK.getId()) {
tryFixFishingHookVelocity(wrapper); tryFixFishingHookVelocity(wrapper);
} else if (type == EntityTypes1_10.ObjectType.ITEM.getId()) {
// Older clients used stone as fallback as long as the entity data was not set
wrapper.send(Protocol1_10To1_11.class);
wrapper.cancel();
final int entityId = wrapper.get(Types.VAR_INT, 0);
final List<EntityData> entityDataList = new ArrayList<>();
entityDataList.add(new EntityData(6, EntityDataTypes1_9.ITEM, new DataItem(1, (byte) 1, null)));
final PacketWrapper setItem = PacketWrapper.create(ClientboundPackets1_9_3.SET_ENTITY_DATA, wrapper.user());
setItem.write(Types.VAR_INT, entityId);
setItem.write(Types1_9.ENTITY_DATA_LIST, entityDataList);
setItem.send(Protocol1_10To1_11.class);
} }
}); });
handler(objectTrackerHandler());
} }
}); });

Datei anzeigen

@ -34,6 +34,7 @@ import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer; import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType; import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_13; import com.viaversion.viaversion.api.type.types.version.Types1_13;
@ -145,7 +146,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
}).scheduleSend(Protocol1_12_2To1_13.class); }).scheduleSend(Protocol1_12_2To1_13.class);
// Send tags packet // Send tags packet
w.create(ClientboundPackets1_13.UPDATE_TAGS, wrapper -> { final PacketWrapper tagsPacket = w.create(ClientboundPackets1_13.UPDATE_TAGS, wrapper -> {
wrapper.write(Types.VAR_INT, MAPPINGS.getBlockTags().size()); // block tags wrapper.write(Types.VAR_INT, MAPPINGS.getBlockTags().size()); // block tags
for (Map.Entry<String, int[]> tag : MAPPINGS.getBlockTags().entrySet()) { for (Map.Entry<String, int[]> tag : MAPPINGS.getBlockTags().entrySet()) {
wrapper.write(Types.STRING, tag.getKey()); wrapper.write(Types.STRING, tag.getKey());
@ -164,7 +165,13 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
// Needs copy as other protocols may modify it // Needs copy as other protocols may modify it
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, tag.getValue().clone()); wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, tag.getValue().clone());
} }
}).scheduleSend(Protocol1_12_2To1_13.class); });
if (w.user().getProtocolInfo().protocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_5)) {
// Make sure it's included in the configuration packets as it may already be required for registry data
tagsPacket.send(Protocol1_12_2To1_13.class);
} else {
tagsPacket.scheduleSend(Protocol1_12_2To1_13.class);
}
}; };
@Override @Override
@ -346,7 +353,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
registerClientbound(ClientboundPackets1_12_1.PLACE_GHOST_RECIPE, new PacketHandlers() { registerClientbound(ClientboundPackets1_12_1.PLACE_GHOST_RECIPE, new PacketHandlers() {
@Override @Override
public void register() { public void register() {
map(Types.BYTE); map(Types.UNSIGNED_BYTE);
handler(wrapper -> wrapper.write(Types.STRING, "viaversion:legacy/" + wrapper.read(Types.VAR_INT))); handler(wrapper -> wrapper.write(Types.STRING, "viaversion:legacy/" + wrapper.read(Types.VAR_INT)));
} }
}); });
@ -587,7 +594,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
registerServerbound(ServerboundPackets1_13.PLACE_RECIPE, new PacketHandlers() { registerServerbound(ServerboundPackets1_13.PLACE_RECIPE, new PacketHandlers() {
@Override @Override
public void register() { public void register() {
map(Types.BYTE); // Window id map(Types.UNSIGNED_BYTE); // Window id
handler(wrapper -> { handler(wrapper -> {
String s = wrapper.read(Types.STRING); String s = wrapper.read(Types.STRING);
@ -768,7 +775,10 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
for (Item[] ingredient : recipe.ingredients()) { for (Item[] ingredient : recipe.ingredients()) {
Item[] clone = new Item[ingredient.length]; Item[] clone = new Item[ingredient.length];
for (int i = 0; i < ingredient.length; i++) { for (int i = 0; i < ingredient.length; i++) {
if (clone[i] == null) continue; if (ingredient[i] == null) {
continue;
}
clone[i] = ingredient[i].copy(); clone[i] = ingredient[i].copy();
} }
recipesPacket.write(Types.ITEM1_13_ARRAY, clone); recipesPacket.write(Types.ITEM1_13_ARRAY, clone);
@ -782,7 +792,10 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
for (Item[] ingredient : recipe.ingredients()) { for (Item[] ingredient : recipe.ingredients()) {
Item[] clone = new Item[ingredient.length]; Item[] clone = new Item[ingredient.length];
for (int i = 0; i < ingredient.length; i++) { for (int i = 0; i < ingredient.length; i++) {
if (clone[i] == null) continue; if (ingredient[i] == null) {
continue;
}
clone[i] = ingredient[i].copy(); clone[i] = ingredient[i].copy();
} }
recipesPacket.write(Types.ITEM1_13_ARRAY, clone); recipesPacket.write(Types.ITEM1_13_ARRAY, clone);
@ -793,7 +806,10 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
recipesPacket.write(Types.STRING, recipe.group()); recipesPacket.write(Types.STRING, recipe.group());
Item[] ingredient = new Item[recipe.ingredient().length]; Item[] ingredient = new Item[recipe.ingredient().length];
for (int i = 0; i < ingredient.length; i++) { for (int i = 0; i < ingredient.length; i++) {
if (recipe.ingredient()[i] == null) continue; if (recipe.ingredient()[i] == null) {
continue;
}
ingredient[i] = recipe.ingredient()[i].copy(); ingredient[i] = recipe.ingredient()[i].copy();
} }
recipesPacket.write(Types.ITEM1_13_ARRAY, ingredient); recipesPacket.write(Types.ITEM1_13_ARRAY, ingredient);

Datei anzeigen

@ -33,6 +33,7 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.FlowerPotHandler; import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.FlowerPotHandler;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.SkullHandler; import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.SkullHandler;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.SpawnerHandler; import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities.SpawnerHandler;
import com.viaversion.viaversion.util.ComponentUtil;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -46,6 +47,21 @@ public class BlockEntityProvider implements Provider {
handlers.put("minecraft:skull", new SkullHandler()); handlers.put("minecraft:skull", new SkullHandler());
handlers.put("minecraft:mob_spawner", new SpawnerHandler()); handlers.put("minecraft:mob_spawner", new SpawnerHandler());
handlers.put("minecraft:command_block", new CommandBlockHandler()); handlers.put("minecraft:command_block", new CommandBlockHandler());
final BlockEntityHandler customNameHandler = (user, tag) -> {
final StringTag name = tag.getStringTag("CustomName");
if (name != null) {
name.setValue(ComponentUtil.legacyToJsonString(name.getValue()));
}
return -1;
};
handlers.put("minecraft:chest", customNameHandler);
handlers.put("minecraft:dispenser", customNameHandler);
handlers.put("minecraft:dropper", customNameHandler);
handlers.put("minecraft:enchanting_table", customNameHandler);
handlers.put("minecraft:furnace", customNameHandler);
handlers.put("minecraft:hopper", customNameHandler);
handlers.put("minecraft:shulker_box", customNameHandler);
} }
/** /**

Datei anzeigen

@ -18,16 +18,19 @@
package com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities; package com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.blockentities;
import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.NumberTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.BlockEntityProvider; import com.viaversion.viaversion.protocols.v1_12_2to1_13.provider.BlockEntityProvider;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class FlowerPotHandler implements BlockEntityProvider.BlockEntityHandler { public class FlowerPotHandler implements BlockEntityProvider.BlockEntityHandler {
// Object -> string (id without namespace) or byte (numeric id) private static final int EMPTY_POT = 5265;
private static final Map<Pair<?, Byte>, Integer> flowers = new ConcurrentHashMap<>(); private static final Map<String, Byte> STRING_TO_BYTE_ID = new HashMap<>();
private static final Map<IntIdPair, Integer> FLOWERS = new HashMap<>();
static { static {
register("air", (byte) 0, (byte) 0, 5265); register("air", (byte) 0, (byte) 0, 5265);
@ -55,37 +58,40 @@ public class FlowerPotHandler implements BlockEntityProvider.BlockEntityHandler
} }
public static void register(String identifier, byte numbericBlockId, byte blockData, int newId) { private static void register(String identifier, byte blockId, byte blockData, int newId) {
flowers.put(new Pair<>(identifier, blockData), newId); STRING_TO_BYTE_ID.put(identifier, blockId);
flowers.put(new Pair<>(numbericBlockId, blockData), newId); FLOWERS.put(new IntIdPair(blockId, blockData), newId);
} }
@Override @Override
public int transform(UserConnection user, CompoundTag tag) { public int transform(UserConnection user, CompoundTag tag) {
Object item = tag.contains("Item") ? tag.get("Item").getValue() : null;
Object data = tag.contains("Data") ? tag.get("Data").getValue() : null;
// Convert item to String without namespace or to Byte // Convert item to String without namespace or to Byte
if (item instanceof String) { Tag itemTag = tag.get("Item");
item = Key.stripMinecraftNamespace((String) item); byte item = 0;
} else if (item instanceof Number) { if (itemTag instanceof StringTag stringTag) {
item = ((Number) item).byteValue(); item = STRING_TO_BYTE_ID.getOrDefault(Key.stripMinecraftNamespace(stringTag.getValue()), (byte) 0);
} else { } else if (itemTag instanceof NumberTag numberTag) {
item = (byte) 0; item = numberTag.asByte();
} }
// Convert data to Byte byte data = 0;
if (data instanceof Number) { if (tag.get("Data") instanceof NumberTag dataTag) {
data = ((Number) data).byteValue(); data = dataTag.asByte();
} else {
data = (byte) 0;
} }
Integer flower = flowers.get(new Pair<>(item, (byte) data)); Integer flower = FLOWERS.get(new IntIdPair(item, data));
if (flower != null) return flower; if (flower != null) {
flower = flowers.get(new Pair<>(item, (byte) 0)); return flower;
if (flower != null) return flower; }
return 5265; // Fallback to empty pot flower = FLOWERS.get(new IntIdPair(item, (byte) 0));
if (flower != null) {
return flower;
}
return EMPTY_POT; // Fallback to empty pot
}
private record IntIdPair(int id, byte data) {
} }
} }

Datei anzeigen

@ -205,23 +205,23 @@ public class ItemPacketRewriter1_13 extends ItemRewriter<ClientboundPackets1_12_
String old = channel; String old = channel;
channel = getOldPluginChannelId(channel); channel = getOldPluginChannelId(channel);
if (channel == null) { if (channel == null) {
if (!Via.getConfig().isSuppressConversionWarnings()) { if (Via.getManager().isDebug()) {
protocol.getLogger().warning("Ignoring serverbound plugin message with channel: " + old); protocol.getLogger().warning("Ignoring serverbound plugin message with channel: " + old);
} }
wrapper.cancel(); wrapper.cancel();
return; return;
} else if (channel.equals("REGISTER") || channel.equals("UNREGISTER")) { } else if (channel.equals("REGISTER") || channel.equals("UNREGISTER")) {
String[] channels = new String(wrapper.read(Types.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0"); String[] channels = new String(wrapper.read(Types.SERVERBOUND_CUSTOM_PAYLOAD_DATA), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>(); List<String> rewrittenChannels = new ArrayList<>();
for (String s : channels) { for (String s : channels) {
String rewritten = getOldPluginChannelId(s); String rewritten = getOldPluginChannelId(s);
if (rewritten != null) { if (rewritten != null) {
rewrittenChannels.add(rewritten); rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings()) { } else if (Via.getManager().isDebug()) {
protocol.getLogger().warning("Ignoring plugin channel in serverbound " + channel + ": " + s); protocol.getLogger().warning("Ignoring plugin channel in serverbound " + channel + ": " + s);
} }
} }
wrapper.write(Types.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8)); wrapper.write(Types.SERVERBOUND_CUSTOM_PAYLOAD_DATA, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
} }
wrapper.set(Types.STRING, 0, channel); wrapper.set(Types.STRING, 0, channel);
}); });

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen