mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2026-11-04 17:00:06 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd45a6e7ce | ||
|
|
271362da78 | ||
|
|
05562c27c1 | ||
|
|
5b4ed02748 | ||
|
|
fe4e407520 | ||
|
|
f003b6b84a | ||
|
|
207e085120 | ||
|
|
0a155651a1 | ||
|
|
d061083a8a | ||
|
|
ad4c8e42f2 | ||
|
|
b8b13f5831 | ||
|
|
4dc533506f | ||
|
|
a166b70996 | ||
|
|
639e8c454d | ||
|
|
61fc96ee11 | ||
|
|
56259c8318 | ||
|
|
a8637d9a06 | ||
|
|
ce607b5cc7 | ||
|
|
aa9a615c6b | ||
|
|
8febef07c3 | ||
|
|
13fcce6059 | ||
|
|
cf6427325c | ||
|
|
2c30a2748c | ||
|
|
1ca5b33304 | ||
|
|
265859bdae | ||
|
|
93e29ac832 | ||
|
|
4735795323 | ||
|
|
fe5732b616 | ||
|
|
b0d9b747de | ||
|
|
3f0f973fac | ||
|
|
1fa3f15d91 | ||
|
|
2979b9d63d | ||
|
|
a734a4a9d1 |
No files matched your search
+1
-1
@@ -1,3 +1,3 @@
|
||||
github: kennytv
|
||||
patreon: kennytv
|
||||
custom: ['https://florianmichael.de/donate']
|
||||
custom: ['https://florianreuth.de/donate']
|
||||
@@ -6,3 +6,9 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
- package-ecosystem: "gradle"
|
||||
cooldown:
|
||||
default-days: 7
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
@@ -11,13 +11,13 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # 5.0.0
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # 5.0.1
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # 5.1.0
|
||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # 5.2.0
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
@@ -16,13 +16,13 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # 5.0.0
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # 5.0.1
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # 5.1.0
|
||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # 5.2.0
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
name: Update Gradle Wrapper
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * 0"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update-gradle-wrapper:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- name: Update Gradle Wrapper
|
||||
uses: gradle-update/update-gradle-wrapper-action@512b1875f3b6270828abfe77b247d5895a2da1e5 # 2.1.0
|
||||
@@ -134,6 +134,15 @@ public interface ProtocolInfo {
|
||||
|
||||
void setUuid(UUID uuid);
|
||||
|
||||
/**
|
||||
* Returns whether compression is enabled for this connection.
|
||||
*
|
||||
* @return whether compression is enabled
|
||||
*/
|
||||
boolean compressionEnabled();
|
||||
|
||||
void setCompressionEnabled(boolean compressionEnabled);
|
||||
|
||||
/**
|
||||
* Returns the user's pipeline.
|
||||
*
|
||||
|
||||
@@ -58,8 +58,8 @@ public record PaintingVariant(int width, int height, String assetId, @Nullable T
|
||||
final int width = Types.VAR_INT.readPrimitive(buffer);
|
||||
final int height = Types.VAR_INT.readPrimitive(buffer);
|
||||
final String assetId = Types.STRING.read(buffer);
|
||||
final Tag title = Types.OPTIONAL_TAG.read(buffer);
|
||||
final Tag author = Types.OPTIONAL_TAG.read(buffer);
|
||||
final Tag title = Types.TRUSTED_OPTIONAL_TAG.read(buffer);
|
||||
final Tag author = Types.TRUSTED_OPTIONAL_TAG.read(buffer);
|
||||
return new PaintingVariant(width, height, assetId, title, author);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ public record PaintingVariant(int width, int height, String assetId, @Nullable T
|
||||
Types.VAR_INT.writePrimitive(buffer, variant.width());
|
||||
Types.VAR_INT.writePrimitive(buffer, variant.height());
|
||||
Types.STRING.write(buffer, variant.assetId());
|
||||
Types.OPTIONAL_TAG.write(buffer, variant.title());
|
||||
Types.OPTIONAL_TAG.write(buffer, variant.author());
|
||||
Types.TRUSTED_OPTIONAL_TAG.write(buffer, variant.title());
|
||||
Types.TRUSTED_OPTIONAL_TAG.write(buffer, variant.author());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,8 +79,8 @@ public record PaintingVariant(int width, int height, String assetId, @Nullable T
|
||||
.write("width", Types.INT, value.width())
|
||||
.write("height", Types.INT, value.height())
|
||||
.write("asset_id", Types.IDENTIFIER, Key.of(value.assetId()))
|
||||
.writeOptional("title", Types.TAG, value.title())
|
||||
.writeOptional("author", Types.TAG, value.author()));
|
||||
.writeOptional("title", Types.TRUSTED_TAG, value.title())
|
||||
.writeOptional("author", Types.TRUSTED_TAG, value.author()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
@@ -160,6 +160,10 @@ public final class StructuredDataContainer implements Copyable {
|
||||
}
|
||||
|
||||
public <T, V> void replace(final StructuredDataKey<T> key, final StructuredDataKey<V> toKey, final Function<T, @Nullable V> valueMapper) {
|
||||
replace(key, toKey, valueMapper, null);
|
||||
}
|
||||
|
||||
public <T, V> void replace(final StructuredDataKey<T> key, final StructuredDataKey<V> toKey, final Function<T, @Nullable V> valueMapper, final Runnable emptyValueHandler) {
|
||||
final StructuredData<?> data = this.data.remove(key);
|
||||
if (data == null) {
|
||||
return;
|
||||
@@ -175,6 +179,9 @@ public final class StructuredDataContainer implements Copyable {
|
||||
} else {
|
||||
// Also replace the key for empty data
|
||||
setEmpty(toKey);
|
||||
if (emptyValueHandler != null) {
|
||||
emptyValueHandler.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -33,8 +33,8 @@ public final class EntityDataTypes1_20_3 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType = add(7, Types.ITEM1_20_2);
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
+2
-2
@@ -33,8 +33,8 @@ public final class EntityDataTypes1_20_5 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ public final class EntityDataTypes1_21 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ public final class EntityDataTypes1_21_11 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ public final class EntityDataTypes1_21_2 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ public final class EntityDataTypes1_21_5 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ public final class EntityDataTypes1_21_9 extends AbstractEntityDataTypes {
|
||||
public final EntityDataType longType = add(2, Types.VAR_LONG);
|
||||
public final EntityDataType floatType = add(3, Types.FLOAT);
|
||||
public final EntityDataType stringType = add(4, Types.STRING);
|
||||
public final EntityDataType componentType = add(5, Types.TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.OPTIONAL_TAG);
|
||||
public final EntityDataType componentType = add(5, Types.TRUSTED_TAG);
|
||||
public final EntityDataType optionalComponentType = add(6, Types.TRUSTED_OPTIONAL_TAG);
|
||||
public final EntityDataType itemType;
|
||||
public final EntityDataType booleanType = add(8, Types.BOOLEAN);
|
||||
public final EntityDataType rotationsType = add(9, Types.ROTATIONS);
|
||||
|
||||
@@ -59,7 +59,7 @@ public record ChatType(ChatTypeDecoration chatDecoration, ChatTypeDecoration nar
|
||||
public ChatTypeDecoration read(final ByteBuf buffer) {
|
||||
final String translationKey = Types.STRING.read(buffer);
|
||||
final int[] parameters = Types.INT_ARRAY_PRIMITIVE.read(buffer);
|
||||
final Tag style = Types.TAG.read(buffer);
|
||||
final Tag style = Types.TRUSTED_TAG.read(buffer);
|
||||
return new ChatTypeDecoration(translationKey, parameters, style);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public record ChatType(ChatTypeDecoration chatDecoration, ChatTypeDecoration nar
|
||||
public void write(final ByteBuf buffer, final ChatTypeDecoration value) {
|
||||
Types.STRING.write(buffer, value.translationKey());
|
||||
Types.INT_ARRAY_PRIMITIVE.write(buffer, value.parameters());
|
||||
Types.TAG.write(buffer, value.style());
|
||||
Types.TRUSTED_TAG.write(buffer, value.style());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -53,6 +53,6 @@ public final class EnumTypes {
|
||||
// Hardcoded registries
|
||||
public static final RegistryValueType VILLAGER_TYPE = new RegistryValueType(Key.of("villager_type"), "desert", "jungle", "plains", "savanna", "snow", "swamp", "taiga");
|
||||
public static final RegistryValueType POTION = new RegistryValueType(Key.of("potion"), "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(Key.of("mob_effect"), "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");
|
||||
public static final RegistryValueType MOB_EFFECT = new RegistryValueType(Key.of("mob_effect"), "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", "breath_of_the_nautilus");
|
||||
public static final RegistryValueType CONSUME_EFFECT = new RegistryValueType(Key.of("consume_effect_type"), "apply_effects", "remove_effects", "clear_all_effects", "teleport_randomly", "play_sound");
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public interface ViaInjector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the encoder for then netty pipeline for this platform.
|
||||
* Get the name of the encoder for the netty pipeline for this platform.
|
||||
*
|
||||
* @return The name
|
||||
*/
|
||||
@@ -88,7 +88,7 @@ public interface ViaInjector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the decoder for then netty pipeline for this platform.
|
||||
* Get the name of the decoder for the netty pipeline for this platform.
|
||||
*
|
||||
* @return The name
|
||||
*/
|
||||
|
||||
+44
-3
@@ -27,9 +27,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Wrapper class file for {@link com.google.common.collect.Range} to support multiple ranges. This class is used to
|
||||
* Wrapper class file for {@link Range} to support multiple ranges. This class is used to
|
||||
* compare {@link ProtocolVersion} objects.
|
||||
*/
|
||||
public class ProtocolVersionRange {
|
||||
@@ -43,7 +44,7 @@ public class ProtocolVersionRange {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a range that contains all versions.
|
||||
* Returns a range that contains all versions. Adding new ranges to this range is not supported.
|
||||
*
|
||||
* @return the range
|
||||
*/
|
||||
@@ -159,6 +160,46 @@ public class ProtocolVersionRange {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum version in this range. If there are multiple ranges, the lowest minimum is returned.
|
||||
*
|
||||
* @return the minimum version, or null if there is no minimum
|
||||
*/
|
||||
public @Nullable ProtocolVersion getMin() {
|
||||
ProtocolVersion min = null;
|
||||
if (this.ranges != null) {
|
||||
for (Range<ProtocolVersion> range : this.ranges) {
|
||||
if (range.hasLowerBound()) {
|
||||
ProtocolVersion rangeMin = range.lowerEndpoint();
|
||||
if (min == null || rangeMin.compareTo(min) < 0) {
|
||||
min = rangeMin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum version in this range. If there are multiple ranges, the highest maximum is returned.
|
||||
*
|
||||
* @return the maximum version, or null if there is no maximum
|
||||
*/
|
||||
public @Nullable ProtocolVersion getMax() {
|
||||
ProtocolVersion max = null;
|
||||
if (this.ranges != null) {
|
||||
for (Range<ProtocolVersion> range : this.ranges) {
|
||||
if (range.hasUpperBound()) {
|
||||
ProtocolVersion rangeMax = range.upperEndpoint();
|
||||
if (max == null || rangeMax.compareTo(max) > 0) {
|
||||
max = rangeMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.ranges != null) {
|
||||
@@ -197,7 +238,7 @@ public class ProtocolVersionRange {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a range from a string.
|
||||
* Parses a range from a string generated by {@link #toString()}.
|
||||
*
|
||||
* @param str the string
|
||||
* @return the range
|
||||
|
||||
@@ -117,8 +117,8 @@ 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;
|
||||
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.ResolvableProfileType;
|
||||
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;
|
||||
@@ -204,13 +204,19 @@ public final class Types {
|
||||
public static final Type<CompoundTag> OPTIONAL_NAMED_COMPOUND_TAG = new NamedCompoundTagType.OptionalNamedCompoundTagType();
|
||||
public static final Type<CompoundTag[]> NAMED_COMPOUND_TAG_ARRAY = new ArrayType<>(Types.NAMED_COMPOUND_TAG);
|
||||
public static final Type<CompoundTag> COMPOUND_TAG = new CompoundTagType();
|
||||
public static final Type<CompoundTag> OPTIONAL_COMPOUND_TAG = new CompoundTagType.OptionalCompoundTagType();
|
||||
public static final Type<CompoundTag> OPTIONAL_COMPOUND_TAG = CompoundTagType.OptionalCompoundTagType.type();
|
||||
|
||||
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> OPTIONAL_TAG = TagType.OptionalTagType.type();
|
||||
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<Tag> TRUSTED_TAG = new TagType(false);
|
||||
public static final Type<Tag> TRUSTED_OPTIONAL_TAG = TagType.OptionalTagType.trustedType();
|
||||
public static final Type<CompoundTag> TRUSTED_COMPOUND_TAG = new CompoundTagType(false);
|
||||
public static final Type<CompoundTag> TRUSTED_OPTIONAL_COMPOUND_TAG = CompoundTagType.OptionalCompoundTagType.trustedType();
|
||||
|
||||
public static final Type<GlobalBlockPosition> GLOBAL_POSITION = new GlobalBlockPositionType();
|
||||
public static final Type<GlobalBlockPosition> OPTIONAL_GLOBAL_POSITION = new GlobalBlockPositionType.OptionalGlobalPositionType();
|
||||
public static final Type<ChunkPosition> CHUNK_POSITION = new ChunkPositionType();
|
||||
|
||||
+18
-3
@@ -41,14 +41,21 @@ import java.util.Map;
|
||||
*/
|
||||
public class CompoundTagType extends Type<CompoundTag> {
|
||||
|
||||
private final int maxBytes;
|
||||
|
||||
public CompoundTagType() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public CompoundTagType(final boolean limitMaxBytes) {
|
||||
super(CompoundTag.class);
|
||||
this.maxBytes = limitMaxBytes ? NamedCompoundTagType.MAX_NBT_BYTES : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag read(final ByteBuf buffer) {
|
||||
try {
|
||||
return NamedCompoundTagType.read(buffer, false);
|
||||
return NamedCompoundTagType.read(buffer, this.maxBytes, false);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -74,8 +81,16 @@ public class CompoundTagType extends Type<CompoundTag> {
|
||||
|
||||
public static final class OptionalCompoundTagType extends OptionalType<CompoundTag> {
|
||||
|
||||
public OptionalCompoundTagType() {
|
||||
super(Types.COMPOUND_TAG);
|
||||
private OptionalCompoundTagType(final Type<CompoundTag> tagType) {
|
||||
super(tagType);
|
||||
}
|
||||
|
||||
public static OptionalCompoundTagType type() {
|
||||
return new OptionalCompoundTagType(Types.COMPOUND_TAG);
|
||||
}
|
||||
|
||||
public static OptionalCompoundTagType trustedType() {
|
||||
return new OptionalCompoundTagType(Types.TRUSTED_COMPOUND_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -46,7 +46,7 @@ public class NamedCompoundTagType extends Type<CompoundTag> {
|
||||
@Override
|
||||
public CompoundTag read(final ByteBuf buffer) {
|
||||
try {
|
||||
return read(buffer, true);
|
||||
return read(buffer, MAX_NBT_BYTES, true);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class NamedCompoundTagType extends Type<CompoundTag> {
|
||||
}
|
||||
}
|
||||
|
||||
public static CompoundTag read(final ByteBuf buffer, final boolean readName) throws IOException {
|
||||
public static CompoundTag read(final ByteBuf buffer, final int maxBytes, final boolean readName) throws IOException {
|
||||
final byte id = buffer.readByte();
|
||||
if (id == 0) {
|
||||
return null;
|
||||
@@ -74,7 +74,7 @@ public class NamedCompoundTagType extends Type<CompoundTag> {
|
||||
buffer.skipBytes(buffer.readUnsignedShort());
|
||||
}
|
||||
|
||||
final TagLimiter tagLimiter = TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL);
|
||||
final TagLimiter tagLimiter = TagLimiter.create(maxBytes, MAX_NESTING_LEVEL);
|
||||
return CompoundTag.read(new ByteBufInputStream(buffer), tagLimiter, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,15 @@ import java.util.Map;
|
||||
|
||||
public class TagType extends Type<Tag> {
|
||||
|
||||
private final int maxBytes;
|
||||
|
||||
public TagType() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public TagType(final boolean limitBytes) {
|
||||
super(Tag.class);
|
||||
this.maxBytes = limitBytes ? NamedCompoundTagType.MAX_NBT_BYTES : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,7 +68,7 @@ public class TagType extends Type<Tag> {
|
||||
return null;
|
||||
}
|
||||
|
||||
final TagLimiter tagLimiter = TagLimiter.create(NamedCompoundTagType.MAX_NBT_BYTES, NamedCompoundTagType.MAX_NESTING_LEVEL);
|
||||
final TagLimiter tagLimiter = TagLimiter.create(this.maxBytes, NamedCompoundTagType.MAX_NESTING_LEVEL);
|
||||
try {
|
||||
return TagRegistry.read(id, new ByteBufInputStream(buffer), tagLimiter, 0);
|
||||
} catch (final IOException e) {
|
||||
@@ -127,8 +134,16 @@ public class TagType extends Type<Tag> {
|
||||
|
||||
public static final class OptionalTagType extends OptionalType<Tag> {
|
||||
|
||||
public OptionalTagType() {
|
||||
super(Types.TAG);
|
||||
private OptionalTagType(final Type<Tag> tagType) {
|
||||
super(tagType);
|
||||
}
|
||||
|
||||
public static OptionalTagType type() {
|
||||
return new OptionalTagType(Types.TAG);
|
||||
}
|
||||
|
||||
public static OptionalTagType trustedType() {
|
||||
return new OptionalTagType(Types.TRUSTED_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -37,7 +37,7 @@ import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public final class BukkitEncodeHandler extends ViaEncodeHandler {
|
||||
private boolean handledCompression = BukkitChannelInitializer.COMPRESSION_ENABLED_EVENT != null;
|
||||
private boolean handledCompression = BukkitChannelInitializer.COMPRESSION_ENABLED_EVENT != null || Boolean.getBoolean("com.viaversion.disableLegacyCompressionReorder");
|
||||
|
||||
public BukkitEncodeHandler(final UserConnection connection) {
|
||||
super(connection);
|
||||
@@ -56,7 +56,7 @@ public final class BukkitEncodeHandler extends ViaEncodeHandler {
|
||||
|
||||
final ByteBuf transformedBuf = ByteBufUtil.copy(ctx.alloc(), bytebuf);
|
||||
try {
|
||||
final boolean needsCompression = !handledCompression && handleCompressionOrder(ctx, transformedBuf);
|
||||
final boolean needsCompression = !handledCompression && connection.getProtocolInfo().compressionEnabled() && handleCompressionOrder(ctx, transformedBuf);
|
||||
connection.transformClientbound(transformedBuf, CancelEncoderException::generate);
|
||||
if (needsCompression) {
|
||||
recompress(ctx, transformedBuf);
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.classgenerator.generated;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.bukkit.handlers.BukkitDecodeHandler;
|
||||
import com.viaversion.viaversion.bukkit.handlers.BukkitEncodeHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
|
||||
public interface HandlerSupplier {
|
||||
|
||||
MessageToMessageEncoder<ByteBuf> newEncodeHandler(UserConnection connection);
|
||||
|
||||
MessageToMessageDecoder<ByteBuf> newDecodeHandler(UserConnection connection);
|
||||
|
||||
final class DefaultHandlerSupplier implements HandlerSupplier {
|
||||
@Override
|
||||
public MessageToMessageEncoder<ByteBuf> newEncodeHandler(final UserConnection connection) {
|
||||
return new BukkitEncodeHandler(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageToMessageDecoder<ByteBuf> newDecodeHandler(final UserConnection connection) {
|
||||
return new BukkitDecodeHandler(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,11 @@ import java.util.Arrays;
|
||||
public final class HashBuilder {
|
||||
|
||||
private static final byte[] EMPTY_BYTES = new byte[0];
|
||||
private static final int MAX_RETAINED_CAPACITY = 4096;
|
||||
private final HashFunction hashFunction;
|
||||
private byte[] bytes = EMPTY_BYTES;
|
||||
private int index;
|
||||
private boolean direct;
|
||||
|
||||
public HashBuilder(final HashFunction hashFunction) {
|
||||
this.hashFunction = hashFunction;
|
||||
@@ -43,11 +45,17 @@ public final class HashBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given bytes directly, avoiding a copy if currently empty.
|
||||
*
|
||||
* @param bytes the bytes to write directly
|
||||
*/
|
||||
public void writeBytesDirect(final byte[] bytes) {
|
||||
if (this.bytes.length == 0) {
|
||||
// Set bytes directly if still empty
|
||||
this.bytes = bytes;
|
||||
this.index = bytes.length;
|
||||
this.direct = true;
|
||||
} else {
|
||||
writeBytes(bytes);
|
||||
}
|
||||
@@ -75,9 +83,11 @@ public final class HashBuilder {
|
||||
|
||||
public HashBuilder writeString(final CharSequence sequence) {
|
||||
final int length = sequence.length();
|
||||
this.ensureSize(length);
|
||||
this.ensureSize(length * 2);
|
||||
for (int i = 0; i < length; i++) {
|
||||
this.writeChar(sequence.charAt(i));
|
||||
final char c = sequence.charAt(i);
|
||||
this.bytes[this.index++] = (byte) c;
|
||||
this.bytes[this.index++] = (byte) (c >> 8);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -130,9 +140,11 @@ public final class HashBuilder {
|
||||
|
||||
private void ensureSize(final int bytes) {
|
||||
final int length = this.bytes.length;
|
||||
if (this.index + bytes > length) {
|
||||
final int newLength = Math.max(length * 2, this.index + bytes);
|
||||
final int required = this.index + bytes;
|
||||
if (required > length) {
|
||||
final int newLength = Math.max(length * 2, required);
|
||||
this.bytes = Arrays.copyOf(this.bytes, newLength);
|
||||
this.direct = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +154,11 @@ public final class HashBuilder {
|
||||
|
||||
public void reset() {
|
||||
this.index = 0;
|
||||
this.bytes = EMPTY_BYTES;
|
||||
// Discard the buffer if it was direct (externally owned) or exceeds max retained capacity
|
||||
if (this.direct || this.bytes.length > MAX_RETAINED_CAPACITY) {
|
||||
this.bytes = EMPTY_BYTES;
|
||||
this.direct = false;
|
||||
}
|
||||
}
|
||||
|
||||
public HashFunction function() {
|
||||
|
||||
@@ -64,24 +64,20 @@ public final class ConnectionDetails {
|
||||
return;
|
||||
}
|
||||
|
||||
final ProtocolInfo protocolInfo = connection.getProtocolInfo();
|
||||
final ProtocolVersion nativeVersion = protocolInfo.protocolVersion();
|
||||
final ProtocolVersion serverVersion = protocolInfo.serverProtocolVersion();
|
||||
if (serverVersion.equals(nativeVersion)) {
|
||||
// No need to send details if the native version is the same as the server version
|
||||
return;
|
||||
}
|
||||
final JsonObject payload = new JsonObject();
|
||||
payload.addProperty("specVersion", VERSION);
|
||||
|
||||
final String platformName = Via.getPlatform().getPlatformName();
|
||||
final String platformVersion = Via.getPlatform().getPlatformVersion();
|
||||
|
||||
final JsonObject payload = new JsonObject();
|
||||
payload.addProperty("specVersion", VERSION);
|
||||
final ProtocolInfo protocolInfo = connection.getProtocolInfo();
|
||||
final ProtocolVersion clientVersion = protocolInfo.protocolVersion();
|
||||
|
||||
payload.addProperty("platformName", platformName);
|
||||
payload.addProperty("platformVersion", platformVersion);
|
||||
payload.addProperty("version", nativeVersion.getOriginalVersion());
|
||||
payload.addProperty("versionName", nativeVersion.getName());
|
||||
payload.addProperty("version", clientVersion.getOriginalVersion());
|
||||
payload.addProperty("versionName", clientVersion.getName());
|
||||
payload.addProperty("versionType", clientVersion.getVersionType().name());
|
||||
|
||||
Via.getPlatform().sendCustomPayload(connection, channel, payload.toString().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
@@ -98,13 +94,14 @@ public final class ConnectionDetails {
|
||||
return;
|
||||
}
|
||||
|
||||
final ProtocolInfo protocolInfo = connection.getProtocolInfo();
|
||||
final ProtocolVersion serverVersion = protocolInfo.serverProtocolVersion();
|
||||
final JsonObject payload = new JsonObject();
|
||||
payload.addProperty("specVersion", VERSION);
|
||||
|
||||
final ProtocolInfo protocolInfo = connection.getProtocolInfo();
|
||||
final ProtocolVersion serverVersion = protocolInfo.serverProtocolVersion();
|
||||
payload.addProperty("version", serverVersion.getOriginalVersion());
|
||||
payload.addProperty("versionName", serverVersion.getName());
|
||||
payload.addProperty("versionType", serverVersion.getVersionType().name());
|
||||
|
||||
Via.getPlatform().sendCustomPayloadToClient(connection, channel, payload.toString().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public class ProtocolInfoImpl implements ProtocolInfo {
|
||||
private String username;
|
||||
private UUID uuid;
|
||||
private ProtocolPipeline pipeline;
|
||||
private boolean compressionEnabled;
|
||||
|
||||
@Override
|
||||
public State getClientState() {
|
||||
@@ -99,6 +100,16 @@ public class ProtocolInfoImpl implements ProtocolInfo {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compressionEnabled() {
|
||||
return compressionEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompressionEnabled(final boolean compressionEnabled) {
|
||||
this.compressionEnabled = compressionEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolPipeline getPipeline() {
|
||||
return pipeline;
|
||||
|
||||
+5
@@ -49,6 +49,11 @@ public abstract class UserConnectionViaVersionPlatform implements ViaPlatform<Us
|
||||
@Override
|
||||
public abstract Logger createLogger(String name);
|
||||
|
||||
@Override
|
||||
public boolean isProxy() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.platform;
|
||||
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.platform.ViaInjector;
|
||||
import com.viaversion.viaversion.connection.UserConnectionImpl;
|
||||
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -59,6 +62,30 @@ public abstract class ViaChannelInitializer extends ChannelInitializer<Channel>
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorders the ViaVersion handlers in the pipeline to be after the specified handlers. This is needed in platforms
|
||||
* where enabling the compression breaks the order of Via handlers to be: encoder -> compressor -> via encoder.
|
||||
*
|
||||
* @param pipeline The channel pipeline
|
||||
* @param compress The name of the compress handler where Via's encoder was initially placed after
|
||||
* @param decompress The name of the decompress handler where Via's decoder was initially placed after
|
||||
*/
|
||||
public static void reorderPipeline(final ChannelPipeline pipeline, final String compress, final String decompress) {
|
||||
final ViaInjector injector = Via.getManager().getInjector();
|
||||
final int decompressIndex = pipeline.names().indexOf(decompress);
|
||||
if (decompressIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (decompressIndex > pipeline.names().indexOf(injector.getDecoderName())) {
|
||||
final ChannelHandler encoderHandler = pipeline.remove(injector.getEncoderName());
|
||||
final ChannelHandler decoderHandler = pipeline.remove(injector.getDecoderName());
|
||||
|
||||
pipeline.addAfter(compress, injector.getEncoderName(), encoderHandler);
|
||||
pipeline.addAfter(decompress, injector.getDecoderName(), decoderHandler);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void injectPipeline(ChannelPipeline pipeline, UserConnection connection);
|
||||
|
||||
@Override
|
||||
|
||||
+5
@@ -128,6 +128,11 @@ public class ClientboundBaseProtocol1_7 extends AbstractProtocol<BaseClientbound
|
||||
}
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundLoginPackets.LOGIN_COMPRESSION, wrapper -> {
|
||||
final int threshold = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.user().getProtocolInfo().setCompressionEnabled(threshold >= 0);
|
||||
});
|
||||
|
||||
// Track player name/uuid and setup connection + track state
|
||||
registerClientbound(ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
|
||||
final ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
|
||||
+1
-4
@@ -67,10 +67,7 @@ public class ItemPacketRewriter1_11 extends ItemRewriter<ClientboundPackets1_9_3
|
||||
if (enchTag != null && enchTag.isEmpty()) {
|
||||
tag.putBoolean(nbtTagName("clearEnch"), true);
|
||||
|
||||
CompoundTag dummyTag = new CompoundTag();
|
||||
dummyTag.putShort("id", Short.MAX_VALUE);
|
||||
|
||||
enchTag.add(dummyTag);
|
||||
enchTag.add(new CompoundTag());
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
+9
-32
@@ -23,17 +23,18 @@ import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.minecraft.item.DataItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.StringType;
|
||||
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_17to1_17_1.packet.ClientboundPackets1_17_1;
|
||||
import com.viaversion.viaversion.protocols.v1_17to1_17_1.rewriter.ItemPacketRewriter1_17_1;
|
||||
|
||||
public final class Protocol1_17To1_17_1 extends AbstractProtocol<ClientboundPackets1_17, ClientboundPackets1_17_1, ServerboundPackets1_17, ServerboundPackets1_17> {
|
||||
|
||||
private static final StringType PAGE_STRING_TYPE = new StringType(8192);
|
||||
private static final StringType TITLE_STRING_TYPE = new StringType(128);
|
||||
private final ItemPacketRewriter1_17_1 itemRewriter = new ItemPacketRewriter1_17_1(this);
|
||||
|
||||
public Protocol1_17To1_17_1() {
|
||||
super(ClientboundPackets1_17.class, ClientboundPackets1_17_1.class, ServerboundPackets1_17.class, ServerboundPackets1_17.class);
|
||||
@@ -41,43 +42,14 @@ public final class Protocol1_17To1_17_1 extends AbstractProtocol<ClientboundPack
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
super.registerPackets();
|
||||
|
||||
registerClientbound(ClientboundPackets1_17.REMOVE_ENTITY, ClientboundPackets1_17_1.REMOVE_ENTITIES, wrapper -> {
|
||||
// Aaaaand back to an array again!
|
||||
int entityId = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, new int[]{entityId});
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_17.CONTAINER_SET_SLOT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Container id
|
||||
create(Types.VAR_INT, 0); // Add arbitrary state id
|
||||
}
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_17.CONTAINER_SET_CONTENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Container id
|
||||
create(Types.VAR_INT, 0); // Add arbitrary state id
|
||||
handler(wrapper -> {
|
||||
// Length encoded as var int now
|
||||
wrapper.write(Types.ITEM1_13_2_ARRAY, wrapper.read(Types.ITEM1_13_2_SHORT_ARRAY));
|
||||
|
||||
// Carried item - should work like this
|
||||
wrapper.write(Types.ITEM1_13_2, null);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
registerServerbound(ServerboundPackets1_17.CONTAINER_CLICK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Container id
|
||||
read(Types.VAR_INT); // Remove state id
|
||||
}
|
||||
});
|
||||
|
||||
registerServerbound(ServerboundPackets1_17.EDIT_BOOK, wrapper -> {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
Item item = new DataItem(942, (byte) 1, tag); // Magic value for writable books
|
||||
@@ -122,4 +94,9 @@ public final class Protocol1_17To1_17_1 extends AbstractProtocol<ClientboundPack
|
||||
wrapper.write(Types.VAR_INT, slot);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemPacketRewriter1_17_1 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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_17to1_17_1.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
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_17to1_17_1.Protocol1_17To1_17_1;
|
||||
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RecipeRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.Limit;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class ItemPacketRewriter1_17_1 extends ItemRewriter<ClientboundPackets1_17, ServerboundPackets1_17, Protocol1_17To1_17_1> {
|
||||
|
||||
public ItemPacketRewriter1_17_1(Protocol1_17To1_17_1 protocol) {
|
||||
super(protocol, Types.ITEM1_13_2, Types.ITEM1_13_2_SHORT_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
registerMerchantOffers(ClientboundPackets1_17.MERCHANT_OFFERS);
|
||||
registerSetEquipment(ClientboundPackets1_17.SET_EQUIPMENT);
|
||||
registerAdvancements(ClientboundPackets1_17.UPDATE_ADVANCEMENTS);
|
||||
|
||||
new RecipeRewriter<>(protocol).register(ClientboundPackets1_17.UPDATE_RECIPES);
|
||||
|
||||
registerSetCreativeModeSlot(ServerboundPackets1_17.SET_CREATIVE_MODE_SLOT);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_17.CONTAINER_SET_SLOT, wrapper -> {
|
||||
wrapper.passthrough(Types.BYTE); // Container id
|
||||
wrapper.write(Types.VAR_INT, 0); // Add arbitrary state id
|
||||
wrapper.passthrough(Types.SHORT); // Slot id
|
||||
passthroughClientboundItem(wrapper);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_17.CONTAINER_SET_CONTENT, wrapper -> {
|
||||
wrapper.passthrough(Types.UNSIGNED_BYTE); // Container id
|
||||
wrapper.write(Types.VAR_INT, 0); // Add arbitrary state id
|
||||
// Length encoded as var int now
|
||||
Item[] items = wrapper.passthroughAndMap(Types.ITEM1_13_2_SHORT_ARRAY, Types.ITEM1_13_2_ARRAY);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
|
||||
// Carried item - should work like this
|
||||
wrapper.write(Types.ITEM1_13_2, null);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_17.CONTAINER_CLICK, wrapper -> {
|
||||
wrapper.passthrough(Types.BYTE); // Container id
|
||||
wrapper.read(Types.VAR_INT); // Remove state id
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
wrapper.passthrough(Types.BYTE); // Button
|
||||
wrapper.passthrough(Types.VAR_INT); // Mode
|
||||
|
||||
// Affected items
|
||||
final int length = Limit.max(wrapper.passthrough(Types.VAR_INT), 128);
|
||||
for (int i = 0; i < length; i++) {
|
||||
wrapper.passthrough(Types.SHORT); // Slot
|
||||
wrapper.write(Types.ITEM1_13_2, handleItemToServer(wrapper.user(), wrapper.read(Types.ITEM1_13_2)));
|
||||
}
|
||||
|
||||
// Carried item
|
||||
wrapper.write(Types.ITEM1_13_2, handleItemToServer(wrapper.user(), wrapper.read(Types.ITEM1_13_2)));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item handleItemToClient(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
|
||||
final CompoundTag tag = item.tag();
|
||||
if (tag == null) {
|
||||
return item;
|
||||
}
|
||||
|
||||
int hideFlags = tag.getInt("HideFlags");
|
||||
if ((hideFlags & 1) == 0) {
|
||||
replaceInvalidEnchantments(tag, "Enchantments");
|
||||
}
|
||||
if ((hideFlags & 1 << 5) == 0) {
|
||||
replaceInvalidEnchantments(tag, "StoredEnchantments");
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Item handleItemToServer(final UserConnection connection, @Nullable final Item item) {
|
||||
if (item == null) return null;
|
||||
|
||||
final CompoundTag tag = item.tag();
|
||||
if (tag == null) {
|
||||
return item;
|
||||
}
|
||||
|
||||
restoreInvalidEnchantments(tag, "Enchantments");
|
||||
restoreInvalidEnchantments(tag, "StoredEnchantments");
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void replaceInvalidEnchantments(CompoundTag tag, String tagName) {
|
||||
final ListTag<CompoundTag> enchantments = tag.getListTag(tagName, CompoundTag.class);
|
||||
if (enchantments == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any enchantment has an invalid level
|
||||
boolean hasInvalidLevel = false;
|
||||
for (final CompoundTag enchantment : enchantments.getValue()) {
|
||||
final short lvl = enchantment.getShort("lvl");
|
||||
if (lvl < 0 || lvl > 255) {
|
||||
hasInvalidLevel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasInvalidLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
tag.put(nbtTagName(tagName), new ByteTag(true));
|
||||
|
||||
final int originalHideFlags = tag.getInt("HideFlags");
|
||||
tag.put(nbtTagName("HideFlags"), new ByteTag((byte) originalHideFlags));
|
||||
|
||||
final int hideBit = tagName.equals("Enchantments") ? 1 : (1 << 5);
|
||||
tag.put("HideFlags", new ByteTag((byte) (originalHideFlags | hideBit)));
|
||||
|
||||
CompoundTag display = tag.getCompoundTag("display");
|
||||
if (display != null) {
|
||||
tag.put(nbtTagName("display"), display.copy());
|
||||
} else {
|
||||
tag.put("display", display = new CompoundTag());
|
||||
}
|
||||
|
||||
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
|
||||
if (lore == null) {
|
||||
display.put("Lore", lore = new ListTag<>(StringTag.class));
|
||||
}
|
||||
|
||||
// Add all enchantments to lore in reverse order (so first enchantment ends up at top)
|
||||
for (int i = enchantments.size() - 1; i >= 0; i--) {
|
||||
final CompoundTag enchantment = enchantments.get(i);
|
||||
final String id = enchantment.getString("id");
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final short lvl = enchantment.getShort("lvl");
|
||||
final Key key = Key.of(id);
|
||||
lore.getValue().add(0, new StringTag("{\"italic\":false,\"color\":\"gray\",\"translate\":\"enchantment." + key.namespace() + "." + key.path() + "\",\"extra\":[\" \",{\"translate\":\"enchantment.level." + lvl + "\"}]}"));
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreInvalidEnchantments(final CompoundTag tag, final String tagName) {
|
||||
final Tag marker = tag.remove(nbtTagName(tagName));
|
||||
if (marker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Tag hideFlags = tag.remove(nbtTagName("HideFlags"));
|
||||
if (hideFlags != null) {
|
||||
if (((ByteTag) hideFlags).asByte() == 0) {
|
||||
tag.remove("HideFlags");
|
||||
} else {
|
||||
tag.put("HideFlags", hideFlags);
|
||||
}
|
||||
}
|
||||
|
||||
final Tag display = tag.remove(nbtTagName("display"));
|
||||
if (display != null) {
|
||||
tag.put("display", display);
|
||||
} else {
|
||||
tag.remove("display");
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -102,7 +102,7 @@ public final class Protocol1_20_2To1_20_3 extends AbstractProtocol<ClientboundPa
|
||||
wrapper.passthrough(Types.VAR_INT); // Score
|
||||
|
||||
// Null display and number format
|
||||
wrapper.write(Types.OPTIONAL_TAG, null);
|
||||
wrapper.write(Types.TRUSTED_OPTIONAL_TAG, null);
|
||||
wrapper.write(Types.BOOLEAN, false);
|
||||
});
|
||||
registerClientbound(ClientboundPackets1_20_2.SET_OBJECTIVE, wrapper -> {
|
||||
@@ -338,11 +338,11 @@ public final class Protocol1_20_2To1_20_3 extends AbstractProtocol<ClientboundPa
|
||||
}
|
||||
|
||||
private void convertComponent(final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.TAG, ComponentUtil.jsonToTag(wrapper.read(Types.COMPONENT)));
|
||||
wrapper.write(Types.TRUSTED_TAG, ComponentUtil.jsonToTag(wrapper.read(Types.COMPONENT)));
|
||||
}
|
||||
|
||||
private void convertOptionalComponent(final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.OPTIONAL_TAG, ComponentUtil.jsonToTag(wrapper.read(Types.OPTIONAL_COMPONENT)));
|
||||
wrapper.write(Types.TRUSTED_OPTIONAL_TAG, ComponentUtil.jsonToTag(wrapper.read(Types.OPTIONAL_COMPONENT)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_20_3.SERVER_DATA, wrapper -> {
|
||||
wrapper.passthrough(Types.TAG); // MOTD
|
||||
wrapper.passthrough(Types.TRUSTED_TAG); // MOTD
|
||||
wrapper.passthrough(Types.OPTIONAL_BYTE_ARRAY_PRIMITIVE); // Icon
|
||||
|
||||
// Moved to join game
|
||||
|
||||
+4
-4
@@ -163,14 +163,14 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag tag = wrapper.read(Types.COMPOUND_TAG);
|
||||
CompoundTag tag = wrapper.read(Types.TRUSTED_COMPOUND_TAG);
|
||||
if (tag != null) {
|
||||
updateBlockEntityTag(wrapper.user(), null, tag);
|
||||
} else {
|
||||
// No longer nullable
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
wrapper.write(Types.COMPOUND_TAG, tag);
|
||||
wrapper.write(Types.TRUSTED_COMPOUND_TAG, tag);
|
||||
});
|
||||
|
||||
registerCooldown(ClientboundPackets1_20_3.COOLDOWN);
|
||||
@@ -196,8 +196,8 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
wrapper.passthrough(Types.TAG); // Title
|
||||
wrapper.passthrough(Types.TAG); // Description
|
||||
wrapper.passthrough(Types.TRUSTED_TAG); // Title
|
||||
wrapper.passthrough(Types.TRUSTED_TAG); // Description
|
||||
|
||||
Item item = handleNonEmptyItemToClient(wrapper.user(), wrapper.read(itemType()));
|
||||
wrapper.write(mappedItemType(), item);
|
||||
|
||||
+4
-4
@@ -99,7 +99,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
particleRewriter.registerExplode1_20_5(ClientboundPackets1_20_5.EXPLODE); // Rewrites the included sound and particles
|
||||
|
||||
registerClientbound(ClientboundPackets1_20_5.DISGUISED_CHAT, wrapper -> {
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Message
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG)); // Message
|
||||
|
||||
// Holder time
|
||||
final int chatType = wrapper.read(Types.VAR_INT);
|
||||
@@ -121,7 +121,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
}
|
||||
}
|
||||
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Unsigned content
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Unsigned content
|
||||
|
||||
final int filterMaskType = wrapper.passthrough(Types.VAR_INT);
|
||||
if (filterMaskType == 2) {
|
||||
@@ -130,8 +130,8 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
|
||||
final int chatType = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(ChatType.TYPE, Holder.of(chatType));
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Target Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG)); // Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Target Name
|
||||
});
|
||||
|
||||
registerClientbound(ClientboundPackets1_20_5.UPDATE_ATTRIBUTES, wrapper -> {
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.BLOCK_ENTITY_DATA, wrapper -> {
|
||||
wrapper.passthrough(Types.BLOCK_POSITION1_14); // Position
|
||||
wrapper.passthrough(Types.VAR_INT); // Type
|
||||
wrapper.write(Types.COMPOUND_TAG, handleBlockEntity(wrapper.read(Types.NAMED_COMPOUND_TAG)));
|
||||
wrapper.write(Types.TRUSTED_COMPOUND_TAG, handleBlockEntity(wrapper.read(Types.NAMED_COMPOUND_TAG)));
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.LEVEL_CHUNK_WITH_LIGHT, wrapper -> {
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ public final class Protocol1_21_2To1_21_4 extends AbstractProtocol<ClientboundPa
|
||||
if (actions.get(4)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Latency
|
||||
}
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG));
|
||||
if (actions.get(6)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // List order
|
||||
}
|
||||
|
||||
+3
-3
@@ -140,7 +140,7 @@ public final class Protocol1_21_4To1_21_5 extends AbstractProtocol<ClientboundPa
|
||||
}
|
||||
}
|
||||
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Unsigned content
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Unsigned content
|
||||
|
||||
final int filterMaskType = wrapper.passthrough(Types.VAR_INT);
|
||||
if (filterMaskType == 2) { // Partially filtered
|
||||
@@ -148,8 +148,8 @@ public final class Protocol1_21_4To1_21_5 extends AbstractProtocol<ClientboundPa
|
||||
}
|
||||
|
||||
wrapper.passthrough(ChatType.TYPE); // Chat Type
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Target Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG)); // Name
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Target Name
|
||||
});
|
||||
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND_SIGNED, wrapper -> {
|
||||
wrapper.passthrough(Types.STRING); // Command
|
||||
|
||||
+2
-2
@@ -211,8 +211,8 @@ public final class BlockItemPacketRewriter1_21_5 extends StructuredItemRewriter<
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
final Tag title = wrapper.passthrough(Types.TAG);
|
||||
final Tag description = wrapper.passthrough(Types.TAG);
|
||||
final Tag title = wrapper.passthrough(Types.TRUSTED_TAG);
|
||||
final Tag description = wrapper.passthrough(Types.TRUSTED_TAG);
|
||||
final ComponentRewriter componentRewriter = protocol.getComponentRewriter();
|
||||
if (componentRewriter != null) {
|
||||
componentRewriter.processTag(wrapper.user(), title);
|
||||
|
||||
+1
-2
@@ -46,7 +46,6 @@ import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundCon
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.rewriter.BlockItemPacketRewriter1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.rewriter.ComponentRewriter1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.rewriter.EntityPacketRewriter1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.storage.SneakStorage;
|
||||
import com.viaversion.viaversion.rewriter.AttributeRewriter;
|
||||
@@ -68,7 +67,7 @@ public final class Protocol1_21_5To1_21_6 extends AbstractProtocol<ClientboundPa
|
||||
private final BlockItemPacketRewriter1_21_6 itemRewriter = new BlockItemPacketRewriter1_21_6(this);
|
||||
private final ParticleRewriter<ClientboundPacket1_21_5> particleRewriter = new ParticleRewriter<>(this);
|
||||
private final TagRewriter<ClientboundPacket1_21_5> tagRewriter = new TagRewriter<>(this);
|
||||
private final NBTComponentRewriter<ClientboundPacket1_21_5> componentRewriter = new ComponentRewriter1_21_6(this);
|
||||
private final NBTComponentRewriter<ClientboundPacket1_21_5> componentRewriter = new NBTComponentRewriter<>(this);
|
||||
private final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(this);
|
||||
|
||||
public Protocol1_21_5To1_21_6() {
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_21_5to1_21_6.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPacket1_21_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.Protocol1_21_5To1_21_6;
|
||||
import com.viaversion.viaversion.rewriter.text.NBTComponentRewriter;
|
||||
|
||||
public final class ComponentRewriter1_21_6 extends NBTComponentRewriter<ClientboundPacket1_21_5> {
|
||||
|
||||
public ComponentRewriter1_21_6(final Protocol1_21_5To1_21_6 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
|
||||
super.handleShowItem(connection, itemTag, componentsTag);
|
||||
if (componentsTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove or update data from componentsTag
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -40,6 +40,7 @@ import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.storage.DimensionScal
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
|
||||
import com.viaversion.viaversion.rewriter.block.BlockRewriter1_21_5;
|
||||
|
||||
public final class BlockItemPacketRewriter1_21_9 extends StructuredItemRewriter<ClientboundPacket1_21_6, ServerboundPacket1_21_9, Protocol1_21_7To1_21_9> {
|
||||
|
||||
@@ -49,7 +50,7 @@ public final class BlockItemPacketRewriter1_21_9 extends StructuredItemRewriter<
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
final BlockRewriter<ClientboundPacket1_21_6> blockRewriter = BlockRewriter.for1_20_2(protocol);
|
||||
final BlockRewriter<ClientboundPacket1_21_6> blockRewriter = new BlockRewriter1_21_5<>(protocol);
|
||||
blockRewriter.registerBlockEvent(ClientboundPackets1_21_6.BLOCK_EVENT);
|
||||
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_6.BLOCK_UPDATE);
|
||||
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_6.SECTION_BLOCKS_UPDATE);
|
||||
|
||||
+104
-3
@@ -67,6 +67,7 @@ import com.viaversion.viaversion.rewriter.text.NBTComponentRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@@ -75,6 +76,7 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
public final class Protocol1_21_9To1_21_11 extends AbstractProtocol<ClientboundPacket1_21_9, ClientboundPacket1_21_11, ServerboundPacket1_21_9, ServerboundPacket1_21_9> {
|
||||
|
||||
public static final MappingData1_21_11 MAPPINGS = new MappingData1_21_11();
|
||||
private static final Set<String> REMOVE_SKY_COLOR_FROM_BIOMES = Set.of("warped_forest", "basalt_deltas", "nether_wastes", "soul_sand_valley", "crimson_forest"); // rendered via the already defined fog instead
|
||||
private final EntityPacketRewriter1_21_11 entityRewriter = new EntityPacketRewriter1_21_11(this);
|
||||
private final BlockItemPacketRewriter1_21_11 itemRewriter = new BlockItemPacketRewriter1_21_11(this);
|
||||
private final ParticleRewriter<ClientboundPacket1_21_9> particleRewriter = new ParticleRewriter<>(this);
|
||||
@@ -115,8 +117,9 @@ public final class Protocol1_21_9To1_21_11 extends AbstractProtocol<ClientboundP
|
||||
final CompoundTag attributes = new CompoundTag();
|
||||
tag.put("attributes", attributes);
|
||||
|
||||
// Fill in the new defaults
|
||||
if (Key.equals(key, "the_nether")) {
|
||||
tag.put("timelines", new ListTag<>(List.of(new StringTag("villager_schedule"))));
|
||||
tag.put("timelines", new ListTag<>(List.of(new StringTag("villager_schedule")))); // inline the actual tag values
|
||||
tag.putString("skybox", "none");
|
||||
tag.putString("cardinal_light", "nether");
|
||||
attributes.putString("visual/sky_light_color", "#7a7aff");
|
||||
@@ -129,11 +132,29 @@ public final class Protocol1_21_9To1_21_11 extends AbstractProtocol<ClientboundP
|
||||
attributes.putString("visual/fog_color", "#181318");
|
||||
attributes.putString("visual/sky_color", "#000000");
|
||||
attributes.putString("visual/sky_light_color", "#e580ff");
|
||||
addAmbientCaveSound(attributes);
|
||||
|
||||
final CompoundTag backgroundMusic = new CompoundTag();
|
||||
backgroundMusic.put("default", backgroundMusicEntry("music.game", false, 12000));
|
||||
backgroundMusic.put("creative", backgroundMusicEntry("music.creative", false, 12000));
|
||||
attributes.put("audio/background_music", backgroundMusic);
|
||||
} else {
|
||||
final ListTag<StringTag> timelines = new ListTag<>(List.of(new StringTag("day"), new StringTag("moon"), new StringTag("early_game")));
|
||||
tag.put("timelines", timelines);
|
||||
attributes.putString("visual/fog_color", "#c0d8ff");
|
||||
attributes.putString("visual/sky_color", "#78a7ff");
|
||||
addAmbientCaveSound(attributes);
|
||||
|
||||
final CompoundTag backgroundMusic = new CompoundTag();
|
||||
backgroundMusic.put("default", backgroundMusicEntry("music.end", true, 6000));
|
||||
attributes.put("audio/background_music", backgroundMusic);
|
||||
}
|
||||
|
||||
// Migrate existing values
|
||||
final Tag fixedTime = tag.remove("fixed_time");
|
||||
if (fixedTime != null) {
|
||||
tag.putBoolean("has_fixed_time", true);
|
||||
}
|
||||
if (!tag.getBoolean("natural")) {
|
||||
attributes.putFloat("visual/sky_light_factor", 0F);
|
||||
}
|
||||
@@ -144,7 +165,7 @@ public final class Protocol1_21_9To1_21_11 extends AbstractProtocol<ClientboundP
|
||||
}
|
||||
|
||||
moveAttribute(tag, attributes, "cloud_height", "visual/cloud_height", cloudHeight -> {
|
||||
if (cloudHeight instanceof NumberTag numberTag) {
|
||||
if (cloudHeight instanceof final NumberTag numberTag) {
|
||||
attributes.putString("visual/cloud_color", "#ccffffff");
|
||||
return new FloatTag(numberTag.asFloat());
|
||||
}
|
||||
@@ -160,11 +181,69 @@ public final class Protocol1_21_9To1_21_11 extends AbstractProtocol<ClientboundP
|
||||
final CompoundTag effects = tag.getCompoundTag("effects");
|
||||
final CompoundTag attributes = new CompoundTag();
|
||||
tag.put("attributes", attributes);
|
||||
moveAttribute(effects, attributes, "sky_color", "visual/sky_color", Function.identity(), new IntTag(0));
|
||||
|
||||
// Move color attributes
|
||||
if (!REMOVE_SKY_COLOR_FROM_BIOMES.contains(Key.stripMinecraftNamespace(key))) {
|
||||
moveAttribute(effects, attributes, "sky_color", "visual/sky_color", Function.identity(), new IntTag(0));
|
||||
}
|
||||
if (!Key.equals(key, "the_end")) {
|
||||
moveAttribute(effects, attributes, "water_fog_color", "visual/water_fog_color", Function.identity(), new IntTag(-16448205));
|
||||
moveAttribute(effects, attributes, "fog_color", "visual/fog_color", Function.identity(), new IntTag(0));
|
||||
}
|
||||
|
||||
// Move music and sound attributes
|
||||
final ListTag<CompoundTag> musicTag = effects.getListTag("music", CompoundTag.class);
|
||||
if (musicTag != null && !musicTag.isEmpty()) {
|
||||
final CompoundTag data = musicTag.get(0).getCompoundTag("data");
|
||||
if (data != null) {
|
||||
final CompoundTag defaultMusic = new CompoundTag();
|
||||
final Tag maxDelay = data.get("max_delay");
|
||||
final Tag minDelay = data.get("min_delay");
|
||||
final Tag sound = data.get("sound");
|
||||
if (maxDelay != null) {
|
||||
defaultMusic.put("max_delay", maxDelay);
|
||||
}
|
||||
if (minDelay != null) {
|
||||
defaultMusic.put("min_delay", minDelay);
|
||||
}
|
||||
if (sound != null) {
|
||||
defaultMusic.put("sound", sound);
|
||||
}
|
||||
|
||||
final CompoundTag backgroundMusic = new CompoundTag();
|
||||
backgroundMusic.put("default", defaultMusic);
|
||||
attributes.put("audio/background_music", backgroundMusic);
|
||||
}
|
||||
}
|
||||
|
||||
final CompoundTag ambientSounds = new CompoundTag();
|
||||
final Tag moodSound = effects.get("mood_sound");
|
||||
if (moodSound != null) {
|
||||
ambientSounds.put("mood", moodSound);
|
||||
}
|
||||
final Tag additionsSound = effects.get("additions_sound");
|
||||
if (additionsSound != null) {
|
||||
ambientSounds.put("additions", additionsSound);
|
||||
}
|
||||
final Tag loopSound = effects.get("ambient_sound");
|
||||
if (loopSound != null) {
|
||||
ambientSounds.put("loop", loopSound);
|
||||
}
|
||||
if (!ambientSounds.isEmpty()) {
|
||||
attributes.put("audio/ambient_sounds", ambientSounds);
|
||||
}
|
||||
|
||||
// Move particles
|
||||
final CompoundTag particleTag = effects.getCompoundTag("particle");
|
||||
if (particleTag != null) {
|
||||
final CompoundTag entry = new CompoundTag();
|
||||
entry.put("probability", particleTag.get("probability"));
|
||||
entry.put("particle", particleTag.get("options"));
|
||||
|
||||
final ListTag<CompoundTag> ambientParticles = new ListTag<>(CompoundTag.class);
|
||||
ambientParticles.add(entry);
|
||||
attributes.put("visual/ambient_particles", ambientParticles);
|
||||
}
|
||||
});
|
||||
registerClientbound(ClientboundConfigurationPackets1_21_9.REGISTRY_DATA, registryDataRewriter::handle);
|
||||
|
||||
@@ -199,6 +278,28 @@ public final class Protocol1_21_9To1_21_11 extends AbstractProtocol<ClientboundP
|
||||
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21_9.UPDATE_ATTRIBUTES);
|
||||
}
|
||||
|
||||
private void addAmbientCaveSound(final CompoundTag attributes) {
|
||||
final CompoundTag ambientSounds = new CompoundTag();
|
||||
final CompoundTag moodSound = new CompoundTag();
|
||||
moodSound.putInt("tick_delay", 6000);
|
||||
moodSound.putFloat("offset", 2);
|
||||
moodSound.putString("sound", "ambient.cave");
|
||||
moodSound.putInt("block_search_extent", 8);
|
||||
ambientSounds.put("mood", moodSound);
|
||||
attributes.put("audio/ambient_sounds", ambientSounds);
|
||||
}
|
||||
|
||||
private CompoundTag backgroundMusicEntry(final String soundKey, final boolean replaceCurrentMusic, final int minDelay) {
|
||||
final CompoundTag sound = new CompoundTag();
|
||||
if (replaceCurrentMusic) {
|
||||
sound.putBoolean("replace_current_music", true);
|
||||
}
|
||||
sound.putInt("max_delay", 24000);
|
||||
sound.putString("sound", soundKey);
|
||||
sound.putInt("min_delay", minDelay);
|
||||
return sound;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMappingDataLoaded() {
|
||||
EntityTypes1_21_11.initialize(this);
|
||||
|
||||
+2
-1
@@ -36,6 +36,7 @@ import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.storage.GameTimeStor
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
|
||||
import com.viaversion.viaversion.rewriter.block.BlockRewriter1_21_5;
|
||||
|
||||
public final class BlockItemPacketRewriter1_21_11 extends StructuredItemRewriter<ClientboundPacket1_21_9, ServerboundPacket1_21_9, Protocol1_21_9To1_21_11> {
|
||||
|
||||
@@ -45,7 +46,7 @@ public final class BlockItemPacketRewriter1_21_11 extends StructuredItemRewriter
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
final BlockRewriter<ClientboundPacket1_21_9> blockRewriter = BlockRewriter.for1_20_2(protocol);
|
||||
final BlockRewriter<ClientboundPacket1_21_9> blockRewriter = new BlockRewriter1_21_5<>(protocol);
|
||||
blockRewriter.registerBlockEvent(ClientboundPackets1_21_9.BLOCK_EVENT);
|
||||
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_9.BLOCK_UPDATE);
|
||||
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_9.SECTION_BLOCKS_UPDATE);
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
|
||||
if (actions.get(4)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Latency
|
||||
}
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+3
@@ -567,6 +567,9 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
|
||||
dataContainer.set(StructuredDataKey.V1_21_2.useRemainder, food.usingConvertsTo());
|
||||
}
|
||||
return new FoodProperties1_21_2(food.nutrition(), food.saturationModifier(), food.canAlwaysEat());
|
||||
}, () -> {
|
||||
dataContainer.setEmpty(StructuredDataKey.CONSUMABLE1_21_2);
|
||||
dataContainer.setEmpty(StructuredDataKey.V1_21_2.useRemainder);
|
||||
});
|
||||
dataContainer.replaceKey(StructuredDataKey.POTION_CONTENTS1_20_5, StructuredDataKey.POTION_CONTENTS1_21_2);
|
||||
dataContainer.replace(StructuredDataKey.FIRE_RESISTANT, StructuredDataKey.DAMAGE_RESISTANT, fireResistant -> new DamageResistant(Key.of("minecraft:is_fire")));
|
||||
|
||||
+32
-16
@@ -34,23 +34,31 @@ import java.util.zip.Inflater;
|
||||
|
||||
public class CompressionProvider implements Provider {
|
||||
public void handlePlayCompression(UserConnection user, int threshold) {
|
||||
if (!user.isClientSide()) throw new IllegalStateException("PLAY state Compression packet is unsupported");
|
||||
if (!user.isClientSide()) {
|
||||
throw new IllegalStateException("PLAY state Compression packet is unsupported");
|
||||
}
|
||||
|
||||
ChannelPipeline pipe = user.getChannel().pipeline();
|
||||
|
||||
if (threshold < 0) {
|
||||
if (pipe.get("compress") != null) {
|
||||
pipe.remove("compress");
|
||||
pipe.remove("decompress");
|
||||
}
|
||||
} else {
|
||||
if (pipe.get("compress") == null) {
|
||||
pipe.addBefore(Via.getManager().getInjector().getEncoderName(), "compress", getEncoder(threshold));
|
||||
pipe.addBefore(Via.getManager().getInjector().getDecoderName(), "decompress", getDecoder(threshold));
|
||||
} else {
|
||||
((CompressionHandler) pipe.get("compress")).setCompressionThreshold(threshold);
|
||||
((CompressionHandler) pipe.get("decompress")).setCompressionThreshold(threshold);
|
||||
}
|
||||
removeHandlers(pipe);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipe.get(getCompressName()) instanceof CompressionHandler compressionHandler) {
|
||||
compressionHandler.setCompressionThreshold(threshold);
|
||||
((CompressionHandler) pipe.get(getDecompressName())).setCompressionThreshold(threshold);
|
||||
return;
|
||||
}
|
||||
|
||||
removeHandlers(pipe);
|
||||
pipe.addBefore(Via.getManager().getInjector().getEncoderName(), getCompressName(), getEncoder(threshold));
|
||||
pipe.addBefore(Via.getManager().getInjector().getDecoderName(), getDecompressName(), getDecoder(threshold));
|
||||
}
|
||||
|
||||
private void removeHandlers(ChannelPipeline pipeline) {
|
||||
if (pipeline.get(getCompressName()) != null) {
|
||||
pipeline.remove(getCompressName());
|
||||
pipeline.remove(getDecompressName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,12 +70,20 @@ public class CompressionProvider implements Provider {
|
||||
return new Decompressor(threshold);
|
||||
}
|
||||
|
||||
protected String getCompressName() {
|
||||
return "compress";
|
||||
}
|
||||
|
||||
protected String getDecompressName() {
|
||||
return "decompress";
|
||||
}
|
||||
|
||||
public interface CompressionHandler extends ChannelHandler {
|
||||
void setCompressionThreshold(int threshold);
|
||||
}
|
||||
|
||||
private static class Decompressor extends MessageToMessageDecoder<ByteBuf> implements CompressionHandler {
|
||||
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
|
||||
|
||||
private final Inflater inflater;
|
||||
private int threshold;
|
||||
|
||||
@@ -118,7 +134,7 @@ public class CompressionProvider implements Provider {
|
||||
}
|
||||
|
||||
private static class Compressor extends MessageToByteEncoder<ByteBuf> implements CompressionHandler {
|
||||
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
|
||||
|
||||
private final Deflater deflater;
|
||||
private int threshold;
|
||||
|
||||
|
||||
+5
-2
@@ -331,9 +331,12 @@ public class PlayerPacketRewriter1_9 {
|
||||
/* Removed packets */
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_COMPRESSION, null, wrapper -> {
|
||||
wrapper.cancel();
|
||||
CompressionProvider provider = Via.getManager().getProviders().get(CompressionProvider.class);
|
||||
|
||||
provider.handlePlayCompression(wrapper.user(), wrapper.read(Types.VAR_INT));
|
||||
int threshold = wrapper.read(Types.VAR_INT);
|
||||
wrapper.user().getProtocolInfo().setCompressionEnabled(threshold >= 0);
|
||||
|
||||
CompressionProvider provider = Via.getManager().getProviders().get(CompressionProvider.class);
|
||||
provider.handlePlayCompression(wrapper.user(), threshold);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -472,8 +472,8 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
final Tag title = wrapper.passthrough(Types.TAG);
|
||||
final Tag description = wrapper.passthrough(Types.TAG);
|
||||
final Tag title = wrapper.passthrough(Types.TRUSTED_TAG);
|
||||
final Tag description = wrapper.passthrough(Types.TRUSTED_TAG);
|
||||
final ComponentRewriter componentRewriter = protocol.getComponentRewriter();
|
||||
if (componentRewriter != null) {
|
||||
componentRewriter.processTag(wrapper.user(), title);
|
||||
|
||||
+36
-7
@@ -116,6 +116,14 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
wrapper.passthrough(Types.STRING); // Objective name
|
||||
wrapper.passthrough(Types.VAR_INT); // Score
|
||||
passthroughAndProcessOptional(wrapper);
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
final int numberFormatType = wrapper.passthrough(Types.VAR_INT);
|
||||
if (numberFormatType == 1) { // styled
|
||||
passthroughAndProcess(wrapper); // Only contains the style
|
||||
} else if (numberFormatType == 2) { // fixed
|
||||
passthroughAndProcess(wrapper);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -179,7 +187,7 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
wrapper.passthrough(Types.VAR_INT); // Latency
|
||||
}
|
||||
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG));
|
||||
|
||||
if (actions.get(6)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // List order
|
||||
@@ -210,14 +218,14 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
public void passthroughAndProcess(final PacketWrapper wrapper) {
|
||||
switch (type) {
|
||||
case JSON -> processText(wrapper.user(), wrapper.passthrough(Types.COMPONENT));
|
||||
case NBT -> processTag(wrapper.user(), wrapper.passthrough(Types.TAG));
|
||||
case NBT -> processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG));
|
||||
}
|
||||
}
|
||||
|
||||
public void passthroughAndProcessOptional(final PacketWrapper wrapper) {
|
||||
switch (type) {
|
||||
case JSON -> processText(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_COMPONENT));
|
||||
case NBT -> processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
case NBT -> processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,8 +360,12 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
return;
|
||||
}
|
||||
|
||||
handleAttributeModifiers(componentsTag);
|
||||
handleNestedComponent(connection, TagUtil.getNamespacedTag(componentsTag, "item_name"));
|
||||
handleNestedComponent(connection, TagUtil.getNamespacedTag(componentsTag, "custom_name"));
|
||||
handleLore(connection, componentsTag);
|
||||
handleWrittenBookContents(connection, componentsTag);
|
||||
|
||||
handleAttributeModifiers(componentsTag);
|
||||
handleContainerContents(connection, componentsTag);
|
||||
handleItemArrayContents(connection, componentsTag, "bundle_contents");
|
||||
handleItemArrayContents(connection, componentsTag, "charged_projectiles");
|
||||
@@ -401,6 +413,17 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleLore(final UserConnection connection, final CompoundTag tag) {
|
||||
final ListTag<? extends Tag> loreTag = TagUtil.getNamespacedTagList(tag, "lore");
|
||||
if (loreTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final Tag lore : loreTag) {
|
||||
handleNestedComponent(connection, lore);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleWrittenBookContents(final UserConnection connection, final CompoundTag tag) {
|
||||
final CompoundTag book = TagUtil.getNamespacedCompoundTag(tag, "written_book_content");
|
||||
if (book == null) {
|
||||
@@ -413,8 +436,8 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
}
|
||||
|
||||
for (final CompoundTag compoundTag : pagesTag) {
|
||||
handleNestedComponent(connection, compoundTag, "raw");
|
||||
handleNestedComponent(connection, compoundTag, "filtered");
|
||||
handleNestedComponent(connection, compoundTag.get("raw"));
|
||||
handleNestedComponent(connection, compoundTag.get("filtered"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +478,13 @@ public abstract class ComponentRewriterBase<C extends ClientboundPacketType> imp
|
||||
|| tag.remove("!" + Key.stripMinecraftNamespace(key)) != null;
|
||||
}
|
||||
|
||||
protected abstract void handleNestedComponent(UserConnection connection, CompoundTag parent, String key);
|
||||
/**
|
||||
* Rewrites a nested text component. Stored as a regular tag in 1.21.5+, but is nested via snbt in string components before that.
|
||||
*
|
||||
* @param connection user connection
|
||||
* @param tag nested tag to handle
|
||||
*/
|
||||
protected abstract void handleNestedComponent(UserConnection connection, @Nullable Tag tag);
|
||||
|
||||
public enum ReadType {
|
||||
|
||||
|
||||
+8
-9
@@ -112,7 +112,7 @@ public class JsonNBTComponentRewriter<C extends ClientboundPacketType> extends C
|
||||
if (actions.get(4)) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Latency
|
||||
}
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG));
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class JsonNBTComponentRewriter<C extends ClientboundPacketType> extends C
|
||||
}
|
||||
}
|
||||
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Unsigned content
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Unsigned content
|
||||
|
||||
final int filterMaskType = wrapper.passthrough(Types.VAR_INT);
|
||||
if (filterMaskType == 2) { // Partially filtered
|
||||
@@ -142,8 +142,8 @@ public class JsonNBTComponentRewriter<C extends ClientboundPacketType> extends C
|
||||
}
|
||||
|
||||
wrapper.passthrough(chatType); // Chat Type
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Name
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Target Name
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG)); // Name
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Target Name
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,9 +203,8 @@ public class JsonNBTComponentRewriter<C extends ClientboundPacketType> extends C
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleNestedComponent(final UserConnection connection, final CompoundTag parent, final String key) {
|
||||
final StringTag tag = parent.getStringTag(key);
|
||||
if (tag == null) {
|
||||
protected void handleNestedComponent(final UserConnection connection, @Nullable final Tag tag) {
|
||||
if (!(tag instanceof StringTag stringTag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -213,10 +212,10 @@ public class JsonNBTComponentRewriter<C extends ClientboundPacketType> extends C
|
||||
final var input = inputSerializerVersion();
|
||||
final var output = outputSerializerVersion();
|
||||
|
||||
final Tag asTag = input.toTag(input.toComponent(tag.getValue()));
|
||||
final Tag asTag = input.toTag(input.toComponent(stringTag.getValue()));
|
||||
processTag(connection, asTag);
|
||||
|
||||
tag.setValue(output.toString(output.toComponent(asTag)));
|
||||
stringTag.setValue(output.toString(output.toComponent(asTag)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-8
@@ -26,6 +26,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.ChatType;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Rewrites nbt serialized components from 1.21.5 upwards. Can also handle json components outside of hover events.
|
||||
@@ -68,11 +69,8 @@ public class NBTComponentRewriter<C extends ClientboundPacketType> extends Compo
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleNestedComponent(final UserConnection connection, final CompoundTag parent, final String key) {
|
||||
final Tag tag = parent.get(key);
|
||||
if (tag != null) {
|
||||
processTag(connection, tag);
|
||||
}
|
||||
protected void handleNestedComponent(final UserConnection connection, @Nullable final Tag tag) {
|
||||
processTag(connection, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +96,7 @@ public class NBTComponentRewriter<C extends ClientboundPacketType> extends Compo
|
||||
}
|
||||
}
|
||||
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Unsigned content
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Unsigned content
|
||||
|
||||
final int filterMaskType = wrapper.passthrough(Types.VAR_INT);
|
||||
if (filterMaskType == 2) { // Partially filtered
|
||||
@@ -106,8 +104,8 @@ public class NBTComponentRewriter<C extends ClientboundPacketType> extends Compo
|
||||
}
|
||||
|
||||
wrapper.passthrough(ChatType.TYPE); // Chat Type
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Name
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Target Name
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_TAG)); // Name
|
||||
processTag(wrapper.user(), wrapper.passthrough(Types.TRUSTED_OPTIONAL_TAG)); // Target Name
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.logging.Logger;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
@@ -139,9 +139,9 @@ public abstract class Config extends ConfigSection {
|
||||
|
||||
handleConfig(mergedConfig);
|
||||
|
||||
if (!mergedConfig.equals(existingConfig)) {
|
||||
originalRoot = existingConfig != null ? new ConfigSection(this, "", existingConfig) : null;
|
||||
originalRoot = existingConfig != null ? new ConfigSection(this, "", existingConfig) : null;
|
||||
|
||||
if (!mergedConfig.equals(existingConfig)) {
|
||||
// Also updates comments once values need to be saved
|
||||
save(location, mergedConfig);
|
||||
}
|
||||
@@ -212,7 +212,7 @@ public abstract class Config extends ConfigSection {
|
||||
if (this.configFile.getParentFile() != null) {
|
||||
this.configFile.getParentFile().mkdirs();
|
||||
}
|
||||
this.values = new ConcurrentSkipListMap<>(loadConfig(this.configFile));
|
||||
this.values = Collections.synchronizedMap(loadConfig(this.configFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,7 +228,7 @@ public abstract class Config extends ConfigSection {
|
||||
/**
|
||||
* Returns the pre-modification root section of the config if present.
|
||||
*
|
||||
* @return pre-modification root section, or null if no config existed or it did not require changes on load
|
||||
* @return pre-modification root section, or null if no config existed
|
||||
*/
|
||||
public @Nullable ConfigSection originalRootSection() {
|
||||
return originalRoot;
|
||||
|
||||
@@ -75,6 +75,11 @@ public final class TagUtil {
|
||||
return compoundTag != null ? compoundTag : tag.getCompoundTag(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public static @Nullable ListTag<? extends Tag> getNamespacedTagList(final CompoundTag tag, final String key) {
|
||||
final ListTag<? extends Tag> listTag = tag.getListTag(Key.namespaced(key));
|
||||
return listTag != null ? listTag : tag.getListTag(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public static @Nullable ListTag<CompoundTag> getNamespacedCompoundTagList(final CompoundTag tag, final String key) {
|
||||
final ListTag<CompoundTag> listTag = tag.getListTag(Key.namespaced(key), CompoundTag.class);
|
||||
return listTag != null ? listTag : tag.getListTag(Key.stripMinecraftNamespace(key), CompoundTag.class);
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
|
||||
projectVersion=5.7.1
|
||||
projectVersion=5.7.2
|
||||
|
||||
# Smile emoji (note that modrinth may not have added the version on release yet)
|
||||
mcVersions=1.21.11, 1.21.10, 1.21.9, 1.21.8, 1.21.7, 1.21.6, 1.21.5, 1.21.4, 1.21.3, 1.21.2, 1.21.1, 1.21, 1.20.6, 1.20.5, 1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
|
||||
mcVersionRange=1.8-1.21.11
|
||||
velocityVersion=3.4
|
||||
velocityVersion=3.4-3.5
|
||||
|
||||
# Gradle properties
|
||||
org.gradle.daemon=true
|
||||
|
||||
@@ -2,7 +2,7 @@ metadata.format.version = "1.1"
|
||||
|
||||
[versions]
|
||||
|
||||
gson = "2.13.1"
|
||||
gson = "2.13.2"
|
||||
snakeYaml = "2.5"
|
||||
fastutil = "8.5.15"
|
||||
vianbt = "5.1.2"
|
||||
@@ -12,14 +12,14 @@ mcstructs = "5-3.2.2-SNAPSHOT"
|
||||
netty = "4.0.20.Final"
|
||||
guava = "17.0"
|
||||
|
||||
junit = "6.0.1"
|
||||
junit = "6.0.2"
|
||||
platformLauncher = "6.0.1"
|
||||
checkerQual = "3.52.1"
|
||||
|
||||
# Platforms
|
||||
paper = "1.20.4-R0.1-SNAPSHOT"
|
||||
legacyBukkit = "1.8.8-R0.1-SNAPSHOT"
|
||||
velocity = "3.1.1"
|
||||
velocity = "3.4.0"
|
||||
viaProxy = "[3.0.0,4.0.0)"
|
||||
|
||||
[libraries]
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
distributionSha256Sum=b266d5ff6b90eada6dc3b20cb090e3731302e553a27c5d3e4df1f0d76beaff06
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.viaversion.viaversion;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.command.CommandManager;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
@@ -80,21 +81,10 @@ public class VelocityPlugin implements ViaServerProxyPlatform<Player> {
|
||||
|
||||
@Subscribe
|
||||
public void onProxyInit(ProxyInitializeEvent e) {
|
||||
if (!hasConnectionEvent()) {
|
||||
// No way to disable the plugin :(
|
||||
Logger logger = this.loggerslf4j;
|
||||
logger.error(" / \\");
|
||||
logger.error(" / \\");
|
||||
logger.error(" / | \\");
|
||||
logger.error(" / | \\ VELOCITY 3.0.0 IS REQUIRED");
|
||||
logger.error(" / \\ VIAVERSION WILL NOT WORK AS INTENDED");
|
||||
logger.error(" / o \\");
|
||||
logger.error("/_____________\\");
|
||||
}
|
||||
|
||||
PROXY = proxy;
|
||||
VelocityCommandHandler commandHandler = new VelocityCommandHandler();
|
||||
PROXY.getCommandManager().register("viaver", commandHandler, "vvvelocity", "viaversion");
|
||||
CommandManager commandManager = PROXY.getCommandManager();
|
||||
commandManager.register(commandManager.metaBuilder("viaver").aliases("vvvelocity", "viaversion").plugin(this).build(), commandHandler);
|
||||
api = new VelocityViaAPI();
|
||||
logger = new LoggerWrapper(loggerslf4j);
|
||||
conf = new VelocityViaConfig(configDir.toFile(), logger);
|
||||
@@ -106,6 +96,7 @@ public class VelocityPlugin implements ViaServerProxyPlatform<Player> {
|
||||
conf.reload();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onProxyLateInit(ProxyInitializeEvent e) {
|
||||
final ViaManagerImpl manager = (ViaManagerImpl) Via.getManager();
|
||||
@@ -240,13 +231,4 @@ public class VelocityPlugin implements ViaServerProxyPlatform<Player> {
|
||||
public ProtocolDetectorService protocolDetectorService() {
|
||||
return protocolDetectorService;
|
||||
}
|
||||
|
||||
private boolean hasConnectionEvent() {
|
||||
try {
|
||||
Class.forName("com.velocitypowered.proxy.protocol.VelocityConnectionEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user