Compare commits

..
36 Commits
Author SHA1 Message Date
Nassim Jahnke 4738945a7a 5.9.0 Release 2026-04-19 15:36:05 +02:00
Florian Reuth 4c55ef9cab Remove rewriter overrides in AbstractProtocol (#4913) 2026-04-19 08:30:13 +02:00
Niko a66dbf77aa Fix profile with multiple properties of the same key in 1.20.5->1.20.3 (#4909) 2026-04-17 22:33:28 +02:00
Nassim Jahnke c6cc380c3c Fix fluid block counting
Fixes #4912
2026-04-17 14:44:57 +02:00
Acrylic Style cd3f146781 Fix block state translation in falling block (#4910)
Fixes #4908
2026-04-15 20:31:15 +02:00
Florian Reuth d0da13edd8 Add missing tags for client-interaction in 1.21.11->26.1 (#4906)
Fixes swing animation when placing plants and some container-specific interactions
2026-04-10 14:57:50 +02:00
Nassim Jahnke ec1f570f4b Update 26.1 protocol version range 2026-04-09 13:38:39 +02:00
Nassim Jahnke e41e216903 Fix jukebox_song registry key in 1.21.11->26.1 2026-04-07 21:03:59 +02:00
Nassim Jahnke 43ee417e20 [ci skip] Update template protocol, clean up imports and indents 2026-04-06 15:47:22 +02:00
Nassim Jahnke 4dc57e3d53 Make entity data type id mapping less manual 2026-04-06 13:34:19 +02:00
Nassim Jahnke 31f257fee1 Register empty handlers for transient data components in 1.20.5->1.20.3 2026-04-05 18:58:03 +02:00
Nassim Jahnke cda72574fc Change tag type in 1.20.2 block entity 2026-04-04 17:42:05 +02:00
Nassim Jahnke ef1b6a10ea Fix ocelot parent entity type 2026-04-04 14:59:32 +02:00
Nassim Jahnke c45c700301 Fix 1.21 player chat read type 2026-04-02 16:13:39 +02:00
Nassim Jahnke c43de2b88d Move 26.1 container empty item handling into proper upgrade/downgrade methods 2026-04-02 15:10:19 +02:00
Drex 898b6c8774 Improve enchantment term conversion (#4879) 2026-04-02 14:32:48 +02:00
Florian Reuth 2e3c47d292 Track sneaking state for secondary action in 1.21.11->26.1 (#4890) 2026-04-02 13:23:16 +02:00
Florian Reuth 7974d1a570 [ci skip] Update missing year references (#4786) 2026-04-02 11:56:51 +02:00
Florian Reuth cf2c1c5b76 Update time command translations in 1.21.11->26.1 (#4891) 2026-04-02 11:47:55 +02:00
Florian Reuth d75c54cc70 Fix kick when opening "edit game rules" screen (#4882) 2026-04-02 11:44:50 +02:00
Florian Reuth ead13b2bb9 Deprecate packet register methods with override boolean (#4881)
Replaced by Protocol#registerClientbound & Protocol#registerServerbound
2026-04-01 17:24:33 +02:00
Nassim Jahnke 2e91b841b0 Automatically call mapTypes in entity rewriter 2026-04-01 17:21:53 +02:00
Nassim Jahnke 50486fa43a Don't apply shared registrations to differing version types 2026-04-01 17:05:07 +02:00
Nassim Jahnke 31d4cd453d Add 26.1.1 to version string 2026-04-01 13:02:29 +02:00
Nassim Jahnke c5482b99bf [ci skip] Update error message 2026-03-31 21:15:01 +02:00
Nassim Jahnke 98ef806887 Fix baby wolf assets 2026-03-31 15:21:48 +02:00
Florian Reuth a26745862f Handle show_dialog click events (#4878) 2026-03-31 14:36:09 +02:00
Florian ReuthandNassim Jahnke 6bd081cefd Handle in-depth components in dialogs (#4876)
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2026-03-31 11:25:47 +02:00
Nassim Jahnke bb9aa8b31c Fix adventure mode predicate index check in 1.20.4->1.20.5 2026-03-31 11:07:01 +02:00
Nassim Jahnke 572f7a2677 Fix hashing of attribute_modifiers with override text 2026-03-30 23:29:20 +02:00
Nassim Jahnke 11a5c9e32c Fix block entity tag read type 2026-03-30 23:09:37 +02:00
Nassim Jahnke 02b65dcb36 Fix command rewriter check being too early 2026-03-30 22:32:08 +02:00
Nassim Jahnke 0121534e7e Deduplicate particle type fillers 2026-03-30 21:53:47 +02:00
Florian Reuth 941e6f6df4 Null check block entity tag in 1.20->1.20.2 (#4872) 2026-03-30 20:40:26 +02:00
Nassim Jahnke fe6e18845b Make tests fail if error occurs during platform 2026-03-30 20:40:26 +02:00
Nassim Jahnke 8f8f5e72c0 Default rewriter registrations across protocols
In total it doesn't (yet) reduce the lines of code (though there is also some other changes adding code here), but makes adding single rewriter calls to a range of protocols much easier than having to individually check an ever increasing number of classes. This also moved Protocol#registerPackets until after mappings have been loaded (which makes onMappingDataLoaded redundant for now, but will become relevant later again)
2026-03-30 20:40:25 +02:00
192 changed files with 3411 additions and 2259 deletions

No files matched your search

+2 -2
View File
@@ -15,7 +15,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # 5.0.1
uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f # 6.0.1
- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # 5.2.0
with:
@@ -27,7 +27,7 @@ jobs:
- name: Upload Artifacts to GitHub
# Only upload on the preview repository as there is no CI job for it.
if: ${{ github.repository == 'ViaVersion/ViaVersionDev' && github.ref_name == 'preview' }}
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
with:
name: Artifacts
path: build/libs/
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # 5.0.1
uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f # 6.0.1
- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # 5.2.0
with:
+2
View File
@@ -19,6 +19,8 @@ classes/
*.ipr
*.iws
benchmark/
# VSCode
.settings/
@@ -1,6 +1,6 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
* Copyright (C) 2016-2026 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
@@ -37,6 +37,7 @@ public interface ViaVersionCommand {
/**
* Removes a subcommand by name, can be used to unload default subcommands which are not supported
* on the platform.
*
* @param name Subcommand name
*/
void removeSubCommand(String name);
@@ -0,0 +1,123 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.data;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class FullIdentityMappings implements FullMappings {
private static final String[] EMPTY_ARRAY = new String[0];
private final Object2IntMap<String> stringToId;
private final String[] idToString;
private final Mappings mappings;
public FullIdentityMappings(final IdentifiersPair identifiersPair, final Mappings mappings) {
Preconditions.checkNotNull(mappings, "Mappings cannot be null");
this.mappings = mappings;
this.stringToId = FullMappingsBase.toInverseMap(identifiersPair.unmapped());
this.idToString = identifiersPair.unmapped().toArray(EMPTY_ARRAY);
}
private FullIdentityMappings(final Object2IntMap<String> stringToId, final String[] idToString, final Mappings mappings) {
this.stringToId = stringToId;
this.idToString = idToString;
this.mappings = mappings;
}
@Override
public int id(final String identifier) {
return stringToId.getInt(Key.stripMinecraftNamespace(identifier));
}
@Override
public int mappedId(final String mappedIdentifier) {
return id(mappedIdentifier);
}
@Override
public String identifier(final int id) {
if (id < 0 || id >= idToString.length) {
return null;
}
final String identifier = idToString[id];
return Key.namespaced(identifier);
}
@Override
public @Nullable String identifier(final String mappedIdentifier) {
final int mappedId = mappedId(mappedIdentifier);
if (mappedId == -1) {
return null;
}
final int id = mappings.inverse().getNewId(mappedId);
return id != -1 ? identifier(id) : null;
}
@Override
public @Nullable String mappedIdentifier(final int mappedId) {
return identifier(mappedId);
}
@Override
public @Nullable String mappedIdentifier(final String identifier) {
return identifier(identifier);
}
@Override
public int getNewId(int id) {
return mappings.getNewId(id);
}
@Override
public void setNewId(int id, int mappedId) {
mappings.setNewId(id, mappedId);
}
@Override
public int size() {
return mappings.size();
}
@Override
public int mappedSize() {
return mappings.mappedSize();
}
@Override
public boolean isIdentity() {
return true;
}
@Override
public boolean isIntIdIdentity() {
return true;
}
@Override
public FullMappings inverse() {
return new FullIdentityMappings(stringToId, idToString, mappings.inverse());
}
}
@@ -77,6 +77,14 @@ public interface FullMappings extends BiMappings {
*/
@Nullable String mappedIdentifier(String identifier);
/**
* Returns whether the int id mappings are identity mappings.
*
* @return whether the int id mappings are identity mappings
* @see #isIdentity()
*/
boolean isIntIdIdentity();
@Override
FullMappings inverse();
}
@@ -23,6 +23,7 @@
package com.viaversion.viaversion.api.data;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
@@ -37,13 +38,13 @@ public class FullMappingsBase implements FullMappings {
private final String[] mappedIdToString;
private final Mappings mappings;
public FullMappingsBase(final List<String> unmappedIdentifiers, final List<String> mappedIdentifiers, final Mappings mappings) {
public FullMappingsBase(final IdentifiersPair identifiersPair, final Mappings mappings) {
Preconditions.checkNotNull(mappings, "Mappings cannot be null");
this.mappings = mappings;
this.stringToId = toInverseMap(unmappedIdentifiers);
this.mappedStringToId = toInverseMap(mappedIdentifiers);
this.idToString = unmappedIdentifiers.toArray(EMPTY_ARRAY);
this.mappedIdToString = mappedIdentifiers.toArray(EMPTY_ARRAY);
this.stringToId = toInverseMap(identifiersPair.unmapped());
this.idToString = identifiersPair.unmapped().toArray(EMPTY_ARRAY);
this.mappedStringToId = toInverseMap(identifiersPair.mapped());
this.mappedIdToString = identifiersPair.mapped().toArray(EMPTY_ARRAY);
}
private FullMappingsBase(final Object2IntMap<String> stringToId, final Object2IntMap<String> mappedStringToId, final String[] idToString, final String[] mappedIdToString, final Mappings mappings) {
@@ -54,7 +55,11 @@ public class FullMappingsBase implements FullMappings {
this.mappings = mappings;
}
private static Object2IntMap<String> toInverseMap(final List<String> list) {
public static FullMappings of(final IdentifiersPair identifiersPair, final Mappings mappings) {
return mappings.isIdentity() && identifiersPair.identity() ? new FullIdentityMappings(identifiersPair, mappings) : new FullMappingsBase(identifiersPair, mappings);
}
static Object2IntMap<String> toInverseMap(final List<String> list) {
final Object2IntMap<String> map = new Object2IntOpenHashMap<>(list.size());
map.defaultReturnValue(-1);
for (int i = 0; i < list.size(); i++) {
@@ -135,6 +140,11 @@ public class FullMappingsBase implements FullMappings {
return mappings.mappedSize();
}
@Override
public boolean isIntIdIdentity() {
return mappings.isIdentity();
}
@Override
public FullMappings inverse() {
return new FullMappingsBase(mappedStringToId, stringToId, mappedIdToString, idToString, mappings.inverse());
@@ -38,4 +38,9 @@ public record IdentityMappings(int size, int mappedSize) implements Mappings {
public Mappings inverse() {
return new IdentityMappings(mappedSize, size);
}
@Override
public boolean isIdentity() {
return true;
}
}
@@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntArrayTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.TagData;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
@@ -96,14 +97,13 @@ public class MappingDataBase implements MappingData {
attributeMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "attributes");
blockEntityMappings = loadFullMappings(data, unmappedIdentifierData, mappedIdentifierData, "blockentities");
final List<String> unmappedParticles = identifiersFromGlobalIds(unmappedIdentifierData, "particles");
final List<String> mappedParticles = identifiersFromGlobalIds(mappedIdentifierData, "particles");
if (unmappedParticles != null && mappedParticles != null) {
final IdentifiersPair particleIdentifiers = identifiersFromGlobalIds(unmappedIdentifierData, mappedIdentifierData, "particles");
if (particleIdentifiers != null) {
Mappings particleMappings = loadMappings(data, "particles");
if (particleMappings == null) {
particleMappings = new IdentityMappings(unmappedParticles.size(), mappedParticles.size());
particleMappings = new IdentityMappings(particleIdentifiers.unmapped().size(), particleIdentifiers.mapped().size());
}
this.particleMappings = new ParticleMappings(unmappedParticles, mappedParticles, particleMappings);
this.particleMappings = new ParticleMappings(particleIdentifiers, particleMappings);
}
} else {
// Might not have identifiers in older versions
@@ -132,6 +132,10 @@ public class MappingDataBase implements MappingData {
return MappingDataLoader.INSTANCE.identifiersFromGlobalIds(mappingsTag, key);
}
protected @Nullable IdentifiersPair identifiersFromGlobalIds(final CompoundTag unmappedTag, final CompoundTag mappedTag, final String key) {
return MappingDataLoader.INSTANCE.identifiersFromGlobalIds(unmappedTag, mappedTag, key);
}
protected @Nullable CompoundTag readMappingsFile(final String name) {
return MappingDataLoader.INSTANCE.loadNBT(name);
}
@@ -158,14 +162,12 @@ public class MappingDataBase implements MappingData {
return null;
}
final List<String> unmappedIdentifiers = identifiersFromGlobalIds(unmappedIdentifiersTag, key);
final List<String> mappedIdentifiers = identifiersFromGlobalIds(mappedIdentifiersTag, key);
final IdentifiersPair identifiersPair = identifiersFromGlobalIds(unmappedIdentifiersTag, mappedIdentifiersTag, key);
Mappings mappings = loadBiMappings(data, key); // Load as bi-mappings to keep the inverse cached
if (mappings == null) {
mappings = new IdentityMappings(unmappedIdentifiers.size(), mappedIdentifiers.size());
mappings = new IdentityMappings(identifiersPair.unmapped().size(), identifiersPair.mapped().size());
}
return new FullMappingsBase(unmappedIdentifiers, mappedIdentifiers, mappings);
return FullMappingsBase.of(identifiersPair, mappings);
}
protected @Nullable BiMappings loadBiMappings(final CompoundTag data, final String key) {
@@ -81,8 +81,9 @@ public class MappingDataLoader {
for (final Map.Entry<String, Tag> entry : globalIdentifiers.entrySet()) {
//noinspection unchecked
final ListTag<StringTag> value = (ListTag<StringTag>) entry.getValue();
final String[] array = new String[value.size()];
for (int i = 0, size = value.size(); i < size; i++) {
final int size = value.size();
final String[] array = new String[size];
for (int i = 0; i < size; i++) {
array[i] = value.get(i).getValue();
}
GLOBAL_IDENTIFIER_INDEXES.put(entry.getKey(), array);
@@ -272,13 +273,60 @@ public class MappingDataLoader {
public @Nullable List<String> identifiersFromGlobalIds(final CompoundTag mappingsTag, final String key) {
final Mappings mappings = loadMappings(mappingsTag, key);
if (mappings == null) {
return mappings != null ? identifiers(mappings, key) : null;
}
/**
* Returns a pair of identifier lists, also keeping track of whether the two lists are equal.
*
* @param unmappedTag unmapped mappings tag
* @param mappedTag mapped mappings tag
* @param key mappings key
* @return pair of identifier lists
*/
public @Nullable IdentifiersPair identifiersFromGlobalIds(final CompoundTag unmappedTag, final CompoundTag mappedTag, final String key) {
final Mappings unmapped = loadMappings(unmappedTag, key);
if (unmapped == null) {
return null;
}
final Mappings mapped = loadMappings(mappedTag, key);
if (mapped == null) {
return null;
}
final int size = unmapped.size();
if (size != mapped.size()) {
return new IdentifiersPair(identifiers(unmapped, key), identifiers(mapped, key), false);
}
// Small optimization to only load one array and reduce loading for full mappings
final List<String> unmappedIdentifiers = new ArrayList<>(size);
final List<String> mappedIdentifiers = new ArrayList<>(size);
boolean identity = true;
for (int i = 0; i < size; i++) {
final int unmappedGlobalId = unmapped.getNewId(i);
final int mappedGlobalId = mapped.getNewId(i);
final String unmappedIdentifier = identifierFromGlobalId(key, unmappedGlobalId);
if (unmappedGlobalId == mappedGlobalId) {
unmappedIdentifiers.add(unmappedIdentifier);
mappedIdentifiers.add(unmappedIdentifier);
continue;
}
identity = false;
unmappedIdentifiers.add(unmappedIdentifier);
mappedIdentifiers.add(identifierFromGlobalId(key, mappedGlobalId));
}
return identity ? new IdentifiersPair(unmappedIdentifiers) : new IdentifiersPair(unmappedIdentifiers, mappedIdentifiers);
}
private List<String> identifiers(final Mappings mappings, final String key) {
final List<String> identifiers = new ArrayList<>(mappings.size());
for (int i = 0; i < mappings.size(); i++) {
identifiers.add(identifierFromGlobalId(key, mappings.getNewId(i)));
final int globalId = mappings.getNewId(i);
identifiers.add(identifierFromGlobalId(key, globalId));
}
return identifiers;
}
@@ -342,4 +390,15 @@ public class MappingDataLoader {
T create(V mappings, int mappedSize);
}
public record IdentifiersPair(List<String> unmapped, List<String> mapped, boolean identity) {
public IdentifiersPair(final List<String> unmapped, final List<String> mapped) {
this(unmapped, mapped, false);
}
public IdentifiersPair(final List<String> identifiers) {
this(identifiers, identifiers, true);
}
}
}
@@ -22,6 +22,8 @@
*/
package com.viaversion.viaversion.api.data;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface Mappings {
/**
@@ -84,4 +86,40 @@ public interface Mappings {
* @return mappings with keys and values swapped
*/
Mappings inverse();
/**
* Returns whether the mappings are unchanged identity mappings.
*
* @return whether the mappings are unchanged identity mappings
*/
default boolean isIdentity() {
return false;
}
/**
* Returns whether the mappings null or identity mappings.
*
* @param mappings mappings
* @return whether the mappings are identity mappings
* @see #isFullIdentity(Mappings)
*/
static boolean isIntIdIdentity(@Nullable final Mappings mappings) {
if (mappings == null) {
return true;
}
return mappings instanceof FullMappings fullMappings ? fullMappings.isIntIdIdentity() : mappings.isIdentity();
}
/**
* Returns whether the mappings null or full identity mappings.
* Stronger than {@link #isIntIdIdentity(Mappings)}, but equal to that if not {@link FullMappings}.
*
* @param mappings mappings
* @return whether the mappings are full identity mappings
* @see #isIntIdIdentity(Mappings)
*/
static boolean isFullIdentity(@Nullable final Mappings mappings) {
return mappings == null || mappings.isIdentity();
}
}
@@ -22,16 +22,16 @@
*/
package com.viaversion.viaversion.api.data;
import com.viaversion.viaversion.api.data.MappingDataLoader.IdentifiersPair;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import java.util.List;
public class ParticleMappings extends FullMappingsBase {
private final IntList itemParticleIds = new IntArrayList(4);
private final IntList blockParticleIds = new IntArrayList(4);
public ParticleMappings(final List<String> unmappedIdentifiers, final List<String> mappedIdentifiers, final Mappings mappings) {
super(unmappedIdentifiers, mappedIdentifiers, mappings);
public ParticleMappings(final IdentifiersPair identifiersPair, final Mappings mappings) {
super(identifiersPair, mappings);
addBlockParticle("block");
addBlockParticle("falling_dust");
addBlockParticle("block_marker");
@@ -31,8 +31,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
* Represents an animal variant (e.g. for cows, pigs, chickens).
*
* @param modelType model type id
* @param texture texture path
* @param biomes biomes this variant can spawn in, if limited to specific biomes
* @param texture texture path
* @param biomes biomes this variant can spawn in, if limited to specific biomes
*/
public record AnimalVariant(int modelType, String texture, @Nullable HolderSet biomes) {
@@ -38,7 +38,7 @@ public interface EitherHolder<T> {
/**
* Returns an indirect holder via the resource key.
*
* @param key the resource key
* @param key the resource key
* @param <T> the type of the value
* @return a new holder with the given resource key
*/
@@ -163,7 +163,7 @@ public final class DataPaletteImpl implements DataPalette {
}
}
private class ByteChunkData implements ChunkData {
private final class ByteChunkData implements ChunkData {
private final byte[] data;
public ByteChunkData(int size) {
@@ -187,7 +187,7 @@ public final class DataPaletteImpl implements DataPalette {
}
}
private static class ShortChunkData implements ChunkData {
private static final class ShortChunkData implements ChunkData {
private final short[] data;
public ShortChunkData(byte[] data) {
@@ -53,7 +53,7 @@ public interface CodecContext {
* Returns the key for a stored mapping type and its numeric id.
*
* @param mappingType mapping type
* @param id numeric id
* @param id numeric id
* @return the key
*/
Key key(MappingData.MappingType mappingType, int id);
@@ -62,7 +62,7 @@ public interface CodecContext {
* Returns the numeric id for a stored mapping type and its identifier.
*
* @param mappingType mapping type
* @param identifier identifier
* @param identifier identifier
* @return the numeric id, or -1 if not found
*/
int id(MappingData.MappingType mappingType, String identifier);
@@ -75,7 +75,7 @@ public interface CodecContext {
* Returns the key for a client-synchronized registry element.
*
* @param registry registry key
* @param id numeric id
* @param id numeric id
* @return the key
*/
Key registryKey(String registry, int id);
@@ -81,12 +81,12 @@ public interface Ops {
/**
* Writes the given value or default value if the value is null.
*
* @param key map key
* @param type type of the value
* @param key map key
* @param type type of the value
* @param value the value to write, or null
* @param def default value to write if the value is null
* @param def default value to write if the value is null
* @param <V> value type
* @return self
* @param <V> value type
*/
default <V> MapSerializer write(final String key, final Type<V> type, @Nullable final V value, final V def) {
write(Types.STRING, key, type, value != null ? value : def);
@@ -96,11 +96,11 @@ public interface Ops {
/**
* Writes the given value if it is not null.
*
* @param key map key
* @param type type of the value
* @param key map key
* @param type type of the value
* @param value the value to write, or null
* @param <V> value type
* @return self
* @param <V> value type
*/
default <V> MapSerializer writeOptional(final String key, final Type<V> type, @Nullable final V value) {
if (value != null) {
@@ -112,12 +112,12 @@ public interface Ops {
/**
* Writes the given value if it is not null and not equal to the default value.
*
* @param key map key
* @param type type of the value
* @param key map key
* @param type type of the value
* @param value the value to write, or null
* @param def default value to compare against
* @param def default value to compare against
* @param <V> value type
* @return self
* @param <V> value type
*/
default <V> MapSerializer writeOptional(final String key, final Type<V> type, @Nullable final V value, final V def) {
if (value != null && !Objects.deepEquals(value, def)) {
@@ -145,13 +145,13 @@ public enum EntityTypes1_14 implements EntityType {
SHEEP(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -146,13 +146,13 @@ public enum EntityTypes1_15 implements EntityType {
BEE(ABSTRACT_ANIMAL),
TURTLE(ABSTRACT_ANIMAL),
FOX(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -148,13 +148,13 @@ public enum EntityTypes1_16 implements EntityType {
FOX(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -148,13 +148,13 @@ public enum EntityTypes1_16_2 implements EntityType {
FOX(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -154,13 +154,13 @@ public enum EntityTypes1_17 implements EntityType {
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -158,13 +158,13 @@ public enum EntityTypes1_19 implements EntityType {
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -158,13 +158,13 @@ public enum EntityTypes1_19_3 implements EntityType {
GOAT(ABSTRACT_ANIMAL),
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -165,13 +165,13 @@ public enum EntityTypes1_19_4 implements EntityType {
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -166,13 +166,13 @@ public enum EntityTypes1_20_3 implements EntityType {
HOGLIN(ABSTRACT_ANIMAL),
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -171,13 +171,13 @@ public enum EntityTypes1_20_5 implements EntityType {
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -185,6 +185,7 @@ public enum EntityTypes1_21_11 implements EntityType {
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
HAPPY_GHAST(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
@@ -192,7 +193,6 @@ public enum EntityTypes1_21_11 implements EntityType {
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -176,13 +176,13 @@ public enum EntityTypes1_21_2 implements EntityType {
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -176,13 +176,13 @@ public enum EntityTypes1_21_4 implements EntityType {
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
COW(ABSTRACT_ANIMAL),
MOOSHROOM(COW),
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -179,6 +179,7 @@ public enum EntityTypes1_21_5 implements EntityType {
STRIDER(ABSTRACT_ANIMAL),
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
@@ -186,7 +187,6 @@ public enum EntityTypes1_21_5 implements EntityType {
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -180,6 +180,7 @@ public enum EntityTypes1_21_6 implements EntityType {
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
HAPPY_GHAST(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
@@ -187,7 +188,6 @@ public enum EntityTypes1_21_6 implements EntityType {
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -185,6 +185,7 @@ public enum EntityTypes1_21_9 implements EntityType {
SNIFFER(ABSTRACT_ANIMAL),
ARMADILLO(ABSTRACT_ANIMAL),
HAPPY_GHAST(ABSTRACT_ANIMAL),
OCELOT(ABSTRACT_ANIMAL),
ABSTRACT_COW(ABSTRACT_ANIMAL, null),
COW(ABSTRACT_COW),
@@ -192,7 +193,6 @@ public enum EntityTypes1_21_9 implements EntityType {
TAMABLE_ANIMAL(ABSTRACT_ANIMAL, null),
CAT(TAMABLE_ANIMAL),
OCELOT(TAMABLE_ANIMAL),
WOLF(TAMABLE_ANIMAL),
PARROT(TAMABLE_ANIMAL),
@@ -43,6 +43,10 @@ public abstract class AbstractEntityDataTypes implements EntityDataTypes {
return values;
}
public Class<? extends EntityDataType> getDataTypeClass() {
return byId(0).getClass();
}
protected EntityDataType add(final int typeId, final Type<?> type) {
if (values[typeId] != null) {
throw new IllegalArgumentException("Entity data type ID " + typeId + " is already registered as " + values[typeId]);
@@ -37,6 +37,7 @@ import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable, Rewritable {
@@ -226,7 +227,7 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
}
public static class Display implements Copyable {
public static final String[] DISPLAY_TYPES = {"default", "hidden", "override_text"};
public static final String[] DISPLAY_TYPES = {"default", "hidden", "override"};
public static final Display DEFAULT = new Display(0);
private final int id;
@@ -246,6 +247,17 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
public Display copy() {
return this;
}
@Override
public boolean equals(final Object o) {
if (!(o instanceof final Display display)) return false;
return id == display.id;
}
@Override
public int hashCode() {
return id;
}
}
public static final class OverrideText extends Display {
@@ -271,5 +283,19 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
public OverrideText copy() {
return new OverrideText(this.component.copy());
}
@Override
public boolean equals(final Object o) {
if (!(o instanceof final OverrideText that)) return false;
if (!super.equals(o)) return false;
return Objects.equals(component, that.component);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + Objects.hashCode(component);
return result;
}
}
}
@@ -180,7 +180,7 @@ public interface ViaPlatform<T> {
/**
* Modify the server details payload before it is sent.
* This method allows adding, changing, or removing fields from the payload.
* It is only called if {@link ViaVersionConfig#sendPlayerDetails()} is true.
* It is only called if {@link ViaVersionConfig#sendServerDetails()} is true.
*
* @param connection The UserConnection
* @param payload The constructed payload to modify
@@ -1,36 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol;
/**
* A simple protocol which does not have any packet types.
* <p>
* {@link AbstractProtocol} should be preferred over this class in most cases.
*/
public abstract class AbstractSimpleProtocol extends AbstractProtocol<SimpleProtocol.DummyPacketTypes, SimpleProtocol.DummyPacketTypes,
SimpleProtocol.DummyPacketTypes, SimpleProtocol.DummyPacketTypes> implements SimpleProtocol {
protected AbstractSimpleProtocol() {
super(null, null, null, null);
}
}
@@ -68,10 +68,6 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
registerServerbound(state, packetType.getId(), packetType.getId(), handler, false);
}
default void registerServerbound(State state, int unmappedPacketId, int mappedPacketId, @Nullable PacketHandler handler) {
registerServerbound(state, unmappedPacketId, mappedPacketId, handler, false);
}
/**
* Registers a serverbound packet, with id transformation and remapper.
*
@@ -79,19 +75,17 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
* @param unmappedPacketId unmapped packet id
* @param mappedPacketId mapped packet id
* @param handler packet handler
* @param override whether an existing mapper should be overridden
* @see #registerServerbound(ServerboundPacketType, ServerboundPacketType, PacketHandler, boolean)
*/
default void registerServerbound(State state, int unmappedPacketId, int mappedPacketId, @Nullable PacketHandler handler) {
registerServerbound(state, unmappedPacketId, mappedPacketId, handler, false);
}
@Deprecated(forRemoval = true)
void registerServerbound(State state, int unmappedPacketId, int mappedPacketId, @Nullable PacketHandler handler, boolean override);
void cancelServerbound(State state, int mappedPacketId);
default void registerClientbound(State state, int unmappedPacketId, int mappedPacketId, @Nullable PacketHandler handler) {
registerClientbound(state, unmappedPacketId, mappedPacketId, handler, false);
}
void cancelClientbound(State state, int unmappedPacketId);
/**
* Registers a clientbound packet, with id transformation and remapper.
*
@@ -99,9 +93,15 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
* @param unmappedPacketId unmapped packet id
* @param mappedPacketId mapped packet id
* @param handler packet handler
* @param override whether an existing mapper should be overridden
* @see #registerClientbound(ClientboundPacketType, ClientboundPacketType, PacketHandler, boolean)
*/
default void registerClientbound(State state, int unmappedPacketId, int mappedPacketId, @Nullable PacketHandler handler) {
registerClientbound(state, unmappedPacketId, mappedPacketId, handler, false);
}
void cancelClientbound(State state, int unmappedPacketId);
@Deprecated(forRemoval = true)
void registerClientbound(State state, int unmappedPacketId, int mappedPacketId, @Nullable PacketHandler handler, boolean override);
// ---------------------------------------------------------------------------------------
@@ -144,6 +144,7 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
* @param handler packet handler
* @param override whether an existing mapping should be overridden if present
*/
@Deprecated(forRemoval = true)
void registerClientbound(CU packetType, @Nullable CM mappedPacketType, @Nullable PacketHandler handler, boolean override);
/**
@@ -191,6 +192,7 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
* @param handler packet handler
* @param override whether an existing mapping should be overridden if present
*/
@Deprecated(forRemoval = true)
void registerServerbound(SU packetType, @Nullable SM mappedPacketType, @Nullable PacketHandler handler, boolean override);
/**
@@ -260,6 +262,22 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
*/
void appendServerbound(SU type, PacketHandler handler);
/**
* Replaces a clientbound packet type handler with another.
*
* @param type clientbound packet type
* @param handler packet handler
*/
void replaceClientbound(CU type, @Nullable PacketHandler handler);
/**
* Replaces a serverbound packet type handler with another.
*
* @param type serverbound packet type
* @param handler packet handler
*/
void replaceServerbound(SU type, @Nullable PacketHandler handler);
/**
* Transform a packet using this protocol
*
@@ -441,4 +459,13 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
default boolean isBaseProtocol() {
return false;
}
/**
* Marks this protocol as dependent on another. Before being initialized, it will wait for the dependency's completion.
*
* @return protocol class to depend on
*/
default @Nullable Class<? extends Protocol<?, ?, ?, ?>> dependsOn() {
return null;
}
}
@@ -249,7 +249,17 @@ public interface ProtocolManager {
*
* @return true if the executor has now been shut down
*/
boolean checkForMappingCompletion();
default boolean checkForMappingCompletion() {
return checkForMappingCompletion(false);
}
/**
* Shuts down the executor and uncaches mappings if all futures have been completed.
*
* @param propagateErrors whether to propagate errors from the futures to the caller
* @return true if the executor has now been shut down
*/
boolean checkForMappingCompletion(boolean propagateErrors);
/**
* Executes the given runnable asynchronously, adding a {@link CompletableFuture}
@@ -50,6 +50,11 @@ final class PacketIdMapping implements PacketMapping {
}
}
@Override
public void setHandler(@Nullable final PacketHandler handler) {
this.handler = handler;
}
@Override
public @Nullable PacketHandler handler() {
return handler;
@@ -39,6 +39,13 @@ public interface PacketMapping {
*/
void applyType(PacketWrapper wrapper);
/**
* Replaces the current packet handler.
*
* @param handler packet transformer
*/
void setHandler(@Nullable PacketHandler handler);
/**
* Returns a packet transformer to transform a packet from one protocol version to another.
*
@@ -52,6 +52,11 @@ final class PacketTypeMapping implements PacketMapping {
}
}
@Override
public void setHandler(@Nullable final PacketHandler handler) {
this.handler = handler;
}
@Override
public @Nullable PacketHandler handler() {
return handler;
@@ -93,7 +93,7 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_21_7 = register(772, "1.21.7-1.21.8", new SubVersionRange("1.21", 7, 8));
public static final ProtocolVersion v1_21_9 = register(773, "1.21.9-1.21.10", new SubVersionRange("1.21", 9, 10));
public static final ProtocolVersion v1_21_11 = register(774, "1.21.11");
public static final ProtocolVersion v26_1 = register(775, "26.1");
public static final ProtocolVersion v26_1 = register(775, "26.1-26.1.2", new SubVersionRange("26.1", 0, 2));
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
static {
@@ -26,6 +26,7 @@ import com.google.gson.JsonElement;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface ComponentRewriter {
@@ -37,4 +38,6 @@ public interface ComponentRewriter {
JsonElement processText(UserConnection connection, @Nullable String json);
void handleShowItem(UserConnection connection, CompoundTag itemTag);
void passthroughAndProcess(PacketWrapper wrapper);
}
@@ -28,6 +28,7 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.protocol.Protocol;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter<T> {
@@ -39,6 +40,8 @@ public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter
*/
EntityType typeFromId(int type);
@Nullable EntityType typeFromId(String type);
/**
* Returns the entity type from the given id.
* From 1.14 and onwards, this is the same exact value as {@link #typeFromId(int)}.
@@ -70,9 +73,9 @@ public interface EntityRewriter<T extends Protocol<?, ?, ?, ?>> extends Rewriter
/**
* Handles and transforms entity data of an entity.
*
* @param entityId entity id
* @param dataList full, mutable list of entity data
* @param connection user connection
* @param entityId entity id
* @param dataList full, mutable list of entity data
* @param connection user connection
*/
void handleEntityData(int entityId, List<EntityData> dataList, UserConnection connection);
@@ -24,15 +24,20 @@ package com.viaversion.viaversion.api.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.util.KeyMappings;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface RegistryDataRewriter {
void handle(PacketWrapper wrapper);
@Nullable
KeyMappings getMappings(String registryKey);
boolean shouldRemoveRegistry(String registryKey);
boolean hasRegistriesToRemove();
void updateDialog(UserConnection connection, CompoundTag tag);
}
@@ -40,7 +40,7 @@ public class BlockEntityType1_20_2 extends Type<BlockEntity> {
final byte xz = buffer.readByte();
final short y = buffer.readShort();
final int typeId = Types.VAR_INT.readPrimitive(buffer);
final CompoundTag tag = Types.COMPOUND_TAG.read(buffer);
final CompoundTag tag = Types.TRUSTED_COMPOUND_TAG.read(buffer);
return new BlockEntityImpl(xz, y, typeId, tag);
}
@@ -49,6 +49,6 @@ public class BlockEntityType1_20_2 extends Type<BlockEntity> {
buffer.writeByte(entity.packedXZ());
buffer.writeShort(entity.y());
Types.VAR_INT.writePrimitive(buffer, entity.typeId());
Types.COMPOUND_TAG.write(buffer, entity.tag());
Types.TRUSTED_COMPOUND_TAG.write(buffer, entity.tag());
}
}
@@ -59,17 +59,13 @@ public class ParticleType extends DynamicType<Particle> {
return protocol.getMappingData().getParticleMappings();
}
public static DataReader<Particle> itemHandler(final Type<Item> itemType) {
return (buf, particle) -> particle.add(itemType, itemType.read(buf));
}
public static final class Readers {
public static final DataReader<Particle> BLOCK = (buf, particle) -> {
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Flat Block
};
public static final DataReader<Particle> ITEM1_13 = itemHandler(Types.ITEM1_13);
public static final DataReader<Particle> ITEM1_13_2 = itemHandler(Types.ITEM1_13_2);
public static final DataReader<Particle> ITEM1_13 = item(Types.ITEM1_13);
public static final DataReader<Particle> ITEM1_13_2 = item(Types.ITEM1_13_2);
public static final DataReader<Particle> DUST = (buf, particle) -> {
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Red 0-1
particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green 0-1
@@ -172,4 +168,103 @@ public class ParticleType extends DynamicType<Particle> {
return (buf, particle) -> particle.add(item, item.read(buf));
}
}
public static final class Fillers {
public static DynamicType<Particle>.DataFiller fill1_13_2(final Protocol<?, ?, ?, ?> protocol, final ParticleType type, final boolean useMappedNames) {
return type.filler(protocol, useMappedNames)
.reader("item", Readers.item(protocol.getItemRewriter().mappedItemType()))
.reader("block", Readers.BLOCK)
.reader("dust", Readers.DUST)
.reader("falling_dust", Readers.BLOCK);
}
public static DataFiller fill1_17(final Protocol<?, ?, ?, ?> protocol, final ParticleType type) {
return fill1_13_2(protocol, type, true)
.reader("dust_color_transition", Readers.DUST_TRANSITION)
.reader("vibration", Readers.VIBRATION);
}
public static void fill1_18(final Protocol<?, ?, ?, ?> protocol, final ParticleType type) {
fill1_17(protocol, type).reader("block_marker", Readers.BLOCK);
}
public static void fill1_19(final Protocol<?, ?, ?, ?> protocol, final ParticleType type) {
type.filler(protocol)
.reader("item", Readers.item(protocol.getItemRewriter().mappedItemType()))
.reader("block", Readers.BLOCK)
.reader("block_marker", Readers.BLOCK)
.reader("dust", Readers.DUST)
.reader("falling_dust", Readers.BLOCK)
.reader("dust_color_transition", Readers.DUST_TRANSITION)
.reader("vibration", Readers.VIBRATION1_19)
.reader("sculk_charge", Readers.SCULK_CHARGE)
.reader("shriek", Readers.SHRIEK);
}
public static DataFiller fill1_20_3(final Protocol<?, ?, ?, ?> protocol, final ParticleType type) {
return type.filler(protocol)
.reader("item", Readers.item(protocol.getItemRewriter().mappedItemType()))
.reader("block", Readers.BLOCK)
.reader("block_marker", Readers.BLOCK)
.reader("dust", Readers.DUST)
.reader("falling_dust", Readers.BLOCK)
.reader("dust_color_transition", Readers.DUST_TRANSITION)
.reader("vibration", Readers.VIBRATION1_20_3)
.reader("sculk_charge", Readers.SCULK_CHARGE)
.reader("shriek", Readers.SHRIEK);
}
public static void fill1_20_5(final Protocol<?, ?, ?, ?> protocol, final ParticleType type) {
fill1_20_3(protocol, type)
.reader("dust_pillar", Readers.BLOCK)
.reader("entity_effect", Readers.COLOR);
}
public static void fill1_21_2(final Protocol<?, ?, ?, ?> protocol) {
protocol.mappedTypes().particle().filler(protocol)
.reader("item", Readers.item(protocol.getItemRewriter().mappedItemType()))
.reader("block", Readers.BLOCK)
.reader("block_marker", Readers.BLOCK)
.reader("dust_pillar", Readers.BLOCK)
.reader("falling_dust", Readers.BLOCK)
.reader("block_crumble", Readers.BLOCK)
.reader("dust", Readers.DUST1_21_2)
.reader("dust_color_transition", Readers.DUST_TRANSITION1_21_2)
.reader("vibration", Readers.VIBRATION1_20_3)
.reader("sculk_charge", Readers.SCULK_CHARGE)
.reader("shriek", Readers.SHRIEK)
.reader("entity_effect", Readers.COLOR)
.reader("trail", Readers.TRAIL1_21_2);
}
public static DataFiller fill1_21_4(final Protocol<?, ?, ?, ?> protocol) {
return protocol.mappedTypes().particle().filler(protocol)
.reader("item", Readers.item(protocol.getItemRewriter().mappedItemTemplateType()))
.reader("block", Readers.BLOCK)
.reader("block_marker", Readers.BLOCK)
.reader("dust_pillar", Readers.BLOCK)
.reader("falling_dust", Readers.BLOCK)
.reader("block_crumble", Readers.BLOCK)
.reader("dust", Readers.DUST1_21_2)
.reader("dust_color_transition", Readers.DUST_TRANSITION1_21_2)
.reader("vibration", Readers.VIBRATION1_20_3)
.reader("sculk_charge", Readers.SCULK_CHARGE)
.reader("shriek", Readers.SHRIEK)
.reader("entity_effect", Readers.COLOR)
.reader("trail", Readers.TRAIL1_21_4);
}
public static DataFiller fill1_21_5(final Protocol<?, ?, ?, ?> protocol) {
return fill1_21_4(protocol).reader("tinted_leaves", Readers.COLOR);
}
public static void fill1_21_9(final Protocol<?, ?, ?, ?> protocol) {
fill1_21_5(protocol)
.reader("dragon_breath", Readers.POWER)
.reader("effect", Readers.SPELL)
.reader("instant_effect", Readers.SPELL)
.reader("flash", Readers.COLOR);
}
}
}
@@ -60,7 +60,7 @@ public class InformativeException extends RuntimeException {
@Override
public String getMessage() {
final 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 the full error (!) from the console on the Via support Discord or open an issue on the relevant GitHub repository.\n");
boolean first = true;
for (final DataEntry entry : dataEntries) {
if (!first) {
@@ -48,7 +48,7 @@ public final class Key {
* Creates a new key with the given namespace and path.
*
* @param namespace the namespace of the identifier
* @param path the path of the identifier
* @param path the path of the identifier
* @return a new key with the given namespace and path
*/
public static Key of(final String namespace, final String path) {
@@ -49,6 +49,20 @@ public final class NMSUtil {
}
}
public static Class<?> nms(String className, String... fallbackFullClassNames) throws ClassNotFoundException {
try {
return Class.forName(NMS + "." + className);
} catch (ClassNotFoundException ignored) {
}
for (final String fallbackFullClassName : fallbackFullClassNames) {
try {
return Class.forName(fallbackFullClassName);
} catch (ClassNotFoundException ignored) {
}
}
throw new ClassNotFoundException(className);
}
public static Class<?> obc(String className) throws ClassNotFoundException {
return Class.forName(BASE + "." + className);
}
@@ -105,7 +105,8 @@ public class BukkitViaInjector extends LegacyViaInjector {
// Grab the ping class and find the field to access it
Class<?> pingClazz = NMSUtil.nms(
"ServerPing",
"net.minecraft.network.protocol.status.ServerPing"
"net.minecraft.network.protocol.status.ServerPing",
"net.minecraft.network.protocol.status.ServerStatus"
);
Object ping = null;
for (Field field : serverClazz.getDeclaredFields()) {
@@ -120,7 +121,8 @@ public class BukkitViaInjector extends LegacyViaInjector {
// Now get the ServerData inside ServerPing
Class<?> serverDataClass = NMSUtil.nms(
"ServerPing$ServerData",
"net.minecraft.network.protocol.status.ServerPing$ServerData"
"net.minecraft.network.protocol.status.ServerPing$ServerData",
"net.minecraft.network.protocol.status.ServerStatus$Version"
);
Object serverData = null;
for (Field field : pingClazz.getDeclaredFields()) {
@@ -155,7 +157,8 @@ public class BukkitViaInjector extends LegacyViaInjector {
);
Class<?> connectionClass = NMSUtil.nms(
"ServerConnection",
"net.minecraft.server.network.ServerConnection"
"net.minecraft.server.network.ServerConnection",
"net.minecraft.server.network.ServerConnectionListener"
);
Object server = ReflectionUtil.invokeStatic(serverClass, "getServer");
@@ -2,23 +2,18 @@
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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:
* 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.
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 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.
*
* 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.
* 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.protocol;
@@ -27,6 +22,7 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.item.ItemHasher;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketType;
@@ -39,10 +35,17 @@ import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypeMap;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.rewriter.MappingDataListener;
import com.viaversion.viaversion.api.rewriter.Rewriter;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.data.item.ItemHasherBase;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.exception.InformativeException;
import com.viaversion.viaversion.protocol.shared_registration.SharedRegistrations;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
import com.viaversion.viaversion.util.ProtocolLogger;
import com.viaversion.viaversion.util.ProtocolUtil;
import java.util.HashMap;
@@ -74,6 +77,8 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
private final Map<Class<?>, Object> storedObjects = new HashMap<>();
private boolean initialized;
private ProtocolLogger logger;
private ProtocolVersion serverVersion;
private ProtocolVersion clientVersion;
@Deprecated
protected AbstractProtocol() {
@@ -104,6 +109,11 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
if (logger == null) {
logger = createLogger();
}
// Apply shared registrations based on protocol version range
// Run before registerPackets, so implementations have to call append intentionally
applySharedRegistrations();
registerPackets();
registerConfigurationChangeHandlers();
@@ -128,6 +138,13 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
/**
* Applies shared registrations. Can be overridden to remove or add registrations.
*/
protected void applySharedRegistrations() {
SharedRegistrations.defaultRegistrations().applyMatching(this);
}
protected ProtocolLogger createLogger() {
return new ProtocolLogger(getClass());
}
@@ -177,6 +194,20 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
@Override
public void replaceClientbound(final CU type, @Nullable final PacketHandler handler) {
final PacketMapping mapping = clientboundMappings.mappedPacket(type.state(), type.getId());
Preconditions.checkNotNull(mapping, "Packet %s has no handler to replace", type);
mapping.setHandler(handler);
}
@Override
public void replaceServerbound(final SU type, @Nullable final PacketHandler handler) {
final PacketMapping mapping = serverboundMappings.mappedPacket(type.state(), type.getId());
Preconditions.checkNotNull(mapping, "Packet %s has no handler to replace", type);
mapping.setHandler(handler);
}
private <U extends PacketType, M extends PacketType> void registerPacketIdChanges(
Map<State, PacketTypeMap<U>> unmappedPacketTypes,
Map<State, PacketTypeMap<M>> mappedPacketTypes,
@@ -214,6 +245,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
@Override
public final void loadMappingData() {
getMappingData().load();
initialize();
onMappingDataLoaded();
}
@@ -248,10 +280,21 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
}
}
protected void addEntityTracker(UserConnection connection) {
final EntityType playerEntityType = getEntityRewriter().typeFromId("player");
Preconditions.checkNotNull(playerEntityType, "Player entity type not found");
connection.addEntityTracker(this.getClass(), new EntityTrackerBase(connection, playerEntityType));
}
protected void addEntityTracker(UserConnection connection, EntityTracker tracker) {
connection.addEntityTracker(this.getClass(), tracker);
}
protected void addItemHasher(UserConnection connection) {
connection.addItemHasher(this.getClass(), new ItemHasherBase(this, connection));
}
@Deprecated(forRemoval = true)
protected void addItemHasher(UserConnection connection, ItemHasher hasher) {
connection.addItemHasher(this.getClass(), hasher);
}
@@ -289,6 +332,46 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
return packetTypesProvider.unmappedClientboundType(State.CONFIGURATION, "FINISH_CONFIGURATION");
}
/**
* Returns the server protocol version for this protocol,
* or null if not set (e.g. for base protocols).
*
* @return the server protocol version
*/
public @Nullable ProtocolVersion getServerVersion() {
return serverVersion;
}
/**
* Sets the server protocol version for this protocol.
* Called by the protocol manager before {@link #initialize()}.
*
* @param serverVersion the server protocol version
*/
public void setServerVersion(final ProtocolVersion serverVersion) {
this.serverVersion = serverVersion;
}
/**
* Returns the client protocol version for this protocol,
* or null if not set (e.g. for base protocols).
*
* @return the client protocol version for this protocol
*/
public @Nullable ProtocolVersion getClientVersion() {
return clientVersion;
}
/**
* Sets the client protocol version for this protocol.
* Called by the protocol manager before {@link #initialize()}.
*
* @param clientVersion the client protocol version for this protocol
*/
public void setClientVersion(final ProtocolVersion clientVersion) {
this.clientVersion = clientVersion;
}
// ---------------------------------------------------------------------------------
@Override
@@ -297,7 +380,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
PacketMapping packetMapping = PacketMapping.of(mappedPacketId, handler);
if (!override && serverboundMappings.hasMapping(state, unmappedPacketId)) {
Via.getPlatform().getLogger().log(Level.WARNING, unmappedPacketId + " already registered!" +
" If this override is intentional, set override to true. Stacktrace: ", new Exception());
" If this override is intentional, use replaceServerbound instead. Stacktrace: ", new Exception());
}
serverboundMappings.addMapping(state, unmappedPacketId, packetMapping);
}
@@ -313,7 +396,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
PacketMapping packetMapping = PacketMapping.of(mappedPacketId, handler);
if (!override && clientboundMappings.hasMapping(state, unmappedPacketId)) {
Via.getPlatform().getLogger().log(Level.WARNING, unmappedPacketId + " already registered!" +
" If override is intentional, set override to true. Stacktrace: ", new Exception());
" If override is intentional, use replaceClientbound instead. Stacktrace: ", new Exception());
}
clientboundMappings.addMapping(state, unmappedPacketId, packetMapping);
}
@@ -373,8 +456,8 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
PacketMapping packetMapping = PacketMapping.of(mappedPacketType, handler);
if (!override && packetMappings.hasMapping(packetType)) {
getLogger().log(Level.WARNING, packetType + " already registered!" +
" If override is intentional, set override to true. Stacktrace: ", new Exception());
throw new IllegalArgumentException("Packet type " + packetType + " already registered! If override is intentional, use "
+ (packetType.direction() == Direction.SERVERBOUND ? "replaceServerbound" : "replaceClientbound") + " instead.");
}
packetMappings.addMapping(packetType, packetMapping);
}
@@ -443,6 +526,14 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
return logger;
}
public com.viaversion.viaversion.rewriter.@Nullable BlockRewriter<CU> getBlockRewriter() {
return null;
}
public @Nullable RecipeDisplayRewriter<CU> getRecipeRewriter() {
return null;
}
private void printRemapError(Direction direction, State state, int unmappedPacketId, int mappedPacketId, InformativeException e) {
// Don't print errors during handshake/login/status
if (state != State.PLAY && direction == Direction.SERVERBOUND && !Via.getManager().debugHandler().enabled()) {
@@ -43,6 +43,7 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.CodecException;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@@ -52,7 +53,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class UserConnectionImpl implements UserConnection {
@@ -34,8 +34,6 @@ import com.viaversion.viaversion.codec.CodecRegistryContext;
import com.viaversion.viaversion.codec.hash.HashFunction;
import com.viaversion.viaversion.codec.hash.HashOps;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -58,7 +56,7 @@ public class ItemHasherBase implements ItemHasher {
/**
* Returns the hashed item for the given item. Not all data may be successfully hashed.
*
* @param item the item to hash
* @param item the item to hash
* @param mapped whether the item is mapped to the client version
* @return the hashed item
*/
@@ -83,7 +81,7 @@ public class ItemHasherBase implements ItemHasher {
/**
* Tracks the data for the given data container, storing the original hashes via the now transformed data hashes.
*
* @param customData custom_data tag
* @param customData custom_data tag
* @param originalHashedItem the original (pre-transformed) hashed item
*/
public void trackOriginalHashedItem(final CompoundTag customData, final HashedItem originalHashedItem) {
@@ -97,7 +95,7 @@ public class ItemHasherBase implements ItemHasher {
* Returns a copy of the original hashed item for a given custom_data hash.
*
* @param customDataHash custom_data hash
* @param clientItem the hashed item from the client that the original should be retrieved for
* @param clientItem the hashed item from the client that the original should be retrieved for
* @return the original hashed item, or null if not found
*/
public @Nullable HashedItem originalHashedItem(final int customDataHash, final HashedItem clientItem) {
@@ -0,0 +1,34 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.SimpleProtocol;
/**
* A simple protocol which does not have any packet types.
* <p>
* {@link AbstractProtocol} should be preferred over this class in most cases.
*/
public abstract class AbstractSimpleProtocol extends AbstractProtocol<SimpleProtocol.DummyPacketTypes, SimpleProtocol.DummyPacketTypes,
SimpleProtocol.DummyPacketTypes, SimpleProtocol.DummyPacketTypes> implements SimpleProtocol {
protected AbstractSimpleProtocol() {
super(null, null, null, null);
}
}
@@ -23,6 +23,7 @@ import com.google.common.collect.Range;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.ProtocolManager;
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
@@ -38,6 +39,7 @@ import com.viaversion.viaversion.api.protocol.version.ServerProtocolVersion;
import com.viaversion.viaversion.api.protocol.version.VersionType;
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
import com.viaversion.viaversion.protocol.packet.VersionedPacketTransformerImpl;
import com.viaversion.viaversion.protocol.shared_registration.def.DefaultRegistrations;
import com.viaversion.viaversion.protocols.base.InitialBaseProtocol;
import com.viaversion.viaversion.protocols.base.v1_16.ClientboundBaseProtocol1_16;
import com.viaversion.viaversion.protocols.base.v1_7.ClientboundBaseProtocol1_7;
@@ -95,6 +97,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectSortedMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -113,9 +116,7 @@ import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.logging.Level;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ProtocolManagerImpl implements ProtocolManager {
@@ -146,6 +147,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
worker.setName("Via-Mappingloader-" + threadIndex.incrementAndGet());
return worker;
}, ForkJoinWorkerThread.getDefaultUncaughtExceptionHandler(), true);
DefaultRegistrations.apply();
}
public void registerProtocols() {
@@ -225,8 +228,11 @@ public class ProtocolManagerImpl implements ProtocolManager {
@Override
public void registerProtocol(Protocol protocol, List<ProtocolVersion> supportedClientVersion, ProtocolVersion serverVersion) {
// Register the protocol's handlers
protocol.initialize();
// Set the server version on AbstractProtocol instances before initialization
if (protocol instanceof AbstractProtocol<?, ?, ?, ?> abstractProtocol) {
abstractProtocol.setServerVersion(serverVersion);
abstractProtocol.setClientVersion(supportedClientVersion.stream().max(ProtocolVersion::compareTo).orElseThrow());
}
// Clear cache as this may make new routes.
if (!pathCache.isEmpty()) {
@@ -248,14 +254,22 @@ public class ProtocolManagerImpl implements ProtocolManager {
refreshVersions();
}
if (protocol.hasMappingDataToLoad()) {
if (mappingLoaderExecutor != null) {
// Submit mapping data loading
addMappingLoaderFuture(protocol.getClass(), protocol::loadMappingData);
// Load mapping data and register the protocol's handlers
if (!protocol.hasMappingDataToLoad()) {
protocol.initialize();
return;
}
// Submit mapping data loading
if (mappingLoaderExecutor != null) {
if (protocol.dependsOn() != null) {
addMappingLoaderFuture(protocol.getClass(), protocol.dependsOn(), protocol::loadMappingData);
} else {
// Late protocol adding - just do it on the current thread
protocol.loadMappingData();
addMappingLoaderFuture(protocol.getClass(), protocol::loadMappingData);
}
} else {
// Late protocol adding - just do it on the current thread
protocol.loadMappingData();
}
}
@@ -484,7 +498,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
}
@Override
public boolean checkForMappingCompletion() {
public boolean checkForMappingCompletion(final boolean propagateErrors) {
mappingLoaderLock.readLock().lock();
try {
if (mappingsLoaded) {
@@ -496,6 +510,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
if (!future.isDone()) {
return false;
}
if (propagateErrors) {
future.join();
}
}
shutdownLoaderExecutor();
@@ -507,7 +524,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
@Override
public void addMappingLoaderFuture(Class<? extends Protocol> protocolClass, Runnable runnable) {
CompletableFuture<Void> future = CompletableFuture.runAsync(runnable, mappingLoaderExecutor).exceptionally(mappingLoaderThrowable(protocolClass));
CompletableFuture<Void> future = CompletableFuture.runAsync(runnable, mappingLoaderExecutor)
.whenComplete(($, t) -> logIfErrored(protocolClass, t));
mappingLoaderLock.writeLock().lock();
try {
@@ -519,8 +537,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
@Override
public void addMappingLoaderFuture(Class<? extends Protocol> protocolClass, Class<? extends Protocol> dependsOn, Runnable runnable) {
CompletableFuture<Void> future = getMappingLoaderFuture(dependsOn)
.whenCompleteAsync((v, throwable) -> runnable.run(), mappingLoaderExecutor).exceptionally(mappingLoaderThrowable(protocolClass));
CompletableFuture<Void> future = getMappingLoaderFuture(dependsOn).thenRunAsync(runnable, mappingLoaderExecutor)
.whenComplete(($, t) -> logIfErrored(protocolClass, t));
mappingLoaderLock.writeLock().lock();
try {
@@ -571,10 +589,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
MappingDataLoader.INSTANCE.clearCache();
}
private Function<Throwable, Void> mappingLoaderThrowable(Class<? extends Protocol> protocolClass) {
return throwable -> {
Via.getPlatform().getLogger().log(Level.SEVERE, "Error during mapping loading of " + protocolClass.getSimpleName(), throwable);
return null;
};
private void logIfErrored(final Class<? extends Protocol> protocolClass, @Nullable final Throwable throwable) {
if (throwable != null) {
Via.getPlatform().getLogger().log(Level.SEVERE, "Error during loading of " + protocolClass.getSimpleName(), throwable);
}
}
}
@@ -0,0 +1,23 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration;
public enum PacketBound {
ADDED_AT_MIN,
REMOVED_AT_MAX
}
@@ -0,0 +1,151 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.protocol.version.VersionType;
import com.viaversion.viaversion.protocol.shared_registration.SharedRegistrations.RegistrationAction;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public final class RegistrationBuilder {
private final List<VersionedTemplateGroup> groups = new ArrayList<>();
private final SharedRegistrations registrations;
private VersionType versionType;
RegistrationBuilder(final SharedRegistrations registrations) {
this.registrations = registrations;
}
/**
* Adds a registration for an open-ended version range.
*
* @param min minimum version, inclusive
* @param action registration action
* @return this
*/
public RegistrationBuilder since(final ProtocolVersion min, final RegistrationAction<?, ?> action) {
checkVersionType(min);
groups.add(new VersionedTemplateGroup(action, min, null));
return this;
}
/**
* Adds a registration for a version range.
*
* @param min minimum version, inclusive
* @param max maximum version, exclusive
* @param action registration action
* @return this
*/
public RegistrationBuilder range(final ProtocolVersion min, final ProtocolVersion max, final RegistrationAction<?, ?> action) {
checkVersionType(min);
checkVersionType(max);
groups.add(new VersionedTemplateGroup(action, min, max));
return this;
}
public <CU extends ClientboundPacketType, SU extends ServerboundPacketType> RegistrationBuilder ranges(
final ProtocolVersion min, final Consumer<RangesBuilder<CU, SU>> consumer
) {
consumer.accept(new RangesBuilder<>(min));
return this;
}
public <CU extends ClientboundPacketType, SU extends ServerboundPacketType, R> RegistrationBuilder ranges(
final Function<RegistrationContext<CU, SU>, R> adapter, final ProtocolVersion min,
final Consumer<TypedRangesBuilder<CU, SU, R>> consumer
) {
consumer.accept(new TypedRangesBuilder<>(adapter, min));
return this;
}
public void register() {
registrations.register(versionType, groups);
}
private void checkVersionType(final ProtocolVersion version) {
if (versionType == null) {
versionType = version.getVersionType();
} else if (versionType != version.getVersionType()) {
throw new IllegalArgumentException("Cannot mix different version types in the same registration builder");
}
}
public class RangesBuilder<CU extends ClientboundPacketType, SU extends ServerboundPacketType> {
private ProtocolVersion currentMin;
private boolean completed;
private RangesBuilder(final ProtocolVersion min) {
this.currentMin = min;
}
public RangesBuilder<CU, SU> to(final ProtocolVersion max, final RegistrationAction<CU, SU> action) {
Preconditions.checkState(!completed, "Range chain already completed");
RegistrationBuilder.this.range(currentMin, max, action);
currentMin = max;
return this;
}
public RegistrationBuilder since(final RegistrationAction<CU, SU> action) {
Preconditions.checkState(!completed, "Range chain already completed");
completed = true;
return RegistrationBuilder.this.since(currentMin, action);
}
}
public final class TypedRangesBuilder<CU extends ClientboundPacketType, SU extends ServerboundPacketType, R> extends RangesBuilder<CU, SU> {
private final Function<RegistrationContext<CU, SU>, R> adapter;
private TypedRangesBuilder(final Function<RegistrationContext<CU, SU>, R> adapter, final ProtocolVersion min) {
super(min);
this.adapter = adapter;
}
public TypedRangesBuilder<CU, SU, R> to(final ProtocolVersion max, final TypedRegistrationAction<CU, SU, R> action) {
to(max, wrapAction(action));
return this;
}
public TypedRangesBuilder<CU, SU, R> since(final TypedRegistrationAction<CU, SU, R> action) {
since(wrapAction(action));
return this;
}
private RegistrationAction<CU, SU> wrapAction(final TypedRegistrationAction<CU, SU, R> action) {
return ctx -> {
final R rewriter = adapter.apply(ctx);
if (rewriter != null) {
action.accept(ctx, rewriter);
}
};
}
}
@FunctionalInterface
public interface TypedRegistrationAction<CU extends ClientboundPacketType, SU extends ServerboundPacketType, R> {
void accept(RegistrationContext<CU, SU> ctx, R r);
}
}
@@ -0,0 +1,127 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.function.Consumer;
import org.checkerframework.checker.nullness.qual.Nullable;
public record RegistrationContext<CU extends ClientboundPacketType, SU extends ServerboundPacketType>(
AbstractProtocol<CU, ?, ?, SU> protocol,
ProtocolVersion min,
@Nullable ProtocolVersion max
) {
public <P extends AbstractProtocol<CU, ?, ?, SU>> P protocol(@SuppressWarnings("unused") final Class<P> protocolClass) {
//noinspection unchecked
return (P) protocol;
}
public <P extends AbstractProtocol<CU, ?, ?, SU>> P castProtocol() {
//noinspection unchecked
return (P) protocol;
}
public void clientbound(final ClientboundPacketType type, final Consumer<CU> action) {
action.accept(clientboundPacketType(type));
}
public void clientbound(final ClientboundPacketType type, final Consumer<CU> action, final PacketBound... markers) {
if (!shouldSkip(markers)) {
action.accept(clientboundPacketType(type));
}
}
public void clientboundHandler(final ClientboundPacketType type, final PacketHandler handler) {
protocol.registerClientbound(clientboundPacketType(type), handler);
}
public void clientboundHandler(final ClientboundPacketType type, final PacketHandler handler, final PacketBound... markers) {
if (!shouldSkip(markers)) {
protocol.registerClientbound(clientboundPacketType(type), handler);
}
}
public void serverbound(final ServerboundPacketType type, final Consumer<SU> action) {
action.accept(serverboundPacketType(type));
}
public void serverbound(final ServerboundPacketType type, final Consumer<SU> action, final PacketBound... markers) {
if (!shouldSkip(markers)) {
action.accept(serverboundPacketType(type));
}
}
public void serverboundHandler(final ServerboundPacketType type, final PacketHandler handler) {
protocol.registerServerbound(serverboundPacketType(type), handler);
}
public void serverboundHandler(final ServerboundPacketType type, final PacketHandler handler, final PacketBound... markers) {
if (!shouldSkip(markers)) {
protocol.registerServerbound(serverboundPacketType(type), handler);
}
}
private boolean shouldSkip(final PacketBound... markers) {
if (markers.length == 0) {
return false;
}
final ProtocolVersion serverVersion = protocol.getServerVersion();
final ProtocolVersion clientVersion = protocol.getClientVersion();
final ProtocolVersion lowerVersion = serverVersion.olderThan(clientVersion) ? serverVersion : clientVersion;
final ProtocolVersion higherVersion = serverVersion.newerThan(clientVersion) ? serverVersion : clientVersion;
for (final PacketBound marker : markers) {
switch (marker) {
case ADDED_AT_MIN -> {
if (lowerVersion.olderThan(min)) {
return true;
}
}
case REMOVED_AT_MAX -> {
Preconditions.checkArgument(max != null, "Cannot use REMOVED_AT_MAX in an open-ended range");
if (higherVersion.newerThanOrEqualTo(max)) {
return true;
}
}
}
}
return false;
}
private SU serverboundPacketType(final ServerboundPacketType genericPacketType) {
final SU type = protocol.getPacketTypesProvider().unmappedServerboundType(genericPacketType.state(), genericPacketType.getName());
if (type == null) {
throw new IllegalArgumentException("Could not find serverbound packet type for " + genericPacketType.state() + " " + genericPacketType.getName());
}
return type;
}
private CU clientboundPacketType(final ClientboundPacketType genericPacketType) {
final CU type = protocol.getPacketTypesProvider().unmappedClientboundType(genericPacketType.state(), genericPacketType.getName());
if (type == null) {
throw new IllegalArgumentException("Could not find clientbound packet type for " + genericPacketType.state() + " " + genericPacketType.getName() + " in " + protocol.getClass().getSimpleName());
}
return type;
}
}
@@ -0,0 +1,107 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.protocol.version.VersionType;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.List;
/**
* Central registry for shared packet registrations that are automatically applied
* to protocols based on their version range.
* <p>
* Registrations are done BEFORE registerPackets in {@link AbstractProtocol}.
*/
public final class SharedRegistrations {
private static final SharedRegistrations DEFAULT_REGISTRATIONS = new SharedRegistrations();
private final EnumMap<VersionType, List<VersionedTemplateGroup>> versionedTemplates = new EnumMap<>(VersionType.class);
/**
* Returns the default ViaVersion registration set.
*/
public static SharedRegistrations defaultRegistrations() {
return DEFAULT_REGISTRATIONS;
}
/**
* Creates an independent shared registration set that external projects can populate and apply.
*/
public static SharedRegistrations create() {
return new SharedRegistrations();
}
public RegistrationBuilder registrations() {
return new RegistrationBuilder(this);
}
/**
* Applies all shared registrations whose version range matches the given protocol.
*
* @param protocol the protocol to apply shared registrations to
*/
public void applyMatching(final AbstractProtocol<?, ?, ?, ?> protocol) {
if (protocol.isBaseProtocol()) {
return;
}
final ProtocolVersion version = protocol.getServerVersion();
if (version.getVersionType() != protocol.getClientVersion().getVersionType()) {
// Built on continuous version ranges
return;
}
final List<VersionedTemplateGroup> groups = versionedTemplates.get(version.getVersionType());
if (groups == null) {
return;
}
for (final VersionedTemplateGroup group : groups) {
if (group.min().newerThan(version)) { // TODO binary search?
// Sorted by the minimum, so we can stop early if we're out
break;
}
if (group.max() != null && version.newerThanOrEqualTo(group.max())) {
continue;
}
final RegistrationContext<?, ?> context = new RegistrationContext<>(protocol, group.min(), group.max());
//noinspection unchecked,rawtypes
((RegistrationAction) group.action()).accept(context);
}
}
@FunctionalInterface
public interface RegistrationAction<CU extends ClientboundPacketType, SU extends ServerboundPacketType> {
void accept(RegistrationContext<CU, SU> context);
}
void register(final VersionType versionType, final List<VersionedTemplateGroup> toAdd) {
final List<VersionedTemplateGroup> groups = versionedTemplates.computeIfAbsent(versionType, $ -> new ArrayList<>());
groups.addAll(toAdd);
groups.sort(Comparator.comparing(VersionedTemplateGroup::min, Comparator.nullsFirst(Comparator.naturalOrder())));
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocol.shared_registration.SharedRegistrations.RegistrationAction;
record VersionedTemplateGroup(
RegistrationAction<?, ?> action,
ProtocolVersion min,
ProtocolVersion max
) {
public boolean contains(final ProtocolVersion version) {
return version.newerThanOrEqualTo(min) && (max == null || version.olderThan(max));
}
}
@@ -0,0 +1,95 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.protocol.shared_registration.PacketBound;
import com.viaversion.viaversion.protocol.shared_registration.RegistrationContext;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_14_3to1_14_4.packet.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
final class BlockRegistrations {
static <CU extends ClientboundPacketType> void registerBlockPackets1_13(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_13(ctx, br);
ctx.clientbound(ClientboundPackets1_13.CHUNK_BLOCKS_UPDATE, br::registerChunkBlocksUpdate);
}
private static <CU extends ClientboundPacketType> void common1_13(RegistrationContext<CU, ?> ctx, BlockRewriter<CU> br) {
ctx.clientbound(ClientboundPackets1_13.BLOCK_EVENT, br::registerBlockEvent);
ctx.clientbound(ClientboundPackets1_13.BLOCK_UPDATE, br::registerBlockUpdate);
ctx.clientbound(ClientboundPackets1_13.LEVEL_EVENT, br::registerLevelEvent1_13);
}
static <CU extends ClientboundPacketType> void registerBlockPackets1_14_4(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_13(ctx, br);
ctx.clientbound(ClientboundPackets1_14_4.CHUNK_BLOCKS_UPDATE, br::registerChunkBlocksUpdate, PacketBound.REMOVED_AT_MAX);
ctx.clientbound(ClientboundPackets1_14_4.BLOCK_BREAK_ACK, br::registerBlockBreakAck, PacketBound.ADDED_AT_MIN);
}
static <CU extends ClientboundPacketType> void registerBlockPackets1_16_2(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_13(ctx, br);
ctx.clientbound(ClientboundPackets1_16_2.BLOCK_BREAK_ACK, br::registerBlockBreakAck);
ctx.clientbound(ClientboundPackets1_16_2.SECTION_BLOCKS_UPDATE, br::registerSectionBlocksUpdate, PacketBound.ADDED_AT_MIN);
}
static <CU extends ClientboundPacketType> void registerBlockPackets1_18(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_13(ctx, br);
ctx.clientbound(ClientboundPackets1_18.BLOCK_BREAK_ACK, br::registerBlockBreakAck, PacketBound.REMOVED_AT_MAX);
ctx.clientbound(ClientboundPackets1_18.LEVEL_CHUNK_WITH_LIGHT, br::registerLevelChunk1_18, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_18.SECTION_BLOCKS_UPDATE, br::registerSectionBlocksUpdate);
ctx.clientbound(ClientboundPackets1_18.BLOCK_ENTITY_DATA, br::registerBlockEntityData1_18);
}
static <CU extends ClientboundPacketType> void registerBlockPackets1_19(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_19(ctx, br);
ctx.clientbound(ClientboundPackets1_19.LEVEL_EVENT, br::registerLevelEvent1_13);
ctx.clientbound(ClientboundPackets1_19.SECTION_BLOCKS_UPDATE, br::registerSectionBlocksUpdate);
}
private static <CU extends ClientboundPacketType> void common1_19(RegistrationContext<CU, ?> ctx, BlockRewriter<CU> br) {
ctx.clientbound(ClientboundPackets1_19.BLOCK_EVENT, br::registerBlockEvent);
ctx.clientbound(ClientboundPackets1_19.BLOCK_UPDATE, br::registerBlockUpdate);
ctx.clientbound(ClientboundPackets1_19.LEVEL_CHUNK_WITH_LIGHT, br::registerLevelChunk1_18);
ctx.clientbound(ClientboundPackets1_19.BLOCK_ENTITY_DATA, br::registerBlockEntityData1_18);
}
static <CU extends ClientboundPacketType> void registerBlockPackets1_20(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_19(ctx, br);
ctx.clientbound(ClientboundPackets1_19_4.LEVEL_EVENT, br::registerLevelEvent1_13);
ctx.clientbound(ClientboundPackets1_19_4.SECTION_BLOCKS_UPDATE, br::registerSectionBlocksUpdate1_20);
}
static <CU extends ClientboundPacketType> void registerBlockPackets1_21(final RegistrationContext<CU, ?> ctx, final BlockRewriter<CU> br) {
common1_19(ctx, br);
ctx.clientbound(ClientboundPackets1_21.LEVEL_EVENT, br::registerLevelEvent1_21);
ctx.clientbound(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE, br::registerSectionBlocksUpdate1_20);
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> BlockRewriter<CU> block(final RegistrationContext<CU, SU> ctx) {
return ctx.protocol().getBlockRewriter();
}
}
@@ -0,0 +1,110 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocol.shared_registration.SharedRegistrations;
public final class DefaultRegistrations {
public static void apply() {
SharedRegistrations.defaultRegistrations().registrations()
.ranges(EntityRegistrations::entity, ProtocolVersion.v1_13, b -> b
.to(ProtocolVersion.v1_14_4, EntityRegistrations::registerEntityPackets1_13)
.to(ProtocolVersion.v1_16_2, EntityRegistrations::registerEntityPackets1_14_4)
.to(ProtocolVersion.v1_17_1, EntityRegistrations::registerEntityPackets1_16_2)
.to(ProtocolVersion.v1_19, EntityRegistrations::registerEntityPackets1_17_1)
.to(ProtocolVersion.v1_20_5, EntityRegistrations::registerEntityPackets1_19)
.to(ProtocolVersion.v1_21_4, EntityRegistrations::registerEntityPackets1_20_5)
.to(ProtocolVersion.v1_21_9, EntityRegistrations::registerEntityPackets1_21_4)
.since(EntityRegistrations::registerEntityPackets1_21_9)
)
.ranges(ItemRegistrations::item, ProtocolVersion.v1_13, b -> b
.to(ProtocolVersion.v1_14, ItemRegistrations::registerItemPackets1_13)
.to(ProtocolVersion.v1_14_4, ItemRegistrations::registerItemPackets1_14)
.to(ProtocolVersion.v1_16, ItemRegistrations::registerItemPackets1_14_4)
.to(ProtocolVersion.v1_17_1, ItemRegistrations::registerItemPackets1_16)
.to(ProtocolVersion.v1_19_1, ItemRegistrations::registerItemPackets1_17_1)
.to(ProtocolVersion.v1_20_3, ItemRegistrations::registerItemPackets1_19_1)
.to(ProtocolVersion.v1_20_5, ItemRegistrations::registerItemPackets1_20_3)
.to(ProtocolVersion.v1_21, ItemRegistrations::registerItemPackets1_20_5)
.to(ProtocolVersion.v1_21_2, ItemRegistrations::registerItemPackets1_21)
.to(ProtocolVersion.v1_21_5, ItemRegistrations::registerItemPackets1_21_2)
)
.ranges(ItemRegistrations::structuredItem, ProtocolVersion.v1_21_5, b -> b
.to(ProtocolVersion.v1_21_6, ItemRegistrations::registerItemPackets1_21_5)
.since(ItemRegistrations::registerItemPackets1_21_6)
)
.ranges(BlockRegistrations::block, ProtocolVersion.v1_13, steps -> steps
.to(ProtocolVersion.v1_14_4, BlockRegistrations::registerBlockPackets1_13)
.to(ProtocolVersion.v1_16_2, BlockRegistrations::registerBlockPackets1_14_4)
.to(ProtocolVersion.v1_18, BlockRegistrations::registerBlockPackets1_16_2)
.to(ProtocolVersion.v1_19, BlockRegistrations::registerBlockPackets1_18)
.to(ProtocolVersion.v1_20, BlockRegistrations::registerBlockPackets1_19)
.to(ProtocolVersion.v1_21, BlockRegistrations::registerBlockPackets1_20)
.since(BlockRegistrations::registerBlockPackets1_21)
)
.ranges(ParticleRegistrations::particle, ProtocolVersion.v1_13, steps -> steps
.to(ProtocolVersion.v1_15_2, ParticleRegistrations::registerParticlePackets1_13)
.to(ProtocolVersion.v1_19, ParticleRegistrations::registerParticlePackets1_15_2)
.to(ProtocolVersion.v1_20, ParticleRegistrations::registerParticlePackets1_19)
.to(ProtocolVersion.v1_20_5, ParticleRegistrations::registerParticlePackets1_20)
.to(ProtocolVersion.v1_21_2, ParticleRegistrations::registerParticlePackets1_20_5)
.to(ProtocolVersion.v1_21_4, ParticleRegistrations::registerParticlePackets1_21_2)
.to(ProtocolVersion.v1_21_9, ParticleRegistrations::registerParticlePackets1_21_4)
.since(ParticleRegistrations::registerParticlePackets1_21_9)
)
.ranges(TextComponentRegistrations::text, ProtocolVersion.v1_12_2, b -> b
.to(ProtocolVersion.v1_14, TextComponentRegistrations::registerComponents1_12_2)
.to(ProtocolVersion.v1_16_2, TextComponentRegistrations::registerComponents1_14)
.to(ProtocolVersion.v1_17, TextComponentRegistrations::registerComponents1_16_2)
.to(ProtocolVersion.v1_19, TextComponentRegistrations::registerComponents1_17)
.to(ProtocolVersion.v1_20_3, TextComponentRegistrations::registerComponents1_19)
.to(ProtocolVersion.v1_20_5, TextComponentRegistrations::registerComponents1_20_3)
.to(ProtocolVersion.v1_21, TextComponentRegistrations::registerComponents1_20_5)
.to(ProtocolVersion.v1_21_4, TextComponentRegistrations::registerComponents1_21)
.to(ProtocolVersion.v1_21_5, TextComponentRegistrations::registerComponents1_21_4)
)
.ranges(TextComponentRegistrations::nbtText, ProtocolVersion.v1_21_5, b -> b
.since(TextComponentRegistrations::registerComponents1_21_5)
)
.ranges(ProtocolVersion.v1_17_1, sbeps -> sbeps
.to(ProtocolVersion.v1_20_2, RegistryRegistrations::registerTags1_17_1)
.since(RegistryRegistrations::registerTags1_20_2)
)
.ranges(ProtocolVersion.v1_10, b -> b
.to(ProtocolVersion.v1_14, RegistryRegistrations::registerSounds1_10)
.to(ProtocolVersion.v1_19_3, RegistryRegistrations::registerSounds1_14)
.since(RegistryRegistrations::registerSounds1_19_3)
)
.since(ProtocolVersion.v1_13, RegistryRegistrations::registerStatistics1_13)
.since(ProtocolVersion.v1_19, RegistryRegistrations::registerCommands1_19)
.since(ProtocolVersion.v1_21, RegistryRegistrations::registerRegistryData1_21)
.since(ProtocolVersion.v1_21, RegistryRegistrations::registerAttributes1_21)
.since(ProtocolVersion.v1_21_2, RegistryRegistrations::registerRecipePackets1_21_2)
.register();
}
}
@@ -0,0 +1,96 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.protocol.shared_registration.PacketBound;
import com.viaversion.viaversion.protocol.shared_registration.RegistrationContext;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_14_3to1_14_4.packet.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
final class EntityRegistrations {
static <CU extends ClientboundPacketType> void registerEntityPackets1_13(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
ctx.clientbound(ClientboundPackets1_13.REMOVE_ENTITIES, er::registerRemoveEntities);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_14_4(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
ctx.clientbound(ClientboundPackets1_14_4.REMOVE_ENTITIES, er::registerRemoveEntities);
ctx.clientbound(ClientboundPackets1_14_4.ADD_ENTITY, er::registerTrackerWithData);
ctx.clientbound(ClientboundPackets1_14_4.ADD_MOB, er::registerTracker);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_16_2(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
// remove_entities got temporarily changed to only take a single entity...
ctx.clientbound(ClientboundPackets1_14_4.ADD_ENTITY, er::registerTrackerWithData);
ctx.clientbound(ClientboundPackets1_14_4.ADD_MOB, er::registerTracker);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_17_1(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
ctx.clientbound(ClientboundPackets1_14_4.REMOVE_ENTITIES, er::registerRemoveEntities);
ctx.clientbound(ClientboundPackets1_14_4.ADD_ENTITY, er::registerTrackerWithData);
ctx.clientbound(ClientboundPackets1_14_4.ADD_MOB, er::registerTracker, PacketBound.REMOVED_AT_MAX);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_19(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
ctx.clientbound(ClientboundPackets1_9.REMOVE_ENTITIES, er::registerRemoveEntities);
ctx.clientbound(ClientboundPackets1_19.ADD_ENTITY, er::registerTrackerWithData1_19);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_20_5(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
common1_20_5(ctx, er);
ctx.clientbound(ClientboundPackets1_19.ADD_ENTITY, er::registerTrackerWithData1_19);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_21_4(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
common1_20_5(ctx, er);
registerGameModeTrackers1_21_4(ctx, er);
ctx.clientbound(ClientboundPackets1_21_2.ADD_ENTITY, er::registerTrackerWithData1_19);
}
static <CU extends ClientboundPacketType> void registerEntityPackets1_21_9(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
common1_20_5(ctx, er);
registerGameModeTrackers1_21_4(ctx, er);
ctx.clientbound(ClientboundPackets1_21_9.ADD_ENTITY, er::registerTrackerWithData1_21_9);
}
private static <CU extends ClientboundPacketType> void common1_20_5(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
ctx.clientbound(ClientboundPackets1_20_5.SET_ENTITY_DATA, er::registerSetEntityData);
ctx.clientbound(ClientboundPackets1_20_5.REMOVE_ENTITIES, er::registerRemoveEntities);
ctx.clientbound(ClientboundPackets1_20_5.LOGIN, er::registerLogin1_20_5);
ctx.clientbound(ClientboundPackets1_20_5.RESPAWN, er::registerRespawn1_20_5);
}
private static <CU extends ClientboundPacketType> void registerGameModeTrackers1_21_4(final RegistrationContext<CU, ?> ctx, final EntityRewriter<CU, ?> er) {
ctx.clientbound(ClientboundPackets1_21_2.GAME_EVENT, er::registerGameEvent);
ctx.clientbound(ClientboundPackets1_21_2.PLAYER_ABILITIES, er::registerPlayerAbilities);
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> EntityRewriter<CU, ?> entity(final RegistrationContext<CU, SU> ctx) {
return (EntityRewriter<CU, ?>) ctx.protocol().getEntityRewriter();
}
}
@@ -0,0 +1,185 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.protocol.shared_registration.PacketBound;
import com.viaversion.viaversion.protocol.shared_registration.RegistrationContext;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.v1_14_3to1_14_4.packet.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ServerboundPackets1_19_3;
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPackets1_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.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPackets1_21_5;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ServerboundPackets1_21_5;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundConfigurationPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
final class ItemRegistrations {
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_13(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
common1_13(ctx, ir);
ctx.clientbound(ClientboundPackets1_13.SET_EQUIPPED_ITEM, ir::registerSetEquippedItem);
}
private static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void common1_13(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_13.CONTAINER_SET_DATA, ir::registerContainerSetData);
ctx.clientbound(ClientboundPackets1_13.CONTAINER_SET_SLOT, ir::registerSetSlot);
ctx.clientbound(ClientboundPackets1_13.CONTAINER_SET_CONTENT, ir::registerSetContent);
ctx.clientbound(ClientboundPackets1_13.UPDATE_ADVANCEMENTS, ir::registerAdvancements);
ctx.clientbound(ClientboundPackets1_13.COOLDOWN, ir::registerCooldown);
ctx.serverbound(ServerboundPackets1_13.CONTAINER_CLICK, ir::registerContainerClick);
ctx.serverbound(ServerboundPackets1_13.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_14(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
common1_13(ctx, ir);
ctx.clientbound(ClientboundPackets1_14.SET_EQUIPPED_ITEM, ir::registerSetEquippedItem);
ctx.clientbound(ClientboundPackets1_14.OPEN_SCREEN, ir::registerOpenScreen);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_14_4(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
common1_13(ctx, ir);
ctx.clientbound(ClientboundPackets1_14_4.SET_EQUIPPED_ITEM, ir::registerSetEquippedItem, PacketBound.REMOVED_AT_MAX);
ctx.clientbound(ClientboundPackets1_14_4.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_14_4.MERCHANT_OFFERS, ir::registerMerchantOffers1_14_4);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_16(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
common1_13(ctx, ir);
ctx.clientbound(ClientboundPackets1_16.SET_EQUIPMENT, ir::registerSetEquipment, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_16.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_16.MERCHANT_OFFERS, ir::registerMerchantOffers1_14_4);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_17_1(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_17_1.CONTAINER_SET_DATA, ir::registerContainerSetData);
ctx.clientbound(ClientboundPackets1_17_1.CONTAINER_SET_SLOT, ir::registerSetSlot1_17_1);
ctx.clientbound(ClientboundPackets1_17_1.CONTAINER_SET_CONTENT, ir::registerSetContent1_17_1);
ctx.clientbound(ClientboundPackets1_17_1.UPDATE_ADVANCEMENTS, ir::registerAdvancements);
ctx.clientbound(ClientboundPackets1_17_1.COOLDOWN, ir::registerCooldown);
ctx.serverbound(ServerboundPackets1_17.CONTAINER_CLICK, ir::registerContainerClick1_17_1);
ctx.serverbound(ServerboundPackets1_17.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot);
ctx.clientbound(ClientboundPackets1_17_1.SET_EQUIPMENT, ir::registerSetEquipment);
ctx.clientbound(ClientboundPackets1_17_1.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_17_1.MERCHANT_OFFERS, ir::registerMerchantOffers1_14_4);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_19_1(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_19_1.CONTAINER_SET_DATA, ir::registerContainerSetData);
ctx.clientbound(ClientboundPackets1_19_1.CONTAINER_SET_SLOT, ir::registerSetSlot1_17_1);
ctx.clientbound(ClientboundPackets1_19_1.CONTAINER_SET_CONTENT, ir::registerSetContent1_17_1);
ctx.clientbound(ClientboundPackets1_19_1.UPDATE_ADVANCEMENTS, ir::registerAdvancements);
ctx.clientbound(ClientboundPackets1_19_1.COOLDOWN, ir::registerCooldown);
ctx.serverbound(ServerboundPackets1_19_3.CONTAINER_CLICK, ir::registerContainerClick1_17_1);
ctx.serverbound(ServerboundPackets1_19_3.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot);
ctx.clientbound(ClientboundPackets1_19_1.SET_EQUIPMENT, ir::registerSetEquipment);
ctx.clientbound(ClientboundPackets1_19_1.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_19_1.MERCHANT_OFFERS, ir::registerMerchantOffers1_19);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_20_3(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_20_3.CONTAINER_SET_DATA, ir::registerContainerSetData);
ctx.clientbound(ClientboundPackets1_20_3.CONTAINER_SET_SLOT, ir::registerSetSlot1_17_1);
ctx.clientbound(ClientboundPackets1_20_3.CONTAINER_SET_CONTENT, ir::registerSetContent1_17_1);
ctx.clientbound(ClientboundPackets1_20_5.UPDATE_ADVANCEMENTS, ir::registerAdvancements1_20_3);
ctx.clientbound(ClientboundPackets1_20_3.COOLDOWN, ir::registerCooldown);
ctx.serverbound(ServerboundPackets1_20_3.CONTAINER_CLICK, ir::registerContainerClick1_17_1);
ctx.serverbound(ServerboundPackets1_20_2.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot);
ctx.clientbound(ClientboundPackets1_20_5.SET_EQUIPMENT, ir::registerSetEquipment);
ctx.clientbound(ClientboundPackets1_19_4.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_20_2.MERCHANT_OFFERS, ir::registerMerchantOffers1_19);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_20_5(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_20_3.CONTAINER_SET_DATA, ir::registerContainerSetData);
registerItemPackets1_21(ctx, ir);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_21(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_21.CONTAINER_SET_SLOT, ir::registerSetSlot1_17_1);
ctx.clientbound(ClientboundPackets1_21.CONTAINER_SET_CONTENT, ir::registerSetContent1_17_1);
ctx.clientbound(ClientboundPackets1_21.UPDATE_ADVANCEMENTS, ir::registerAdvancements1_20_3);
ctx.clientbound(ClientboundPackets1_21.COOLDOWN, ir::registerCooldown);
ctx.serverbound(ServerboundPackets1_20_5.CONTAINER_CLICK, ir::registerContainerClick1_17_1);
ctx.serverbound(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot);
ctx.clientbound(ClientboundPackets1_21.SET_EQUIPMENT, ir::registerSetEquipment);
ctx.clientbound(ClientboundPackets1_21.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_21.MERCHANT_OFFERS, ir::registerMerchantOffers1_20_5);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_21_2(final RegistrationContext<CU, SU> ctx, final ItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_21_2.CONTAINER_SET_SLOT, ir::registerSetSlot1_21_2);
ctx.clientbound(ClientboundPackets1_21_2.CONTAINER_SET_CONTENT, ir::registerSetContent1_21_2);
ctx.clientbound(ClientboundPackets1_21_2.UPDATE_ADVANCEMENTS, ir::registerAdvancements1_20_3);
ctx.clientbound(ClientboundPackets1_21_2.COOLDOWN, ir::registerCooldown1_21_2);
ctx.serverbound(ServerboundPackets1_21_2.CONTAINER_CLICK, ir::registerContainerClick1_21_2);
ctx.serverbound(ServerboundPackets1_21_2.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot);
ctx.clientbound(ClientboundPackets1_21_2.SET_EQUIPMENT, ir::registerSetEquipment);
ctx.clientbound(ClientboundPackets1_21_2.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_21_2.MERCHANT_OFFERS, ir::registerMerchantOffers1_20_5);
ctx.clientbound(ClientboundPackets1_21_2.SET_PLAYER_INVENTORY, ir::registerSetPlayerInventory, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_21_2.SET_CURSOR_ITEM, ir::registerSetCursorItem, PacketBound.ADDED_AT_MIN);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_21_5(final RegistrationContext<CU, SU> ctx, final StructuredItemRewriter<CU, SU, ?> ir) {
ctx.clientbound(ClientboundPackets1_21_5.CONTAINER_SET_SLOT, ir::registerSetSlot1_21_2);
ctx.clientbound(ClientboundPackets1_21_5.CONTAINER_SET_CONTENT, ir::registerSetContent1_21_2);
ctx.clientbound(ClientboundPackets1_21_5.UPDATE_ADVANCEMENTS, ir::registerAdvancements1_20_3);
ctx.clientbound(ClientboundPackets1_21_5.COOLDOWN, ir::registerCooldown1_21_2);
ctx.serverbound(ServerboundPackets1_21_5.CONTAINER_CLICK, ir::registerContainerClick1_21_5);
ctx.serverbound(ServerboundPackets1_21_5.SET_CREATIVE_MODE_SLOT, ir::registerSetCreativeModeSlot1_21_5);
ctx.clientbound(ClientboundPackets1_21_5.SET_EQUIPMENT, ir::registerSetEquipment);
ctx.clientbound(ClientboundPackets1_21_5.OPEN_SCREEN, ir::registerOpenScreen);
ctx.clientbound(ClientboundPackets1_21_5.MERCHANT_OFFERS, ir::registerMerchantOffers1_20_5);
ctx.clientbound(ClientboundPackets1_21_5.SET_PLAYER_INVENTORY, ir::registerSetPlayerInventory);
ctx.clientbound(ClientboundPackets1_21_5.SET_CURSOR_ITEM, ir::registerSetCursorItem);
}
static <CU extends ClientboundPacketType, SU extends ServerboundPacketType> void registerItemPackets1_21_6(final RegistrationContext<CU, SU> ctx, final StructuredItemRewriter<CU, SU, ?> ir) {
registerItemPackets1_21_5(ctx, ir);
ctx.clientbound(ClientboundPackets1_21_6.SHOW_DIALOG, ir::registerShowDialog, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundConfigurationPackets1_21_6.SHOW_DIALOG, ir::registerShowDialogDirect, PacketBound.ADDED_AT_MIN);
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> ItemRewriter<CU, SU, ?> item(final RegistrationContext<CU, SU> ctx) {
return (ItemRewriter<CU, SU, ?>) ctx.protocol().getItemRewriter();
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> StructuredItemRewriter<CU, SU, ?> structuredItem(final RegistrationContext<CU, SU> ctx) {
return (StructuredItemRewriter<CU, SU, ?>) ctx.protocol().getItemRewriter();
}
}
@@ -0,0 +1,74 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocol.shared_registration.RegistrationContext;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
final class ParticleRegistrations {
static <CU extends ClientboundPacketType> void registerParticlePackets1_13(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_13.LEVEL_PARTICLES, type -> pr.registerLevelParticles1_13(type, Types.FLOAT));
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_15_2(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_15.LEVEL_PARTICLES, type -> pr.registerLevelParticles1_13(type, Types.DOUBLE));
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_19(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_19.LEVEL_PARTICLES, pr::registerLevelParticles1_19);
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_20(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_19.LEVEL_PARTICLES, pr::registerLevelParticles1_19);
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_20_5(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_20_5.LEVEL_PARTICLES, pr::registerLevelParticles1_20_5);
ctx.clientbound(ClientboundPackets1_20_5.EXPLODE, pr::registerExplode1_20_5);
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_21_2(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_21_2.LEVEL_PARTICLES, pr::registerLevelParticles1_20_5);
ctx.clientbound(ClientboundPackets1_21_2.EXPLODE, pr::registerExplode1_21_2);
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_21_4(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_21_2.LEVEL_PARTICLES, pr::registerLevelParticles1_21_4);
ctx.clientbound(ClientboundPackets1_21_2.EXPLODE, pr::registerExplode1_21_2);
}
static <CU extends ClientboundPacketType> void registerParticlePackets1_21_9(final RegistrationContext<CU, ?> ctx, final ParticleRewriter<CU> pr) {
ctx.clientbound(ClientboundPackets1_21_9.LEVEL_PARTICLES, pr::registerLevelParticles1_21_4);
ctx.clientbound(ClientboundPackets1_21_9.EXPLODE, pr::registerExplode1_21_9);
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> ParticleRewriter<CU> particle(final RegistrationContext<CU, SU> ctx) {
return (ParticleRewriter<CU>) ctx.protocol().getParticleRewriter();
}
}
@@ -0,0 +1,105 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.protocol.shared_registration.PacketBound;
import com.viaversion.viaversion.protocol.shared_registration.RegistrationContext;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter.CommandRewriter1_19_4;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ClientboundPackets1_9_3;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
final class RegistryRegistrations {
static <CU extends ClientboundPacketType> void registerTags1_17_1(final RegistrationContext<CU, ?> ctx) {
if (ctx.protocol().getTagRewriter() instanceof final TagRewriter tagRewriter) {
ctx.clientbound(ClientboundPackets1_17_1.UPDATE_TAGS, tagRewriter::registerGeneric);
}
}
static <CU extends ClientboundPacketType> void registerTags1_20_2(final RegistrationContext<CU, ?> ctx) {
if (ctx.protocol().getTagRewriter() instanceof final TagRewriter tagRewriter) {
ctx.clientbound(ClientboundPackets1_20_2.UPDATE_TAGS, tagRewriter::registerGeneric);
ctx.clientbound(ClientboundConfigurationPackets1_20_2.UPDATE_TAGS, tagRewriter::registerGeneric, PacketBound.ADDED_AT_MIN);
}
}
static <CU extends ClientboundPacketType> void registerRegistryData1_21(final RegistrationContext<CU, ?> ctx) {
if (ctx.protocol().getRegistryDataRewriter() == null) return;
ctx.clientboundHandler(ClientboundConfigurationPackets1_21.REGISTRY_DATA, ctx.protocol().getRegistryDataRewriter()::handle);
}
static <CU extends ClientboundPacketType> void registerRecipePackets1_21_2(final RegistrationContext<CU, ?> ctx) {
final RecipeDisplayRewriter<CU> rr = ctx.protocol().getRecipeRewriter();
if (rr == null) return;
ctx.clientbound(ClientboundPackets1_21_2.UPDATE_RECIPES, rr::registerUpdateRecipes);
ctx.clientbound(ClientboundPackets1_21_2.RECIPE_BOOK_ADD, rr::registerRecipeBookAdd, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_21_2.PLACE_GHOST_RECIPE, rr::registerPlaceGhostRecipe);
}
static <CU extends ClientboundPacketType> void registerStatistics1_13(final RegistrationContext<CU, ?> ctx) {
ctx.clientbound(ClientboundPackets1_13.AWARD_STATS, new StatisticsRewriter<>(ctx.protocol())::register);
}
static <CU extends ClientboundPacketType> void registerSounds1_10(final RegistrationContext<CU, ?> ctx) {
ctx.clientbound(ClientboundPackets1_9_3.SOUND, new SoundRewriter<>(ctx.protocol())::registerSound);
}
static <CU extends ClientboundPacketType> void registerSounds1_14(final RegistrationContext<CU, ?> ctx) {
final SoundRewriter<CU> sr = new SoundRewriter<>(ctx.protocol());
ctx.clientbound(ClientboundPackets1_14.SOUND, sr::registerSound);
ctx.clientbound(ClientboundPackets1_14.SOUND_ENTITY, sr::registerSound, PacketBound.ADDED_AT_MIN);
}
static <CU extends ClientboundPacketType> void registerSounds1_19_3(final RegistrationContext<CU, ?> ctx) {
final SoundRewriter<CU> sr = new SoundRewriter<>(ctx.protocol());
ctx.clientbound(ClientboundPackets1_19_3.SOUND, sr::registerSound1_19_3);
ctx.clientbound(ClientboundPackets1_19_3.SOUND_ENTITY, sr::registerSound1_19_3);
}
static <CU extends ClientboundPacketType> void registerCommands1_19(final RegistrationContext<CU, ?> ctx) {
if ((ctx.protocol().getMappingData() != null && !Mappings.isIntIdIdentity(ctx.protocol().getMappingData().getArgumentTypeMappings()))
|| ctx.protocol().getRegistryDataRewriter() != null) {
ctx.clientbound(ClientboundPackets1_19_3.COMMANDS, new CommandRewriter1_19_4<>(ctx.protocol())::registerDeclareCommands1_19);
}
}
static <CU extends ClientboundPacketType> void registerAttributes1_21(final RegistrationContext<CU, ?> ctx) {
ctx.clientbound(ClientboundPackets1_21.UPDATE_ATTRIBUTES, new AttributeRewriter<>(ctx.protocol())::register1_21);
}
}
@@ -0,0 +1,194 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2026 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.protocol.shared_registration.def;
import com.viaversion.viaversion.api.minecraft.item.data.ChatType;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocol.shared_registration.PacketBound;
import com.viaversion.viaversion.protocol.shared_registration.RegistrationContext;
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPackets1_21_5;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import com.viaversion.viaversion.rewriter.text.NBTComponentRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
final class TextComponentRegistrations {
static <CU extends ClientboundPacketType> void registerComponents1_12_2(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
ctx.clientbound(ClientboundPackets1_12_1.CHAT, cr::registerComponentPacket);
registerCombatAndTitle1_12_2(ctx, cr);
registerComponentsFrom1_12_2(ctx, cr);
}
static <CU extends ClientboundPacketType> void registerComponents1_14(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
ctx.clientbound(ClientboundPackets1_12_1.CHAT, cr::registerComponentPacket);
registerCombatAndTitle1_12_2(ctx, cr);
registerComponentsFrom1_12_2(ctx, cr);
ctx.clientbound(ClientboundPackets1_16_2.SET_OBJECTIVE, cr::registerSetObjective);
ctx.clientbound(ClientboundPackets1_16_2.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
}
static <CU extends ClientboundPacketType> void registerComponents1_16_2(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
ctx.clientbound(ClientboundPackets1_16.CHAT, cr::registerComponentPacket);
registerComponentsFrom1_12_2(ctx, cr);
ctx.clientbound(ClientboundPackets1_16_2.SET_OBJECTIVE, cr::registerSetObjective);
ctx.clientbound(ClientboundPackets1_16_2.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
if (!(cr instanceof final JsonNBTComponentRewriter<CU> jcr)) return;
ctx.clientbound(ClientboundPackets1_12_1.PLAYER_COMBAT, jcr::registerPlayerCombat, PacketBound.REMOVED_AT_MAX);
ctx.clientbound(ClientboundPackets1_12_1.SET_TITLES, jcr::registerTitle, PacketBound.REMOVED_AT_MAX);
}
static <CU extends ClientboundPacketType> void registerComponents1_17(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
ctx.clientbound(ClientboundPackets1_16.CHAT, cr::registerComponentPacket, PacketBound.REMOVED_AT_MAX);
registerComponentsFrom1_12_2(ctx, cr);
ctx.clientbound(ClientboundPackets1_17_1.SET_ACTION_BAR_TEXT, cr::registerComponentPacket, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_17_1.SET_TITLE_TEXT, cr::registerComponentPacket, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_17_1.SET_SUBTITLE_TEXT, cr::registerComponentPacket, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_16_2.SET_OBJECTIVE, cr::registerSetObjective);
if (cr instanceof final JsonNBTComponentRewriter<CU> jcr) {
ctx.clientbound(ClientboundPackets1_17_1.PLAYER_COMBAT_KILL, jcr::registerPlayerCombatKill, PacketBound.ADDED_AT_MIN);
}
ctx.clientbound(ClientboundPackets1_16_2.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
}
static <CU extends ClientboundPacketType> void registerComponents1_19(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
registerComponentsFrom1_12_2(ctx, cr);
registerActionBarTitleSubtitle1_17_1(ctx, cr);
ctx.clientbound(ClientboundPackets1_16_2.SET_OBJECTIVE, cr::registerSetObjective);
if (cr instanceof final JsonNBTComponentRewriter<CU> jcr) {
ctx.clientbound(ClientboundPackets1_17_1.PLAYER_COMBAT_KILL, jcr::registerPlayerCombatKill);
}
ctx.clientbound(ClientboundPackets1_16_2.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
ctx.clientbound(ClientboundPackets1_19.SYSTEM_CHAT, cr::registerComponentPacket, PacketBound.ADDED_AT_MIN);
ctx.clientbound(ClientboundPackets1_19.SERVER_DATA, cr::registerComponentPacket, PacketBound.ADDED_AT_MIN);
}
static <CU extends ClientboundPacketType> void registerComponents1_20_3(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
registerComponentsFrom1_12_2(ctx, cr);
registerActionBarTitleSubtitle1_17_1(ctx, cr);
ctx.clientbound(ClientboundPackets1_16_2.SET_OBJECTIVE, cr::registerSetObjective);
ctx.clientbound(ClientboundPackets1_19_1.SYSTEM_CHAT, cr::registerComponentPacket);
ctx.clientbound(ClientboundConfigurationPackets1_20_3.DISCONNECT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_3.DISGUISED_CHAT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_3.SET_SCORE, cr::registerSetScore1_20_3);
ctx.clientbound(ClientboundPackets1_20_3.PLAYER_COMBAT_KILL, cr::registerPlayerCombatKill1_20);
ctx.clientbound(ClientboundPackets1_20_5.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
ctx.clientbound(ClientboundPackets1_19.SERVER_DATA, cr::registerComponentPacket);
if (cr instanceof final JsonNBTComponentRewriter<CU> jcr) {
ctx.clientbound(ClientboundPackets1_20_3.PLAYER_CHAT, cu -> jcr.registerPlayerChat(cu, Types.VAR_INT));
ctx.clientbound(ClientboundPackets1_20_3.PLAYER_INFO_UPDATE, jcr::registerPlayerInfoUpdate1_20_3);
}
}
static <CU extends ClientboundPacketType> void registerCombatAndTitle1_12_2(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
if (!(cr instanceof final JsonNBTComponentRewriter<CU> jcr)) return;
ctx.clientbound(ClientboundPackets1_12_1.PLAYER_COMBAT, jcr::registerPlayerCombat);
ctx.clientbound(ClientboundPackets1_12_1.SET_TITLES, jcr::registerTitle);
}
private static <CU extends ClientboundPacketType> void registerComponentsFrom1_12_2(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
// not including set_score, player_info, update_advancements, and open_screen
ctx.clientbound(ClientboundPackets1_12_1.BOSS_EVENT, cr::registerBossEvent);
ctx.clientbound(ClientboundPackets1_12_1.DISCONNECT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_12_1.TAB_LIST, cr::registerTabList);
cr.registerLoginDisconnect();
}
static <CU extends ClientboundPacketType> void registerActionBarTitleSubtitle1_17_1(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
ctx.clientbound(ClientboundPackets1_17_1.SET_ACTION_BAR_TEXT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_17_1.SET_TITLE_TEXT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_17_1.SET_SUBTITLE_TEXT, cr::registerComponentPacket);
}
static <CU extends ClientboundPacketType> void registerComponents1_20_5(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
common1_20_5(ctx, cr);
ctx.clientbound(ClientboundPackets1_20_5.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
ctx.clientbound(ClientboundPackets1_20_5.DISGUISED_CHAT, cr::registerComponentPacket);
if (cr instanceof final JsonNBTComponentRewriter<CU> jcr) {
ctx.clientbound(ClientboundPackets1_20_5.PLAYER_CHAT, cu -> jcr.registerPlayerChat(cu, Types.VAR_INT));
ctx.clientbound(ClientboundPackets1_20_5.PLAYER_INFO_UPDATE, jcr::registerPlayerInfoUpdate1_20_3);
}
}
private static <CU extends ClientboundPacketType> void common1_20_5(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
ctx.clientbound(ClientboundConfigurationPackets1_20_5.DISCONNECT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_5.DISCONNECT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_5.SET_ACTION_BAR_TEXT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_5.SET_TITLE_TEXT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_5.SET_SUBTITLE_TEXT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_5.BOSS_EVENT, cr::registerBossEvent);
ctx.clientbound(ClientboundPackets1_20_5.TAB_LIST, cr::registerTabList);
ctx.clientbound(ClientboundPackets1_20_5.SET_OBJECTIVE, cr::registerSetObjective);
ctx.clientbound(ClientboundPackets1_20_5.SET_SCORE, cr::registerSetScore1_20_3);
ctx.clientbound(ClientboundPackets1_20_5.SYSTEM_CHAT, cr::registerComponentPacket);
ctx.clientbound(ClientboundPackets1_20_5.PLAYER_COMBAT_KILL, cr::registerPlayerCombatKill1_20);
ctx.clientbound(ClientboundPackets1_20_5.SERVER_DATA, cr::registerComponentPacket);
cr.registerLoginDisconnect();
}
static <CU extends ClientboundPacketType> void registerComponents1_21(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
common1_20_5(ctx, cr);
ctx.clientbound(ClientboundPackets1_21.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
ctx.clientbound(ClientboundPackets1_21.DISGUISED_CHAT, cr::registerDisguisedChat);
if (cr instanceof final JsonNBTComponentRewriter<CU> jcr) {
ctx.clientbound(ClientboundPackets1_21.PLAYER_CHAT, cu -> jcr.registerPlayerChat(cu, ChatType.TYPE));
ctx.clientbound(ClientboundPackets1_21.PLAYER_INFO_UPDATE, jcr::registerPlayerInfoUpdate1_20_3);
}
}
static <CU extends ClientboundPacketType> void registerComponents1_21_4(final RegistrationContext<CU, ?> ctx, final ComponentRewriterBase<CU> cr) {
common1_20_5(ctx, cr);
ctx.clientbound(ClientboundPackets1_21_2.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_13);
ctx.clientbound(ClientboundPackets1_21_2.DISGUISED_CHAT, cr::registerDisguisedChat);
ctx.clientbound(ClientboundPackets1_21_2.PLAYER_INFO_UPDATE, cr::registerPlayerInfoUpdate1_21_4);
if (cr instanceof final JsonNBTComponentRewriter<CU> jcr) {
ctx.clientbound(ClientboundPackets1_21_2.PLAYER_CHAT, cu -> jcr.registerPlayerChat(cu, ChatType.TYPE));
}
}
static <CU extends ClientboundPacketType> void registerComponents1_21_5(final RegistrationContext<CU, ?> ctx, final NBTComponentRewriter<CU> cr) {
common1_20_5(ctx, cr);
ctx.clientbound(ClientboundPackets1_21_5.SET_PLAYER_TEAM, cr::registerSetPlayerTeam1_21_5);
ctx.clientbound(ClientboundPackets1_21_5.DISGUISED_CHAT, cr::registerDisguisedChat);
ctx.clientbound(ClientboundPackets1_21_5.PLAYER_INFO_UPDATE, cr::registerPlayerInfoUpdate1_21_4);
ctx.clientbound(ClientboundPackets1_21_5.PLAYER_CHAT, cr::registerPlayerChat1_21_5);
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> ComponentRewriterBase<CU> text(final RegistrationContext<CU, SU> ctx) {
return (ComponentRewriterBase<CU>) ctx.protocol().getComponentRewriter();
}
static @Nullable <CU extends ClientboundPacketType, SU extends ServerboundPacketType> NBTComponentRewriter<CU> nbtText(final RegistrationContext<CU, SU> ctx) {
return (NBTComponentRewriter<CU>) ctx.protocol().getComponentRewriter();
}
}
@@ -21,20 +21,10 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType26_1;
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPacket26_1;
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPackets26_1;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.rewriter.RecipeDisplayRewriter1_21_5;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundPacket1_21_9;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
import com.viaversion.viaversion.rewriter.block.BlockRewriter1_21_5;
// To replace if needed:
// ChunkType26_1
// RecipeDisplayRewriter
final class BlockItemPacketRewriter99_1 extends StructuredItemRewriter<ClientboundPacket26_1, ServerboundPacket1_21_9, Protocol98_1To99_1> {
public BlockItemPacketRewriter99_1(final Protocol98_1To99_1 protocol) {
@@ -43,37 +33,8 @@ final class BlockItemPacketRewriter99_1 extends StructuredItemRewriter<Clientbou
@Override
public void registerPackets() {
// Register block and block state id changes
// Other places using block state id mappings: Spawn particle, entity data, entity spawn (falling blocks)
// Tags and statistics use block (!) ids
final BlockRewriter<ClientboundPacket26_1> blockRewriter = new BlockRewriter1_21_5<>(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets26_1.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets26_1.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets26_1.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets26_1.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets26_1.LEVEL_CHUNK_WITH_LIGHT, ChunkType26_1::new);
blockRewriter.registerBlockEntityData(ClientboundPackets26_1.BLOCK_ENTITY_DATA);
// Registers item id changes
// Other places using item ids are: Entity data, tags, statistics, effect
// registerOpenScreen(ClientboundPackets26_1.OPEN_SCREEN); If a new container type was added; also remove from the component rewriter registration
registerSetCursorItem(ClientboundPackets26_1.SET_CURSOR_ITEM);
registerSetPlayerInventory(ClientboundPackets26_1.SET_PLAYER_INVENTORY);
registerCooldown1_21_2(ClientboundPackets26_1.COOLDOWN);
registerSetContent1_21_2(ClientboundPackets26_1.CONTAINER_SET_CONTENT);
registerSetSlot1_21_2(ClientboundPackets26_1.CONTAINER_SET_SLOT);
registerAdvancements1_20_3(ClientboundPackets26_1.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets26_1.SET_EQUIPMENT);
registerMerchantOffers1_20_5(ClientboundPackets26_1.MERCHANT_OFFERS);
registerContainerClick1_21_5(ServerboundPackets1_21_6.CONTAINER_CLICK);
registerSetCreativeModeSlot1_21_5(ServerboundPackets1_21_6.SET_CREATIVE_MODE_SLOT);
final RecipeDisplayRewriter<ClientboundPacket26_1> recipeRewriter = new RecipeDisplayRewriter1_21_5<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets26_1.UPDATE_RECIPES);
recipeRewriter.registerRecipeBookAdd(ClientboundPackets26_1.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets26_1.PLACE_GHOST_RECIPE);
// OR do this if serialization of recipes changed and override the relevant method
// Add new serializers to RecipeDisplayRewriter, or extend the last one for changes
// Common block, item, recipe, and entity registrations are handled by SharedRegistrations
// If recipe serializers changed: add new serializers to RecipeDisplayRewriter, or extend the last one for changes
}
@Override
@@ -84,20 +45,21 @@ final class BlockItemPacketRewriter99_1 extends StructuredItemRewriter<Clientbou
@Override
protected void handleItemDataComponentsToClient(final UserConnection connection, final Item item, final StructuredDataContainer container) {
upgradeData(item, container);
upgradeData(container);
super.handleItemDataComponentsToClient(connection, item, container);
}
public static void upgradeData(final Item item, final StructuredDataContainer container) { // public for VB
}
@Override
protected void handleItemDataComponentsToServer(final UserConnection connection, final Item item, final StructuredDataContainer container) {
downgradeData(item, container);
downgradeData(container);
super.handleItemDataComponentsToServer(connection, item, container);
}
public static void downgradeData(final Item item, final StructuredDataContainer container) {
// public for VB
public static void upgradeData(final StructuredDataContainer container) {
}
public static void downgradeData(final StructuredDataContainer container) {
}
@Override
@@ -21,11 +21,9 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_11;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes26_1;
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPacket26_1;
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPackets26_1;
import com.viaversion.viaversion.rewriter.EntityRewriter;
// Replace if needed
// VersionedTypes
// EntityTypes1_21_11
final class EntityPacketRewriter99_1 extends EntityRewriter<ClientboundPacket26_1, Protocol98_1To99_1> {
@@ -35,28 +33,19 @@ final class EntityPacketRewriter99_1 extends EntityRewriter<ClientboundPacket26_
@Override
public void registerPackets() {
// Tracks entities, applies entity data rewrites registered below, untracks entities
registerTrackerWithData1_21_9(ClientboundPackets26_1.ADD_ENTITY, EntityTypes1_21_11.FALLING_BLOCK);
registerSetEntityData(ClientboundPackets26_1.SET_ENTITY_DATA);
registerRemoveEntities(ClientboundPackets26_1.REMOVE_ENTITIES);
registerPlayerAbilities(ClientboundPackets26_1.PLAYER_ABILITIES);
registerGameEvent(ClientboundPackets26_1.GAME_EVENT);
registerLogin1_20_5(ClientboundPackets26_1.LOGIN);
registerRespawn1_20_5(ClientboundPackets26_1.RESPAWN);
// Common entity registrations (including LOGIN, RESPAWN) are handled by SharedRegistrations.
}
@Override
protected void registerRewrites() {
final EntityDataTypes26_1 entityDataTypes = protocol.mappedTypes().entityDataTypes();
filter().mapDataType(entityDataTypes::byId);
/* ... or something this if entity data classes changed
filter().mapDataType(typeId -> {
int id = typeId;
if (id >= SomeAddedIndex) {
id++;
}
return entityDataTypes.byId(id);
});*/
dataTypeMapper().register();
/* ... or like this for additions and removals that are not at the very end
dataTypeMapper()
.added(entityDataTypes.catSoundVariant)
.removed(entityDataTypes.cowSoundVariant)
.skip(entityDataTypes.pigSoundVariant) // if neither removed nor added, but the value type has to be changed separately
.register();*/
// Registers registry type id changes
registerEntityDataTypeHandler(
@@ -70,12 +59,6 @@ final class EntityPacketRewriter99_1 extends EntityRewriter<ClientboundPacket26_
);
}
@Override
public void onMappingDataLoaded() {
// IF ENTITY TYPES CHANGED: Automatically map entity id changes AFTER entity ids have been loaded
mapTypes();
}
@Override
public EntityType typeFromId(final int type) {
return EntityTypes1_21_11.getTypeFromId(type);
@@ -21,27 +21,24 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_11;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_11;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes26_1;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType26_1;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.data.item.ItemHasherBase;
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPacket26_1;
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPackets26_1;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundConfigurationPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundConfigurationPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundPacket1_21_9;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.rewriter.block.BlockRewriter1_21_5;
import com.viaversion.viaversion.rewriter.text.NBTComponentRewriter;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
@@ -49,14 +46,15 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
// Placeholders to replace (in the entire package):
// ClientboundPacket26_1
// ServerboundPacket1_21_9
// EntityDataTypes26_1 (MAPPED type)
// VersionedTypes.V26_1
// ChunkType26_1::new
// 98.1, 99.1
final class Protocol98_1To99_1 extends AbstractProtocol<ClientboundPacket26_1, ClientboundPacket26_1, ServerboundPacket1_21_9, ServerboundPacket1_21_9> {
public static final MappingData MAPPINGS = new MappingDataBase("98.1", "99.1");
private final EntityPacketRewriter99_1 entityRewriter = new EntityPacketRewriter99_1(this);
private final BlockItemPacketRewriter99_1 itemRewriter = new BlockItemPacketRewriter99_1(this);
private final BlockRewriter<ClientboundPacket26_1> blockRewriter = new BlockRewriter1_21_5<>(this, ChunkType26_1::new);
private final ParticleRewriter<ClientboundPacket26_1> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPacket26_1> tagRewriter = new TagRewriter<>(this);
private final NBTComponentRewriter<ClientboundPacket26_1> componentRewriter = new ComponentRewriter99_1(this);
@@ -71,40 +69,9 @@ final class Protocol98_1To99_1 extends AbstractProtocol<ClientboundPacket26_1, C
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundConfigurationPackets1_21_9.REGISTRY_DATA, registryDataRewriter::handle);
tagRewriter.registerGeneric(ClientboundPackets26_1.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_9.UPDATE_TAGS);
// If needed for item or component changes
componentRewriter.registerOpenScreen1_14(ClientboundPackets26_1.OPEN_SCREEN);
componentRewriter.registerComponentPacket(ClientboundPackets26_1.SET_ACTION_BAR_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets26_1.SET_TITLE_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets26_1.SET_SUBTITLE_TEXT);
componentRewriter.registerBossEvent(ClientboundPackets26_1.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets26_1.DISCONNECT);
componentRewriter.registerComponentPacket(ClientboundConfigurationPackets1_21_9.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets26_1.TAB_LIST);
componentRewriter.registerSetPlayerTeam1_21_5(ClientboundPackets26_1.SET_PLAYER_TEAM);
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets26_1.PLAYER_COMBAT_KILL);
componentRewriter.registerPlayerInfoUpdate1_21_4(ClientboundPackets26_1.PLAYER_INFO_UPDATE);
componentRewriter.registerComponentPacket(ClientboundPackets26_1.SYSTEM_CHAT);
componentRewriter.registerDisguisedChat(ClientboundPackets26_1.DISGUISED_CHAT);
componentRewriter.registerPlayerChat1_21_5(ClientboundPackets26_1.PLAYER_CHAT);
componentRewriter.registerSetObjective(ClientboundPackets26_1.SET_OBJECTIVE);
componentRewriter.registerSetScore1_20_3(ClientboundPackets26_1.SET_SCORE);
componentRewriter.registerPing();
// If needed for any particle, item, or block changes. Extend ParticleRewriter for particle serializer changes
particleRewriter.registerLevelParticles1_21_4(ClientboundPackets26_1.LEVEL_PARTICLES);
particleRewriter.registerExplode1_21_9(ClientboundPackets26_1.EXPLODE); // Rewrites the included sound and particles
final SoundRewriter<ClientboundPacket26_1> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets26_1.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets26_1.SOUND_ENTITY);
new StatisticsRewriter<>(this).register(ClientboundPackets26_1.AWARD_STATS);
new AttributeRewriter<>(this).register1_21(ClientboundPackets26_1.UPDATE_ATTRIBUTES);
// Common registrations (tags, components, particles, sounds, statistics, attributes)
// are automatically applied via SharedRegistrations based on the protocol's version range.
// Only protocol-specific registrations need to be added here.
// 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) {
@@ -125,26 +92,8 @@ final class Protocol98_1To99_1 extends AbstractProtocol<ClientboundPacket26_1, C
// Uncomment this if the entity types enum has been newly added specifically for this Protocol
// EntityTypes1_21_11.initialize(this);
// Uncomment if a new particle was added = ids shifted; requires a new Types_ class copied from the last
/*mappedTypes().particle.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust_pillar", ParticleType.Readers.BLOCK)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("block_crumble", ParticleType.Readers.BLOCK)
.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("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK)
.reader("entity_effect", ParticleType.Readers.COLOR)
.reader("tinted_leaves", ParticleType.Readers.COLOR)
.reader("trail", ParticleType.Readers.TRAIL1_21_4)
.reader("dragon_breath", ParticleType.Readers.POWER)
.reader("effect", ParticleType.Readers.SPELL)
.reader("instant_effect", ParticleType.Readers.SPELL)
.reader("flash", ParticleType.Readers.COLOR)
.reader("item", ParticleType.Readers.item(itemRewriter.mappedItemTemplateType()));*/
// Uncomment if versioned types changed
// ParticleType.Fillers.fill1_21_9(this);
super.onMappingDataLoaded(); // Calls load methods on rewriters. Last in case the rewriters access the above filled data
}
@@ -152,8 +101,8 @@ final class Protocol98_1To99_1 extends AbstractProtocol<ClientboundPacket26_1, C
@Override
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)
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_11.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection));
addEntityTracker(connection);
addItemHasher(connection);
}
// Overriding these methods is important as they are relied on various rewriter classes
@@ -173,6 +122,11 @@ final class Protocol98_1To99_1 extends AbstractProtocol<ClientboundPacket26_1, C
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPacket26_1> getBlockRewriter() {
return blockRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
@@ -37,7 +37,6 @@ import com.viaversion.viaversion.protocols.v1_10to1_11.rewriter.ItemPacketRewrit
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.ServerboundPackets1_9_3;
import com.viaversion.viaversion.rewriter.SoundRewriter;
public class Protocol1_10To1_11 extends AbstractProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
@@ -59,7 +58,15 @@ public class Protocol1_10To1_11 extends AbstractProtocol<ClientboundPackets1_9_3
protected void registerPackets() {
super.registerPackets();
new SoundRewriter<>(this, this::getNewSoundId).registerSound(ClientboundPackets1_9_3.SOUND);
registerClientbound(ClientboundPackets1_9_3.SOUND, wrapper -> {
int soundId = wrapper.read(Types.VAR_INT);
int mappedId = getNewSoundId(soundId);
if (mappedId == -1) {
wrapper.cancel();
} else {
wrapper.write(Types.VAR_INT, mappedId);
}
});
registerClientbound(ClientboundPackets1_9_3.SET_TITLES, new PacketHandlers() {
@Override
@@ -43,7 +43,6 @@ import com.viaversion.viaversion.protocols.v1_11_1to1_12.rewriter.EntityPacketRe
import com.viaversion.viaversion.protocols.v1_11_1to1_12.rewriter.ItemPacketRewriter1_12;
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.ServerboundPackets1_9_3;
import com.viaversion.viaversion.rewriter.SoundRewriter;
public class Protocol1_11_1To1_12 extends AbstractProtocol<ClientboundPackets1_9_3, ClientboundPackets1_12, ServerboundPackets1_9_3, ServerboundPackets1_12> {
@@ -58,6 +57,16 @@ public class Protocol1_11_1To1_12 extends AbstractProtocol<ClientboundPackets1_9
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundPackets1_9_3.SOUND, wrapper -> {
int soundId = wrapper.read(Types.VAR_INT);
int mappedId = getNewSoundId(soundId);
if (mappedId == -1) {
wrapper.cancel();
} else {
wrapper.write(Types.VAR_INT, mappedId);
}
});
registerClientbound(ClientboundPackets1_9_3.CHAT, wrapper -> {
final JsonElement element = wrapper.passthrough(Types.COMPONENT);
TranslateRewriter.toClient(wrapper.user(), element);
@@ -96,9 +105,6 @@ public class Protocol1_11_1To1_12 extends AbstractProtocol<ClientboundPackets1_9
}
});
new SoundRewriter<>(this, this::getNewSoundId).registerSound(ClientboundPackets1_9_3.SOUND);
// New packet at 0x01
cancelServerbound(ServerboundPackets1_12.CRAFTING_RECIPE_PLACEMENT);
@@ -40,7 +40,6 @@ import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_13;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ClientboundStatusPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.blockconnections.ConnectionData;
@@ -65,7 +64,6 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.storage.BlockStorage;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.storage.TabCompleteTracker;
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ServerboundPackets1_12_1;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.util.ChatColorUtil;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.GsonUtil;
@@ -181,10 +179,6 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
WorldPacketRewriter1_13.register(this);
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_DISCONNECT, wrapper -> {
componentRewriter.processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
});
registerClientbound(State.STATUS, ClientboundStatusPackets.STATUS_RESPONSE, new PacketHandlers() {
@Override
public void register() {
@@ -253,9 +247,6 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
});
componentRewriter.registerBossEvent(ClientboundPackets1_12_1.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_12_1.CHAT);
registerClientbound(ClientboundPackets1_12_1.COMMAND_SUGGESTIONS, wrapper -> {
wrapper.write(Types.VAR_INT, wrapper.user().get(TabCompleteTracker.class).getTransactionId());
@@ -329,8 +320,6 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
}
});
componentRewriter.registerComponentPacket(ClientboundPackets1_12_1.DISCONNECT);
registerClientbound(ClientboundPackets1_12_1.LEVEL_EVENT, new PacketHandlers() {
@Override
public void register() {
@@ -359,8 +348,6 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
}
});
componentRewriter.registerPlayerCombat(ClientboundPackets1_12_1.PLAYER_COMBAT);
registerClientbound(ClientboundPackets1_12_1.MAP_ITEM_DATA, new PacketHandlers() {
@Override
public void register() {
@@ -510,17 +497,6 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
}
});
componentRewriter.registerTitle(ClientboundPackets1_12_1.SET_TITLES);
// New 0x4C - Stop Sound
new SoundRewriter<>(this).registerSound(ClientboundPackets1_12_1.SOUND);
registerClientbound(ClientboundPackets1_12_1.TAB_LIST, wrapper -> {
componentRewriter.processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
componentRewriter.processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
});
registerClientbound(ClientboundPackets1_12_1.UPDATE_ADVANCEMENTS, wrapper -> {
wrapper.passthrough(Types.BOOLEAN); // Reset/clear
int size = wrapper.passthrough(Types.VAR_INT); // Mapping size
@@ -701,7 +677,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
String stringMode = mode == 0 ? "SEQUENCE"
: mode == 1 ? "AUTO"
: "REDSTONE";
: "REDSTONE";
wrapper.write(Types.BOOLEAN, (flags & 0x1) != 0); // Track output
wrapper.write(Types.STRING, stringMode);
@@ -742,8 +718,8 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
public String transform(PacketWrapper wrapper, Integer mode) {
return mode == 0 ? "SAVE"
: mode == 1 ? "LOAD"
: mode == 2 ? "CORNER"
: "DATA";
: mode == 2 ? "CORNER"
: "DATA";
}
});
map(Types.STRING); // Name
@@ -758,7 +734,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
public String transform(PacketWrapper wrapper, Integer mirror) {
return mirror == 0 ? "NONE"
: mirror == 1 ? "LEFT_RIGHT"
: "FRONT_BACK";
: "FRONT_BACK";
}
});
map(Types.VAR_INT, new ValueTransformer<>(Types.STRING) { // Rotation
@@ -766,8 +742,8 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
public String transform(PacketWrapper wrapper, Integer rotation) {
return rotation == 0 ? "NONE"
: rotation == 1 ? "CLOCKWISE_90"
: rotation == 2 ? "CLOCKWISE_180"
: "COUNTERCLOCKWISE_90";
: rotation == 2 ? "CLOCKWISE_180"
: "COUNTERCLOCKWISE_90";
}
});
map(Types.STRING);
@@ -23,7 +23,6 @@ import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_13_2;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
@@ -38,10 +37,9 @@ import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.ItemPacketRewr
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.PlayerPacketRewriter1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.WorldPacketRewriter1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.storage.EntityTracker1_14;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import com.viaversion.viaversion.util.ProtocolLogger;
@@ -55,6 +53,7 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
private final ItemPacketRewriter1_14 itemRewriter = new ItemPacketRewriter1_14(this);
private final ParticleRewriter<ClientboundPackets1_13> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_13> tagRewriter = new TagRewriter<>(this);
private final BlockRewriter<ClientboundPackets1_13> blockRewriter = BlockRewriter.for1_14(this);
public Protocol1_13_2To1_14() {
super(ClientboundPackets1_13.class, ClientboundPackets1_14.class, ServerboundPackets1_13.class, ServerboundPackets1_14.class);
@@ -67,11 +66,6 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
WorldPacketRewriter1_14.register(this);
PlayerPacketRewriter1_14.register(this);
new SoundRewriter<>(this).registerSound(ClientboundPackets1_13.SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_13.AWARD_STATS);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_13.LEVEL_PARTICLES, Types.FLOAT);
JsonNBTComponentRewriter<ClientboundPackets1_13> componentRewriter = new ComponentRewriter1_14<>(this);
componentRewriter.registerComponentPacket(ClientboundPackets1_13.CHAT);
@@ -109,16 +103,8 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
WorldPacketRewriter1_14.caveAir = MAPPINGS.getBlockStateMappings().getNewId(8592);
EntityTypes1_14.initialize(this);
Types1_13_2.PARTICLE.filler(this, false)
.reader("block", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("item", ParticleType.Readers.ITEM1_13_2);
Types1_14.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("item", ParticleType.Readers.ITEM1_13_2);
ParticleType.Fillers.fill1_13_2(this, Types1_13_2.PARTICLE, false);
ParticleType.Fillers.fill1_13_2(this, Types1_14.PARTICLE, true);
tagRewriter.addEmptyTag(RegistryType.BLOCK, "bamboo_plantable_on");
@@ -151,6 +137,11 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPackets1_13> getBlockRewriter() {
return blockRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_13> getParticleRewriter() {
return particleRewriter;
@@ -252,7 +252,6 @@ public class EntityPacketRewriter1_14 extends EntityRewriter<ClientboundPackets1
}
});
registerRemoveEntities(ClientboundPackets1_13.REMOVE_ENTITIES);
registerSetEntityData(ClientboundPackets1_13.SET_ENTITY_DATA, Types1_13_2.ENTITY_DATA_LIST, Types1_14.ENTITY_DATA_LIST);
}
@@ -386,7 +385,7 @@ public class EntityPacketRewriter1_14 extends EntityRewriter<ClientboundPackets1
@Override
public void onMappingDataLoaded() {
mapTypes();
super.onMappingDataLoaded();
if (Via.getConfig().translateOcelotToCat()) {
// A better solution for this would be to despawn the ocelot and spawn a cat in its place, but that would
// require a lot of data tracking and is not worth the effort.
@@ -64,9 +64,6 @@ public class ItemPacketRewriter1_14 extends ItemRewriter<ClientboundPackets1_13,
@Override
public void registerPackets() {
registerCooldown(ClientboundPackets1_13.COOLDOWN);
registerAdvancements(ClientboundPackets1_13.UPDATE_ADVANCEMENTS);
protocol.registerClientbound(ClientboundPackets1_13.OPEN_SCREEN, null, wrapper -> {
Short windowId = wrapper.read(Types.UNSIGNED_BYTE);
String type = wrapper.read(Types.STRING);
@@ -112,9 +109,6 @@ public class ItemPacketRewriter1_14 extends ItemRewriter<ClientboundPackets1_13,
}
});
registerSetContent(ClientboundPackets1_13.CONTAINER_SET_CONTENT);
registerSetSlot(ClientboundPackets1_13.CONTAINER_SET_SLOT);
protocol.registerClientbound(ClientboundPackets1_13.CUSTOM_PAYLOAD, new PacketHandlers() {
@Override
public void register() {
@@ -166,8 +160,6 @@ public class ItemPacketRewriter1_14 extends ItemRewriter<ClientboundPackets1_13,
}
});
registerSetEquippedItem(ClientboundPackets1_13.SET_EQUIPPED_ITEM);
RecipeRewriter<ClientboundPackets1_13> recipeRewriter = new RecipeRewriter<>(protocol);
protocol.registerClientbound(ClientboundPackets1_13.UPDATE_RECIPES, wrapper -> {
int size = wrapper.passthrough(Types.VAR_INT);
@@ -188,8 +180,6 @@ public class ItemPacketRewriter1_14 extends ItemRewriter<ClientboundPackets1_13,
});
registerContainerClick(ServerboundPackets1_14.CONTAINER_CLICK);
protocol.registerServerbound(ServerboundPackets1_14.SELECT_TRADE, wrapper -> {
// Selecting trade now moves the items, we need to resync the inventory
PacketWrapper resyncPacket = wrapper.create(ServerboundPackets1_13.CONTAINER_CLICK);
@@ -204,8 +194,6 @@ public class ItemPacketRewriter1_14 extends ItemRewriter<ClientboundPackets1_13,
resyncPacket.write(Types.ITEM1_13_2, new DataItem(1, (byte) 1, tag)); // 5 - Clicked Item
resyncPacket.scheduleSendToServer(Protocol1_13_2To1_14.class);
});
registerSetCreativeModeSlot(ServerboundPackets1_14.SET_CREATIVE_MODE_SLOT);
}
@Override
@@ -37,7 +37,6 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPacke
import com.viaversion.viaversion.protocols.v1_13_2to1_14.Protocol1_13_2To1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.storage.EntityTracker1_14;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.util.CompactArrayUtil;
import java.util.Arrays;
@@ -53,8 +52,6 @@ public class WorldPacketRewriter1_14 {
}
public static void register(Protocol1_13_2To1_14 protocol) {
BlockRewriter<ClientboundPackets1_13> blockRewriter = BlockRewriter.for1_14(protocol);
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_DESTRUCTION, new PacketHandlers() {
@Override
public void register() {
@@ -69,7 +66,7 @@ public class WorldPacketRewriter1_14 {
map(Types.BLOCK_POSITION1_8, Types.BLOCK_POSITION1_14);
}
});
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_EVENT, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_13.BLOCK_EVENT, new PacketHandlers() {
@Override
public void register() {
map(Types.BLOCK_POSITION1_8, Types.BLOCK_POSITION1_14); // Location
@@ -79,7 +76,7 @@ public class WorldPacketRewriter1_14 {
handler(wrapper -> wrapper.set(Types.VAR_INT, 0, protocol.getMappingData().getNewBlockId(wrapper.get(Types.VAR_INT, 0))));
}
});
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_UPDATE, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_13.BLOCK_UPDATE, new PacketHandlers() {
@Override
public void register() {
map(Types.BLOCK_POSITION1_8, Types.BLOCK_POSITION1_14);
@@ -102,8 +99,6 @@ public class WorldPacketRewriter1_14 {
}
});
blockRewriter.registerChunkBlocksUpdate(ClientboundPackets1_13.CHUNK_BLOCKS_UPDATE);
protocol.registerClientbound(ClientboundPackets1_13.EXPLODE, new PacketHandlers() {
@Override
public void register() {
@@ -247,7 +242,7 @@ public class WorldPacketRewriter1_14 {
}
});
protocol.registerClientbound(ClientboundPackets1_13.LEVEL_EVENT, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_13.LEVEL_EVENT, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // Effect Id
@@ -35,8 +35,8 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPacke
import com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter.EntityPacketRewriter1_13_1;
import com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter.ItemPacketRewriter1_13_1;
import com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter.WorldPacketRewriter1_13_1;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_13, ClientboundPackets1_13, ServerboundPackets1_13, ServerboundPackets1_13> {
@@ -46,6 +46,7 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_1
private final ItemPacketRewriter1_13_1 itemRewriter = new ItemPacketRewriter1_13_1(this);
private final ParticleRewriter<ClientboundPackets1_13> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_13> tagRewriter = new TagRewriter<>(this);
private final BlockRewriter<ClientboundPackets1_13> blockRewriter = BlockRewriter.legacy(this);
public Protocol1_13To1_13_1() {
super(ClientboundPackets1_13.class, ClientboundPackets1_13.class, ServerboundPackets1_13.class, ServerboundPackets1_13.class);
@@ -130,9 +131,6 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_1
});
tagRewriter.register(ClientboundPackets1_13.UPDATE_TAGS, RegistryType.ITEM);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_13.LEVEL_PARTICLES, Types.FLOAT);
new StatisticsRewriter<>(this).register(ClientboundPackets1_13.AWARD_STATS);
}
@Override
@@ -156,6 +154,11 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPackets1_13> getBlockRewriter() {
return blockRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_13> getParticleRewriter() {
return particleRewriter;
@@ -133,7 +133,6 @@ public class EntityPacketRewriter1_13_1 extends EntityRewriter<ClientboundPacket
}
});
registerRemoveEntities(ClientboundPackets1_13.REMOVE_ENTITIES);
registerSetEntityData(ClientboundPackets1_13.SET_ENTITY_DATA, Types1_13.ENTITY_DATA_LIST);
}
@@ -36,11 +36,6 @@ public class ItemPacketRewriter1_13_1 extends ItemRewriter<ClientboundPackets1_1
@Override
public void registerPackets() {
registerSetSlot(ClientboundPackets1_13.CONTAINER_SET_SLOT);
registerSetContent(ClientboundPackets1_13.CONTAINER_SET_CONTENT);
registerAdvancements(ClientboundPackets1_13.UPDATE_ADVANCEMENTS);
registerCooldown(ClientboundPackets1_13.COOLDOWN);
protocol.registerClientbound(ClientboundPackets1_13.CUSTOM_PAYLOAD, new PacketHandlers() {
@Override
public void register() {
@@ -72,8 +67,6 @@ public class ItemPacketRewriter1_13_1 extends ItemRewriter<ClientboundPackets1_1
}
});
registerSetEquippedItem(ClientboundPackets1_13.SET_EQUIPPED_ITEM);
RecipeRewriter<ClientboundPackets1_13> recipeRewriter = new RecipeRewriter<>(protocol) {
@Override
protected Type<Item> itemType() {
@@ -94,8 +87,5 @@ public class ItemPacketRewriter1_13_1 extends ItemRewriter<ClientboundPackets1_1
recipeRewriter.handleRecipeType(wrapper, type);
}
});
registerContainerClick(ServerboundPackets1_13.CONTAINER_CLICK);
registerSetCreativeModeSlot(ServerboundPackets1_13.SET_CREATIVE_MODE_SLOT);
}
}
@@ -24,25 +24,18 @@ import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_13;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_13to1_13_1.Protocol1_13To1_13_1;
import com.viaversion.viaversion.rewriter.BlockRewriter;
public class WorldPacketRewriter1_13_1 {
public static void register(Protocol1_13To1_13_1 protocol) {
BlockRewriter<ClientboundPackets1_13> blockRewriter = BlockRewriter.legacy(protocol);
protocol.registerClientbound(ClientboundPackets1_13.LEVEL_CHUNK, wrapper -> {
ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13To1_13_1.class);
Chunk chunk = wrapper.passthrough(ChunkType1_13.forEnvironment(clientWorld.getEnvironment()));
blockRewriter.handleChunk(chunk);
protocol.getBlockRewriter().handleChunk(chunk);
});
blockRewriter.registerBlockEvent(ClientboundPackets1_13.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_13.BLOCK_UPDATE);
blockRewriter.registerChunkBlocksUpdate(ClientboundPackets1_13.CHUNK_BLOCKS_UPDATE);
protocol.registerClientbound(ClientboundPackets1_13.LEVEL_EVENT, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_13.LEVEL_EVENT, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // Effect Id
@@ -32,9 +32,8 @@ import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPacke
import com.viaversion.viaversion.protocols.v1_14_4to1_15.rewriter.EntityPacketRewriter1_15;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.rewriter.ItemPacketRewriter1_15;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.rewriter.WorldPacketRewriter1_15;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
public class Protocol1_14_4To1_15 extends AbstractProtocol<ClientboundPackets1_14_4, ClientboundPackets1_15, ServerboundPackets1_14, ServerboundPackets1_14> {
@@ -44,6 +43,7 @@ public class Protocol1_14_4To1_15 extends AbstractProtocol<ClientboundPackets1_1
private final ItemPacketRewriter1_15 itemRewriter = new ItemPacketRewriter1_15(this);
private final ParticleRewriter<ClientboundPackets1_14_4> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_14_4> tagRewriter = new TagRewriter<>(this);
private final BlockRewriter<ClientboundPackets1_14_4> blockRewriter = BlockRewriter.for1_14(this);
public Protocol1_14_4To1_15() {
super(ClientboundPackets1_14_4.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
@@ -55,12 +55,6 @@ public class Protocol1_14_4To1_15 extends AbstractProtocol<ClientboundPackets1_1
WorldPacketRewriter1_15.register(this);
SoundRewriter<ClientboundPackets1_14_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_14_4.SOUND_ENTITY); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14_4.SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_14_4.AWARD_STATS);
registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> itemRewriter.handleItemToServer(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)));
tagRewriter.register(ClientboundPackets1_14_4.UPDATE_TAGS, RegistryType.ENTITY);
@@ -99,6 +93,11 @@ public class Protocol1_14_4To1_15 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPackets1_14_4> getBlockRewriter() {
return blockRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_14_4> getParticleRewriter() {
return particleRewriter;
@@ -40,9 +40,7 @@ public class EntityPacketRewriter1_15 extends EntityRewriter<ClientboundPackets1
@Override
protected void registerPackets() {
registerTrackerWithData(ClientboundPackets1_14_4.ADD_ENTITY, EntityTypes1_15.FALLING_BLOCK);
protocol.registerClientbound(ClientboundPackets1_14_4.ADD_MOB, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_14_4.ADD_MOB, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // 0 - Entity ID
@@ -123,7 +121,6 @@ public class EntityPacketRewriter1_15 extends EntityRewriter<ClientboundPackets1
});
registerSetEntityData(ClientboundPackets1_14_4.SET_ENTITY_DATA, Types1_14.ENTITY_DATA_LIST);
registerRemoveEntities(ClientboundPackets1_14_4.REMOVE_ENTITIES);
}
@Override
@@ -32,16 +32,6 @@ public class ItemPacketRewriter1_15 extends ItemRewriter<ClientboundPackets1_14_
@Override
public void registerPackets() {
registerCooldown(ClientboundPackets1_14_4.COOLDOWN);
registerSetContent(ClientboundPackets1_14_4.CONTAINER_SET_CONTENT);
registerMerchantOffers(ClientboundPackets1_14_4.MERCHANT_OFFERS);
registerSetSlot(ClientboundPackets1_14_4.CONTAINER_SET_SLOT);
registerSetEquippedItem(ClientboundPackets1_14_4.SET_EQUIPPED_ITEM);
registerAdvancements(ClientboundPackets1_14_4.UPDATE_ADVANCEMENTS);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_14_4.UPDATE_RECIPES);
registerContainerClick(ServerboundPackets1_14.CONTAINER_CLICK);
registerSetCreativeModeSlot(ServerboundPackets1_14.SET_CREATIVE_MODE_SLOT);
}
}
@@ -23,18 +23,11 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_14;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_15;
import com.viaversion.viaversion.protocols.v1_14_3to1_14_4.packet.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.Protocol1_14_4To1_15;
import com.viaversion.viaversion.rewriter.BlockRewriter;
public final class WorldPacketRewriter1_15 {
public static void register(Protocol1_14_4To1_15 protocol) {
BlockRewriter<ClientboundPackets1_14_4> blockRewriter = BlockRewriter.for1_14(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_14_4.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_14_4.BLOCK_UPDATE);
blockRewriter.registerChunkBlocksUpdate(ClientboundPackets1_14_4.CHUNK_BLOCKS_UPDATE);
blockRewriter.registerBlockBreakAck(ClientboundPackets1_14_4.BLOCK_BREAK_ACK);
blockRewriter.registerLevelChunk(ClientboundPackets1_14_4.LEVEL_CHUNK, ChunkType1_14.TYPE, ChunkType1_15.TYPE, (connection, chunk) -> {
protocol.getBlockRewriter().registerLevelChunk(ClientboundPackets1_14_4.LEVEL_CHUNK, ChunkType1_14.TYPE, ChunkType1_15.TYPE, (connection, chunk) -> {
if (chunk.isFullChunk()) {
int[] biomeData = chunk.getBiomeData();
int[] newBiomeData = new int[1024];
@@ -58,8 +51,7 @@ public final class WorldPacketRewriter1_15 {
}
});
blockRewriter.registerLevelEvent(ClientboundPackets1_14_4.LEVEL_EVENT, 1010, 2001);
protocol.registerClientbound(ClientboundPackets1_14_4.LEVEL_PARTICLES, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_14_4.LEVEL_PARTICLES, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // 0 - Particle ID
@@ -55,8 +55,6 @@ public class EntityPacketRewriter1_14_1 extends EntityRewriter<ClientboundPacket
}
});
registerRemoveEntities(ClientboundPackets1_14.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_14.ADD_PLAYER, new PacketHandlers() {
@Override
public void register() {
@@ -47,9 +47,8 @@ import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.EntityPacketRe
import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.ItemPacketRewriter1_16;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.WorldPacketRewriter1_16;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.storage.InventoryTracker1_16;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.GsonUtil;
import com.viaversion.viaversion.util.Key;
@@ -67,6 +66,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
private final ParticleRewriter<ClientboundPackets1_15> particleRewriter = new ParticleRewriter<>(this);
private final ComponentRewriter1_16 componentRewriter = new ComponentRewriter1_16(this);
private final TagRewriter<ClientboundPackets1_15> tagRewriter = new TagRewriter<>(this);
private final BlockRewriter<ClientboundPackets1_15> blockRewriter = BlockRewriter.for1_14(this);
public Protocol1_15_2To1_16() {
super(ClientboundPackets1_15.class, ClientboundPackets1_16.class, ServerboundPackets1_14.class, ServerboundPackets1_16.class);
@@ -79,10 +79,6 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
WorldPacketRewriter1_16.register(this);
tagRewriter.register(ClientboundPackets1_15.UPDATE_TAGS, RegistryType.ENTITY);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_15.LEVEL_PARTICLES, Types.DOUBLE);
new StatisticsRewriter<>(this).register(ClientboundPackets1_15.AWARD_STATS);
// Login Success
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
// Transform string to a uuid
@@ -126,7 +122,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
});
// Handle (relevant) component cases for translatable and score changes
registerClientbound(ClientboundPackets1_15.CHAT, new PacketHandlers() {
replaceClientbound(ClientboundPackets1_15.CHAT, new PacketHandlers() {
@Override
public void register() {
map(Types.COMPONENT);
@@ -137,13 +133,6 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
});
}
});
componentRewriter.registerBossEvent(ClientboundPackets1_15.BOSS_EVENT);
componentRewriter.registerTitle(ClientboundPackets1_15.SET_TITLES);
componentRewriter.registerPlayerCombat(ClientboundPackets1_15.PLAYER_COMBAT);
SoundRewriter<ClientboundPackets1_15> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_15.SOUND);
soundRewriter.registerSound(ClientboundPackets1_15.SOUND_ENTITY);
registerServerbound(ServerboundPackets1_16.INTERACT, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity Id
@@ -217,11 +206,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
@Override
protected void onMappingDataLoaded() {
EntityTypes1_16.initialize(this);
Types1_16.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("item", ParticleType.Readers.ITEM1_13_2);
ParticleType.Fillers.fill1_13_2(this, Types1_16.PARTICLE, true);
tagRewriter.addEmptyTags(RegistryType.ITEM, "minecraft:crimson_stems", "minecraft:non_flammable_wood", "minecraft:piglin_loved",
"minecraft:piglin_repellents", "minecraft:soul_fire_base_blocks", "minecraft:warped_stems");
@@ -258,6 +243,11 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPackets1_15> getBlockRewriter() {
return blockRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_15> getParticleRewriter() {
return particleRewriter;
@@ -107,11 +107,8 @@ public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1
wrapper.write(Types.SHORT, (short) 0); // velocity
});
registerTrackerWithData(ClientboundPackets1_15.ADD_ENTITY, EntityTypes1_16.FALLING_BLOCK);
registerTracker(ClientboundPackets1_15.ADD_MOB);
registerTracker(ClientboundPackets1_15.ADD_PLAYER, EntityTypes1_16.PLAYER);
registerSetEntityData(ClientboundPackets1_15.SET_ENTITY_DATA, Types1_14.ENTITY_DATA_LIST, Types1_16.ENTITY_DATA_LIST);
registerRemoveEntities(ClientboundPackets1_15.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_15.RESPAWN, new PacketHandlers() {
@Override
@@ -227,11 +224,6 @@ public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1
});
}
@Override
public void onMappingDataLoaded() {
mapTypes();
}
@Override
public EntityType typeFromId(int type) {
return EntityTypes1_16.getTypeFromId(type);
@@ -57,7 +57,7 @@ public class ItemPacketRewriter1_16 extends ItemRewriter<ClientboundPackets1_15,
clearPacket.send(Protocol1_15_2To1_16.class);
};
protocol.registerClientbound(ClientboundPackets1_15.OPEN_SCREEN, new PacketHandlers() {
protocol.replaceClientbound(ClientboundPackets1_15.OPEN_SCREEN, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Window Id
@@ -106,12 +106,6 @@ public class ItemPacketRewriter1_16 extends ItemRewriter<ClientboundPackets1_15,
}
});
registerCooldown(ClientboundPackets1_15.COOLDOWN);
registerSetContent(ClientboundPackets1_15.CONTAINER_SET_CONTENT);
registerMerchantOffers(ClientboundPackets1_15.MERCHANT_OFFERS);
registerSetSlot(ClientboundPackets1_15.CONTAINER_SET_SLOT);
registerAdvancements(ClientboundPackets1_15.UPDATE_ADVANCEMENTS);
protocol.registerClientbound(ClientboundPackets1_15.SET_EQUIPPED_ITEM, ClientboundPackets1_16.SET_EQUIPMENT, new PacketHandlers() {
@Override
public void register() {
@@ -127,9 +121,6 @@ public class ItemPacketRewriter1_16 extends ItemRewriter<ClientboundPackets1_15,
new RecipeRewriter<>(protocol).register(ClientboundPackets1_15.UPDATE_RECIPES);
registerContainerClick(ServerboundPackets1_16.CONTAINER_CLICK);
registerSetCreativeModeSlot(ServerboundPackets1_16.SET_CREATIVE_MODE_SLOT);
protocol.registerServerbound(ServerboundPackets1_16.CONTAINER_CLOSE, wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventoryOpen(false);
@@ -30,7 +30,6 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_15;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_16;
import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.Protocol1_15_2To1_16;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.util.CompactArrayUtil;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.UUIDUtil;
@@ -40,13 +39,7 @@ import java.util.UUID;
public class WorldPacketRewriter1_16 {
public static void register(Protocol1_15_2To1_16 protocol) {
BlockRewriter<ClientboundPackets1_15> blockRewriter = BlockRewriter.for1_14(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_15.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_15.BLOCK_UPDATE);
blockRewriter.registerChunkBlocksUpdate(ClientboundPackets1_15.CHUNK_BLOCKS_UPDATE);
blockRewriter.registerBlockBreakAck(ClientboundPackets1_15.BLOCK_BREAK_ACK);
blockRewriter.registerLevelChunk(ClientboundPackets1_15.LEVEL_CHUNK, ChunkType1_15.TYPE, ChunkType1_16.TYPE, (connection, chunk) -> {
protocol.getBlockRewriter().registerLevelChunk(ClientboundPackets1_15.LEVEL_CHUNK, ChunkType1_15.TYPE, ChunkType1_16.TYPE, (connection, chunk) -> {
chunk.setIgnoreOldLightData(chunk.isFullChunk());
CompoundTag heightMaps = chunk.getHeightMap();
@@ -78,8 +71,6 @@ public class WorldPacketRewriter1_16 {
CompoundTag tag = wrapper.passthrough(Types.NAMED_COMPOUND_TAG);
handleBlockEntity(protocol, wrapper.user(), tag);
});
blockRewriter.registerLevelEvent(ClientboundPackets1_15.LEVEL_EVENT, 1010, 2001);
}
private static void handleBlockEntity(Protocol1_15_2To1_16 protocol, UserConnection connection, CompoundTag compoundTag) {
@@ -31,9 +31,8 @@ import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.EntityPacketRewriter1_16_2;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.ItemPacketRewriter1_16_2;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.rewriter.WorldPacketRewriter1_16_2;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1_16, ClientboundPackets1_16_2, ServerboundPackets1_16, ServerboundPackets1_16_2> {
@@ -43,6 +42,7 @@ public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1
private final ItemPacketRewriter1_16_2 itemRewriter = new ItemPacketRewriter1_16_2(this);
private final ParticleRewriter<ClientboundPackets1_16> particleRewriter = new ParticleRewriter<>(this);
private final TagRewriter<ClientboundPackets1_16> tagRewriter = new TagRewriter<>(this);
private final BlockRewriter<ClientboundPackets1_16> blockRewriter = BlockRewriter.for1_14(this);
public Protocol1_16_1To1_16_2() {
super(ClientboundPackets1_16.class, ClientboundPackets1_16_2.class, ServerboundPackets1_16.class, ServerboundPackets1_16_2.class);
@@ -55,13 +55,6 @@ public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1
WorldPacketRewriter1_16_2.register(this);
tagRewriter.register(ClientboundPackets1_16.UPDATE_TAGS, RegistryType.ENTITY);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_16.LEVEL_PARTICLES, Types.DOUBLE);
new StatisticsRewriter<>(this).register(ClientboundPackets1_16.AWARD_STATS);
SoundRewriter<ClientboundPackets1_16> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_16.SOUND);
soundRewriter.registerSound(ClientboundPackets1_16.SOUND_ENTITY);
// Recipe book data has been split into 2 separate packets
registerServerbound(ServerboundPackets1_16_2.RECIPE_BOOK_CHANGE_SETTINGS, ServerboundPackets1_16.RECIPE_BOOK_UPDATE, wrapper -> {
@@ -114,6 +107,11 @@ public class Protocol1_16_1To1_16_2 extends AbstractProtocol<ClientboundPackets1
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPackets1_16> getBlockRewriter() {
return blockRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_16> getParticleRewriter() {
return particleRewriter;
@@ -35,11 +35,8 @@ public class EntityPacketRewriter1_16_2 extends EntityRewriter<ClientboundPacket
@Override
protected void registerPackets() {
registerTrackerWithData(ClientboundPackets1_16.ADD_ENTITY, EntityTypes1_16_2.FALLING_BLOCK);
registerTracker(ClientboundPackets1_16.ADD_MOB);
registerTracker(ClientboundPackets1_16.ADD_PLAYER, EntityTypes1_16_2.PLAYER);
registerSetEntityData(ClientboundPackets1_16.SET_ENTITY_DATA, Types1_16.ENTITY_DATA_LIST);
registerRemoveEntities(ClientboundPackets1_16.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_16.LOGIN, new PacketHandlers() {
@Override
@@ -96,11 +93,6 @@ public class EntityPacketRewriter1_16_2 extends EntityRewriter<ClientboundPacket
});
}
@Override
public void onMappingDataLoaded() {
mapTypes();
}
@Override
public EntityType typeFromId(int type) {
return EntityTypes1_16_2.getTypeFromId(type);
@@ -32,13 +32,6 @@ public class ItemPacketRewriter1_16_2 extends ItemRewriter<ClientboundPackets1_1
@Override
public void registerPackets() {
registerCooldown(ClientboundPackets1_16.COOLDOWN);
registerSetContent(ClientboundPackets1_16.CONTAINER_SET_CONTENT);
registerMerchantOffers(ClientboundPackets1_16.MERCHANT_OFFERS);
registerSetSlot(ClientboundPackets1_16.CONTAINER_SET_SLOT);
registerSetEquipment(ClientboundPackets1_16.SET_EQUIPMENT);
registerAdvancements(ClientboundPackets1_16.UPDATE_ADVANCEMENTS);
protocol.registerClientbound(ClientboundPackets1_16.RECIPE, wrapper -> {
wrapper.passthrough(Types.VAR_INT);
wrapper.passthrough(Types.BOOLEAN); // Open
@@ -54,8 +47,6 @@ public class ItemPacketRewriter1_16_2 extends ItemRewriter<ClientboundPackets1_1
new RecipeRewriter<>(protocol).register(ClientboundPackets1_16.UPDATE_RECIPES);
registerContainerClick(ServerboundPackets1_16_2.CONTAINER_CLICK);
registerSetCreativeModeSlot(ServerboundPackets1_16_2.SET_CREATIVE_MODE_SLOT);
protocol.registerServerbound(ServerboundPackets1_16_2.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)));
}
}
@@ -26,7 +26,6 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_16_2;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.Protocol1_16_1To1_16_2;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import java.util.ArrayList;
import java.util.List;
@@ -35,12 +34,7 @@ public class WorldPacketRewriter1_16_2 {
private static final BlockChangeRecord[] EMPTY_RECORDS = new BlockChangeRecord[0];
public static void register(Protocol1_16_1To1_16_2 protocol) {
BlockRewriter<ClientboundPackets1_16> blockRewriter = BlockRewriter.for1_14(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_16.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_16.BLOCK_UPDATE);
blockRewriter.registerBlockBreakAck(ClientboundPackets1_16.BLOCK_BREAK_ACK);
blockRewriter.registerLevelChunk(ClientboundPackets1_16.LEVEL_CHUNK, ChunkType1_16.TYPE, ChunkType1_16_2.TYPE);
protocol.getBlockRewriter().registerLevelChunk(ClientboundPackets1_16.LEVEL_CHUNK, ChunkType1_16.TYPE, ChunkType1_16_2.TYPE);
protocol.registerClientbound(ClientboundPackets1_16.CHUNK_BLOCKS_UPDATE, ClientboundPackets1_16_2.SECTION_BLOCKS_UPDATE, wrapper -> {
wrapper.cancel();
@@ -78,7 +72,5 @@ public class WorldPacketRewriter1_16_2 {
newPacket.send(Protocol1_16_1To1_16_2.class);
}
});
blockRewriter.registerLevelEvent(ClientboundPackets1_16.LEVEL_EVENT, 1010, 2001);
}
}
@@ -38,11 +38,9 @@ import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.ComponentRewri
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.EntityPacketRewriter1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.ItemPacketRewriter1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.WorldPacketRewriter1_17;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPackets1_16_2, ClientboundPackets1_17, ServerboundPackets1_16_2, ServerboundPackets1_17> {
@@ -52,6 +50,7 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
private final ParticleRewriter<ClientboundPackets1_16_2> particleRewriter = new ParticleRewriter<>(this);
private final ComponentRewriter1_17 componentRewriter = new ComponentRewriter1_17(this);
private final TagRewriter<ClientboundPackets1_16_2> tagRewriter = new TagRewriter<>(this);
private final BlockRewriter<ClientboundPackets1_16_2> blockRewriter = BlockRewriter.for1_14(this);
public Protocol1_16_4To1_17() {
super(ClientboundPackets1_16_2.class, ClientboundPackets1_17.class, ServerboundPackets1_16_2.class, ServerboundPackets1_17.class);
@@ -85,23 +84,6 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
tagRewriter.appendNewTags(wrapper, RegistryType.GAME_EVENT);
});
new StatisticsRewriter<>(this).register(ClientboundPackets1_16_2.AWARD_STATS);
componentRewriter.registerComponentPacket(ClientboundPackets1_16_2.CHAT);
componentRewriter.registerBossEvent(ClientboundPackets1_16_2.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_16_2.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_16_2.TAB_LIST);
componentRewriter.registerOpenScreen1_14(ClientboundPackets1_16_2.OPEN_SCREEN);
componentRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_16_2.SET_PLAYER_TEAM);
componentRewriter.registerSetObjective(ClientboundPackets1_16_2.SET_OBJECTIVE);
componentRewriter.registerPing();
SoundRewriter<ClientboundPackets1_16_2> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_16_2.SOUND);
soundRewriter.registerSound(ClientboundPackets1_16_2.SOUND_ENTITY);
particleRewriter.registerLevelParticles1_13(ClientboundPackets1_16_2.LEVEL_PARTICLES, Types.DOUBLE);
registerClientbound(ClientboundPackets1_16_2.RESOURCE_PACK, wrapper -> {
wrapper.passthrough(Types.STRING);
wrapper.passthrough(Types.STRING);
@@ -187,13 +169,7 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
@Override
protected void onMappingDataLoaded() {
EntityTypes1_17.initialize(this);
Types1_17.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.ITEM1_13_2)
.reader("vibration", ParticleType.Readers.VIBRATION);
ParticleType.Fillers.fill1_17(this, Types1_17.PARTICLE);
tagRewriter.addEmptyTags(RegistryType.ITEM, "minecraft:axolotl_tempt_items", "minecraft:candles", "minecraft:cluster_max_harvestables",
"minecraft:copper_ores", "minecraft:freeze_immune_wearables", "minecraft:occludes_vibration_signals");
@@ -227,13 +203,18 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
return itemRewriter;
}
@Override
public BlockRewriter<ClientboundPackets1_16_2> getBlockRewriter() {
return blockRewriter;
}
@Override
public ParticleRewriter<ClientboundPackets1_16_2> getParticleRewriter() {
return particleRewriter;
}
@Override
public @Nullable ComponentRewriter1_17 getComponentRewriter() {
public ComponentRewriter1_17 getComponentRewriter() {
return componentRewriter;
}
@@ -43,8 +43,6 @@ public final class EntityPacketRewriter1_17 extends EntityRewriter<ClientboundPa
@Override
public void registerPackets() {
registerTrackerWithData(ClientboundPackets1_16_2.ADD_ENTITY, EntityTypes1_17.FALLING_BLOCK);
registerTracker(ClientboundPackets1_16_2.ADD_MOB);
registerTracker(ClientboundPackets1_16_2.ADD_PLAYER, EntityTypes1_17.PLAYER);
registerSetEntityData(ClientboundPackets1_16_2.SET_ENTITY_DATA, Types1_16.ENTITY_DATA_LIST, Types1_17.ENTITY_DATA_LIST);
@@ -190,11 +188,6 @@ public final class EntityPacketRewriter1_17 extends EntityRewriter<ClientboundPa
filter().type(EntityTypes1_17.SHULKER).removeIndex(17);
}
@Override
public void onMappingDataLoaded() {
mapTypes();
}
@Override
public EntityType typeFromId(int type) {
return EntityTypes1_17.getTypeFromId(type);
@@ -40,20 +40,11 @@ public final class ItemPacketRewriter1_17 extends ItemRewriter<ClientboundPacket
@Override
public void registerPackets() {
registerCooldown(ClientboundPackets1_16_2.COOLDOWN);
registerSetContent(ClientboundPackets1_16_2.CONTAINER_SET_CONTENT);
registerMerchantOffers(ClientboundPackets1_16_2.MERCHANT_OFFERS);
registerSetSlot(ClientboundPackets1_16_2.CONTAINER_SET_SLOT);
registerAdvancements(ClientboundPackets1_16_2.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_16_2.SET_EQUIPMENT);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_16_2.UPDATE_RECIPES);
registerSetCreativeModeSlot(ServerboundPackets1_17.SET_CREATIVE_MODE_SLOT);
protocol.registerServerbound(ServerboundPackets1_17.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)));
protocol.registerServerbound(ServerboundPackets1_17.CONTAINER_CLICK, new PacketHandlers() {
protocol.replaceServerbound(ServerboundPackets1_17.CONTAINER_CLICK, new PacketHandlers() {
@Override
public void register() {
map(Types.BYTE); // Window Id
Loaded 100 of 192 files, more files were not shown because too many files have changed in this diff. Show more