Compare commits

...
39 Commits
Author SHA1 Message Date
Nassim Jahnke 4c316de042 5.4.2 Release 2025-07-23 23:03:10 +02:00
EnZaXD 8ee5d7e680 Add missing biome name translations in 1.17.1->1.18 (#4597) 2025-07-22 20:50:33 +02:00
Nassim Jahnke 64c128d414 Fix 1.8/1.9 thrown potion entity data handling
Fixes #4596
2025-07-21 23:55:03 +02:00
Nassim Jahnke 77d11fc593 Update attribute modifier types in show item hovers
Fixes #4593
2025-07-18 20:50:46 +02:00
Nassim Jahnke 2c72a09809 Strip namespace from custom attribute id when getting names 2025-07-18 11:01:52 +02:00
Nassim Jahnke 3dbd81da76 [ci skip] Split up publishing steps
Putting them into the same step meant if one publish action failed, the second one wouldn't run. Before this change, Modrinth would often block Hangar from publishing
2025-07-17 16:10:15 +02:00
Nassim Jahnke a0116c7ea7 Add 1.21.8 version string to 1.21.7 2025-07-17 14:33:58 +02:00
Nassim Jahnke fd5dadbe01 [ci skip] Clean up imports 2025-07-14 12:36:56 +02:00
Kai df87a02c38 Update ViaNBT (#4585) 2025-07-14 12:25:59 +02:00
EnZaXD bb293b3e5d Add cancel-swing-in-inventory option for 1.15.2->1.16 inventory swing fix (#4587) 2025-07-14 12:24:53 +02:00
EnZaXDanddewgs ff03892b25 Fix some directions not being included in chunk-border-fix; Reduce packets sent by checking for needed chunks (#4586)
Co-authored-by: dewgs <23721849+dewgs@users.noreply.github.com>
2025-07-14 12:21:28 +02:00
EnZaXD eb51306d82 Fix ItemFactory#getSpawnEgg NoSuchMethodError on older Paper builds (#4582) 2025-07-13 08:40:09 +02:00
EnZaXD 81eb3362f3 [ci skip] Add Java resolving plugin (#4577) 2025-07-12 10:31:23 +02:00
EnZaXD 7f06b03453 Remove StorableObject#clearOnServerSwitch (#4583) 2025-07-12 10:30:30 +02:00
RK_01 c16432de2a Fix anticheat flags when respawning with 1.21.2+ clients on older servers (#4573)
Fixes #4572
2025-07-07 21:40:01 +02:00
Nassim Jahnke b162dbdff0 Add missing null check to allowed_entities rewrite
Fixes #4568
2025-07-05 13:55:55 +02:00
Nassim Jahnke dfbe57e304 Rewrite Equippable allowed_entities
Fixes #4567
2025-07-04 17:17:05 +02:00
Nassim Jahnke 6f6dc2c641 Rewrite attribute modifiers automatically via interface
An id change in 1.21.5->1.21.6 was missed
2025-06-30 21:27:00 +02:00
Nassim Jahnke 06990ec0c9 Bump version to 5.4.2-SNAPSHOT 2025-06-30 21:26:14 +02:00
Nassim Jahnke 351b42b5e5 5.4.1 Release 2025-06-30 09:56:25 +02:00
Nassim Jahnke 20e3c832fb 1.21.7-rc2 2025-06-30 09:49:48 +02:00
Nassim Jahnke ec9c121da2 1.21.7-rc1 2025-06-30 09:49:47 +02:00
FlorianMichael 12c773edea Add missing translatable mappings (#4542)
Fixes #3331
Fixes #4273
2025-06-30 09:47:33 +02:00
Nassim Jahnke 97b411aa6d Manually handle text component boolean entries
Fixes #4558
2025-06-29 16:36:12 +02:00
Nassim Jahnke 24f6c4f0fd Implement hashing for potion contents 2025-06-29 15:50:56 +02:00
FlorianMichael 9409c7d22a [ci skip] Add SECURITY.md (#4520) 2025-06-29 15:36:49 +02:00
FlorianMichael 17d94a17f0 Always write length in LengthPrefixedTagType 2025-06-29 11:51:38 +02:00
riku6460andFlorianMichael a1cb4d3691 Add Types#CUSTOM_CLICK_ACTION_TAG for VB (#4557)
* Add LengthPrefixedTagType for CUSTOM_CLICK_ACTION

* Move type into own class, add instance into Types

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-06-29 07:21:48 +02:00
Nassim Jahnke 1d5070a480 Allow mapping sound event holders to empty sounds 2025-06-27 10:24:34 +02:00
FlorianMichaelanddewgs f612adbd0a Rewrite player & display name in player info packet in 1.12.2->1.13 (#4550)
Fixes Tablist plugins on some servers breaking since the game profile name sent is used to determine the scoreboard team which name we rewrite in other packets, also adds missing component rewriter calls to the display names (Not that important given its only translation keys, but we are already here).

Co-authored-by: dewgs <23721849+dewgs@users.noreply.github.com>
2025-06-25 13:31:17 +02:00
FlorianMichael 6716beec5a Remove arbitrary chat-nbt-fix config option in 1.11.1->1.12 (#4551) 2025-06-25 13:28:23 +02:00
Nassim Jahnke d22b00e4a6 Add helper methods for registry entry rewriting 2025-06-22 22:53:08 +02:00
Nassim Jahnke fe9ca49920 Update mcstructs 2025-06-22 10:38:33 +02:00
PacksoliteandNassim Jahnke e1837dc578 Fix legacy block picking on some Paper forks (#4496)
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2025-06-21 11:22:22 +02:00
booky 66eead2927 Fix missing clouds in 1.21.5->1.21.6 (#4538) 2025-06-21 11:00:19 +02:00
booky 937a2a2532 Fix server links button not visible in 1.21.5->1.21.6 (#4536)
The Minecraft 1.21.6 client will only show the server links if the the server_links dialog has been sent
2025-06-21 01:47:34 +02:00
Nassim Jahnke bee45ef9ef Use Cache get instead of Map compute
This may or may not fix concurrency issues from... somewhere (bad plugins/old guava impl?)
2025-06-20 21:40:37 +02:00
FlorianMichael 1946a65ab2 Add MathUtil#ceil 2025-06-20 21:36:44 +02:00
Nassim Jahnke f594a946d4 Bump version to 5.4.1-SNAPSHOT 2025-06-20 21:36:33 +02:00
135 changed files with 1700 additions and 434 deletions

No files matched your search

+9 -2
View File
@@ -23,8 +23,15 @@ jobs:
distribution: 'temurin'
java-version: 17
check-latest: true
- name: Publish
- name: Build
run: ./gradlew build
- name: Publish to Hangar
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
run: ./gradlew publishAllPublicationsToHangar --stacktrace
continue-on-error: true
- name: Publish to Modrinth
env:
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew build modrinth publishAllPublicationsToHangar --stacktrace
run: ./gradlew modrinth --stacktrace
continue-on-error: true
+10
View File
@@ -0,0 +1,10 @@
# Security Policy
## Reporting a Vulnerability
If you discover a **security vulnerability**, please **do not** open a public issue. Instead, use one of the following **confidential contact methods**:
* **Email:** [security@viaversion.com](mailto:security@viaversion.com)
* **Discord:** Join our [Discord server](https://discord.gg/viaversion) and visit the [#exploit-report](https://discord.com/channels/316206679014244363/1388847764137316485) channel for further instructions.
If your issue is **not security-related** (e.g., bug reports, feature requests, or usage questions), please use the [GitHub Issues page](https://github.com/ViaVersion/ViaVersion/issues) or contact us via the [Discord server](https://discord.gg/viaversion).
@@ -233,13 +233,6 @@ public interface ViaVersionConfig extends Config {
*/
boolean isChunkBorderFix();
/**
* Should we fix nbt array's in json chat messages for 1.12 clients
*
* @return true if enabled
*/
boolean is1_12NBTArrayFix();
/**
* Should we make team colours based on the last colour in team prefix
*
@@ -485,4 +478,12 @@ public interface ViaVersionConfig extends Config {
* @return true if enabled
*/
boolean fix1_21PlacementRotation();
/**
* If enabled, cancel swing packets sent while having an inventory opened on 1.15.2 and below servers.
* This can cause false positives with anti-cheat plugins.
*
* @return true if enabled
*/
boolean cancelSwingInInventory();
}
@@ -30,15 +30,6 @@ package com.viaversion.viaversion.api.connection;
*/
public interface StorableObject {
/**
* Returns whether the object should be uncached on a server switch.
*
* @return whether the object should be uncached on a server switch
*/
default boolean clearOnServerSwitch() {
return true;
}
default void onRemove() {
}
}
@@ -139,17 +139,7 @@ public interface UserConnection {
/**
* Clear stored objects, entity trackers and client worlds.
*/
default void clearStoredObjects() {
clearStoredObjects(false);
}
/**
* Clear stored objects, entity trackers and client worlds.
* If cleared for a proxy server switch, some stored objects and tracker data will be retained.
*
* @param isServerSwitch whether the clear is due to a server switch
*/
void clearStoredObjects(boolean isServerSwitch);
void clearStoredObjects();
/**
* Sends a raw packet to the connection on the current thread.
@@ -208,8 +208,8 @@ public class MappingDataBase implements MappingData {
}
@Override
public int getOldSoundId(final int i) {
return soundMappings.getNewIdOrDefault(i, 0);
public int getOldSoundId(final int id) {
return soundMappings.inverse().getNewIdOrDefault(id, 0);
}
@Override
@@ -33,7 +33,6 @@ public enum BlockFace {
TOP((byte) 0, (byte) 1, (byte) 0, EnumAxis.Y),
BOTTOM((byte) 0, (byte) -1, (byte) 0, EnumAxis.Y);
public static final BlockFace[] HORIZONTAL = {NORTH, SOUTH, EAST, WEST};
private static final Map<BlockFace, BlockFace> opposites = new EnumMap<>(BlockFace.class);
static {
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
import java.util.function.Supplier;
public interface Holder<T> {
@@ -89,7 +90,18 @@ public interface Holder<T> {
* @param rewriteFunction the function to rewrite the id
* @return a new holder with the id rewritten, or self
*/
Holder<T> updateId(final Int2IntFunction rewriteFunction);
default Holder<T> updateId(final Int2IntFunction rewriteFunction) {
return this.updateId(rewriteFunction, null);
}
/**
* Returns a new holder with the id rewritten using the given function, or self if this is a direct holder or the id did not change.
*
* @param rewriteFunction the function to rewrite the id
* @param ifMissing a supplier that provides a new holder if the id is missing (i.e. -1)
* @return a new holder with the id rewritten, or self
*/
Holder<T> updateId(Int2IntFunction rewriteFunction, Supplier<Holder<T>> ifMissing);
/**
* Returns a new holder with the value rewritten using the given function, or self if this is an id holder or the value did not change.
@@ -25,6 +25,7 @@ package com.viaversion.viaversion.api.minecraft;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
import java.util.function.Supplier;
record IdHolder<T>(int id) implements Holder<T> {
@@ -48,12 +49,15 @@ record IdHolder<T>(int id) implements Holder<T> {
}
@Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
public Holder<T> updateId(final Int2IntFunction rewriteFunction, final Supplier<Holder<T>> ifMissing) {
final int rewrittenId = rewriteFunction.applyAsInt(id);
if (rewrittenId == id) {
return this;
}
if (rewrittenId == -1) {
if (ifMissing != null) {
return ifMissing.get();
}
throw new IllegalArgumentException("Received invalid id in updateId");
}
return Holder.of(rewrittenId);
@@ -22,11 +22,21 @@
*/
package com.viaversion.viaversion.api.minecraft;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import org.checkerframework.checker.nullness.qual.Nullable;
public record SoundEvent(String identifier, @Nullable Float fixedRange) {
private static final Holder<SoundEvent> UNKNOWN = Holder.of(new SoundEvent("viaversion:unknown", 0F));
public SoundEvent withIdentifier(final String identifier) {
return new SoundEvent(identifier, this.fixedRange);
}
public static @Nullable Holder<SoundEvent> rewriteHolder(@Nullable final Holder<SoundEvent> holder, final Int2IntFunction soundRewriteFunction) {
if (holder == null) {
return null;
}
return holder.updateId(soundRewriteFunction, () -> UNKNOWN);
}
}
@@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.function.Function;
import java.util.function.Supplier;
record ValueHolder<T>(T value) implements Holder<T> {
@@ -43,7 +44,7 @@ record ValueHolder<T>(T value) implements Holder<T> {
}
@Override
public Holder<T> updateId(final Int2IntFunction rewriteFunction) {
public Holder<T> updateId(final Int2IntFunction rewriteFunction, final Supplier<Holder<T>> ifMissing) {
return this;
}
@@ -0,0 +1,110 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.type.Type;
import java.util.function.Consumer;
public class DelegatingOps implements Ops {
private final Ops delegate;
public DelegatingOps(final Ops delegate) {
this.delegate = delegate;
}
@Override
public CodecContext context() {
return delegate.context();
}
@Override
public void writeByte(final byte b) {
delegate.writeByte(b);
}
@Override
public void writeBytes(final byte[] array) {
delegate.writeBytes(array);
}
@Override
public void writeBoolean(final boolean b) {
delegate.writeBoolean(b);
}
@Override
public void writeShort(final short s) {
delegate.writeShort(s);
}
@Override
public void writeString(final CharSequence sequence) {
delegate.writeString(sequence);
}
@Override
public void writeInt(final int i) {
delegate.writeInt(i);
}
@Override
public void writeLong(final long l) {
delegate.writeLong(l);
}
@Override
public void writeFloat(final float f) {
delegate.writeFloat(f);
}
@Override
public void writeDouble(final double d) {
delegate.writeDouble(d);
}
@Override
public void writeInts(final int[] array) {
delegate.writeInts(array);
}
@Override
public void writeLongs(final long[] array) {
delegate.writeLongs(array);
}
@Override
public void writeList(final Consumer<ListSerializer> consumer) {
delegate.writeList(consumer);
}
@Override
public void writeMap(final Consumer<MapSerializer> consumer) {
delegate.writeMap(consumer);
}
@Override
public <V> void write(final Type<V> type, final V value) {
delegate.write(type, value);
}
}
@@ -129,5 +129,7 @@ public interface Ops {
MapSerializer writeList(String key, Consumer<ListSerializer> consumer);
MapSerializer writeMap(String key, Consumer<MapSerializer> consumer);
<T> MapSerializer writeInlinedMap(Type<T> valueType, T value);
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.codec;
import com.viaversion.viaversion.api.type.Type;
import java.util.function.Consumer;
public class ThrowingOps implements Ops {
@Override
public CodecContext context() {
throw new UnsupportedOperationException();
}
@Override
public void writeByte(final byte b) {
throw new UnsupportedOperationException();
}
@Override
public void writeBytes(final byte[] array) {
throw new UnsupportedOperationException();
}
@Override
public void writeBoolean(final boolean b) {
throw new UnsupportedOperationException();
}
@Override
public void writeShort(final short s) {
throw new UnsupportedOperationException();
}
@Override
public void writeString(final CharSequence sequence) {
throw new UnsupportedOperationException();
}
@Override
public void writeInt(final int i) {
throw new UnsupportedOperationException();
}
@Override
public void writeLong(final long l) {
throw new UnsupportedOperationException();
}
@Override
public void writeFloat(final float f) {
throw new UnsupportedOperationException();
}
@Override
public void writeDouble(final double d) {
throw new UnsupportedOperationException();
}
@Override
public void writeInts(final int[] array) {
throw new UnsupportedOperationException();
}
@Override
public void writeLongs(final long[] array) {
throw new UnsupportedOperationException();
}
@Override
public void writeList(final Consumer<ListSerializer> consumer) {
throw new UnsupportedOperationException();
}
@Override
public void writeMap(final Consumer<MapSerializer> consumer) {
throw new UnsupportedOperationException();
}
@Override
public <V> void write(final Type<V> type, final V value) {
throw new UnsupportedOperationException();
}
}
@@ -241,7 +241,7 @@ public final class StructuredDataContainer implements Copyable {
/**
* Sets the lookup for serializer ids. Required to call most of the other methods.
*
* @param protocol protocol to retreive the id of the serializer from
* @param protocol protocol to retrieve the id of the serializer from
* @param mappedNames if the names are mapped (true if structures from the mapped version are added, false for the unmapped version)
*/
public void setIdLookup(final Protocol<?, ?, ?, ?> protocol, final boolean mappedNames) {
@@ -95,10 +95,10 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Integer> DAMAGE = new StructuredDataKey<>("damage", Types.VAR_INT);
public static final StructuredDataKey<Unbreakable> UNBREAKABLE1_20_5 = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE);
public static final StructuredDataKey<Unit> UNBREAKABLE1_21_5 = new StructuredDataKey<>("unbreakable", Types.EMPTY);
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TEXT_COMPONENT_TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TEXT_COMPONENT_TAG);
public static final StructuredDataKey<Key> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.RESOURCE_LOCATION);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TAG, 256));
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TEXT_COMPONENT_TAG, 256));
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", EnumTypes.RARITY);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS1_20_5 = new StructuredDataKey<>("enchantments", Enchantments.TYPE1_20_5);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS1_21_5 = new StructuredDataKey<>("enchantments", Enchantments.TYPE1_21_5);
@@ -213,7 +213,7 @@ public enum EntityTypes1_14 implements EntityType {
EntityTypes1_14(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_14(final EntityType parent, @Nullable final String identifier) {
@@ -214,7 +214,7 @@ public enum EntityTypes1_15 implements EntityType {
EntityTypes1_15(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_15(final EntityType parent, @Nullable final String identifier) {
@@ -218,7 +218,7 @@ public enum EntityTypes1_16 implements EntityType {
EntityTypes1_16(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_16(final EntityType parent, @Nullable final String identifier) {
@@ -221,7 +221,7 @@ public enum EntityTypes1_16_2 implements EntityType {
EntityTypes1_16_2(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_16_2(final EntityType parent, @Nullable final String identifier) {
@@ -227,7 +227,7 @@ public enum EntityTypes1_17 implements EntityType {
EntityTypes1_17(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_17(final EntityType parent, @Nullable final String identifier) {
@@ -232,7 +232,7 @@ public enum EntityTypes1_19 implements EntityType {
EntityTypes1_19(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_19(final EntityType parent, @Nullable final String identifier) {
@@ -233,7 +233,7 @@ public enum EntityTypes1_19_3 implements EntityType {
EntityTypes1_19_3(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_19_3(final EntityType parent, @Nullable final String identifier) {
@@ -240,7 +240,7 @@ public enum EntityTypes1_19_4 implements EntityType {
EntityTypes1_19_4(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_19_4(final EntityType parent, @Nullable final String identifier) {
@@ -242,7 +242,7 @@ public enum EntityTypes1_20_3 implements EntityType {
EntityTypes1_20_3(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_20_3(final EntityType parent, @Nullable final String identifier) {
@@ -248,7 +248,7 @@ public enum EntityTypes1_20_5 implements EntityType {
EntityTypes1_20_5(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_20_5(final EntityType parent, @Nullable final String identifier) {
@@ -272,7 +272,7 @@ public enum EntityTypes1_21_2 implements EntityType {
EntityTypes1_21_2(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_2(final EntityType parent, @Nullable final String identifier) {
@@ -271,7 +271,7 @@ public enum EntityTypes1_21_4 implements EntityType {
EntityTypes1_21_4(final EntityType parent) {
this.parent = parent;
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
this.identifier = Key.namespaced(name().toLowerCase(Locale.ROOT));
}
EntityTypes1_21_4(final EntityType parent, @Nullable final String identifier) {
@@ -24,7 +24,6 @@ package com.viaversion.viaversion.api.minecraft.item;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.util.Copyable;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface Item extends ItemBase {
@@ -22,14 +22,21 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public record AttributeModifiers1_20_5(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable {
public record AttributeModifiers1_20_5(AttributeModifier[] modifiers,
boolean showInTooltip) implements Copyable, Rewritable {
public static final Type<AttributeModifiers1_20_5> TYPE = new Type<>(AttributeModifiers1_20_5.class) {
@Override
@@ -51,6 +58,23 @@ public record AttributeModifiers1_20_5(AttributeModifier[] modifiers, boolean sh
return new AttributeModifiers1_20_5(Copyable.copy(modifiers), showInTooltip);
}
@Override
public AttributeModifiers1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
if (mappings == null) {
return this;
}
final List<AttributeModifier> modifiers = new ArrayList<>(this.modifiers.length);
for (final AttributeModifier modifier : this.modifiers) {
final int mappedId = clientbound ? mappings.getNewId(modifier.attribute()) : mappings.inverse().getNewId(modifier.attribute());
if (mappedId != -1) {
modifiers.add(new AttributeModifier(mappedId, modifier.modifier(), modifier.slotType()));
}
}
return new AttributeModifiers1_20_5(modifiers.toArray(AttributeModifier[]::new), this.showInTooltip);
}
public record AttributeModifier(int attribute, ModifierData modifier, int slotType) {
public static final Type<AttributeModifier> TYPE = new Type<>(AttributeModifier.class) {
@@ -23,16 +23,22 @@
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Copyable;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.ArrayList;
import java.util.List;
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable {
public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) implements Copyable, Rewritable {
public AttributeModifiers1_21(final AttributeModifier[] modifiers) {
this(modifiers, true);
@@ -101,6 +107,23 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
return new AttributeModifiers1_21(Copyable.copy(modifiers), showInTooltip);
}
@Override
public AttributeModifiers1_21 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
if (mappings == null) {
return this;
}
final List<AttributeModifier> modifiers = new ArrayList<>(this.modifiers.length);
for (final AttributeModifier modifier : this.modifiers) {
final int mappedId = clientbound ? mappings.getNewId(modifier.attribute()) : mappings.inverse().getNewId(modifier.attribute());
if (mappedId != -1) {
modifiers.add(new AttributeModifier(mappedId, modifier.modifier(), modifier.slotType(), modifier.display()));
}
}
return new AttributeModifiers1_21(modifiers.toArray(AttributeModifier[]::new), this.showInTooltip);
}
public record AttributeModifier(int attribute, ModifierData modifier, int slotType, Display display) {
private static final String[] EQUIPMENT_SLOT_GROUPS = {"any", "mainhand", "offhand", "hand", "feet", "legs", "chest", "head", "armor", "body", "saddle"};
private static final String[] OPERATION = {"add_value", "add_multiplied_base", "add_multiplied_total"};
@@ -173,7 +196,7 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show
map.writeMap("display", display -> {
display.write("type", Types.STRING, Display.DISPLAY_TYPES[value.display.id()]);
if (value.display instanceof final OverrideText overrideText) {
display.write("value", Types.TAG, overrideText.component);
display.write("value", Types.TEXT_COMPONENT_TAG, overrideText.component);
}
});
});
@@ -22,12 +22,15 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.util.Rewritable;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -39,7 +42,7 @@ public record BlocksAttacks(
@Nullable String bypassedByTag,
@Nullable Holder<SoundEvent> blockSound,
@Nullable Holder<SoundEvent> disableSound
) {
) implements Rewritable {
public static final Type<BlocksAttacks> TYPE = new Type<>(BlocksAttacks.class) {
@@ -67,6 +70,13 @@ public record BlocksAttacks(
}
};
@Override
public BlocksAttacks rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> blockSound = SoundEvent.rewriteHolder(this.blockSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> disableSound = SoundEvent.rewriteHolder(this.disableSound, Rewritable.soundRewriteFunction(protocol, clientbound));
return new BlocksAttacks(this.blockDelaySeconds, this.disableCooldownScale, this.damageReductions, this.itemDamage, this.bypassedByTag, blockSound, disableSound);
}
public record DamageReduction(float horizontalBlockingAngle, @Nullable HolderSet type, float base, float factor) {
public static final Type<DamageReduction> TYPE = new Type<>(DamageReduction.class) {
@@ -116,7 +116,7 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
@Override
public Consumable1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundHolder = this.sound.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> soundHolder = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundHolder == this.sound ? this : new Consumable1_21_2(consumeSeconds, animationType, soundHolder, hasConsumeParticles, consumeEffects);
}
@@ -48,4 +48,6 @@ public final class EnumTypes {
public static final FakeEnumType RABBIT_VARIANT = new FakeEnumType(List.of("brown", "white", "black", "white_splotched", "gold", "salt"), of(99, "evil"));
// Pretty much enums, but with a resource location
public static final RegistryValueType VILLAGER_TYPE = new RegistryValueType("desert", "jungle", "plains", "savanna", "snow", "swamp", "taiga");
public static final RegistryValueType POTION = new RegistryValueType("water", "mundane", "thick", "awkward", "night_vision", "long_night_vision", "invisibility", "long_invisibility", "leaping", "long_leaping", "strong_leaping", "fire_resistance", "long_fire_resistance", "swiftness", "long_swiftness", "strong_swiftness", "slowness", "long_slowness", "strong_slowness", "turtle_master", "long_turtle_master", "strong_turtle_master", "water_breathing", "long_water_breathing", "healing", "strong_healing", "harming", "strong_harming", "poison", "long_poison", "strong_poison", "regeneration", "long_regeneration", "strong_regeneration", "strength", "long_strength", "strong_strength", "weakness", "long_weakness", "luck", "slow_falling", "long_slow_falling", "wind_charged", "weaving", "oozing", "infested");
public static final RegistryValueType MOB_EFFECT = new RegistryValueType("speed", "slowness", "haste", "mining_fatigue", "strength", "instant_health", "instant_damage", "jump_boost", "nausea", "regeneration", "resistance", "fire_resistance", "water_breathing", "invisibility", "blindness", "night_vision", "hunger", "weakness", "poison", "wither", "health_boost", "absorption", "saturation", "glowing", "levitation", "luck", "unluck", "slow_falling", "conduit_power", "dolphins_grace", "bad_omen", "hero_of_the_village", "darkness", "trial_omen", "raid_omen", "wind_charged", "weaving", "oozing", "infested");
}
@@ -137,8 +137,10 @@ public record Equippable(int equipmentSlot, Holder<SoundEvent> soundEvent, @Null
@Override
public Equippable rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> shearingSound = this.shearingSound.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
return soundEvent == this.soundEvent && shearingSound == this.shearingSound ? this : new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, canBeSheared, shearingSound);
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> shearingSound = SoundEvent.rewriteHolder(this.shearingSound, Rewritable.soundRewriteFunction(protocol, clientbound));
final HolderSet allowedEntities = this.allowedEntities != null ? this.allowedEntities.rewrite(Rewritable.entityRewriteFunction(protocol, clientbound)) : null;
return soundEvent == this.soundEvent && shearingSound == this.shearingSound && allowedEntities == this.allowedEntities ? this
: new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract, canBeSheared, shearingSound);
}
}
@@ -52,7 +52,7 @@ public record Instrument1_20_5(Holder<SoundEvent> soundEvent, int useDuration, f
@Override
public Instrument1_20_5 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundEvent == this.soundEvent ? this : new Instrument1_20_5(soundEvent, useDuration, range);
}
}
@@ -59,7 +59,7 @@ public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration,
@Override
public Instrument1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundEvent == this.soundEvent ? this : new Instrument1_21_2(soundEvent, useDuration, range, description);
}
@@ -111,7 +111,7 @@ public record JukeboxPlayable(EitherHolder<JukeboxSong> song, boolean showInTool
@Override
public JukeboxSong rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
final Holder<SoundEvent> soundEvent = this.soundEvent.updateId(Rewritable.soundRewriteFunction(protocol, clientbound));
final Holder<SoundEvent> soundEvent = SoundEvent.rewriteHolder(this.soundEvent, Rewritable.soundRewriteFunction(protocol, clientbound));
return soundEvent == this.soundEvent ? this : new JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput);
}
}
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Copyable;
@@ -85,6 +86,15 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC
PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects);
Types.OPTIONAL_STRING.write(buffer, value.customName);
}
@Override
public void write(final Ops ops, final PotionContents value) {
ops.writeMap(map -> map
.writeOptional("potion", EnumTypes.POTION, value.potion)
.writeOptional("custom_color", Types.INT, value.customColor)
.writeOptional("custom_effects", PotionEffect.ARRAY_TYPE, value.customEffects, new PotionEffect[0])
.writeOptional("custom_name", Types.STRING, value.customName));
}
};
@Override
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
@@ -42,6 +43,13 @@ public record PotionEffect(int effect, PotionEffectData effectData) {
Types.VAR_INT.writePrimitive(buffer, value.effect);
PotionEffectData.TYPE.write(buffer, value.effectData);
}
@Override
public void write(final Ops ops, final PotionEffect value) {
ops.writeMap(map -> map
.write("id", EnumTypes.MOB_EFFECT, value.effect)
.writeInlinedMap(PotionEffectData.TYPE, value.effectData));
}
};
public static final Type<PotionEffect[]> ARRAY_TYPE = new ArrayType<>(TYPE);
@@ -22,6 +22,7 @@
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.OptionalType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
@@ -52,6 +53,17 @@ public record PotionEffectData(int amplifier, int duration, boolean ambient, boo
buffer.writeBoolean(value.showIcon);
OPTIONAL_TYPE.write(buffer, value.hiddenEffect);
}
@Override
public void write(final Ops ops, final PotionEffectData value) {
ops.writeMap(map -> map
.writeOptional("amplifier", Types.UNSIGNED_BYTE, (short) value.amplifier, (short) 0)
.writeOptional("duration", Types.INT, value.duration, 0)
.writeOptional("ambient", Types.BOOLEAN, value.ambient, false)
.writeOptional("show_particles", Types.BOOLEAN, value.showParticles, true)
.writeOptional("show_icon", Types.BOOLEAN, value.showIcon)
.writeOptional("hidden_effect", TYPE, value.hiddenEffect));
}
};
public static final Type<PotionEffectData> OPTIONAL_TYPE = new OptionalType<>(TYPE) {
};
@@ -90,6 +90,7 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_21_4 = register(769, "1.21.4");
public static final ProtocolVersion v1_21_5 = register(770, "1.21.5");
public static final ProtocolVersion v1_21_6 = register(771, "1.21.6");
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 unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
static {
@@ -108,6 +108,7 @@ import com.viaversion.viaversion.api.type.types.misc.GameProfileType;
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import com.viaversion.viaversion.api.type.types.misc.KeyType;
import com.viaversion.viaversion.api.type.types.misc.LengthPrefixedTagType;
import com.viaversion.viaversion.api.type.types.misc.NamedCompoundTagType;
import com.viaversion.viaversion.api.type.types.misc.PlayerMessageSignatureType;
import com.viaversion.viaversion.api.type.types.misc.ProfileKeyType;
@@ -115,6 +116,7 @@ import com.viaversion.viaversion.api.type.types.misc.ProfilePropertyType;
import com.viaversion.viaversion.api.type.types.misc.SoundEventType;
import com.viaversion.viaversion.api.type.types.misc.TagKeyType;
import com.viaversion.viaversion.api.type.types.misc.TagType;
import com.viaversion.viaversion.api.type.types.misc.TextComponentTagType;
import com.viaversion.viaversion.api.type.types.misc.VillagerDataType;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.util.Key;
@@ -199,6 +201,8 @@ public final class Types {
public static final Type<Tag> TAG = new TagType();
public static final Type<Tag[]> TAG_ARRAY = new ArrayType<>(TAG);
public static final Type<Tag> OPTIONAL_TAG = new TagType.OptionalTagType();
public static final Type<Tag> TEXT_COMPONENT_TAG = new TextComponentTagType(); // only strictly needed for hashing
public static final Type<Tag> CUSTOM_CLICK_ACTION_TAG = new LengthPrefixedTagType(65536);
public static final Type<GlobalBlockPosition> GLOBAL_POSITION = new GlobalBlockPositionType();
public static final Type<GlobalBlockPosition> OPTIONAL_GLOBAL_POSITION = new GlobalBlockPositionType.OptionalGlobalPositionType();
@@ -41,4 +41,8 @@ public final class RegistryValueType extends VarIntType {
public void write(final Ops ops, final Integer value) {
Types.STRING.write(ops, names[value]);
}
public String[] names() {
return names;
}
}
@@ -25,7 +25,6 @@ package com.viaversion.viaversion.api.type.types.chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
@@ -24,7 +24,6 @@ package com.viaversion.viaversion.api.type.types.item;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.data.item.ItemHasher;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
@@ -0,0 +1,65 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.misc;
import com.google.common.base.Preconditions;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public final class LengthPrefixedTagType extends Type<Tag> {
private final int maxLength;
public LengthPrefixedTagType(int maxLength) {
super(Tag.class);
this.maxLength = maxLength;
}
@Override
public Tag read(final ByteBuf buffer) {
final int length = Types.VAR_INT.readPrimitive(buffer);
Preconditions.checkArgument(length <= maxLength,
"Cannot receive tag longer than %s bytes (got %s bytes)", maxLength, length);
return Types.TAG.read(buffer.readSlice(length));
}
@Override
public void write(final ByteBuf buffer, final Tag tag) {
final ByteBuf tempBuf = buffer.alloc().buffer();
try {
Types.TAG.write(tempBuf, tag);
Preconditions.checkArgument(tempBuf.readableBytes() <= maxLength,
"Cannot send tag longer than %s bytes (got %s bytes)", maxLength, tempBuf.readableBytes());
Types.VAR_INT.writePrimitive(buffer, tempBuf.readableBytes());
buffer.writeBytes(tempBuf);
} finally {
tempBuf.release();
}
}
}
@@ -105,13 +105,13 @@ public class TagType extends Type<Tag> {
} else if (value instanceof CompoundTag compoundTag) {
ops.writeMap(map -> {
for (final Map.Entry<String, Tag> entry : compoundTag.entrySet()) {
map.write(entry.getKey(), Types.TAG, entry.getValue());
map.write(entry.getKey(), this, entry.getValue());
}
});
} else if (value instanceof ListTag<?> listTag) {
ops.writeList(list -> {
for (final Tag tag : listTag) {
list.write(Types.TAG, tag);
list.write(this, tag);
}
});
} else if (value instanceof IntArrayTag intArrayTag) {
@@ -0,0 +1,61 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.misc;
import com.viaversion.nbt.tag.ByteTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.type.Types;
import java.util.Map;
import java.util.Set;
/**
* Only strictly needed for hashing purposes for now.
*/
public class TextComponentTagType extends TagType {
private static final Set<String> BOOLEAN_KEYS = Set.of("bold", "italic", "underlined", "strikethrough", "obfuscated", "interpret");
@Override
public void write(final Ops ops, final Tag value) {
if (value instanceof final CompoundTag compoundTag) {
ops.writeMap(map -> {
for (final Map.Entry<String, Tag> entry : compoundTag.entrySet()) {
write(map, entry.getKey(), entry.getValue());
}
});
} else {
super.write(ops, value);
}
}
private void write(final Ops.MapSerializer map, final String key, final Tag value) {
// Better than fully parsing and re-serializing the component
if (value instanceof final ByteTag byteTag && BOOLEAN_KEYS.contains(key)) {
map.write(key, Types.BOOLEAN, byteTag.asBoolean());
} else {
map.write(key, this, value);
}
}
}
@@ -25,8 +25,8 @@ package com.viaversion.viaversion.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.libs.mcstructs.text.utils.JsonUtils;
import java.util.Comparator;
import net.lenni0451.mcstructs.text.utils.JsonUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class GsonUtil {
@@ -24,6 +24,17 @@ package com.viaversion.viaversion.util;
public final class MathUtil {
/**
* Returns the ceiled integer value of the given float.
*
* @param value float value to ceil
* @return ceiled integer value
*/
public static int ceil(final float value) {
final int intValue = (int) value;
return value > intValue ? intValue + 1 : intValue;
}
/**
* Returns the ceiled log to the base of 2 for the given number.
*
@@ -67,7 +67,12 @@ public interface Rewritable {
static Int2IntFunction soundRewriteFunction(final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return protocol.getMappingData().getSoundMappings() == null ? Int2IntFunction.identity()
: (clientbound ? protocol.getMappingData()::getNewSoundId : protocol.getMappingData()::getOldSoundId);
: (clientbound ? protocol.getMappingData().getSoundMappings()::getNewId : protocol.getMappingData()::getOldSoundId);
}
static Int2IntFunction entityRewriteFunction(final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
return protocol.getMappingData().getEntityMappings() == null ? Int2IntFunction.identity()
: (clientbound ? protocol.getMappingData().getEntityMappings()::getNewId : protocol.getMappingData().getEntityMappings().inverse()::getNewId);
}
static @Nullable String mappedIdentifier(final FullMappings mappings, final String identifier) {
+1 -1
View File
@@ -8,5 +8,5 @@ repositories {
dependencies {
// version must be manually kept in sync with the one in root project settings.gradle.kts
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.6")
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.8")
}
@@ -44,7 +44,6 @@ publishing {
fun ShadowJar.configureRelocations() {
relocate("com.google.gson", "com.viaversion.viaversion.libs.gson")
relocate("it.unimi.dsi.fastutil", "com.viaversion.viaversion.libs.fastutil")
relocate("net.lenni0451.mcstructs", "com.viaversion.viaversion.libs.mcstructs")
relocate("org.yaml.snakeyaml", "com.viaversion.viaversion.libs.snakeyaml")
}
@@ -18,13 +18,13 @@
package com.viaversion.viaversion.bukkit.util;
import com.viaversion.viaversion.api.Via;
import java.lang.reflect.Method;
import java.util.Random;
import java.util.logging.Level;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.lang.reflect.Method;
import java.util.Random;
import java.util.logging.Level;
public class LegacyBlockToItem {
private static final LegacyBlockToItem INSTANCE;
@@ -106,4 +106,12 @@ public final class PaperViaInjector {
return false;
}
}
public static boolean hasMethod(final Class<?> clazz, final Class<?> returnType, final String method, final Class<?>... params) {
try {
return clazz.getDeclaredMethod(method, params).getReturnType().equals(returnType);
} catch (final NoSuchMethodException e) {
return false;
}
}
}
@@ -18,11 +18,14 @@
package com.viaversion.viaversion.bukkit.providers;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.bukkit.platform.PaperViaInjector;
import com.viaversion.viaversion.bukkit.util.LegacyBlockToItem;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.provider.PickItemProvider;
import java.lang.reflect.Method;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@@ -43,12 +46,26 @@ public class BukkitPickItemProvider extends PickItemProvider {
private static final GetStorageContents GET_STORAGE_CONTENT = GetStorageContents.build();
private static final SetInHand SET_IN_HAND = SetInHand.build();
private static final boolean HAS_SPAWN_EGG_METHOD = PaperViaInjector.hasMethod(ItemFactory.class, "getSpawnEgg", EntityType.class);
private static final boolean HAS_SPAWN_EGG_METHOD = PaperViaInjector.hasMethod(ItemFactory.class, Material.class, "getSpawnEgg", EntityType.class);
private static final Method GET_SPAWN_EGG_ITEMSTACK_METHOD;
private static final double BLOCK_RANGE = 4.5 + 1;
private static final double BLOCK_RANGE_SQUARED = BLOCK_RANGE * BLOCK_RANGE;
private static final double ENTITY_RANGE = 3 + 3;
private final ViaVersionPlugin plugin;
static {
if (PaperViaInjector.hasMethod(ItemFactory.class, ItemStack.class, "getSpawnEgg", EntityType.class)) {
try {
GET_SPAWN_EGG_ITEMSTACK_METHOD = ItemFactory.class.getDeclaredMethod("getSpawnEgg", EntityType.class);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
} else {
GET_SPAWN_EGG_ITEMSTACK_METHOD = null;
}
}
public BukkitPickItemProvider(final ViaVersionPlugin plugin) {
this.plugin = plugin;
}
@@ -81,7 +98,7 @@ public class BukkitPickItemProvider extends PickItemProvider {
@Override
public void pickItemFromEntity(final UserConnection connection, final int entityId, final boolean includeData) {
if (!HAS_SPAWN_EGG_METHOD) {
if (!HAS_SPAWN_EGG_METHOD && GET_SPAWN_EGG_ITEMSTACK_METHOD == null) {
return;
}
@@ -100,9 +117,21 @@ public class BukkitPickItemProvider extends PickItemProvider {
return;
}
final Material spawnEggType = Bukkit.getItemFactory().getSpawnEgg(entity.getType());
if (spawnEggType != null) {
pickItem(player, new ItemStack(spawnEggType, 1));
if (GET_SPAWN_EGG_ITEMSTACK_METHOD == null) {
final Material spawnEggType = Bukkit.getItemFactory().getSpawnEgg(entity.getType());
if (spawnEggType != null) {
pickItem(player, new ItemStack(spawnEggType, 1));
}
return;
}
try {
final ItemStack spawnEggItem = (ItemStack) GET_SPAWN_EGG_ITEMSTACK_METHOD.invoke(Bukkit.getItemFactory(), entity.getType());
if (spawnEggItem != null) {
pickItem(player, spawnEggItem);
}
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}, player);
}
@@ -187,14 +216,25 @@ public class BukkitPickItemProvider extends PickItemProvider {
}
return item;
};
} else if (PaperViaInjector.hasMethod(Material.class, "isItem")) {
return (block, includeData) -> new ItemStack(block.getType(), 1);
} else {
LegacyBlockToItem legacy = LegacyBlockToItem.getInstance();
}
final ProtocolVersion version = Via.getAPI().getServerVersion().lowestSupportedProtocolVersion();
if (version.equalTo(ProtocolVersion.v1_8)) {
final LegacyBlockToItem legacy = LegacyBlockToItem.getInstance();
return legacy != null ? (block, includeData) -> legacy.blockToItem(block) : (b, i) -> null;
} else if (PaperViaInjector.hasMethod(Material.class, "isItem")) {
return (block, includeData) -> {
if (!block.getType().isItem()) {
return null;
}
return version.newerThanOrEqualTo(ProtocolVersion.v1_13)
? new ItemStack(block.getType())
: new ItemStack(block.getType(), 1, (short) 0, block.getData());
};
} else {
return (block, includeData) -> null;
}
}
}
@FunctionalInterface
@@ -35,7 +35,7 @@ public record CodecRegistryContext(Protocol<?, ?, ?, ?> protocol, SerializerVers
StructuredDataKey.TRIM1_21_5, StructuredDataKey.TOOL1_21_5, StructuredDataKey.PROVIDES_TRIM_MATERIAL,
StructuredDataKey.CONSUMABLE1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE1_21_5, StructuredDataKey.INSTRUMENT1_21_5,
StructuredDataKey.EQUIPPABLE1_21_5, StructuredDataKey.REPAIRABLE, StructuredDataKey.DEATH_PROTECTION,
StructuredDataKey.BLOCKS_ATTACKS, StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, StructuredDataKey.POTION_CONTENTS1_21_2,
StructuredDataKey.BLOCKS_ATTACKS, StructuredDataKey.SUSPICIOUS_STEW_EFFECTS,
StructuredDataKey.BANNER_PATTERNS, StructuredDataKey.POT_DECORATIONS, StructuredDataKey.BREAK_SOUND,
StructuredDataKey.WOLF_VARIANT, StructuredDataKey.WOLF_SOUND_VARIANT, StructuredDataKey.PIG_VARIANT,
StructuredDataKey.COW_VARIANT, StructuredDataKey.CHICKEN_VARIANT, StructuredDataKey.FROG_VARIANT,
@@ -17,8 +17,8 @@
*/
package com.viaversion.viaversion.codec;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
import com.viaversion.viaversion.api.minecraft.codec.CodecContext;
import com.viaversion.viaversion.api.minecraft.codec.Ops;
public abstract class OpsBase implements Ops {
@@ -74,8 +74,9 @@ public final class HashBuilder {
}
public HashBuilder writeString(final CharSequence sequence) {
this.ensureSize(sequence.length());
for (int i = 0; i < sequence.length(); i++) {
final int length = sequence.length();
this.ensureSize(length);
for (int i = 0; i < length; i++) {
this.writeChar(sequence.charAt(i));
}
return this;
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.codec.hash;
import com.viaversion.viaversion.api.minecraft.codec.CodecContext;
import com.viaversion.viaversion.api.minecraft.codec.ThrowingOps;
import com.viaversion.viaversion.api.minecraft.codec.hash.Hasher;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
@@ -221,6 +222,18 @@ public class HashOps extends OpsBase implements Hasher {
return this;
}
@Override
public <T> MapSerializer writeInlinedMap(final Type<T> valueType, final T value) {
// Only allow writeMap calls here
valueType.write(new ThrowingOps() {
@Override
public void writeMap(final Consumer<MapSerializer> consumer) {
consumer.accept(MapHashBuilder.this);
}
}, value);
return this;
}
public void applyHashToParent() {
if (entries.isEmpty()) {
hashBuilder.writeBytesDirect(EMPTY_MAP);
@@ -29,8 +29,8 @@ import com.viaversion.viaversion.commands.defaultsubs.DontBugMeSubCmd;
import com.viaversion.viaversion.commands.defaultsubs.DumpSubCmd;
import com.viaversion.viaversion.commands.defaultsubs.ListSubCmd;
import com.viaversion.viaversion.commands.defaultsubs.PPSSubCmd;
import com.viaversion.viaversion.commands.defaultsubs.ReloadSubCmd;
import com.viaversion.viaversion.commands.defaultsubs.PlayerSubCmd;
import com.viaversion.viaversion.commands.defaultsubs.ReloadSubCmd;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -22,7 +22,6 @@ import com.viaversion.viaversion.api.command.ViaCommandSender;
import com.viaversion.viaversion.api.command.ViaSubCommand;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -66,7 +66,6 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
private int pistonReplacementId;
private boolean chunkBorderFix;
private boolean autoTeam;
private boolean nbtArrayFix;
private BlockedProtocolVersions blockedProtocolVersions;
private String blockedDisconnectMessage;
private String reloadDisconnectMessage;
@@ -97,6 +96,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
private boolean cancelBlockSounds;
private boolean hideScoreboardNumbers;
private boolean fix1_21PlacementRotation;
private boolean cancelSwingInInventory;
protected AbstractViaConfig(final File configFile, final Logger logger) {
super(configFile, logger);
@@ -133,7 +133,6 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
pistonReplacementId = getInt("replacement-piston-id", 0);
chunkBorderFix = getBoolean("chunk-border-fix", false);
autoTeam = getBoolean("auto-team", true);
nbtArrayFix = getBoolean("chat-nbt-fix", true);
blockedProtocolVersions = loadBlockedProtocolVersions();
blockedDisconnectMessage = getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
reloadDisconnectMessage = getString("reload-disconnect-msg", "Server reload, please rejoin!");
@@ -167,6 +166,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
cancelBlockSounds = getBoolean("cancel-block-sounds", true);
hideScoreboardNumbers = getBoolean("hide-scoreboard-numbers", false);
fix1_21PlacementRotation = getBoolean("fix-1_21-placement-rotation", true);
cancelSwingInInventory = getBoolean("cancel-swing-in-inventory", true);
}
private BlockedProtocolVersions loadBlockedProtocolVersions() {
@@ -379,11 +379,6 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
return preventCollision && autoTeam;
}
@Override
public boolean is1_12NBTArrayFix() {
return nbtArrayFix;
}
@Override
public boolean shouldRegisterUserConnectionOnJoin() {
return false;
@@ -563,4 +558,9 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
public boolean fix1_21PlacementRotation() {
return fix1_21PlacementRotation;
}
@Override
public boolean cancelSwingInInventory() {
return cancelSwingInInventory;
}
}
@@ -154,27 +154,14 @@ public class UserConnectionImpl implements UserConnection {
}
@Override
public void clearStoredObjects(boolean isServerSwitch) {
if (isServerSwitch) {
storedObjects.values().removeIf(storableObject -> {
if (storableObject.clearOnServerSwitch()) {
storableObject.onRemove();
return true;
}
return false;
});
for (EntityTracker tracker : entityTrackers.values()) {
tracker.clearEntities();
}
} else {
for (StorableObject object : storedObjects.values()) {
object.onRemove();
}
storedObjects.clear();
entityTrackers.clear();
itemHashers.clear();
clientWorlds.clear();
public void clearStoredObjects() {
for (StorableObject object : storedObjects.values()) {
object.onRemove();
}
storedObjects.clear();
entityTrackers.clear();
itemHashers.clear();
clientWorlds.clear();
}
@Override
@@ -80,6 +80,7 @@ import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.Protocol1_21_2To1_21_4;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.Protocol1_21_4To1_21_5;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.Protocol1_21_5To1_21_6;
import com.viaversion.viaversion.protocols.v1_21_6to1_21_7.Protocol1_21_6To1_21_7;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.Protocol1_9_1To1_9_3;
@@ -203,6 +204,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_21_4To1_21_5(), ProtocolVersion.v1_21_5, ProtocolVersion.v1_21_4);
registerProtocol(new Protocol1_21_5To1_21_6(), ProtocolVersion.v1_21_6, ProtocolVersion.v1_21_5);
registerProtocol(new Protocol1_21_6To1_21_7(), ProtocolVersion.v1_21_7, ProtocolVersion.v1_21_6);
}
@Override
@@ -32,7 +32,6 @@ import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
import com.viaversion.viaversion.protocols.base.packet.BasePacketTypesProvider;
import com.viaversion.viaversion.protocols.base.packet.BaseServerboundPacket;
import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viaversion.util.ChatColorUtil;
import com.viaversion.viaversion.util.ComponentUtil;
import io.netty.channel.ChannelFuture;
@@ -144,7 +144,7 @@ final class Protocol1_98To1_99 extends AbstractProtocol<ClientboundPacket1_21_2,
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_4.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection, SerializerVersion.V1_21_5, SerializerVersion.V1_21_5));
addItemHasher(connection, new ItemHasherBase(this, connection, SerializerVersion.V1_21_6, SerializerVersion.V1_21_6));
}
// Overriding these methods is important as they are relied on various rewriter classes
@@ -38,7 +38,6 @@ 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;
import com.viaversion.viaversion.util.Pair;
public class Protocol1_10To1_11 extends AbstractProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
@@ -21,7 +21,6 @@ import com.google.gson.JsonElement;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
@@ -32,7 +31,6 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_12;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
@@ -43,8 +41,6 @@ import com.viaversion.viaversion.protocols.v1_11_1to1_12.packet.ServerboundPacke
import com.viaversion.viaversion.protocols.v1_11_1to1_12.provider.InventoryQuickMoveProvider;
import com.viaversion.viaversion.protocols.v1_11_1to1_12.rewriter.EntityPacketRewriter1_12;
import com.viaversion.viaversion.protocols.v1_11_1to1_12.rewriter.ItemPacketRewriter1_12;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
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;
@@ -63,7 +59,6 @@ public class Protocol1_11_1To1_12 extends AbstractProtocol<ClientboundPackets1_9
super.registerPackets();
registerClientbound(ClientboundPackets1_9_3.CHAT, wrapper -> {
if (!Via.getConfig().is1_12NBTArrayFix()) return;
final JsonElement element = wrapper.passthrough(Types.COMPONENT);
TranslateRewriter.toClient(wrapper.user(), element);
ChatItemRewriter.toClient(element);
@@ -177,6 +177,14 @@ public class AchievementTranslations1_12 {
add("achievement.overkill.desc", "Deal nine hearts of damage in a single hit");
add("achievement.bookcase", "Librarian");
add("achievement.bookcase.desc", "Build some bookshelves to improve your enchantment table");
add("commands.achievement.usage", "/achievement <give|take> <name|*> [player]");
add("commands.achievement.give.success.all", "Successfully given all achievements to %s");
add("commands.achievement.take.success.all", "Successfully taken all achievements from %s");
add("commands.achievement.unknownAchievement", "Unknown achievement '%s'");
add("commands.achievement.take.success.one", "Successfully taken the achievement %s from %s");
add("commands.achievement.dontHave", "Player %s doesn't have achievement %s");
add("commands.achievement.alreadyHave", "Player %s already has achievement %s");
add("commands.achievement.give.success.one", "Successfully given %s the achievement %s");
}
private static void add(String key, String value) {
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.protocols.v1_12_2to1_13;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.viaversion.viaversion.api.Via;
@@ -483,6 +484,31 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
displayName = rewriteTeamMemberName(displayName);
wrapper.write(Types.STRING, displayName);
});
registerClientbound(ClientboundPackets1_12_1.PLAYER_INFO, wrapper -> {
final int action = wrapper.passthrough(Types.VAR_INT);
final int count = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < count; i++) {
wrapper.passthrough(Types.UUID); // Player UUID
if (action == 0) { // Add player
final String playerName = wrapper.read(Types.STRING);
wrapper.write(Types.STRING, rewriteTeamMemberName(playerName));
wrapper.passthrough(Types.PROFILE_PROPERTY_ARRAY); // Profile properties
wrapper.passthrough(Types.VAR_INT); // gamemode
wrapper.passthrough(Types.VAR_INT); // ping
final JsonElement displayName = wrapper.passthrough(Types.OPTIONAL_COMPONENT);
if (displayName != null) {
componentRewriter.processText(wrapper.user(), displayName);
}
} else if (action == 1 || action == 2) { // Update Gamemode/Latency
wrapper.passthrough(Types.VAR_INT);
} else if (action == 3) { // Update display name
final JsonElement displayName = wrapper.passthrough(Types.OPTIONAL_COMPONENT);
if (displayName != null) {
componentRewriter.processText(wrapper.user(), displayName);
}
}
}
});
componentRewriter.registerTitle(ClientboundPackets1_12_1.SET_TITLES);
@@ -22,9 +22,9 @@ import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
@@ -39,11 +39,11 @@ import com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter.PlayerPacketRe
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.CommandRewriter;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
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 org.checkerframework.checker.nullness.qual.Nullable;
public class Protocol1_13_2To1_14 extends AbstractProtocol<ClientboundPackets1_13, ClientboundPackets1_14, ServerboundPackets1_13, ServerboundPackets1_14> {
@@ -37,9 +37,9 @@ 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.packet.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.storage.EntityTracker1_14;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
import java.util.Set;
@@ -65,6 +65,8 @@ public class ComponentRewriter1_16 extends JsonNBTComponentRewriter<ClientboundP
mappings.put("advancements.husbandry.break_diamond_hoe.description", "Completely use up a diamond hoe, and then reevaluate your life choices");
mappings.put("biome.minecraft.nether", "Nether");
mappings.put("key.swapHands", "key.swapOffhand");
mappings.put("commands.datapack.enable.success", "commands.datapack.modify.enable");
mappings.put("commands.datapack.disable.success", "commands.datapack.modify.disable");
}
@Override
@@ -201,6 +201,10 @@ public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1
});
protocol.registerServerbound(ServerboundPackets1_16.SWING, wrapper -> {
if (!Via.getConfig().cancelSwingInInventory()) {
return;
}
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
// Don't send an arm swing if the player has an inventory opened.
if (inventoryTracker.isInventoryOpen()) {
@@ -19,7 +19,6 @@ package com.viaversion.viaversion.protocols.v1_16_3to1_16_4;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2;
@@ -34,6 +34,7 @@ import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPac
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ClientboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.ComponentRewriter1_17;
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;
@@ -41,6 +42,7 @@ 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> {
@@ -48,6 +50,7 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
private final EntityPacketRewriter1_17 entityRewriter = new EntityPacketRewriter1_17(this);
private final ItemPacketRewriter1_17 itemRewriter = new ItemPacketRewriter1_17(this);
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);
public Protocol1_16_4To1_17() {
@@ -84,6 +87,13 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
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.registerPing();
SoundRewriter<ClientboundPackets1_16_2> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_16_2.SOUND);
soundRewriter.registerSound(ClientboundPackets1_16_2.SOUND_ENTITY);
@@ -133,6 +143,9 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
default -> throw new IllegalArgumentException("Invalid title type received: " + type);
}
if (type < 3) {
componentRewriter.processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
}
wrapper.setPacketType(packetType);
});
@@ -217,6 +230,11 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol<ClientboundPack
return particleRewriter;
}
@Override
public @Nullable ComponentRewriter1_17 getComponentRewriter() {
return componentRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_16_2> getTagRewriter() {
return tagRewriter;
@@ -0,0 +1,50 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter;
import com.google.gson.JsonObject;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import java.util.HashMap;
import java.util.Map;
public final class ComponentRewriter1_17 extends JsonNBTComponentRewriter<ClientboundPackets1_16_2> {
private final Map<String, String> mappings = new HashMap<>();
public ComponentRewriter1_17(final Protocol<ClientboundPackets1_16_2, ?, ?, ?> protocol) {
super(protocol, ReadType.JSON);
mappings.put("commands.worldborder.set.failed.small.", "commands.worldborder.set.failed.small");
mappings.put("commands.worldborder.set.failed.big.", "commands.worldborder.set.failed.big");
mappings.put("commands.replaceitem.slot.inapplicable", "commands.item.target.no_such_slot");
mappings.put("commands.replaceitem.block.failed", "The target block is not a container");
mappings.put("commands.replaceitem.entity.success.single", "commands.item.entity.set.success.single");
mappings.put("commands.replaceitem.block.success", "commands.item.block.set.success");
mappings.put("commands.debug.reportSaved", "Created debug report in %s");
mappings.put("commands.debug.reportFailed", "Failed to create debug report");
}
@Override
protected void handleTranslate(final JsonObject object, final String translate) {
String mappedTranslation = mappings.get(translate);
if (mappedTranslation != null) {
object.addProperty("translate", mappedTranslation);
}
}
}
@@ -157,6 +157,11 @@ public final class EntityPacketRewriter1_17 extends EntityRewriter<ClientboundPa
default -> throw new IllegalArgumentException("Invalid combat type received: " + type);
};
if (type == 2) {
wrapper.passthrough(Types.VAR_INT); // Duration/Player id
wrapper.passthrough(Types.INT); // Killer id
protocol.getComponentRewriter().processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
}
wrapper.setPacketType(packetType);
});
@@ -30,6 +30,7 @@ import com.viaversion.viaversion.api.type.types.version.Types1_18;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter.ComponentRewriter1_18;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter.EntityPacketRewriter1_18;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter.ItemPacketRewriter1_18;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter.WorldPacketRewriter1_18;
@@ -48,6 +49,7 @@ public final class Protocol1_17_1To1_18 extends AbstractProtocol<ClientboundPack
private final EntityPacketRewriter1_18 entityRewriter = new EntityPacketRewriter1_18(this);
private final ItemPacketRewriter1_18 itemRewriter = new ItemPacketRewriter1_18(this);
private final ParticleRewriter<ClientboundPackets1_17_1> particleRewriter = new ParticleRewriter<>(this);
private final ComponentRewriter1_18 componentRewriter = new ComponentRewriter1_18(this);
private final TagRewriter<ClientboundPackets1_17_1> tagRewriter = new TagRewriter<>(this);
public Protocol1_17_1To1_18() {
@@ -68,6 +70,17 @@ public final class Protocol1_17_1To1_18 extends AbstractProtocol<ClientboundPack
new StatisticsRewriter<>(this).register(ClientboundPackets1_17_1.AWARD_STATS);
componentRewriter.registerComponentPacket(ClientboundPackets1_17_1.CHAT);
componentRewriter.registerComponentPacket(ClientboundPackets1_17_1.SET_ACTION_BAR_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_17_1.SET_TITLE_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_17_1.SET_SUBTITLE_TEXT);
componentRewriter.registerBossEvent(ClientboundPackets1_17_1.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_17_1.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_17_1.TAB_LIST);
componentRewriter.registerOpenScreen1_14(ClientboundPackets1_17_1.OPEN_SCREEN);
componentRewriter.registerPlayerCombatKill(ClientboundPackets1_17_1.PLAYER_COMBAT_KILL);
componentRewriter.registerPing();
registerServerbound(ServerboundPackets1_17.CLIENT_INFORMATION, new PacketHandlers() {
@Override
public void register() {
@@ -130,6 +143,11 @@ public final class Protocol1_17_1To1_18 extends AbstractProtocol<ClientboundPack
return particleRewriter;
}
@Override
public ComponentRewriter1_18 getComponentRewriter() {
return componentRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_17_1> getTagRewriter() {
return tagRewriter;
@@ -0,0 +1,83 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.v1_17_1to1_18.rewriter;
import com.google.gson.JsonObject;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import java.util.HashMap;
import java.util.Map;
public final class ComponentRewriter1_18 extends JsonNBTComponentRewriter<ClientboundPackets1_17_1> {
private final Map<String, String> mappings = new HashMap<>();
public ComponentRewriter1_18(final Protocol<ClientboundPackets1_17_1, ?, ?, ?> protocol) {
super(protocol, ReadType.JSON);
mappings.put("commands.scoreboard.objectives.add.longName", "Objective names cannot be longer than %s characters");
mappings.put("commands.team.add.longName", "Team names cannot be longer than %s characters");
mappings.put("biome.minecraft.snowy_mountains", "Snowy Mountains");
mappings.put("biome.minecraft.wooded_mountains", "Wooded Mountains");
mappings.put("biome.minecraft.jungle_edge", "Jungle Edge");
mappings.put("biome.minecraft.dark_forest_hills", "Dark Forest Hills");
mappings.put("biome.minecraft.modified_wooded_badlands_plateau", "Modified Wooded Badlands Plateau");
mappings.put("biome.minecraft.snowy_tundra", "Snowy Tundra");
mappings.put("biome.minecraft.mountain_edge", "Mountain Edge");
mappings.put("biome.minecraft.modified_badlands_plateau", "Modified Badlands Plateau");
mappings.put("biome.minecraft.mushroom_field_shore", "Mushroom Field Shore");
mappings.put("biome.minecraft.tall_birch_forest", "Tall Birch Forest");
mappings.put("biome.minecraft.wooded_hills", "Wooded Hills");
mappings.put("biome.minecraft.taiga_hills", "Taiga Hills");
mappings.put("biome.minecraft.snowy_taiga_mountains", "Snowy Taiga Mountains");
mappings.put("biome.minecraft.deep_warm_ocean", "Deep Warm Ocean");
mappings.put("biome.minecraft.swamp_hills", "Swamp Hills");
mappings.put("biome.minecraft.giant_tree_taiga_hills", "Giant Tree Taiga Hills");
mappings.put("biome.minecraft.tall_birch_hills", "Tall Birch Hills");
mappings.put("biome.minecraft.bamboo_jungle_hills", "Bamboo Jungle Hills");
mappings.put("biome.minecraft.jungle_hills", "Jungle Hills");
mappings.put("biome.minecraft.gravelly_mountains", "Gravelly Mountains");
mappings.put("biome.minecraft.wooded_badlands_plateau", "Wooded Badlands Plateau");
mappings.put("biome.minecraft.shattered_savanna", "Shattered Savanna");
mappings.put("biome.minecraft.desert_hills", "Desert Hills");
mappings.put("biome.minecraft.badlands_plateau", "Badlands Plateau");
mappings.put("biome.minecraft.modified_jungle_edge", "Modified Jungle Edge");
mappings.put("biome.minecraft.giant_spruce_taiga", "Giant Spruce Taiga");
mappings.put("biome.minecraft.stone_shore", "Stone Shore");
mappings.put("biome.minecraft.mountains", "Mountains");
mappings.put("biome.minecraft.giant_tree_taiga", "Giant Tree Taiga");
mappings.put("biome.minecraft.snowy_taiga_hills", "Snowy Taiga Hills");
mappings.put("biome.minecraft.modified_gravelly_mountains", "Gravelly Mountains+");
mappings.put("biome.minecraft.taiga_mountains", "Taiga Mountains");
mappings.put("biome.minecraft.desert_lakes", "Desert Lakes");
mappings.put("biome.minecraft.shattered_savanna_plateau", "Shattered Savanna Plateau");
mappings.put("biome.minecraft.modified_jungle", "Modified Jungle");
mappings.put("biome.minecraft.birch_forest_hills", "Birch Forest Hills");
mappings.put("biome.minecraft.giant_spruce_taiga_hills", "Giant Spruce Taiga Hills");
}
@Override
protected void handleTranslate(final JsonObject object, final String translate) {
String mappedTranslation = mappings.get(translate);
if (mappedTranslation != null) {
object.addProperty("translate", mappedTranslation);
}
}
}
@@ -39,6 +39,7 @@ import com.viaversion.viaversion.protocols.v1_18_2to1_19.data.MappingData1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ServerboundPackets1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.provider.AckSequenceProvider;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.rewriter.ComponentRewriter1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.rewriter.EntityPacketRewriter1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.rewriter.ItemPacketRewriter1_19;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.rewriter.WorldPacketRewriter1_19;
@@ -60,24 +61,13 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
private final EntityPacketRewriter1_19 entityRewriter = new EntityPacketRewriter1_19(this);
private final ItemPacketRewriter1_19 itemRewriter = new ItemPacketRewriter1_19(this);
private final ParticleRewriter<ClientboundPackets1_18> particleRewriter = new ParticleRewriter<>(this);
private final ComponentRewriter1_19 componentRewriter = new ComponentRewriter1_19(this);
private final TagRewriter<ClientboundPackets1_18> tagRewriter = new TagRewriter<>(this);
public Protocol1_18_2To1_19() {
super(ClientboundPackets1_18.class, ClientboundPackets1_19.class, ServerboundPackets1_17.class, ServerboundPackets1_19.class);
}
public static boolean isTextComponentNull(final JsonElement element) {
return element == null || element.isJsonNull() || (element.isJsonArray() && element.getAsJsonArray().isEmpty());
}
public static JsonElement mapTextComponentIfNull(JsonElement component) {
if (!isTextComponentNull(component)) {
return component;
} else {
return ComponentUtil.emptyJsonComponent();
}
}
@Override
protected void registerPackets() {
tagRewriter.registerGeneric(ClientboundPackets1_18.UPDATE_TAGS);
@@ -131,7 +121,7 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
new StatisticsRewriter<>(this).register(ClientboundPackets1_18.AWARD_STATS);
final PacketHandler singleNullTextComponentMapper = wrapper -> wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.read(Types.COMPONENT)));
final PacketHandler singleNullTextComponentMapper = wrapper -> wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.user(), wrapper.read(Types.COMPONENT)));
registerClientbound(ClientboundPackets1_18.SET_TITLE_TEXT, singleNullTextComponentMapper);
registerClientbound(ClientboundPackets1_18.SET_SUBTITLE_TEXT, singleNullTextComponentMapper);
registerClientbound(ClientboundPackets1_18.SET_ACTION_BAR_TEXT, singleNullTextComponentMapper);
@@ -139,20 +129,59 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
wrapper.passthrough(Types.STRING); // Objective Name
byte action = wrapper.passthrough(Types.BYTE); // Mode
if (action == 0 || action == 2) {
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.read(Types.COMPONENT))); // Display Name
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.user(), wrapper.read(Types.COMPONENT))); // Display Name
}
});
registerClientbound(ClientboundPackets1_18.SET_PLAYER_TEAM, wrapper -> {
wrapper.passthrough(Types.STRING); // Team Name
byte action = wrapper.passthrough(Types.BYTE); // Mode
if (action == 0 || action == 2) {
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.read(Types.COMPONENT))); // Display Name
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.user(), wrapper.read(Types.COMPONENT))); // Display Name
wrapper.passthrough(Types.BYTE); // Flags
wrapper.passthrough(Types.STRING); // Name Tag Visibility
wrapper.passthrough(Types.STRING); // Collision rule
wrapper.passthrough(Types.VAR_INT); // Color
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.read(Types.COMPONENT))); // Prefix
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.read(Types.COMPONENT))); // Suffix
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.user(), wrapper.read(Types.COMPONENT))); // Prefix
wrapper.write(Types.COMPONENT, mapTextComponentIfNull(wrapper.user(), wrapper.read(Types.COMPONENT))); // Suffix
}
});
componentRewriter.registerBossEvent(ClientboundPackets1_18.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_18.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_18.TAB_LIST);
componentRewriter.registerOpenScreen1_14(ClientboundPackets1_18.OPEN_SCREEN);
componentRewriter.registerPlayerCombatKill(ClientboundPackets1_18.PLAYER_COMBAT_KILL);
componentRewriter.registerPing();
registerClientbound(ClientboundPackets1_18.PLAYER_INFO, wrapper -> {
final int action = wrapper.passthrough(Types.VAR_INT);
final int entries = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < entries; i++) {
wrapper.passthrough(Types.UUID); // UUID
if (action == 0) { // Add player
wrapper.passthrough(Types.STRING); // Player Name
wrapper.passthrough(Types.PROFILE_PROPERTY_ARRAY);
wrapper.passthrough(Types.VAR_INT); // Gamemode
wrapper.passthrough(Types.VAR_INT); // Ping
final JsonElement displayName = wrapper.read(Types.OPTIONAL_COMPONENT); // Display name
if (isJsonNotNull(displayName)) {
wrapper.write(Types.OPTIONAL_COMPONENT, displayName);
} else {
wrapper.write(Types.OPTIONAL_COMPONENT, null);
}
// No public profile signature
wrapper.write(Types.OPTIONAL_PROFILE_KEY, null);
} else if (action == 1 || action == 2) { // Update gamemode/update latency
wrapper.passthrough(Types.VAR_INT);
} else if (action == 3) { // Update display name
final JsonElement displayName = wrapper.read(Types.OPTIONAL_COMPONENT); // Display name
if (isJsonNotNull(displayName)) {
wrapper.write(Types.OPTIONAL_COMPONENT, displayName);
} else {
wrapper.write(Types.OPTIONAL_COMPONENT, null);
}
}
}
});
@@ -288,10 +317,23 @@ public final class Protocol1_18_2To1_19 extends AbstractProtocol<ClientboundPack
});
}
private static long randomLong() {
private long randomLong() {
return ThreadLocalRandom.current().nextLong();
}
public boolean isJsonNotNull(final JsonElement element) {
return element != null && !element.isJsonNull() && (!element.isJsonArray() || !element.getAsJsonArray().isEmpty());
}
public JsonElement mapTextComponentIfNull(final UserConnection connection, final JsonElement component) {
if (isJsonNotNull(component)) {
componentRewriter.processText(connection, component);
return component;
} else {
return ComponentUtil.emptyJsonComponent();
}
}
@Override
protected void onMappingDataLoaded() {
Types1_19.PARTICLE.filler(this)
@@ -0,0 +1,53 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.v1_18_2to1_19.rewriter;
import com.google.gson.JsonObject;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import java.util.HashMap;
import java.util.Map;
public final class ComponentRewriter1_19 extends JsonNBTComponentRewriter<ClientboundPackets1_18> {
private final Map<String, String> mappings = new HashMap<>();
public ComponentRewriter1_19(final Protocol<ClientboundPackets1_18, ?, ?, ?> protocol) {
super(protocol, ReadType.JSON);
mappings.put("commands.locate.invalid", "commands.locate.structure.invalid");
mappings.put("commands.locatebiome.success", "commands.locate.biome.success");
mappings.put("command.placefeature.invalid", "commands.place.feature.failed");
mappings.put("commands.locatebiome.invalid", "commands.locate.biome.invalid");
mappings.put("commands.placefeature.invalid", "commands.place.feature.invalid");
mappings.put("commands.locatebiome.notFound", "commands.locate.biome.not_found");
mappings.put("commands.placefeature.success", "commands.place.feature.success");
mappings.put("commands.locate.failed", "commands.locate.structure.not_found");
mappings.put("commands.locate.success", "commands.locate.structure.success");
}
@Override
protected void handleTranslate(final JsonObject object, final String translate) {
String mappedTranslation = mappings.get(translate);
if (mappedTranslation != null) {
object.addProperty("translate", mappedTranslation);
}
}
}
@@ -18,7 +18,6 @@
package com.viaversion.viaversion.protocols.v1_18_2to1_19.rewriter;
import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntTag;
import com.viaversion.nbt.tag.ListTag;
@@ -232,38 +231,6 @@ public final class EntityPacketRewriter1_19 extends EntityRewriter<ClientboundPa
handler(worldDataTrackerHandlerByKey());
}
});
protocol.registerClientbound(ClientboundPackets1_18.PLAYER_INFO, wrapper -> {
final int action = wrapper.passthrough(Types.VAR_INT);
final int entries = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < entries; i++) {
wrapper.passthrough(Types.UUID); // UUID
if (action == 0) { // Add player
wrapper.passthrough(Types.STRING); // Player Name
wrapper.passthrough(Types.PROFILE_PROPERTY_ARRAY);
wrapper.passthrough(Types.VAR_INT); // Gamemode
wrapper.passthrough(Types.VAR_INT); // Ping
final JsonElement displayName = wrapper.read(Types.OPTIONAL_COMPONENT); // Display name
if (!Protocol1_18_2To1_19.isTextComponentNull(displayName)) {
wrapper.write(Types.OPTIONAL_COMPONENT, displayName);
} else {
wrapper.write(Types.OPTIONAL_COMPONENT, null);
}
// No public profile signature
wrapper.write(Types.OPTIONAL_PROFILE_KEY, null);
} else if (action == 1 || action == 2) { // Update gamemode/update latency
wrapper.passthrough(Types.VAR_INT);
} else if (action == 3) { // Update display name
final JsonElement displayName = wrapper.read(Types.OPTIONAL_COMPONENT); // Display name
if (!Protocol1_18_2To1_19.isTextComponentNull(displayName)) {
wrapper.write(Types.OPTIONAL_COMPONENT, displayName);
} else {
wrapper.write(Types.OPTIONAL_COMPONENT, null);
}
}
}
});
}
private void writeDimensionKey(final PacketWrapper wrapper, final DimensionRegistryStorage registryStorage) {
@@ -37,9 +37,4 @@ public final class DimensionRegistryStorage implements StorableObject {
public Map<CompoundTag, String> dimensions() {
return dimensions;
}
@Override
public boolean clearOnServerSwitch() {
return false;
}
}
@@ -45,6 +45,7 @@ import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ServerboundPackets1_19_3;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter.ComponentRewriter1_19_3;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter.EntityPacketRewriter1_19_3;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter.ItemPacketRewriter1_19_3;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.storage.NonceStorage1_19_3;
@@ -70,6 +71,7 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
private final EntityPacketRewriter1_19_3 entityRewriter = new EntityPacketRewriter1_19_3(this);
private final ItemPacketRewriter1_19_3 itemRewriter = new ItemPacketRewriter1_19_3(this);
private final ParticleRewriter<ClientboundPackets1_19_1> particleRewriter = new ParticleRewriter<>(this);
private final ComponentRewriter1_19_3 componentRewriter = new ComponentRewriter1_19_3(this);
private final TagRewriter<ClientboundPackets1_19_1> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_1To1_19_3() {
@@ -105,6 +107,17 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_1.AWARD_STATS);
componentRewriter.registerComponentPacket(ClientboundPackets1_19_1.SYSTEM_CHAT);
componentRewriter.registerComponentPacket(ClientboundPackets1_19_1.SET_ACTION_BAR_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_19_1.SET_TITLE_TEXT);
componentRewriter.registerComponentPacket(ClientboundPackets1_19_1.SET_SUBTITLE_TEXT);
componentRewriter.registerBossEvent(ClientboundPackets1_19_1.BOSS_EVENT);
componentRewriter.registerComponentPacket(ClientboundPackets1_19_1.DISCONNECT);
componentRewriter.registerTabList(ClientboundPackets1_19_1.TAB_LIST);
componentRewriter.registerOpenScreen1_14(ClientboundPackets1_19_1.OPEN_SCREEN);
componentRewriter.registerPlayerCombatKill(ClientboundPackets1_19_1.PLAYER_COMBAT_KILL);
componentRewriter.registerPing();
final CommandRewriter<ClientboundPackets1_19_1> commandRewriter = new CommandRewriter<>(this) {
@Override
public void handleArgument(final PacketWrapper wrapper, final String argumentType) {
@@ -389,6 +402,11 @@ public final class Protocol1_19_1To1_19_3 extends AbstractProtocol<ClientboundPa
return particleRewriter;
}
@Override
public ComponentRewriter1_19_3 getComponentRewriter() {
return componentRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_1> getTagRewriter() {
return tagRewriter;
@@ -0,0 +1,40 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter;
import com.google.gson.JsonObject;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
public final class ComponentRewriter1_19_3 extends JsonNBTComponentRewriter<ClientboundPackets1_19_1> {
public ComponentRewriter1_19_3(final Protocol<ClientboundPackets1_19_1, ?, ?, ?> protocol) {
super(protocol, ReadType.JSON);
}
@Override
protected void handleTranslate(final JsonObject object, final String translate) {
switch (translate) {
case "commands.locate.poi.invalid" -> object.addProperty("translate", "There is no point of interest with type \"%s\"");
case "commands.locate.biome.invalid" -> object.addProperty("translate", "There is no biome with type \"%s\"");
case "multiplayer.disconnect.missing_public_key" -> object.addProperty("translate", "Missing profile public key.\nThis server requires secure profiles.");
case "multiplayer.disconnect.invalid_public_key" -> object.addProperty("translate", "Invalid signature for profile public key.\nTry restarting your game.");
}
}
}
@@ -133,6 +133,10 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
final int gamemode = wrapper.read(Types.VAR_INT);
final int ping = wrapper.read(Types.VAR_INT);
final JsonElement displayName = wrapper.read(Types.OPTIONAL_COMPONENT);
if (displayName != null) {
protocol.getComponentRewriter().processText(wrapper.user(), displayName);
}
wrapper.read(Types.OPTIONAL_PROFILE_KEY);
wrapper.write(Types.BOOLEAN, false); // No chat session data
@@ -143,7 +147,10 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter<Clientbound
} else if (action == 1 || action == 2) { // Update gamemode/update latency
wrapper.passthrough(Types.VAR_INT);
} else if (action == 3) { // Update display name
wrapper.passthrough(Types.OPTIONAL_COMPONENT);
final JsonElement displayName = wrapper.passthrough(Types.OPTIONAL_COMPONENT);
if (displayName != null) {
protocol.getComponentRewriter().processText(wrapper.user(), displayName);
}
}
}
});
@@ -17,11 +17,9 @@
*/
package com.viaversion.viaversion.protocols.v1_19_1to1_19_3.rewriter;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
@@ -35,6 +35,10 @@ import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.libs.mcstructs.text.Style;
import com.viaversion.viaversion.libs.mcstructs.text.TextComponent;
import com.viaversion.viaversion.libs.mcstructs.text.TextFormatting;
import com.viaversion.viaversion.libs.mcstructs.text.components.TranslationComponent;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
@@ -55,10 +59,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.lenni0451.mcstructs.text.Style;
import net.lenni0451.mcstructs.text.TextComponent;
import net.lenni0451.mcstructs.text.TextFormatting;
import net.lenni0451.mcstructs.text.components.TranslationComponent;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class Protocol1_19To1_19_1 extends AbstractProtocol<ClientboundPackets1_19, ClientboundPackets1_19_1, ServerboundPackets1_19, ServerboundPackets1_19_1> {
@@ -39,9 +39,4 @@ public final class ChatTypeStorage implements StorableObject {
public void clear() {
chatTypes.clear();
}
@Override
public boolean clearOnServerSwitch() {
return false;
}
}
@@ -27,11 +27,11 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_3;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPacket1_20_2;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_3;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
@@ -26,7 +26,7 @@ import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewrit
import java.util.ArrayList;
import java.util.List;
final class RecipeRewriter1_20_5 <C extends ClientboundPacketType> extends RecipeRewriter1_20_3<C> {
final class RecipeRewriter1_20_5<C extends ClientboundPacketType> extends RecipeRewriter1_20_3<C> {
public RecipeRewriter1_20_5(final Protocol<C, ?, ?, ?> protocol) {
super(protocol);
@@ -114,9 +114,4 @@ public final class AcknowledgedMessagesStorage implements StorableObject {
lastSeenMessages = new BitSet();
delayedAckCount = 0;
}
@Override
public boolean clearOnServerSwitch() {
return false;
}
}
@@ -38,9 +38,4 @@ public final class BannerPatternStorage implements StorableObject {
public @Nullable String pattern(final int id) {
return bannerPatterns.idToKey(id);
}
@Override
public boolean clearOnServerSwitch() {
return false;
}
}
@@ -92,7 +92,7 @@ public final class AttributeModifierMappings1_21 {
}
public static @Nullable String idToName(final String id) {
return ATTRIBUTE_MODIFIER_NAMES.inverse().get(id);
return ATTRIBUTE_MODIFIER_NAMES.inverse().get(Key.stripMinecraftNamespace(id));
}
private static void add(final long msb, final long lsb, final String id) {
@@ -43,7 +43,6 @@ import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<ClientboundPacket1_20_5, ServerboundPacket1_20_5, Protocol1_20_5To1_21> {
@@ -183,10 +182,9 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
dataContainer.replaceKey(StructuredDataKey.FOOD1_20_5, StructuredDataKey.FOOD1_21);
dataContainer.replace(StructuredDataKey.ATTRIBUTE_MODIFIERS1_20_5, StructuredDataKey.ATTRIBUTE_MODIFIERS1_21, attributeModifiers -> {
final AttributeModifiers1_21.AttributeModifier[] modifiers = Arrays.stream(attributeModifiers.modifiers()).map(modifier -> {
final int mappedAttributeId = Protocol1_20_5To1_21.MAPPINGS.getNewAttributeId(modifier.attribute());
final AttributeModifiers1_20_5.ModifierData modData = modifier.modifier();
final AttributeModifiers1_21.ModifierData updatedModData = new AttributeModifiers1_21.ModifierData(Protocol1_20_5To1_21.mapAttributeUUID(modData.uuid(), modData.name()), modData.amount(), modData.operation());
return new AttributeModifiers1_21.AttributeModifier(mappedAttributeId, updatedModData, modifier.slotType());
return new AttributeModifiers1_21.AttributeModifier(modifier.attribute(), updatedModData, modifier.slotType());
}).toArray(AttributeModifiers1_21.AttributeModifier[]::new);
return new AttributeModifiers1_21(modifiers, attributeModifiers.showInTooltip());
});
@@ -219,11 +217,6 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
dataContainer.remove(StructuredDataKey.JUKEBOX_PLAYABLE1_21);
dataContainer.replace(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21, StructuredDataKey.ATTRIBUTE_MODIFIERS1_20_5, attributeModifiers -> {
final AttributeModifiers1_20_5.AttributeModifier[] modifiers = Arrays.stream(attributeModifiers.modifiers()).map(modifier -> {
final int mappedAttributeId = Protocol1_20_5To1_21.MAPPINGS.getAttributeMappings().inverse().getNewId(modifier.attribute());
if (mappedAttributeId == -1) {
return null;
}
final AttributeModifiers1_21.ModifierData modData = modifier.modifier();
final String name = AttributeModifierMappings1_21.idToName(modData.id());
final AttributeModifiers1_20_5.ModifierData updatedModData = new AttributeModifiers1_20_5.ModifierData(
@@ -232,8 +225,8 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
modData.amount(),
modData.operation()
);
return new AttributeModifiers1_20_5.AttributeModifier(mappedAttributeId, updatedModData, modifier.slotType());
}).filter(Objects::nonNull).toArray(AttributeModifiers1_20_5.AttributeModifier[]::new);
return new AttributeModifiers1_20_5.AttributeModifier(modifier.attribute(), updatedModData, modifier.slotType());
}).toArray(AttributeModifiers1_20_5.AttributeModifier[]::new);
return new AttributeModifiers1_20_5(modifiers, attributeModifiers.showInTooltip());
});
}
@@ -91,11 +91,6 @@ public class ConfigurationState implements StorableObject {
queuedJoinGame = true;
}
@Override
public boolean clearOnServerSwitch() {
return false;
}
@Override
public void onRemove() {
for (final QueuedPacket packet : packetQueue) {
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff. Show more