mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2026-11-04 17:00:06 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
075181f06f | ||
|
|
b712c0055d | ||
|
|
08776de832 | ||
|
|
77b7054629 | ||
|
|
63769b3661 | ||
|
|
12d75daf04 | ||
|
|
413268eb15 | ||
|
|
b27e2a5514 | ||
|
|
c59dfb4d93 | ||
|
|
f66cbd6941 | ||
|
|
1574f343f7 | ||
|
|
022fb96f83 | ||
|
|
7cbc751fea | ||
|
|
366f08d951 | ||
|
|
d628f09334 | ||
|
|
6fecd58773 | ||
|
|
da7619c82d | ||
|
|
b83268efa0 | ||
|
|
309c3e57c1 | ||
|
|
34a445efcd | ||
|
|
3a949d70eb | ||
|
|
99bfa389b4 | ||
|
|
327d4739f5 | ||
|
|
3a7a8e06a8 | ||
|
|
85db19200f | ||
|
|
226609b864 | ||
|
|
7049f7eaf1 | ||
|
|
a062d0905b | ||
|
|
7ac58c104b | ||
|
|
7a6e838eb1 | ||
|
|
57bc53346c | ||
|
|
3df7c76c8c | ||
|
|
3f35005051 | ||
|
|
f9d21e073b |
No files matched your search
@@ -15,12 +15,12 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v6.3.0
|
||||
uses: gradle/actions/setup-gradle@v6.4.0
|
||||
with:
|
||||
cache-disabled: false
|
||||
cache-provider: basic
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v5.7.0
|
||||
uses: actions/setup-java@v6.0.1
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
- name: Upload Artifacts to GitHub
|
||||
# Only upload on the preview repository as there is no CI job for it.
|
||||
if: ${{ github.repository == 'ViaVersion/ViaVersionDev' && github.ref_name == 'preview' }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: Artifacts
|
||||
path: build/libs/
|
||||
|
||||
@@ -20,12 +20,12 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v6.3.0
|
||||
uses: gradle/actions/setup-gradle@v6.4.0
|
||||
with:
|
||||
cache-disabled: false
|
||||
cache-provider: basic
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v5.7.0
|
||||
uses: actions/setup-java@v6.0.1
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
@@ -14,18 +14,23 @@ or as [a standalone proxy](https://github.com/ViaVersion/ViaProxy) to join from
|
||||
any server version from the past decade. **See [HERE](https://viaversion.com) for an overview of the different Via\*
|
||||
projects.**
|
||||
|
||||
Note that ViaVersion will be able to **run best on either Paper servers or
|
||||
through [ViaFabricPlus](https://github.com/ViaVersion/ViaFabricPlus?tab=readme-ov-file#viafabricplus)** due to having
|
||||
direct access to client/server state and more extensive API.
|
||||
**Note:** While ViaVersion works reliably across all listed platforms, it has the highest performance and state accuracy on **Paper** servers and through **[ViaFabricPlus](https://github.com/ViaVersion/ViaFabricPlus)** on clients, since both offer more extensive APIs and direct access to client/server state.
|
||||
|
||||
Supported Versions:
|
||||
### Supported Versions
|
||||
|
||||

|
||||
| Players joining with… | Install |
|
||||
| :--- | :--- |
|
||||
| **Newer** versions than the server | ViaVersion |
|
||||
| **Older** versions than the server, down to 1.9 | ViaVersion + [ViaBackwards](https://github.com/ViaVersion/ViaBackwards) |
|
||||
| **1.7.x – 1.8.x** | ViaVersion + [ViaBackwards](https://github.com/ViaVersion/ViaBackwards) + [ViaRewind](https://github.com/ViaVersion/ViaRewind) |
|
||||
|
||||
**User Docs:** https://docs.viaversion.com
|
||||
If you're stuck, try [this tool](https://viaversion.com/setup) to work out what plugins you need.
|
||||
|
||||
**User Docs:** [docs.viaversion.com](https://docs.viaversion.com)
|
||||
|
||||
Snapshot Support
|
||||
----------
|
||||
|
||||
Snapshot support
|
||||
--------
|
||||
**ViaVersion will only be released a few days *after* a Minecraft update** unless the protocol changes of the update
|
||||
were trivial. If you want early-access, usually days or even weeks before the final release, you can subscribe to
|
||||
either:
|
||||
|
||||
@@ -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.TRUSTED_TAG, value.title())
|
||||
.writeOptional("author", Types.TRUSTED_TAG, value.author()));
|
||||
.writeOptional("title", Types.TEXT_COMPONENT_TAG, value.title())
|
||||
.writeOptional("author", Types.TEXT_COMPONENT_TAG, value.author()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,4 +39,11 @@ public record SoundEvent(String identifier, @Nullable Float fixedRange) {
|
||||
}
|
||||
return holder.updateId(soundRewriteFunction, () -> UNKNOWN);
|
||||
}
|
||||
|
||||
public static @Nullable Holder<SoundEvent> rewriteOptionalHolder(@Nullable final Holder<SoundEvent> holder, final Int2IntFunction soundRewriteFunction) {
|
||||
if (holder == null) {
|
||||
return null;
|
||||
}
|
||||
return holder.updateId(soundRewriteFunction, () -> null);
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -30,7 +30,6 @@ import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryKey;
|
||||
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_20_5;
|
||||
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_11;
|
||||
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_2;
|
||||
@@ -48,6 +47,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.Bee;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BlockEntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BreakSound;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BrewingFuel;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Compostable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.consumable.Consumable1_21_2;
|
||||
@@ -55,7 +55,6 @@ import com.viaversion.viaversion.api.minecraft.item.data.CookingFuel;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.CustomModelData1_21_4;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant26_1;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DebugStickState;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
|
||||
@@ -125,7 +124,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Unit> UNBREAKABLE1_21_5 = new StructuredDataKey<>("unbreakable", Types.EMPTY);
|
||||
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TEXT_COMPONENT_TAG);
|
||||
public static final StructuredDataKey<Float> MINIMUM_ATTACK_CHARGE = new StructuredDataKey<>("minimum_attack_charge", Types.FLOAT);
|
||||
public static final StructuredDataKey<DamageType> DAMAGE_TYPE1_21_11 = new StructuredDataKey<>("damage_type", DamageType.TYPE1_21_11);
|
||||
public static final StructuredDataKey<Either<Integer, String>> DAMAGE_TYPE1_21_11 = new StructuredDataKey<>("damage_type", new SynchronizedRegistryEitherType(RegistryKey.of("damage_type")));
|
||||
public static final StructuredDataKey<Integer> DAMAGE_TYPE26_1 = new StructuredDataKey<>("damage_type", new SynchronizedRegistryValueType(RegistryKey.of("damage_type")));
|
||||
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TEXT_COMPONENT_TAG);
|
||||
public static final StructuredDataKey<ItemModel> ITEM_MODEL = new StructuredDataKey<>("item_model", ItemModel.TYPE);
|
||||
@@ -153,6 +152,8 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<FoodProperties1_20_5> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties1_20_5.TYPE1_21);
|
||||
public static final StructuredDataKey<FoodProperties1_21_2> FOOD1_21_2 = new StructuredDataKey<>("food", FoodProperties1_21_2.TYPE);
|
||||
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_2 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE1_21_2);
|
||||
// 1.21.5-1.21.9 only, animation id 5 was still named spear
|
||||
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE1_21_5 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE1_21_5);
|
||||
public static final StructuredDataKey<Consumable1_21_2> CONSUMABLE26_3 = new StructuredDataKey<>("consumable", Consumable1_21_2.TYPE26_3);
|
||||
public static final StructuredDataKey<UseCooldown> USE_COOLDOWN = new StructuredDataKey<>("use_cooldown", UseCooldown.TYPE);
|
||||
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY);
|
||||
@@ -238,7 +239,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
|
||||
public static final StructuredDataKey<Tag> LOCK1_20_5 = new StructuredDataKey<>("lock", Types.TAG);
|
||||
public static final StructuredDataKey<LockCode> LOCK1_21_2 = new StructuredDataKey<>("lock", LockCode.TYPE);
|
||||
public static final StructuredDataKey<CompoundTag> CONTAINER_LOOT = new StructuredDataKey<>("container_loot", Types.COMPOUND_TAG);
|
||||
public static final StructuredDataKey<Holder<SoundEvent>> BREAK_SOUND = new StructuredDataKey<>("break_sound", Types.SOUND_EVENT);
|
||||
public static final StructuredDataKey<BreakSound> BREAK_SOUND = new StructuredDataKey<>("break_sound", BreakSound.TYPE);
|
||||
public static final StructuredDataKey<Compostable> COMPOSTABLE = new StructuredDataKey<>("compostable", Compostable.TYPE);
|
||||
public static final StructuredDataKey<CookingFuel> COOKING_FUEL = new StructuredDataKey<>("cooking_fuel", CookingFuel.TYPE);
|
||||
public static final StructuredDataKey<BrewingFuel> BREWING_FUEL = new StructuredDataKey<>("brewing_fuel", BrewingFuel.TYPE);
|
||||
|
||||
+1
-1
@@ -32,6 +32,6 @@ public class StructuredDataKeys26_2 extends StructuredDataKeys1_21_11 {
|
||||
|
||||
public StructuredDataKeys26_2(final VersionedTypesHolder types) {
|
||||
super(types);
|
||||
this.sulfurCubeContent = add("sulfur_cube_content", types.item());
|
||||
this.sulfurCubeContent = add("sulfur_cube_content", types.itemTemplate());
|
||||
}
|
||||
}
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2026 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.MappingData.MappingType;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
// TODO move block state provider rewriting to registry data rewriter
|
||||
public record BlockTransformData(CompoundTag blockStateProvider, Holder<SoundEvent> sound, int transformParticle,
|
||||
int[] disallowedFaces, @Nullable String loot, int dropStrategy,
|
||||
boolean updateFromNeighbors, int transformType,
|
||||
boolean consumeOnUse, int itemDamagePerUse) implements Rewritable, Copyable {
|
||||
|
||||
public static final Type<BlockTransformData> TYPE = new Type<>(BlockTransformData.class) {
|
||||
@Override
|
||||
public BlockTransformData read(final ByteBuf buffer) {
|
||||
final CompoundTag blockStateProvider = Types.COMPOUND_TAG.read(buffer);
|
||||
final Holder<SoundEvent> sound = Types.SOUND_EVENT.read(buffer);
|
||||
final int transformParticle = Types.VAR_INT.readPrimitive(buffer);
|
||||
final int[] disallowedFaces = Types.VAR_INT_ARRAY_PRIMITIVE.read(buffer);
|
||||
final String loot = Types.OPTIONAL_STRING.read(buffer);
|
||||
final int dropStrategy = Types.VAR_INT.readPrimitive(buffer);
|
||||
final boolean updateFromNeighbors = Types.BOOLEAN.read(buffer);
|
||||
final int transformType = Types.VAR_INT.readPrimitive(buffer);
|
||||
final boolean consumeOnUse = Types.BOOLEAN.read(buffer);
|
||||
final int itemDamagePerUse = Types.VAR_INT.readPrimitive(buffer);
|
||||
return new BlockTransformData(blockStateProvider, sound, transformParticle, disallowedFaces, loot, dropStrategy, updateFromNeighbors, transformType, consumeOnUse, itemDamagePerUse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final BlockTransformData value) {
|
||||
Types.COMPOUND_TAG.write(buffer, value.blockStateProvider);
|
||||
Types.SOUND_EVENT.write(buffer, value.sound);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.transformParticle);
|
||||
Types.VAR_INT_ARRAY_PRIMITIVE.write(buffer, value.disallowedFaces);
|
||||
Types.OPTIONAL_STRING.write(buffer, value.loot);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.dropStrategy);
|
||||
Types.BOOLEAN.write(buffer, value.updateFromNeighbors);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.transformType);
|
||||
Types.BOOLEAN.write(buffer, value.consumeOnUse);
|
||||
Types.VAR_INT.writePrimitive(buffer, value.itemDamagePerUse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final BlockTransformData data) {
|
||||
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingType.SOUND, "intentionally_empty"));
|
||||
ops.writeMap(map -> map
|
||||
.write("block_state_provider", Types.COMPOUND_TAG, data.blockStateProvider)
|
||||
.writeOptional("sound", Types.SOUND_EVENT, data.sound, defaultSound)
|
||||
.writeOptional("particle", EnumTypes.TRANSFORM_PARTICLE, data.transformParticle, 0)
|
||||
.writeOptional("disallowed_faces", EnumTypes.DIRECTION.new EnumArrayType(), data.disallowedFaces, new int[0])
|
||||
.writeOptional("loot", Types.STRING, data.loot)
|
||||
.writeOptional("drop_strategy", Types.VAR_INT, data.dropStrategy, 1)
|
||||
.writeOptional("update_from_neighbors", Types.BOOLEAN, data.updateFromNeighbors, true)
|
||||
.writeOptional("transform_type", Types.VAR_INT, data.transformType, 0)
|
||||
.writeOptional("consume_on_use", Types.BOOLEAN, data.consumeOnUse, true)
|
||||
.writeOptional("item_damage_per_use", Types.VAR_INT, data.itemDamagePerUse, 0)
|
||||
);
|
||||
}
|
||||
};
|
||||
public static final ArrayType<BlockTransformData> ARRAY_TYPE = new ArrayType<>(TYPE);
|
||||
|
||||
@Override
|
||||
public BlockTransformData rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
CompoundTag updatedTag = blockStateProvider().copy();
|
||||
if (protocol.getRegistryDataRewriter().updateBlockStateProvider(updatedTag)) {
|
||||
// Back it up clientbound so server data doesn't disappear; remove it for newly spawned items serverbound.
|
||||
// Given it's not even encoded properly over the network and would otherwise require keeping full block state mappings
|
||||
// and is not needed on the client, we only do the bare minimum to guarantee compatibility.
|
||||
if (clientbound) {
|
||||
updatedTag.put("backup", this.blockStateProvider);
|
||||
} else {
|
||||
final CompoundTag backupTag = updatedTag.getCompoundTag("backup");
|
||||
updatedTag = backupTag != null ? backupTag : dummyBlockStateProvider();
|
||||
}
|
||||
}
|
||||
return new BlockTransformData(updatedTag, sound, transformParticle, disallowedFaces, loot, dropStrategy, updateFromNeighbors, transformType, consumeOnUse, itemDamagePerUse);
|
||||
}
|
||||
|
||||
private CompoundTag dummyBlockStateProvider() {
|
||||
final CompoundTag state = new CompoundTag();
|
||||
state.putString("Name", "dirt");
|
||||
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.putString("type", "simple");
|
||||
tag.put("state", state);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTransformData copy() {
|
||||
return new BlockTransformData(blockStateProvider.copy(), sound, transformParticle, disallowedFaces, loot, dropStrategy, updateFromNeighbors, transformType, consumeOnUse, itemDamagePerUse);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -130,8 +130,8 @@ public record BlocksAttacks(
|
||||
|
||||
@Override
|
||||
public BlocksAttacks rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> blockSound = SoundEvent.rewriteHolder(this.blockSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> disableSound = SoundEvent.rewriteHolder(this.disableSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> blockSound = SoundEvent.rewriteOptionalHolder(this.blockSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> disableSound = SoundEvent.rewriteOptionalHolder(this.disableSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return new BlocksAttacks(this.blockDelaySeconds, this.disableCooldownScale, this.damageReductions, this.itemDamage, this.bypassedBy, blockSound, disableSound);
|
||||
}
|
||||
|
||||
|
||||
+13
-9
@@ -22,18 +22,22 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.TransformingType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.EitherType;
|
||||
import com.viaversion.viaversion.util.Either;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
/**
|
||||
* 1.21.11-only damage type.
|
||||
*
|
||||
* @param id registry int or string id
|
||||
*/
|
||||
public record DamageType(Either<Integer, String> id) {
|
||||
public record BreakSound(Holder<SoundEvent> sound) implements Rewritable {
|
||||
|
||||
public static final Type<DamageType> TYPE1_21_11 = TransformingType.of(new EitherType<>(Types.VAR_INT, Types.STRING), DamageType.class, DamageType::new, DamageType::id);
|
||||
public static final Type<BreakSound> TYPE = TransformingType.of(Types.SOUND_EVENT, BreakSound.class, BreakSound::new, BreakSound::sound);
|
||||
|
||||
@Override
|
||||
public BreakSound rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> sound = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return this.sound == sound ? this : new BreakSound(sound);
|
||||
}
|
||||
}
|
||||
+12
-3
@@ -22,27 +22,36 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.consumable.ConsumeEffect;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.TransformingType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
public record DeathProtection(ConsumeEffect<?>[] deathEffects) implements Copyable {
|
||||
public record DeathProtection(ConsumeEffect<?>[] deathEffects) implements Copyable, Rewritable {
|
||||
|
||||
public static final Type<DeathProtection> TYPE1_21_2 = new TransformingType<>(ConsumeEffect.ARRAY_TYPE1_21_2, DeathProtection.class, DeathProtection::new, DeathProtection::deathEffects) {
|
||||
@Override
|
||||
public void write(final Ops ops, final DeathProtection value) {
|
||||
ops.writeMap(map -> map.write("death_effects", ConsumeEffect.ARRAY_TYPE1_21_2, value.deathEffects));
|
||||
ops.writeMap(map -> map.writeOptional("death_effects", ConsumeEffect.ARRAY_TYPE1_21_2, value.deathEffects, new ConsumeEffect<?>[0]));
|
||||
}
|
||||
};
|
||||
public static final Type<DeathProtection> TYPE26_3 = new TransformingType<>(ConsumeEffect.ARRAY_TYPE26_3, DeathProtection.class, DeathProtection::new, DeathProtection::deathEffects) {
|
||||
@Override
|
||||
public void write(final Ops ops, final DeathProtection value) {
|
||||
ops.writeMap(map -> map.write("death_effects", ConsumeEffect.ARRAY_TYPE26_3, value.deathEffects));
|
||||
ops.writeMap(map -> map.writeOptional("death_effects", ConsumeEffect.ARRAY_TYPE26_3, value.deathEffects, new ConsumeEffect<?>[0]));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public DeathProtection rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final ConsumeEffect<?>[] deathEffects = ConsumeEffect.rewrite(this.deathEffects, connection, protocol, clientbound);
|
||||
return deathEffects == this.deathEffects ? this : new DeathProtection(deathEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeathProtection copy() {
|
||||
return new DeathProtection(Copyable.copy(deathEffects));
|
||||
|
||||
@@ -47,11 +47,8 @@ public final class EnumTypes {
|
||||
public static final EnumType AXOLOTL_VARIANT = new EnumType("lucy", "wild", "gold", "cyan", "blue");
|
||||
public static final EnumType EQUIPMENT_SLOT = new EnumType("mainhand", "feet", "legs", "chest", "head", "offhand", "body", "saddle");
|
||||
public static final EnumType SWING_ANIMATION1_21_11 = new EnumType("none", "whack", "stab");
|
||||
public static final EnumType ITEM_USE_ANIMATION1_21_5 = new EnumType("none", "eat", "drink", "block", "bow", "spear", "crossbow", "spyglass", "toot_horn", "brush", "bundle");
|
||||
public static final EnumType ITEM_USE_ANIMATION = new EnumType("none", "eat", "drink", "block", "bow", "trident", "crossbow", "spyglass", "toot_horn", "brush", "bundle", "spear");
|
||||
public static final EnumType DIRECTION = new EnumType("down", "up", "north", "south", "west", "east");
|
||||
public static final EnumType TRANSFORM_PARTICLE = new EnumType("none", "scrape", "wax_on", "wax_off");
|
||||
public static final EnumType TRAMNSFORM_DROP_STRATEGY = new EnumType("clicked_face", "from_middle");
|
||||
public static final EnumType TRAMNSFORM_TYPE = new EnumType("single_block", "copper_chest");
|
||||
// Enums with non-ordinal ids
|
||||
public static final FakeEnumType RABBIT_VARIANT = new FakeEnumType(List.of("brown", "white", "black", "white_splotched", "gold", "salt"), of(99, "evil"));
|
||||
// Hardcoded registries
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class FilterableComponent extends Filterable<Tag> implements Copyable, Rewritable {
|
||||
|
||||
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
|
||||
public static final Type<FilterableComponent> TYPE = new FilterableType<>(Types.TEXT_COMPONENT_TAG, Types.OPTIONAL_TAG, FilterableComponent.class) {
|
||||
@Override
|
||||
protected FilterableComponent create(final Tag raw, final Tag filtered) {
|
||||
return new FilterableComponent(raw, filtered);
|
||||
|
||||
+3
-3
@@ -67,7 +67,7 @@ public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration,
|
||||
.write("sound_event", Types.SOUND_EVENT, value.soundEvent())
|
||||
.write("use_duration", Types.FLOAT, value.useDuration())
|
||||
.write("range", Types.FLOAT, value.range())
|
||||
.write("description", Types.TAG, value.description()));
|
||||
.write("description", Types.TEXT_COMPONENT_TAG, value.description()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,8 +103,8 @@ public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration,
|
||||
.write("sound_event", Types.SOUND_EVENT, value.soundEvent())
|
||||
.write("use_duration", Types.FLOAT, value.useDuration())
|
||||
.write("range", Types.FLOAT, value.range())
|
||||
.write("durability_damage", Types.VAR_INT, value.durabilityDamage())
|
||||
.write("description", Types.TAG, value.description()));
|
||||
.writeOptional("durability_damage", Types.VAR_INT, value.durabilityDamage(), 0)
|
||||
.write("description", Types.TEXT_COMPONENT_TAG, value.description()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-1
@@ -22,19 +22,22 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.OptionalType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record KineticWeapon(int contactCooldownTicks, int delayTicks, @Nullable Condition dismountConditions,
|
||||
@Nullable Condition knockbackConditions, @Nullable Condition damageConditions,
|
||||
float forwardMovement, float damageMultiplier,
|
||||
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) {
|
||||
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) implements Rewritable {
|
||||
|
||||
public static final Type<KineticWeapon> TYPE = new Type<>(KineticWeapon.class) {
|
||||
@Override
|
||||
@@ -80,6 +83,13 @@ public record KineticWeapon(int contactCooldownTicks, int delayTicks, @Nullable
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public KineticWeapon rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> sound = SoundEvent.rewriteOptionalHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> hitSound = SoundEvent.rewriteOptionalHolder(this.hitSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return sound == this.sound && hitSound == this.hitSound ? this : new KineticWeapon(contactCooldownTicks, delayTicks, dismountConditions, knockbackConditions, damageConditions, forwardMovement, damageMultiplier, sound, hitSound);
|
||||
}
|
||||
|
||||
public record Condition(int maxDurationTicks, float minSpeed, float minRelativeSpeed) {
|
||||
|
||||
public static final Type<Condition> TYPE = new Type<>(Condition.class) {
|
||||
|
||||
+11
-1
@@ -22,16 +22,19 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public record PiercingWeapon(boolean dealsKnockback, boolean dismounts,
|
||||
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) {
|
||||
@Nullable Holder<SoundEvent> sound, @Nullable Holder<SoundEvent> hitSound) implements Rewritable {
|
||||
|
||||
public static final Type<PiercingWeapon> TYPE = new Type<>(PiercingWeapon.class) {
|
||||
@Override
|
||||
@@ -61,4 +64,11 @@ public record PiercingWeapon(boolean dealsKnockback, boolean dismounts,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public PiercingWeapon rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> sound = SoundEvent.rewriteOptionalHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
final Holder<SoundEvent> hitSound = SoundEvent.rewriteOptionalHolder(this.hitSound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return sound == this.sound && hitSound == this.hitSound ? this : new PiercingWeapon(dealsKnockback, dismounts, sound, hitSound);
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -29,16 +29,19 @@ import com.viaversion.viaversion.api.type.TransformingType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
|
||||
public record PotDecorations1_20_5(int[] itemIds) implements Copyable, Rewritable {
|
||||
|
||||
private static final Key BRICK = Key.ofPath("brick");
|
||||
public static final Type<PotDecorations1_20_5> TYPE = new TransformingType<>(Types.VAR_INT_ARRAY_PRIMITIVE, PotDecorations1_20_5.class, PotDecorations1_20_5::new, PotDecorations1_20_5::itemIds) {
|
||||
@Override
|
||||
public void write(final Ops ops, final PotDecorations1_20_5 value) {
|
||||
// Vanilla always encodes all 4 sides, filling missing ones with bricks
|
||||
ops.writeList(list -> {
|
||||
for (final int itemId : value.itemIds) {
|
||||
list.write(Types.IDENTIFIER, ops.context().registryAccess().item(itemId));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
list.write(Types.IDENTIFIER, i < value.itemIds.length ? ops.context().registryAccess().item(value.itemIds[i]) : BRICK);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -52,10 +52,10 @@ public record SignText(Tag[] messages, Tag @Nullable [] filteredMessages, int co
|
||||
@Override
|
||||
public void write(final Ops ops, final SignText value) {
|
||||
ops.writeMap(map -> map
|
||||
.write("messages", Types.SIGN_TEXT, value.messages)
|
||||
.writeOptional("filtered_messages", Types.SIGN_TEXT, value.filteredMessages)
|
||||
.write("color", Types.VAR_INT, value.color, 15)
|
||||
.write("has_glowing_text", Types.BOOLEAN, value.hasGlowingText, false));
|
||||
.write("messages", Types.TEXT_COMPONENT_TAG_ARRAY, value.messages)
|
||||
.writeOptional("filtered_messages", Types.TEXT_COMPONENT_TAG_ARRAY, value.filteredMessages)
|
||||
.write("color", EnumTypes.DYE_COLOR, value.color)
|
||||
.write("has_glowing_text", Types.BOOLEAN, value.hasGlowingText));
|
||||
}
|
||||
};
|
||||
}
|
||||
+11
-5
@@ -31,6 +31,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.EnumTypes;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.EnumType;
|
||||
import com.viaversion.viaversion.util.Copyable;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -39,16 +40,19 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
|
||||
boolean hasConsumeParticles,
|
||||
ConsumeEffect<?>[] consumeEffects) implements Copyable, Rewritable {
|
||||
|
||||
public static final Type<Consumable1_21_2> TYPE1_21_2 = new ConsumableType(ConsumeEffect.ARRAY_TYPE1_21_2);
|
||||
public static final Type<Consumable1_21_2> TYPE26_3 = new ConsumableType(ConsumeEffect.ARRAY_TYPE26_3);
|
||||
public static final Type<Consumable1_21_2> TYPE1_21_2 = new ConsumableType(ConsumeEffect.ARRAY_TYPE1_21_2, EnumTypes.ITEM_USE_ANIMATION);
|
||||
public static final Type<Consumable1_21_2> TYPE1_21_5 = new ConsumableType(ConsumeEffect.ARRAY_TYPE1_21_2, EnumTypes.ITEM_USE_ANIMATION1_21_5);
|
||||
public static final Type<Consumable1_21_2> TYPE26_3 = new ConsumableType(ConsumeEffect.ARRAY_TYPE26_3, EnumTypes.ITEM_USE_ANIMATION);
|
||||
|
||||
private static final class ConsumableType extends Type<Consumable1_21_2> {
|
||||
|
||||
private final Type<ConsumeEffect<?>[]> consumeEffectType;
|
||||
private final EnumType animationType;
|
||||
|
||||
private ConsumableType(final Type<ConsumeEffect<?>[]> consumeEffectType) {
|
||||
private ConsumableType(final Type<ConsumeEffect<?>[]> consumeEffectType, final EnumType animationType) {
|
||||
super(Consumable1_21_2.class);
|
||||
this.consumeEffectType = consumeEffectType;
|
||||
this.animationType = animationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,7 +79,7 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
|
||||
final Holder<SoundEvent> defaultSound = Holder.of(ops.context().registryAccess().id(MappingData.MappingType.SOUND, "entity.generic.eat"));
|
||||
ops.writeMap(map -> map
|
||||
.writeOptional("consume_seconds", Types.FLOAT, value.consumeSeconds, 1.6F)
|
||||
.writeOptional("animation", EnumTypes.ITEM_USE_ANIMATION, value.animationType, 1)
|
||||
.writeOptional("animation", animationType, value.animationType, 1)
|
||||
.writeOptional("sound", Types.SOUND_EVENT, value.sound, defaultSound)
|
||||
.writeOptional("has_consume_particles", Types.BOOLEAN, value.hasConsumeParticles, true)
|
||||
.writeOptional("on_consume_effects", consumeEffectType, value.consumeEffects, new ConsumeEffect<?>[0]));
|
||||
@@ -85,7 +89,9 @@ public record Consumable1_21_2(float consumeSeconds, int animationType, Holder<S
|
||||
@Override
|
||||
public Consumable1_21_2 rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
final Holder<SoundEvent> soundHolder = SoundEvent.rewriteHolder(this.sound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return soundHolder == this.sound ? this : new Consumable1_21_2(consumeSeconds, animationType, soundHolder, hasConsumeParticles, consumeEffects);
|
||||
final ConsumeEffect<?>[] consumeEffects = ConsumeEffect.rewrite(this.consumeEffects, connection, protocol, clientbound);
|
||||
return soundHolder == this.sound && consumeEffects == this.consumeEffects ? this
|
||||
: new Consumable1_21_2(consumeSeconds, animationType, soundHolder, hasConsumeParticles, consumeEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+33
-4
@@ -22,20 +22,23 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.minecraft.item.data.consumable;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.EnumTypes;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.ArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderSetType;
|
||||
import com.viaversion.viaversion.api.type.types.misc.HolderType;
|
||||
import com.viaversion.viaversion.util.Rewritable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public record ConsumeEffect<T>(int id, Type<T> type, T value) {
|
||||
public record ConsumeEffect<T>(int id, Type<T> type, T value) implements Rewritable {
|
||||
|
||||
private static final HolderSetType REMOVE_EFFECTS_TYPE = new HolderSetType() {
|
||||
@Override
|
||||
@@ -56,7 +59,7 @@ public record ConsumeEffect<T>(int id, Type<T> type, T value) {
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Float value) {
|
||||
ops.writeMap(map -> map.write("diameter", Types.FLOAT, value, 16F));
|
||||
ops.writeMap(map -> map.writeOptional("diameter", Types.FLOAT, value, 16F));
|
||||
}
|
||||
};
|
||||
public static final Type<TeleportRandomlyConsumeEffect> TELEPORT_RANDOMLY_TYPE26_3 = new Type<>(TeleportRandomlyConsumeEffect.class) {
|
||||
@@ -76,8 +79,8 @@ public record ConsumeEffect<T>(int id, Type<T> type, T value) {
|
||||
@Override
|
||||
public void write(final Ops ops, final TeleportRandomlyConsumeEffect value) {
|
||||
ops.writeMap(map -> map
|
||||
.write("diameter", Types.FLOAT, value.diameter(), 16F)
|
||||
.write("directional_particles", Types.BOOLEAN, value.directionalParticles(), true)
|
||||
.writeOptional("diameter", Types.FLOAT, value.diameter(), 16F)
|
||||
.writeOptional("directional_particles", Types.BOOLEAN, value.directionalParticles(), true)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -123,6 +126,32 @@ public record ConsumeEffect<T>(int id, Type<T> type, T value) {
|
||||
return new ConsumeEffect<>(id, type, (T) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsumeEffect<T> rewrite(final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
if (this.type != PLAY_SOUND_TYPE) {
|
||||
return this;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
final Holder<SoundEvent> sound = (Holder<SoundEvent>) this.value;
|
||||
final Holder<SoundEvent> rewrittenSound = SoundEvent.rewriteHolder(sound, Rewritable.soundRewriteFunction(protocol, clientbound));
|
||||
return rewrittenSound == sound ? this : ConsumeEffect.of(this.id, this.type, rewrittenSound);
|
||||
}
|
||||
|
||||
public static ConsumeEffect<?>[] rewrite(final ConsumeEffect<?>[] effects, final UserConnection connection, final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
ConsumeEffect<?>[] rewrittenEffects = effects;
|
||||
for (int i = 0; i < effects.length; i++) {
|
||||
final ConsumeEffect<?> rewrittenEffect = effects[i].rewrite(connection, protocol, clientbound);
|
||||
if (rewrittenEffect != effects[i]) {
|
||||
if (rewrittenEffects == effects) {
|
||||
rewrittenEffects = effects.clone();
|
||||
}
|
||||
rewrittenEffects[i] = rewrittenEffect;
|
||||
}
|
||||
}
|
||||
return rewrittenEffects;
|
||||
}
|
||||
|
||||
void writeValue(final ByteBuf buf) {
|
||||
this.type.write(buf, this.value);
|
||||
}
|
||||
|
||||
@@ -227,6 +227,7 @@ public final class Types {
|
||||
public static final Type<Tag[]> TAG_ARRAY = new ArrayType<>(TAG);
|
||||
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[]> TEXT_COMPONENT_TAG_ARRAY = new ArrayType<>(Types.TEXT_COMPONENT_TAG);
|
||||
|
||||
public static final Type<Tag> CUSTOM_CLICK_ACTION_TAG = new LengthPrefixedTagType(65536);
|
||||
public static final FixedLengthArrayType<Tag> SIGN_TEXT = new FixedLengthArrayType<>(TAG, 4);
|
||||
|
||||
@@ -111,4 +111,14 @@ public class ArrayType<T> extends Type<T[]> {
|
||||
public ArrayType<T> withMaxLength(final int maxLength) {
|
||||
return new ArrayType<>(this.getOutputClass(), this.elementType, maxLength);
|
||||
}
|
||||
|
||||
static int checkLength(final int length, final int elementBytes, final int readable) {
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException("Length " + length + " is negative");
|
||||
}
|
||||
if ((long) length * elementBytes > readable) {
|
||||
throw new IllegalArgumentException("Length " + length + " is larger than readable bytes");
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public class BooleanArrayType extends Type<boolean[]> {
|
||||
@Override
|
||||
public boolean[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is larger than readable bytes");
|
||||
final boolean[] array = new boolean[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = buffer.readBoolean();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ByteArrayType extends Type<byte[]> {
|
||||
@Override
|
||||
public byte[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is larger than readable bytes");
|
||||
final byte[] array = new byte[length];
|
||||
buffer.readBytes(array);
|
||||
return array;
|
||||
|
||||
@@ -27,6 +27,8 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import static com.viaversion.viaversion.api.type.types.ArrayType.checkLength;
|
||||
|
||||
public class FloatArrayType extends Type<float[]> {
|
||||
|
||||
private final int length;
|
||||
@@ -55,8 +57,7 @@ public class FloatArrayType extends Type<float[]> {
|
||||
|
||||
@Override
|
||||
public float[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
final int length = checkLength(this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length, Float.BYTES, buffer.readableBytes());
|
||||
final float[] array = new float[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = buffer.readFloat();
|
||||
|
||||
@@ -28,6 +28,8 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import static com.viaversion.viaversion.api.type.types.ArrayType.checkLength;
|
||||
|
||||
public class IntArrayType extends Type<int[]> {
|
||||
|
||||
private final int length;
|
||||
@@ -56,8 +58,7 @@ public class IntArrayType extends Type<int[]> {
|
||||
|
||||
@Override
|
||||
public int[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
final int length = checkLength(this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length, Integer.BYTES, buffer.readableBytes());
|
||||
final int[] array = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = buffer.readInt();
|
||||
|
||||
@@ -28,6 +28,8 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import static com.viaversion.viaversion.api.type.types.ArrayType.checkLength;
|
||||
|
||||
public class LongArrayType extends Type<long[]> {
|
||||
|
||||
private final int length;
|
||||
@@ -43,8 +45,7 @@ public class LongArrayType extends Type<long[]> {
|
||||
|
||||
@Override
|
||||
public long[] read(final ByteBuf buffer) {
|
||||
final int length = this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length;
|
||||
Preconditions.checkArgument(buffer.isReadable(length), "Length is fewer than readable bytes");
|
||||
final int length = checkLength(this.length == -1 ? Types.VAR_INT.readPrimitive(buffer) : this.length, Long.BYTES, buffer.readableBytes());
|
||||
return readFixedLength(buffer, length);
|
||||
}
|
||||
|
||||
|
||||
+11
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.item;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.codec.Ops;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
@@ -55,6 +56,16 @@ public class ItemTemplateType26_1 extends ItemType1_20_5 {
|
||||
writeData(buffer, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final Ops ops, final Item item) {
|
||||
// Unlike item stacks, templates omit the default count
|
||||
ops.writeMap(map -> {
|
||||
map.write("id", Types.IDENTIFIER, ops.context().registryAccess().item(item.identifier()))
|
||||
.writeOptional("count", Types.VAR_INT, item.amount(), 1);
|
||||
writeComponents(map, item);
|
||||
});
|
||||
}
|
||||
|
||||
public static final class OptionalItemTemplateType extends OptionalType<Item> {
|
||||
|
||||
public OptionalItemTemplateType(final Type<Item> type) {
|
||||
|
||||
+16
-13
@@ -127,22 +127,25 @@ public class ItemType1_20_5 extends Type<Item> {
|
||||
ops.writeMap(map -> {
|
||||
map.write("id", Types.IDENTIFIER, ops.context().registryAccess().item(item.identifier()))
|
||||
.write("count", Types.VAR_INT, item.amount());
|
||||
writeComponents(map, item);
|
||||
});
|
||||
}
|
||||
|
||||
if (item.dataContainer().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
protected void writeComponents(final Ops.MapSerializer map, final Item item) {
|
||||
if (item.dataContainer().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
map.writeMap("components", components -> {
|
||||
for (final StructuredData<?> data : item.dataContainer().data().values()) {
|
||||
String key = Key.namespaced(data.key().identifier());
|
||||
if (data.isEmpty()) {
|
||||
key = "!" + key;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
components.write(key, (Type<StructuredData<?>>) dataType, data);
|
||||
map.writeMap("components", components -> {
|
||||
for (final StructuredData<?> data : item.dataContainer().data().values()) {
|
||||
String key = Key.namespaced(data.key().identifier());
|
||||
if (data.isEmpty()) {
|
||||
key = "!" + key;
|
||||
}
|
||||
});
|
||||
|
||||
//noinspection unchecked
|
||||
components.write(key, (Type<StructuredData<?>>) dataType, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ public interface Rewritable {
|
||||
|
||||
static Int2IntFunction soundRewriteFunction(final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
return protocol.getMappingData().getSoundMappings() == null ? Int2IntFunction.identity()
|
||||
: (clientbound ? protocol.getMappingData().getSoundMappings()::getNewId : protocol.getMappingData()::getOldSoundId);
|
||||
: (clientbound ? protocol.getMappingData().getSoundMappings()::getNewId : protocol.getMappingData().getSoundMappings().inverse()::getNewId);
|
||||
}
|
||||
|
||||
static Int2IntFunction entityRewriteFunction(final Protocol<?, ?, ?, ?> protocol, final boolean clientbound) {
|
||||
|
||||
@@ -233,6 +233,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
callOnMappingDataLoaded(getEntityRewriter());
|
||||
callOnMappingDataLoaded(getItemRewriter());
|
||||
callOnMappingDataLoaded(getTagRewriter());
|
||||
callOnMappingDataLoaded(getBlockRewriter());
|
||||
}
|
||||
|
||||
private void callRegister(@Nullable Rewriter<?> rewriter) {
|
||||
|
||||
@@ -31,7 +31,6 @@ public record CodecRegistryContext(Protocol<?, ?, ?, ?> protocol, RegistryAccess
|
||||
|
||||
// Generally from hardcoded, but highly variable client data
|
||||
private static final Set<StructuredDataKey<?>> NOT_IMPLEMENTED = new ReferenceOpenHashSet<>(List.of(
|
||||
StructuredDataKey.DAMAGE_TYPE1_21_11
|
||||
));
|
||||
|
||||
public CodecRegistryContext(final Protocol<?, ?, ?, ?> protocol, final RegistryAccess registryAccess, final boolean mapped) {
|
||||
|
||||
+15
-3
@@ -494,9 +494,12 @@ public class ItemPacketRewriter1_13 extends ItemRewriter<ClientboundPackets1_12_
|
||||
if (tag == null)
|
||||
item.setTag(tag = new CompoundTag());
|
||||
if (!tag.contains("EntityTag")) {
|
||||
CompoundTag entityTag = new CompoundTag();
|
||||
entityTag.put("id", new StringTag(eggEntityId.get()));
|
||||
tag.put("EntityTag", entityTag);
|
||||
tag.put("EntityTag", new CompoundTag());
|
||||
}
|
||||
// The id is removed from a remaining EntityTag in handleItemToClient
|
||||
CompoundTag entityTag = tag.getCompoundTag("EntityTag");
|
||||
if (entityTag != null && !entityTag.contains("id")) {
|
||||
entityTag.putString("id", eggEntityId.get());
|
||||
}
|
||||
} else {
|
||||
rawId = IdAndData.getId(oldId) << 16 | oldId & 0xF;
|
||||
@@ -548,6 +551,10 @@ public class ItemPacketRewriter1_13 extends ItemRewriter<ClientboundPackets1_12_
|
||||
if (patternsTag != null) {
|
||||
for (CompoundTag pattern : patternsTag) {
|
||||
NumberTag colorTag = pattern.getNumberTag("Color");
|
||||
if (colorTag == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pattern.putInt("Color", 15 - colorTag.asInt()); // Invert color id
|
||||
}
|
||||
}
|
||||
@@ -659,6 +666,11 @@ public class ItemPacketRewriter1_13 extends ItemRewriter<ClientboundPackets1_12_
|
||||
}
|
||||
tag.put("CanDestroy", newCanDestroy);
|
||||
}
|
||||
|
||||
// Damage, map and the original id are stored in a tag created in handleItemToClient
|
||||
if (tag.isEmpty()) {
|
||||
item.setTag(null);
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
+17
@@ -125,6 +125,7 @@ public final class ItemPacketRewriter1_17 extends ItemRewriter<ClientboundPacket
|
||||
}
|
||||
if (tag.getNumberTag("map") == null) {
|
||||
tag.put("map", new IntTag(0));
|
||||
tag.putBoolean(nbtTagName("map"), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,4 +133,20 @@ public final class ItemPacketRewriter1_17 extends ItemRewriter<ClientboundPacket
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item handleItemToServer(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
|
||||
super.handleItemToServer(connection, item);
|
||||
|
||||
CompoundTag tag = item.tag();
|
||||
if (item.identifier() == 733 && tag != null && tag.remove(nbtTagName("map")) != null) {
|
||||
tag.remove("map");
|
||||
if (tag.isEmpty()) {
|
||||
item.setTag(null);
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
+4
-1
@@ -137,7 +137,10 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
|
||||
final CompoundTag filteredPages = tag.getCompoundTag("filtered_pages");
|
||||
if (filteredPages != null) {
|
||||
for (final String string : filteredPages.keySet()) {
|
||||
updatePageTag(filteredPages.getStringTag(string));
|
||||
final StringTag pageTag = filteredPages.getStringTag(string);
|
||||
if (pageTag != null) {
|
||||
updatePageTag(pageTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+66
-34
@@ -692,6 +692,11 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
if (bannerPatterns != null) {
|
||||
restoreBannerPatternsFromBackup(bannerPatterns, data);
|
||||
}
|
||||
|
||||
final CompoundTag trim = backupTag.getCompoundTag("trim");
|
||||
if (trim != null) {
|
||||
restoreArmorTrimFromBackup(trim, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreInstrumentFromBackup(final CompoundTag instrument, final StructuredDataContainer data) {
|
||||
@@ -799,6 +804,25 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
data.set(StructuredDataKey.BANNER_PATTERNS, patternLayer.toArray(new BannerPatternLayer[0]));
|
||||
}
|
||||
|
||||
private void restoreArmorTrimFromBackup(final CompoundTag trim, final StructuredDataContainer data) {
|
||||
final Tag materialTag = trim.get("material");
|
||||
final Holder<ArmorTrimMaterial1_20_5> materialHolder;
|
||||
if (materialTag instanceof IntTag materialIntTag) {
|
||||
materialHolder = Holder.of(materialIntTag.asInt());
|
||||
} else if (materialTag instanceof CompoundTag materialCompoundTag) {
|
||||
ArmorTrimMaterial1_20_5 material = readTrimMaterial(materialCompoundTag);
|
||||
if (material == null) {
|
||||
return;
|
||||
}
|
||||
materialHolder = Holder.of(material);
|
||||
} else return;
|
||||
|
||||
final Holder<ArmorTrimPattern> patternHolder = Holder.of(trim.getInt("pattern"));
|
||||
final boolean showInTooltip = trim.getBoolean("show_in_tooltip");
|
||||
|
||||
data.set(StructuredDataKey.TRIM1_20_5, new ArmorTrim1_20_5(materialHolder, patternHolder, showInTooltip));
|
||||
}
|
||||
|
||||
private AdventureModePredicate updateBlockPredicates(final UserConnection connection, final ListTag<StringTag> tag, final boolean showInTooltip) {
|
||||
final BlockPredicate[] predicates = tag.stream()
|
||||
.map(StringTag::getValue)
|
||||
@@ -969,8 +993,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
private void updateArmorTrim(final UserConnection connection, final StructuredDataContainer data, final CompoundTag trimTag, final boolean showInTooltip) {
|
||||
final Tag materialTag = trimTag.get("material");
|
||||
final Holder<ArmorTrimMaterial1_20_5> materialHolder;
|
||||
final ProtocolStorables1_20_5 storables = connection.storables(protocol);
|
||||
final ArmorTrimStorage trimStorage = storables.armorTrims();
|
||||
final ArmorTrimStorage trimStorage = connection.get(ArmorTrimStorage.class);
|
||||
if (materialTag instanceof StringTag materialStringTag) {
|
||||
final int id = trimStorage.trimMaterials().keyToId(materialStringTag.getValue());
|
||||
if (id == -1) {
|
||||
@@ -979,39 +1002,11 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
|
||||
materialHolder = Holder.of(id);
|
||||
} else if (materialTag instanceof CompoundTag materialCompoundTag) {
|
||||
final StringTag assetNameTag = materialCompoundTag.getStringTag("asset_name");
|
||||
final StringTag ingredientTag = materialCompoundTag.getStringTag("ingredient");
|
||||
if (assetNameTag == null || ingredientTag == null) {
|
||||
ArmorTrimMaterial1_20_5 material = readTrimMaterial(materialCompoundTag);
|
||||
if (material == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int ingredientId = StructuredDataConverter.removeItemBackupTag(materialCompoundTag, toMappedItemId(ingredientTag.getValue()));
|
||||
if (ingredientId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final NumberTag itemModelIndexTag = materialCompoundTag.getNumberTag("item_model_index");
|
||||
final CompoundTag overrideArmorMaterialsTag = materialCompoundTag.getCompoundTag("override_armor_materials");
|
||||
final Tag descriptionTag = materialCompoundTag.get("description");
|
||||
|
||||
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>();
|
||||
if (overrideArmorMaterialsTag != null) {
|
||||
for (final Map.Entry<String, Tag> entry : overrideArmorMaterialsTag.entrySet()) {
|
||||
if (!(entry.getValue() instanceof StringTag valueTag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
overrideArmorMaterials.put(entry.getKey(), valueTag.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
materialHolder = Holder.of(new ArmorTrimMaterial1_20_5(
|
||||
assetNameTag.getValue(),
|
||||
ingredientId,
|
||||
itemModelIndexTag != null ? itemModelIndexTag.asFloat() : 0,
|
||||
overrideArmorMaterials,
|
||||
descriptionTag
|
||||
));
|
||||
materialHolder = Holder.of(material);
|
||||
} else return;
|
||||
|
||||
final Tag patternTag = trimTag.get("pattern");
|
||||
@@ -1048,6 +1043,42 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
data.set(StructuredDataKey.TRIM1_20_5, new ArmorTrim1_20_5(materialHolder, patternHolder, showInTooltip));
|
||||
}
|
||||
|
||||
private ArmorTrimMaterial1_20_5 readTrimMaterial(final CompoundTag tag) {
|
||||
final StringTag assetNameTag = tag.getStringTag("asset_name");
|
||||
final StringTag ingredientTag = tag.getStringTag("ingredient");
|
||||
if (assetNameTag == null || ingredientTag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int ingredientId = StructuredDataConverter.removeItemBackupTag(tag, toMappedItemId(ingredientTag.getValue()));
|
||||
if (ingredientId == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final NumberTag itemModelIndexTag = tag.getNumberTag("item_model_index");
|
||||
final CompoundTag overrideArmorMaterialsTag = tag.getCompoundTag("override_armor_materials");
|
||||
final Tag descriptionTag = tag.get("description");
|
||||
|
||||
final Map<String, String> overrideArmorMaterials = new Object2ObjectArrayMap<>();
|
||||
if (overrideArmorMaterialsTag != null) {
|
||||
for (final Map.Entry<String, Tag> entry : overrideArmorMaterialsTag.entrySet()) {
|
||||
if (!(entry.getValue() instanceof StringTag valueTag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
overrideArmorMaterials.put(entry.getKey(), valueTag.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return new ArmorTrimMaterial1_20_5(
|
||||
assetNameTag.getValue(),
|
||||
ingredientId,
|
||||
itemModelIndexTag != null ? itemModelIndexTag.asFloat() : 0,
|
||||
overrideArmorMaterials,
|
||||
descriptionTag
|
||||
);
|
||||
}
|
||||
|
||||
private void updateMobTags(final StructuredDataContainer data, final CompoundTag tag) {
|
||||
final CompoundTag bucketEntityData = new CompoundTag();
|
||||
for (final String mobTagKey : MOB_TAGS) {
|
||||
@@ -1235,7 +1266,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
if (itemsTag != null) {
|
||||
final Item[] items = itemsTag.stream()
|
||||
.limit(256)
|
||||
.map(item -> itemFromTag(connection, item))
|
||||
.map(item -> itemFromTag(connection, item.copy()))
|
||||
.filter(item -> !item.isEmpty())
|
||||
.toArray(Item[]::new);
|
||||
data.set(dataKey, items);
|
||||
@@ -1521,6 +1552,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
}
|
||||
}
|
||||
|
||||
tag.remove("Items");
|
||||
data.set(StructuredDataKey.V1_20_5.container, filteredItems);
|
||||
addBlockEntityId(tag, "shulker_box");
|
||||
}
|
||||
|
||||
+14
-2
@@ -551,10 +551,22 @@ public final class StructuredDataConverter {
|
||||
} else {
|
||||
final String oldKey = trimStorage.trimPatterns().idToKey(data.pattern().id());
|
||||
if (oldKey != null) {
|
||||
trimTag.putString("pattern", oldKey);
|
||||
if (!"flow".equals(oldKey) && !"bolt".equals(oldKey)) {
|
||||
trimTag.putString("pattern", oldKey);
|
||||
} else if (backupInconvertibleData) {
|
||||
final CompoundTag backupTrim = trimTag.copy();
|
||||
if (!data.material().isDirect()) {
|
||||
backupTrim.putInt("material", data.material().id());
|
||||
}
|
||||
backupTrim.putInt("pattern", data.pattern().id());
|
||||
backupTrim.putBoolean("show_in_tooltip", data.showInTooltip());
|
||||
getBackupTag(tag).put("trim", backupTrim);
|
||||
}
|
||||
}
|
||||
}
|
||||
tag.put("Trim", trimTag);
|
||||
if (trimTag.contains("material") && trimTag.contains("pattern")) {
|
||||
tag.put("Trim", trimTag);
|
||||
}
|
||||
if (!data.showInTooltip()) {
|
||||
putHideFlag(tag, HIDE_ARMOR_TRIM);
|
||||
}
|
||||
|
||||
+2
-1
@@ -55,6 +55,7 @@ import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.UUIDUtil;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -183,7 +184,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
}
|
||||
|
||||
uuid = UUIDUtil.parseUUID(Key.stripNamespace(id).toUpperCase(Locale.ROOT));
|
||||
return uuid != null ? uuid : UUIDUtil.randomUUID();
|
||||
return uuid != null ? uuid : UUID.nameUUIDFromBytes(id.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-4
@@ -33,7 +33,6 @@ import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant1_21_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant26_1;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.DamageType;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ProvidesBannerPatterns;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.trim.ProvidesTrimMaterial1_20_5;
|
||||
@@ -86,7 +85,7 @@ public final class BlockItemPacketRewriter26_1 extends StructuredItemRewriter<Cl
|
||||
container.replace(StructuredDataKey.PROVIDES_TRIM_MATERIAL1_21_5, StructuredDataKey.PROVIDES_TRIM_MATERIAL26_1, providesTrimMaterial -> upgradeHolder(protocol, connection, providesTrimMaterial.material(), "trim_material"));
|
||||
container.replace(StructuredDataKey.CHICKEN_VARIANT1_21_5, StructuredDataKey.CHICKEN_VARIANT26_1, chickenVariant -> upgradeEitherVariant(protocol, connection, chickenVariant, "chicken_variant"));
|
||||
container.replace(StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT1_21_11, StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT26_1, nautilusVariant -> upgradeEitherVariant(protocol, connection, nautilusVariant, "zombie_nautilus_variant"));
|
||||
container.replace(StructuredDataKey.DAMAGE_TYPE1_21_11, StructuredDataKey.DAMAGE_TYPE26_1, damageType -> upgradeEitherVariant(protocol, connection, damageType.id(), "damage_type"));
|
||||
container.replace(StructuredDataKey.DAMAGE_TYPE1_21_11, StructuredDataKey.DAMAGE_TYPE26_1, damageType -> upgradeEitherVariant(protocol, connection, damageType, "damage_type"));
|
||||
container.replace(StructuredDataKey.PROVIDES_BANNER_PATTERNS1_21_5, StructuredDataKey.PROVIDES_BANNER_PATTERNS26_1, key -> new ProvidesBannerPatterns(tagKeyToHolderSet(protocol, connection, "banner_pattern", key.original())));
|
||||
container.replace(StructuredDataKey.DAMAGE_RESISTANT1_21_2, StructuredDataKey.DAMAGE_RESISTANT26_1, damageResistant -> new DamageResistant26_1(tagKeyToHolderSet(protocol, connection, "damage_type", damageResistant.typesTagKey().original())));
|
||||
container.replaceKey(StructuredDataKey.BLOCKS_ATTACKS1_21_5, StructuredDataKey.BLOCKS_ATTACKS26_1);
|
||||
@@ -137,14 +136,14 @@ public final class BlockItemPacketRewriter26_1 extends StructuredItemRewriter<Cl
|
||||
container.replace(StructuredDataKey.PROVIDES_TRIM_MATERIAL26_1, StructuredDataKey.PROVIDES_TRIM_MATERIAL1_21_5, providesTrimMaterial -> new ProvidesTrimMaterial1_20_5(EitherHolder.of(providesTrimMaterial)));
|
||||
container.replace(StructuredDataKey.CHICKEN_VARIANT26_1, StructuredDataKey.CHICKEN_VARIANT1_21_5, Either::left);
|
||||
container.replace(StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT26_1, StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT1_21_11, Either::left);
|
||||
container.replace(StructuredDataKey.DAMAGE_TYPE26_1, StructuredDataKey.DAMAGE_TYPE1_21_11, damageType -> new DamageType(Either.left(damageType)));
|
||||
container.replace(StructuredDataKey.DAMAGE_TYPE26_1, StructuredDataKey.DAMAGE_TYPE1_21_11, Either::left);
|
||||
container.replace(StructuredDataKey.PROVIDES_BANNER_PATTERNS26_1, StructuredDataKey.PROVIDES_BANNER_PATTERNS1_21_5, patterns -> tagOrNull(patterns.patterns()));
|
||||
container.replace(StructuredDataKey.DAMAGE_RESISTANT26_1, StructuredDataKey.DAMAGE_RESISTANT1_21_2, damageResistant -> {
|
||||
final Key key = tagOrNull(damageResistant.types());
|
||||
return key != null ? new DamageResistant1_21_2(key) : null;
|
||||
});
|
||||
container.replace(StructuredDataKey.BLOCKS_ATTACKS26_1, StructuredDataKey.BLOCKS_ATTACKS1_21_5, blocksAttacks -> {
|
||||
if (blocksAttacks.bypassedBy() == null) {
|
||||
if (blocksAttacks.bypassedBy() == null || blocksAttacks.bypassedBy().hasTagKey()) {
|
||||
return blocksAttacks;
|
||||
}
|
||||
// Remove bypassed by ids
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ public final class Protocol1_21_4To1_21_5 extends AbstractProtocol<ClientboundPa
|
||||
StructuredDataKey.POT_DECORATIONS1_20_5, StructuredDataKey.BLOCK_STATE, StructuredDataKey.BEES1_20_5, StructuredDataKey.LOCK1_21_2,
|
||||
StructuredDataKey.CONTAINER_LOOT, StructuredDataKey.TOOL1_21_5, StructuredDataKey.ITEM_NAME, StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER,
|
||||
StructuredDataKey.FOOD1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE1_21_5, StructuredDataKey.ATTRIBUTE_MODIFIERS1_21_5,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_2,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_5,
|
||||
StructuredDataKey.USE_COOLDOWN, StructuredDataKey.DAMAGE, StructuredDataKey.EQUIPPABLE1_21_5, StructuredDataKey.ITEM_MODEL,
|
||||
StructuredDataKey.GLIDER, StructuredDataKey.TOOLTIP_STYLE, StructuredDataKey.DEATH_PROTECTION1_21_2, StructuredDataKey.WEAPON,
|
||||
StructuredDataKey.POTION_DURATION_SCALE, StructuredDataKey.VILLAGER_VARIANT, StructuredDataKey.WOLF_VARIANT, StructuredDataKey.WOLF_COLLAR,
|
||||
|
||||
+54
-2
@@ -19,6 +19,7 @@ package com.viaversion.viaversion.protocols.v1_21_4to1_21_5.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.LongArrayTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
@@ -272,6 +273,7 @@ public final class BlockItemPacketRewriter1_21_5 extends StructuredItemRewriter<
|
||||
|
||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||
updateItemDataComponentTypeIds(dataContainer, true);
|
||||
backupHiddenAttributeModifiers(item);
|
||||
handleRewritablesToClient(connection, dataContainer, null);
|
||||
|
||||
updateItemData(item);
|
||||
@@ -298,10 +300,58 @@ public final class BlockItemPacketRewriter1_21_5 extends StructuredItemRewriter<
|
||||
super.handleItemDataComponentsToServer(connection, item, container);
|
||||
}
|
||||
|
||||
private void backupHiddenAttributeModifiers(final Item item) {
|
||||
final AttributeModifiers1_21 attributeModifiers = item.dataContainer().get(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21);
|
||||
if (attributeModifiers == null || attributeModifiers.showInTooltip()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> modifiersTag = new ListTag<>(CompoundTag.class);
|
||||
for (final AttributeModifiers1_21.AttributeModifier modifier : attributeModifiers.modifiers()) {
|
||||
final CompoundTag modifierTag = new CompoundTag();
|
||||
modifierTag.putInt("attribute", modifier.attribute());
|
||||
modifierTag.putString("id", modifier.modifier().id());
|
||||
modifierTag.putDouble("amount", modifier.modifier().amount());
|
||||
modifierTag.putInt("operation", modifier.modifier().operation());
|
||||
modifierTag.putInt("slot", modifier.slotType());
|
||||
modifiersTag.add(modifierTag);
|
||||
}
|
||||
saveTag(createCustomTag(item), modifiersTag, "hidden_attribute_modifiers");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restoreBackupData(final Item item, final StructuredDataContainer container, final CompoundTag customData) {
|
||||
super.restoreBackupData(item, container, customData);
|
||||
|
||||
final ListTag<CompoundTag> modifiersTag = customData.getListTag(nbtTagName("hidden_attribute_modifiers"), CompoundTag.class);
|
||||
if (modifiersTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
removeBackupTag(customData, "hidden_attribute_modifiers");
|
||||
if (container.has(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21_5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final AttributeModifiers1_21.AttributeModifier[] modifiers = new AttributeModifiers1_21.AttributeModifier[modifiersTag.size()];
|
||||
for (int i = 0; i < modifiers.length; i++) {
|
||||
final CompoundTag modifierTag = modifiersTag.get(i);
|
||||
final AttributeModifiers1_21.ModifierData modifierData = new AttributeModifiers1_21.ModifierData(
|
||||
modifierTag.getString("id"),
|
||||
modifierTag.getDouble("amount"),
|
||||
modifierTag.getInt("operation")
|
||||
);
|
||||
modifiers[i] = new AttributeModifiers1_21.AttributeModifier(modifierTag.getInt("attribute"), modifierData, modifierTag.getInt("slot"));
|
||||
}
|
||||
// Show state is applied from tooltip_display afterwards
|
||||
container.set(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21_5, new AttributeModifiers1_21(modifiers, true));
|
||||
}
|
||||
|
||||
public static void updateItemData(final Item item) {
|
||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||
dataContainer.replaceKey(StructuredDataKey.TOOL1_20_5, StructuredDataKey.TOOL1_21_5);
|
||||
dataContainer.replaceKey(StructuredDataKey.EQUIPPABLE1_21_2, StructuredDataKey.EQUIPPABLE1_21_5);
|
||||
dataContainer.replaceKey(StructuredDataKey.CONSUMABLE1_21_2, StructuredDataKey.CONSUMABLE1_21_5);
|
||||
dataContainer.replace(StructuredDataKey.INSTRUMENT1_21_2, StructuredDataKey.INSTRUMENT1_21_5, EitherHolder::of);
|
||||
|
||||
// Collect hidden tooltips
|
||||
@@ -408,6 +458,7 @@ public final class BlockItemPacketRewriter1_21_5 extends StructuredItemRewriter<
|
||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||
dataContainer.replaceKey(StructuredDataKey.TOOL1_21_5, StructuredDataKey.TOOL1_20_5);
|
||||
dataContainer.replaceKey(StructuredDataKey.EQUIPPABLE1_21_5, StructuredDataKey.EQUIPPABLE1_21_2);
|
||||
dataContainer.replaceKey(StructuredDataKey.CONSUMABLE1_21_5, StructuredDataKey.CONSUMABLE1_21_2);
|
||||
dataContainer.replace(StructuredDataKey.INSTRUMENT1_21_5, StructuredDataKey.INSTRUMENT1_21_2, instrument -> instrument.hasHolder() ? instrument.holder() : null);
|
||||
|
||||
final TooltipDisplay tooltipDisplay = dataContainer.get(StructuredDataKey.TOOLTIP_DISPLAY);
|
||||
@@ -417,7 +468,8 @@ public final class BlockItemPacketRewriter1_21_5 extends StructuredItemRewriter<
|
||||
}
|
||||
|
||||
final FullMappings mappings = Protocol1_21_4To1_21_5.MAPPINGS.getDataComponentSerializerMappings();
|
||||
if (tooltipDisplay.hiddenComponents().containsAll(HIDE_ADDITIONAL_KEYS.stream().map(key -> mappings.id(key.identifier())).toList())) {
|
||||
// Components added in 1.21.5 don't have an id here and have already been dropped from the hidden set
|
||||
if (tooltipDisplay.hiddenComponents().containsAll(HIDE_ADDITIONAL_KEYS.stream().map(key -> mappings.id(key.identifier())).filter(id -> id != -1).toList())) {
|
||||
dataContainer.set(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP);
|
||||
}
|
||||
}
|
||||
@@ -478,7 +530,7 @@ public final class BlockItemPacketRewriter1_21_5 extends StructuredItemRewriter<
|
||||
final ProtocolVersion serverVersion = connection.getProtocolInfo().serverProtocolVersion();
|
||||
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (item.identifier() == 858 || item.identifier() == 863 || item.identifier() == 873 || item.identifier() == 868 || item.identifier() == 878) { // swords
|
||||
item.dataContainer().remove(StructuredDataKey.CONSUMABLE1_21_2);
|
||||
item.dataContainer().remove(StructuredDataKey.CONSUMABLE1_21_5);
|
||||
item.dataContainer().set(StructuredDataKey.BLOCKS_ATTACKS1_21_5,
|
||||
new BlocksAttacks(
|
||||
0F,
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ public final class Protocol1_21_5To1_21_6 extends AbstractProtocol<ClientboundPa
|
||||
StructuredDataKey.POT_DECORATIONS1_20_5, StructuredDataKey.BLOCK_STATE, StructuredDataKey.BEES1_20_5, StructuredDataKey.LOCK1_21_2,
|
||||
StructuredDataKey.CONTAINER_LOOT, StructuredDataKey.TOOL1_21_5, StructuredDataKey.ITEM_NAME, StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER,
|
||||
StructuredDataKey.FOOD1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE1_21_5, StructuredDataKey.ATTRIBUTE_MODIFIERS1_21_6,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_2,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_5,
|
||||
StructuredDataKey.USE_COOLDOWN, StructuredDataKey.DAMAGE, StructuredDataKey.EQUIPPABLE1_21_6, StructuredDataKey.ITEM_MODEL,
|
||||
StructuredDataKey.GLIDER, StructuredDataKey.TOOLTIP_STYLE, StructuredDataKey.DEATH_PROTECTION1_21_2, StructuredDataKey.WEAPON,
|
||||
StructuredDataKey.POTION_DURATION_SCALE, StructuredDataKey.VILLAGER_VARIANT, StructuredDataKey.WOLF_VARIANT, StructuredDataKey.WOLF_COLLAR,
|
||||
|
||||
+1
-1
@@ -155,7 +155,7 @@ public final class Protocol1_21_7To1_21_9 extends AbstractProtocol<ClientboundPa
|
||||
StructuredDataKey.POT_DECORATIONS1_20_5, StructuredDataKey.BLOCK_STATE, StructuredDataKey.BEES1_21_9, StructuredDataKey.LOCK1_21_2,
|
||||
StructuredDataKey.CONTAINER_LOOT, StructuredDataKey.TOOL1_21_5, StructuredDataKey.ITEM_NAME, StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER,
|
||||
StructuredDataKey.FOOD1_21_2, StructuredDataKey.JUKEBOX_PLAYABLE1_21_5, StructuredDataKey.ATTRIBUTE_MODIFIERS1_21_6,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_2,
|
||||
StructuredDataKey.REPAIRABLE, StructuredDataKey.ENCHANTABLE, StructuredDataKey.CONSUMABLE1_21_5,
|
||||
StructuredDataKey.USE_COOLDOWN, StructuredDataKey.DAMAGE, StructuredDataKey.EQUIPPABLE1_21_6, StructuredDataKey.ITEM_MODEL,
|
||||
StructuredDataKey.GLIDER, StructuredDataKey.TOOLTIP_STYLE, StructuredDataKey.DEATH_PROTECTION1_21_2, StructuredDataKey.WEAPON,
|
||||
StructuredDataKey.POTION_DURATION_SCALE, StructuredDataKey.VILLAGER_VARIANT, StructuredDataKey.WOLF_VARIANT, StructuredDataKey.WOLF_COLLAR,
|
||||
|
||||
+7
-1
@@ -81,7 +81,13 @@ public final class BlockItemPacketRewriter1_21_9 extends StructuredItemRewriter<
|
||||
}
|
||||
|
||||
public static void downgradeData(final Item item, final StructuredDataContainer container) {
|
||||
container.replaceKey(StructuredDataKey.BEES1_21_9, StructuredDataKey.BEES1_20_5);
|
||||
container.replace(StructuredDataKey.BEES1_21_9, StructuredDataKey.BEES1_20_5, bees -> {
|
||||
for (final Bee bee : bees) {
|
||||
// Stripped from the tag since 1.21.9 but required to load the entity before
|
||||
bee.entityData().tag().putString("id", "minecraft:bee");
|
||||
}
|
||||
return bees;
|
||||
});
|
||||
container.replace(StructuredDataKey.ENTITY_DATA1_21_9, StructuredDataKey.ENTITY_DATA1_20_5, entityData -> {
|
||||
final String id = Protocol1_21_7To1_21_9.MAPPINGS.getEntityMappings().identifier(entityData.type());
|
||||
entityData.tag().putString("id", id);
|
||||
|
||||
+2
@@ -89,9 +89,11 @@ public final class BlockItemPacketRewriter1_21_11 extends StructuredItemRewriter
|
||||
}
|
||||
|
||||
public static void upgradeData(final Item item, final StructuredDataContainer container) {
|
||||
container.replaceKey(StructuredDataKey.CONSUMABLE1_21_5, StructuredDataKey.CONSUMABLE1_21_2);
|
||||
}
|
||||
|
||||
public static void downgradeData(final Item item, final StructuredDataContainer container) {
|
||||
container.replaceKey(StructuredDataKey.CONSUMABLE1_21_2, StructuredDataKey.CONSUMABLE1_21_5);
|
||||
container.remove(StructuredDataKey.SWING_ANIMATION);
|
||||
container.remove(StructuredDataKey.KINETIC_WEAPON);
|
||||
container.remove(StructuredDataKey.PIERCING_WEAPON);
|
||||
|
||||
+17
-2
@@ -409,7 +409,10 @@ public class ItemPacketRewriter1_9 extends ItemRewriter<ClientboundPackets1_8, S
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag();
|
||||
}
|
||||
CompoundTag entityTag = new CompoundTag();
|
||||
CompoundTag entityTag = tag.getCompoundTag("EntityTag");
|
||||
if (entityTag == null) {
|
||||
entityTag = new CompoundTag();
|
||||
}
|
||||
String entityName = EntityIds1_8.ENTITY_ID_TO_NAME.get((int) item.data());
|
||||
if (entityName != null) {
|
||||
StringTag id = new StringTag(entityName);
|
||||
@@ -493,7 +496,13 @@ public class ItemPacketRewriter1_9 extends ItemRewriter<ClientboundPackets1_8, S
|
||||
data = EntityIds1_8.ENTITY_NAME_TO_ID.get(id.getValue());
|
||||
}
|
||||
}
|
||||
tag.remove("EntityTag");
|
||||
entityTag.remove("id");
|
||||
if (entityTag.isEmpty()) {
|
||||
tag.remove("EntityTag");
|
||||
}
|
||||
}
|
||||
if (tag != null && tag.isEmpty()) {
|
||||
tag = null;
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) data);
|
||||
@@ -509,6 +518,9 @@ public class ItemPacketRewriter1_9 extends ItemRewriter<ClientboundPackets1_8, S
|
||||
}
|
||||
tag.remove("Potion");
|
||||
}
|
||||
if (tag != null && tag.isEmpty()) {
|
||||
tag = null;
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) data);
|
||||
}
|
||||
@@ -525,6 +537,9 @@ public class ItemPacketRewriter1_9 extends ItemRewriter<ClientboundPackets1_8, S
|
||||
}
|
||||
tag.remove("Potion");
|
||||
}
|
||||
if (tag != null && tag.isEmpty()) {
|
||||
tag = null;
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) data);
|
||||
}
|
||||
|
||||
+7
@@ -40,6 +40,7 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.connection.ProtocolStorablesBase;
|
||||
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPacket26_1;
|
||||
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ClientboundPackets26_1;
|
||||
import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ServerboundPacket26_1;
|
||||
@@ -58,6 +59,7 @@ import com.viaversion.viaversion.protocols.v26_2to26_3.rewriter.ComponentRewrite
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.rewriter.EntityPacketRewriter26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.rewriter.RecipeDisplayRewriter26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.rewriter.RegistryDataRewriter26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.storage.ProtocolStorables26_3;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
|
||||
@@ -254,6 +256,11 @@ public final class Protocol26_2To26_3 extends AbstractProtocol<ClientboundPacket
|
||||
super.onMappingDataLoaded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolStorablesBase createStorables() {
|
||||
return new ProtocolStorables26_3();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final UserConnection connection) {
|
||||
addEntityTracker(connection);
|
||||
|
||||
+17
-1
@@ -18,6 +18,7 @@
|
||||
package com.viaversion.viaversion.protocols.v26_2to26_3.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
@@ -235,6 +236,11 @@ public final class BlockItemPacketRewriter26_3 extends StructuredItemRewriter<Cl
|
||||
container.remove(StructuredDataKey.MAP_COLOR);
|
||||
|
||||
container.replaceKey(StructuredDataKey.INSTRUMENT26_1, StructuredDataKey.INSTRUMENT26_3);
|
||||
if (container.hasEmpty(StructuredDataKey.SWING_ANIMATION)) {
|
||||
container.remove(StructuredDataKey.SWING_ANIMATION);
|
||||
container.setEmpty(StructuredDataKey.ATTACK_ANIMATION);
|
||||
container.setEmpty(StructuredDataKey.INTERACT_ANIMATION);
|
||||
}
|
||||
container.replace(StructuredDataKey.SWING_ANIMATION, animation -> {
|
||||
container.set(StructuredDataKey.ATTACK_ANIMATION, animation);
|
||||
container.set(StructuredDataKey.INTERACT_ANIMATION, animation);
|
||||
@@ -293,7 +299,7 @@ public final class BlockItemPacketRewriter26_3 extends StructuredItemRewriter<Cl
|
||||
for (final Map.Entry<String, Tag> entry : mapDecorations.entrySet()) {
|
||||
final StringTag typeTag = ((CompoundTag) entry.getValue()).getStringTag("type");
|
||||
if (NEW_MAP_DECORATION_TYPES.contains(Key.stripMinecraftNamespace(typeTag.getValue()))) {
|
||||
typeTag.setValue("village_plains");
|
||||
typeTag.setValue("target_x");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,6 +379,11 @@ public final class BlockItemPacketRewriter26_3 extends StructuredItemRewriter<Cl
|
||||
}
|
||||
|
||||
backupTrimMaterial(backupTag, "provides_trim_material", container.get(StructuredDataKey.PROVIDES_TRIM_MATERIAL26_1));
|
||||
|
||||
final Integer mapColor = container.get(StructuredDataKey.MAP_COLOR);
|
||||
if (mapColor != null) {
|
||||
backupTag.putInt("map_color", mapColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void backupTrimMaterial(final CompoundTag tag, final String key, @Nullable final Holder<ArmorTrimMaterial1_20_5> materialHolder) {
|
||||
@@ -407,6 +418,11 @@ public final class BlockItemPacketRewriter26_3 extends StructuredItemRewriter<Cl
|
||||
if (providesTrimMaterialTag != null) {
|
||||
container.replace(StructuredDataKey.PROVIDES_TRIM_MATERIAL26_3, StructuredDataKey.PROVIDES_TRIM_MATERIAL26_1, material -> restoreTrimMaterial(material, providesTrimMaterialTag));
|
||||
}
|
||||
|
||||
final IntTag mapColorTag = backupTag.getIntTag("map_color");
|
||||
if (mapColorTag != null) {
|
||||
container.set(StructuredDataKey.MAP_COLOR, mapColorTag.asInt());
|
||||
}
|
||||
}
|
||||
|
||||
private Holder<ArmorTrimMaterial1_20_5> restoreTrimMaterial(final Holder<ArmorTrimMaterial26_3> holder, final CompoundTag tag) {
|
||||
|
||||
+36
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v26_2to26_3.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes26_3;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes26_3;
|
||||
@@ -30,6 +31,7 @@ import com.viaversion.viaversion.protocols.v1_21_11to26_1.packet.ServerboundPack
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.Protocol26_2To26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.packet.ClientboundPackets26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.packet.ServerboundPackets26_3;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.storage.ProtocolStorables26_3;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
|
||||
public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPacket26_1, Protocol26_2To26_3> {
|
||||
@@ -40,7 +42,12 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
|
||||
private static final int INTERPOLATION_STEP_TICKS = 3;
|
||||
private static final int MAIN_HAND = 0;
|
||||
private static final int OFF_HAND = 1;
|
||||
private static final int START_DESTROY_BLOCK_ACTION = 0;
|
||||
private static final int CHANGE_DESTROY_DIRECTION_ACTION = 1;
|
||||
private static final int ABORT_DESTROY_BLOCK_ACTION = 2;
|
||||
private static final int STOP_DESTROY_BLOCK_ACTION = 3;
|
||||
private static final int DESTROY_PROGRESS_PARTICLES = 2019;
|
||||
private static final int DESTROY_PROGRESS_PARTICLES_AND_SOUND = 2020;
|
||||
private static final SwingAnimation DEFAULT_SWING_ANIMATION = new SwingAnimation(EnumTypes.SWING_ANIMATION1_21_11.idFromName("whack"), 6);
|
||||
|
||||
public EntityPacketRewriter26_3(final Protocol26_2To26_3 protocol) {
|
||||
@@ -139,16 +146,45 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets26_3.PUNCH, ServerboundPackets26_1.SWING, wrapper -> {
|
||||
wrapper.write(Types.VAR_INT, 0); // Main hand
|
||||
|
||||
// Sent every tick while destroying a block
|
||||
final ProtocolStorables26_3 storables = wrapper.user().storables(protocol);
|
||||
storables.setPunched();
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets26_3.CLIENT_TICK_END, wrapper -> {
|
||||
// Needs to be sent by the server every tick after starting now
|
||||
final ProtocolStorables26_3 storables = wrapper.user().storables(protocol);
|
||||
final int ticks = storables.endDestroyTick();
|
||||
if (ticks <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PacketWrapper levelEvent = wrapper.create(ClientboundPackets26_3.LEVEL_EVENT);
|
||||
levelEvent.write(Types.INT, ticks % 4 == 0 ? DESTROY_PROGRESS_PARTICLES_AND_SOUND : DESTROY_PROGRESS_PARTICLES);
|
||||
levelEvent.write(Types.BLOCK_POSITION1_14, storables.destroyPosition());
|
||||
levelEvent.write(Types.INT, storables.destroyDirection());
|
||||
levelEvent.write(Types.BOOLEAN, false); // Global
|
||||
levelEvent.scheduleSend(Protocol26_2To26_3.class);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets26_3.PLAYER_ACTION, wrapper -> {
|
||||
final int action = wrapper.read(Types.VAR_INT);
|
||||
final ProtocolStorables26_3 storables = wrapper.user().storables(protocol);
|
||||
if (action == CHANGE_DESTROY_DIRECTION_ACTION) {
|
||||
wrapper.read(Types.BLOCK_POSITION1_14); // Position
|
||||
storables.setDestroyDirection(wrapper.read(Types.UNSIGNED_BYTE));
|
||||
wrapper.cancel(); // 26.2 has no equivalent and never sends anything here
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.write(Types.VAR_INT, action > CHANGE_DESTROY_DIRECTION_ACTION ? action - 1 : action);
|
||||
if (action == START_DESTROY_BLOCK_ACTION) {
|
||||
final BlockPosition position = wrapper.passthrough(Types.BLOCK_POSITION1_14);
|
||||
storables.startDestroying(position, wrapper.passthrough(Types.UNSIGNED_BYTE));
|
||||
} else if (action == ABORT_DESTROY_BLOCK_ACTION || action == STOP_DESTROY_BLOCK_ACTION) {
|
||||
storables.stopDestroying();
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets26_1.ANIMATE, wrapper -> {
|
||||
|
||||
+117
-2
@@ -18,12 +18,15 @@
|
||||
package com.viaversion.viaversion.protocols.v26_2to26_3.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.protocols.v26_2to26_3.Protocol26_2To26_3;
|
||||
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public final class RegistryDataRewriter26_3 extends RegistryDataRewriter {
|
||||
|
||||
@@ -36,9 +39,10 @@ public final class RegistryDataRewriter26_3 extends RegistryDataRewriter {
|
||||
final StringTag condition = term.removeUnchecked("condition");
|
||||
if (condition != null) {
|
||||
term.put("type", condition);
|
||||
updateNumberProviders(term, condition);
|
||||
}
|
||||
|
||||
if (Key.equals(condition.getValue(), "damage_source_properties")) {
|
||||
if (condition != null && Key.equals(condition.getValue(), "damage_source_properties")) {
|
||||
final CompoundTag predicate = term.getCompoundTag("predicate");
|
||||
if (predicate != null) {
|
||||
final ListTag<CompoundTag> tags = predicate.getListTag("tags", CompoundTag.class);
|
||||
@@ -51,7 +55,7 @@ public final class RegistryDataRewriter26_3 extends RegistryDataRewriter {
|
||||
super.updateEnchantmentTerm(term);
|
||||
|
||||
// has to run after super, which maps the block id under the old key
|
||||
if (Key.equals(condition.getValue(), "block_state_property")) {
|
||||
if (condition != null && Key.equals(condition.getValue(), "block_state_property")) {
|
||||
condition.setValue("minecraft:match_block");
|
||||
term.put("blocks", term.remove("block"));
|
||||
|
||||
@@ -62,6 +66,117 @@ public final class RegistryDataRewriter26_3 extends RegistryDataRewriter {
|
||||
}
|
||||
}
|
||||
|
||||
// Number providers have been split into int and float providers
|
||||
private static void updateNumberProviders(final CompoundTag term, final StringTag condition) {
|
||||
if (Key.equals(condition.getValue(), "value_check")) {
|
||||
condition.setValue("int_value_check");
|
||||
convert(term, "value", "value", RegistryDataRewriter26_3::toIntProvider);
|
||||
convert(term, "range", "test", RegistryDataRewriter26_3::updateIntRange);
|
||||
} else if (Key.equals(condition.getValue(), "time_check")) {
|
||||
convert(term, "value", "value", RegistryDataRewriter26_3::updateIntRange);
|
||||
} else if (Key.equals(condition.getValue(), "random_chance")) {
|
||||
convert(term, "chance", "chance", RegistryDataRewriter26_3::toFloatProvider);
|
||||
}
|
||||
}
|
||||
|
||||
private static Tag updateIntRange(final Tag range) {
|
||||
if (range instanceof CompoundTag rangeTag) {
|
||||
convert(rangeTag, "min", "min", RegistryDataRewriter26_3::toIntProvider);
|
||||
convert(rangeTag, "max", "max", RegistryDataRewriter26_3::toIntProvider);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
// Old providers were floats, with getInt rounding the value
|
||||
private static Tag toIntProvider(final Tag tag) {
|
||||
if (tag instanceof NumberTag numberTag) {
|
||||
return new IntTag(Math.round(numberTag.asFloat()));
|
||||
} else if (tag instanceof CompoundTag provider) {
|
||||
final String type = provider.getString("type");
|
||||
if (Key.equals(type, "binomial")) {
|
||||
convert(provider, "n", "n", RegistryDataRewriter26_3::toIntProvider);
|
||||
convert(provider, "p", "p", RegistryDataRewriter26_3::toFloatProvider);
|
||||
return provider;
|
||||
} else if (Key.equals(type, "score") && provider.getFloat("scale", 1) == 1) {
|
||||
provider.remove("scale");
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
return unary("from_float", unary("round", toFloatProvider(tag)));
|
||||
}
|
||||
|
||||
private static Tag toFloatProvider(final Tag tag) {
|
||||
if (!(tag instanceof CompoundTag provider)) {
|
||||
return tag;
|
||||
}
|
||||
|
||||
// Untyped providers used to fall back to uniform
|
||||
switch (Key.stripMinecraftNamespace(provider.getString("type", "uniform"))) {
|
||||
case "uniform" -> {
|
||||
provider.putString("type", "minecraft:uniform");
|
||||
convert(provider, "min", "min", RegistryDataRewriter26_3::toFloatProvider);
|
||||
convert(provider, "max", "max", RegistryDataRewriter26_3::toFloatProvider);
|
||||
}
|
||||
case "sum" -> {
|
||||
provider.putString("type", "minecraft:add");
|
||||
convert(provider, "summands", "inputs", summands -> {
|
||||
final ListTag<CompoundTag> inputs = new ListTag<>(CompoundTag.class);
|
||||
if (summands instanceof ListTag<?> summandsList) {
|
||||
for (final Tag summand : summandsList) {
|
||||
inputs.add(toFloatProviderCompound(summand));
|
||||
}
|
||||
}
|
||||
return inputs;
|
||||
});
|
||||
}
|
||||
case "binomial" -> {
|
||||
return unary("from_int", toIntProvider(provider));
|
||||
}
|
||||
case "score" -> {
|
||||
final Tag scale = provider.remove("scale");
|
||||
final CompoundTag score = unary("from_int", provider);
|
||||
if (scale == null) {
|
||||
return score;
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> inputs = new ListTag<>(CompoundTag.class);
|
||||
inputs.add(score);
|
||||
inputs.add(toFloatProviderCompound(scale));
|
||||
final CompoundTag product = new CompoundTag();
|
||||
product.putString("type", "minecraft:mul");
|
||||
product.put("inputs", inputs);
|
||||
return product;
|
||||
}
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
private static CompoundTag toFloatProviderCompound(final Tag tag) {
|
||||
final Tag provider = toFloatProvider(tag);
|
||||
if (provider instanceof CompoundTag compoundTag) {
|
||||
return compoundTag;
|
||||
}
|
||||
|
||||
final CompoundTag constant = new CompoundTag();
|
||||
constant.putString("type", "minecraft:constant");
|
||||
constant.put("value", provider);
|
||||
return constant;
|
||||
}
|
||||
|
||||
private static CompoundTag unary(final String type, final Tag input) {
|
||||
final CompoundTag provider = new CompoundTag();
|
||||
provider.putString("type", "minecraft:" + type);
|
||||
provider.put("input", input);
|
||||
return provider;
|
||||
}
|
||||
|
||||
private static void convert(final CompoundTag tag, final String key, final String newKey, final UnaryOperator<Tag> converter) {
|
||||
final Tag value = tag.remove(key);
|
||||
if (value != null) {
|
||||
tag.put(newKey, converter.apply(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateBlockStateProvider(final CompoundTag tag) {
|
||||
final StringTag typeTag = tag.getStringTag("type");
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.v26_2to26_3.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.connection.ProtocolStorablesBase;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class ProtocolStorables26_3 extends ProtocolStorablesBase {
|
||||
|
||||
private BlockPosition destroyPosition;
|
||||
private short destroyDirection;
|
||||
private int destroyTicks;
|
||||
private boolean punched;
|
||||
|
||||
public @Nullable BlockPosition destroyPosition() {
|
||||
return destroyPosition;
|
||||
}
|
||||
|
||||
public int destroyDirection() {
|
||||
return destroyDirection;
|
||||
}
|
||||
|
||||
public void setDestroyDirection(final short destroyDirection) {
|
||||
this.destroyDirection = destroyDirection;
|
||||
}
|
||||
|
||||
public void startDestroying(final BlockPosition position, final short direction) {
|
||||
this.destroyPosition = position;
|
||||
this.destroyDirection = direction;
|
||||
this.destroyTicks = 0;
|
||||
this.punched = false;
|
||||
}
|
||||
|
||||
public void stopDestroying() {
|
||||
this.destroyPosition = null;
|
||||
}
|
||||
|
||||
public void setPunched() {
|
||||
this.punched = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the destroy tick that just ended, or -1 if the client did not continue destroying in it.
|
||||
*
|
||||
* @return destroy tick that just ended, or -1
|
||||
*/
|
||||
public int endDestroyTick() {
|
||||
if (destroyPosition == null) {
|
||||
return -1;
|
||||
}
|
||||
if (!punched) {
|
||||
destroyPosition = null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
punched = false;
|
||||
return destroyTicks++;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.rewriter.MappingDataListener;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.util.MathUtil;
|
||||
@@ -44,7 +45,7 @@ import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class BlockRewriter<C extends ClientboundPacketType> {
|
||||
public class BlockRewriter<C extends ClientboundPacketType> implements MappingDataListener {
|
||||
protected final Protocol<C, ?, ?, ?> protocol;
|
||||
private final Type<BlockPosition> positionType;
|
||||
private final Type<CompoundTag> compoundTagType;
|
||||
|
||||
@@ -423,11 +423,11 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
||||
if (customName != null) {
|
||||
container.set(StructuredDataKey.CUSTOM_NAME, customName);
|
||||
}
|
||||
}
|
||||
|
||||
final Tag itemName = removeBackupTag(customData, "item_name");
|
||||
if (itemName != null) {
|
||||
container.set(StructuredDataKey.ITEM_NAME, itemName);
|
||||
}
|
||||
final Tag itemName = removeBackupTag(customData, "item_name");
|
||||
if (itemName != null) {
|
||||
container.set(StructuredDataKey.ITEM_NAME, itemName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+40
-6
@@ -29,6 +29,11 @@ import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class BlockRewriter1_21_5<C extends ClientboundPacketType> extends BlockRewriter<C> {
|
||||
private int signId = -1;
|
||||
private int hangingSignId = -1;
|
||||
private int shelfId = -1;
|
||||
private int campfireId = -1;
|
||||
private int vaultId = -1;
|
||||
|
||||
public BlockRewriter1_21_5(final Protocol<C, ?, ?, ?> protocol, final ChunkTypeSupplier chunkTypeSupplier, @Nullable final ChunkTypeSupplier mappedChunkTypeSupplier) {
|
||||
super(protocol, Types.BLOCK_POSITION1_14, Types.TRUSTED_COMPOUND_TAG, chunkTypeSupplier, mappedChunkTypeSupplier);
|
||||
@@ -41,17 +46,46 @@ public class BlockRewriter1_21_5<C extends ClientboundPacketType> extends BlockR
|
||||
@Override
|
||||
public void handleBlockEntity(final UserConnection connection, final BlockEntity blockEntity) {
|
||||
final CompoundTag tag = blockEntity.tag();
|
||||
if (tag == null) {
|
||||
if (tag == null || protocol.getComponentRewriter() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final FullMappings blockEntityMappings = protocol.getMappingData().getBlockEntityMappings();
|
||||
if (blockEntityMappings != null && protocol.getComponentRewriter() != null) {
|
||||
final int typeId = blockEntity.typeId();
|
||||
if (typeId == signId || typeId == hangingSignId) {
|
||||
// Update sign text components, relevant as of 1.21.5 given they are properly parsed and should not error on the client
|
||||
if (blockEntity.typeId() == blockEntityMappings.mappedId("sign") || blockEntity.typeId() == blockEntityMappings.mappedId("hanging_sign")) {
|
||||
updateSignMessages(connection, tag.getCompoundTag("front_text"));
|
||||
updateSignMessages(connection, tag.getCompoundTag("back_text"));
|
||||
updateSignMessages(connection, tag.getCompoundTag("front_text"));
|
||||
updateSignMessages(connection, tag.getCompoundTag("back_text"));
|
||||
} else if (typeId == shelfId || typeId == campfireId) {
|
||||
// Update items that are actually visible to the client
|
||||
final ListTag<CompoundTag> items = tag.getListTag("Items", CompoundTag.class);
|
||||
if (items != null) {
|
||||
for (final CompoundTag item : items) {
|
||||
updateItem(connection, item);
|
||||
}
|
||||
}
|
||||
} else if (typeId == vaultId) {
|
||||
final CompoundTag sharedData = tag.getCompoundTag("shared_data");
|
||||
if (sharedData != null) {
|
||||
updateItem(connection, sharedData.getCompoundTag("display_item"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMappingDataLoaded() {
|
||||
final FullMappings blockEntityMappings = protocol.getMappingData() != null ? protocol.getMappingData().getBlockEntityMappings() : null;
|
||||
if (blockEntityMappings != null) {
|
||||
signId = blockEntityMappings.mappedId("sign");
|
||||
hangingSignId = blockEntityMappings.mappedId("hanging_sign");
|
||||
shelfId = blockEntityMappings.mappedId("shelf");
|
||||
campfireId = blockEntityMappings.mappedId("campfire");
|
||||
vaultId = blockEntityMappings.mappedId("vault");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItem(final UserConnection connection, @Nullable final CompoundTag item) {
|
||||
if (item != null && item.getStringTag("id") != null) {
|
||||
protocol.getComponentRewriter().handleShowItem(connection, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
+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.12.1-SNAPSHOT
|
||||
projectVersion=5.12.2-SNAPSHOT
|
||||
|
||||
# Smile emoji (note that modrinth may not have added the version on release yet)
|
||||
mcVersions=26.3, 26.2, 26.1.2, 26.1.1, 26.1, 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-26.3
|
||||
velocityVersion=3.4-4.2.0
|
||||
velocityVersion=3.4-4.2.1
|
||||
|
||||
# Gradle properties
|
||||
org.gradle.daemon=true
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata.format.version = "1.1"
|
||||
gson = "2.14.0"
|
||||
snakeYaml = "2.6"
|
||||
fastutil = "8.5.15"
|
||||
vianbt = "5.3.0"
|
||||
vianbt = "5.4.0"
|
||||
mcstructs = "5-3.3.2-SNAPSHOT"
|
||||
|
||||
# Common provided
|
||||
@@ -14,7 +14,7 @@ guava = "17.0"
|
||||
|
||||
junit = "6.1.3"
|
||||
platformLauncher = "6.1.3"
|
||||
checkerQual = "4.2.2"
|
||||
checkerQual = "4.3.0"
|
||||
|
||||
# Platforms
|
||||
paper = "1.20.4-R0.1-SNAPSHOT"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
|
||||
distributionSha256Sum=dce76f55f8e251a3a1f130eb120f30b3d271de2b76c9b0729d316b5a1b6dc01f
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.1-bin.zip
|
||||
networkTimeout=10000
|
||||
retries=0
|
||||
retryBackOffMs=500
|
||||
|
||||
Vendored
+41
-11
@@ -26,6 +26,33 @@
|
||||
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||
setlocal EnableExtensions
|
||||
|
||||
@rem Catch executions from older scripts and ensure they exit cleanly.
|
||||
@rem This can be removed once we can be reasonably confident that few people
|
||||
@rem will be migrating directly to this new wrapper.
|
||||
goto afterSafetyNet
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
goto exitWithErrorLevel
|
||||
:afterSafetyNet
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
@@ -45,13 +72,14 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
1>&2 echo.
|
||||
1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
1>&2 echo.
|
||||
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
|
||||
1>&2 echo location of your Java installation.
|
||||
|
||||
"%COMSPEC%" /c exit 1
|
||||
goto exitWithErrorLevel
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
@@ -59,13 +87,14 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
1>&2 echo.
|
||||
1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
1>&2 echo.
|
||||
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
|
||||
1>&2 echo location of your Java installation.
|
||||
|
||||
"%COMSPEC%" /c exit 1
|
||||
goto exitWithErrorLevel
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
@@ -75,8 +104,9 @@ echo location of your Java installation. 1>&2
|
||||
@rem Execute gradlew
|
||||
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||
@rem which allows us to clear the local environment before executing the java command
|
||||
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
|
||||
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel & goto exitWithErrorLevel
|
||||
|
||||
@rem This label must not be changed. We rely on old scripts being able to jump to this point.
|
||||
:exitWithErrorLevel
|
||||
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||
@@ -1,3 +1,5 @@
|
||||
import com.modrinth.minotaur.TaskModrinthUpload
|
||||
|
||||
plugins {
|
||||
id("io.papermc.hangar-publish-plugin") version "0.1.4"
|
||||
id("com.modrinth.minotaur") version "2.+"
|
||||
@@ -44,10 +46,10 @@ if (runNumber != null && (!isRelease || isMainBranch)) { // Only publish release
|
||||
"[$commitHash](https://github.com/ViaVersion/ViaVersion/commit/$commitHash) ${rootProject.latestCommitMessage()}"
|
||||
}
|
||||
|
||||
val mcVersions: List<String> = (property("mcVersions") as String)
|
||||
.split(",")
|
||||
.map { it.trim() }
|
||||
modrinth {
|
||||
val mcVersions: List<String> = (property("mcVersions") as String)
|
||||
.split(",")
|
||||
.map { it.trim() }
|
||||
token.set(System.getenv("MODRINTH_TOKEN"))
|
||||
projectId.set("viaversion")
|
||||
versionType.set(if (isRelease) "release" else if (isMainBranch) "beta" else "alpha")
|
||||
@@ -56,7 +58,6 @@ if (runNumber != null && (!isRelease || isMainBranch)) { // Only publish release
|
||||
changelog.set(changelogContent)
|
||||
uploadFile.set(tasks.shadowJar.flatMap { it.archiveFile })
|
||||
gameVersions.set(mcVersions)
|
||||
loaders.add("fabric")
|
||||
loaders.add("paper")
|
||||
loaders.add("folia")
|
||||
loaders.add("velocity")
|
||||
@@ -70,6 +71,21 @@ if (runNumber != null && (!isRelease || isMainBranch)) { // Only publish release
|
||||
}
|
||||
tasks.modrinth {
|
||||
notCompatibleWithConfigurationCache("")
|
||||
finalizedBy("modrinthFabric")
|
||||
}
|
||||
// Fabric requires 1.14+ (18w43b), so it is uploaded separately with only the supported versions
|
||||
val modrinthExtension = modrinth
|
||||
tasks.register<TaskModrinthUpload>("modrinthFabric") {
|
||||
group = "publishing"
|
||||
dependsOn(tasks.assemble)
|
||||
notCompatibleWithConfigurationCache("")
|
||||
doFirst {
|
||||
modrinthExtension.loaders.set(listOf("fabric"))
|
||||
modrinthExtension.gameVersions.set(mcVersions.filter { version ->
|
||||
val (major, minor) = version.split(".").map(String::toInt)
|
||||
major > 1 || minor >= 14
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
hangarPublish {
|
||||
|
||||
Reference in new issue
Block a user