Compare commits

...
19 Commits
Author SHA1 Message Date
Nassim Jahnke fdfbee3099 Remove cushion display name 2026-10-29 11:31:43 +01:00
Nassim Jahnke 4e021f23ad 5.12.2 Release 2026-10-27 16:24:13 +01:00
Nassim Jahnke 9bf8a6b447 Remove map decorations from hover events in 26.3->26.2 2026-10-27 16:24:02 +01:00
olcxja 0452ac26f3 Fix unknown block states in registry data for pre-26.3 clients (#1372) 2026-10-27 16:03:46 +01:00
Nassim Jahnke 4938de8a33 Add more vanilla limits/sanity checks 2026-10-27 15:36:38 +01:00
Nassim Jahnke c3bdf7230c Fix project id 2026-10-21 13:35:56 +02:00
Nassim Jahnke 104d68c29f Update deps, move from minotaur to mod-publish-plugin
Minotaur is barely maintained, and mod-publish-plugin lets us remove the annoying version handling
2026-10-21 13:29:09 +02:00
Nassim Jahnke c7702cc5a3 Update VV usage 2026-10-18 22:13:36 +02:00
Florian Reuth 90fb84e012 Fix items atlas text components in 1.21.11->1.21.9 being invalid (#1364) 2026-10-18 22:05:44 +02:00
Florian Reuth 2aec24449e Add missing creative item backup code to 1.21.2->1.21 item handling (#1358) 2026-10-12 18:58:31 +02:00
Nassim Jahnke cbafc0564e Replace block state providers with dummy entries
They're never shown or used by the client.

Closes #1357
2026-10-11 20:36:51 +02:00
Florian Reuth e7b588b965 Handle long arrays inside lists in 1.12->1.11.1 (#1355) 2026-10-11 20:15:24 +02:00
Florian Reuth d85de3461a Fix spawner handling registering in 1.11->1.10 (#1354) 2026-10-11 20:14:31 +02:00
Florian Reuth 924179d2af Always rewrite enchantments in 1.19->1.18.2 (#1356) 2026-10-11 20:10:20 +02:00
mfishma 465dc5bbef Fix 26.3 map decorations not getting restored (#1350) 2026-10-11 09:27:38 +02:00
Rocco 71038072ed Save original int map ID if conversion is lossy in 1.13->1.12 (#1341) 2026-10-11 09:26:05 +02:00
mfishma 6cdf663490 Map poplar leaves backwards to varied leaves in 26.3->26.2 2026-10-09 16:44:14 +02:00
Nassim Jahnke 0ba32cf4a5 Handle experimental minecart velocity in 1.21.2->1.21
Fixes #1333
2026-10-09 15:46:04 +02:00
Nassim Jahnke 5b1c323274 Bump version to 5.12.2-SNAPSHOT 2026-10-09 15:35:31 +02:00
27 changed files with 299 additions and 128 deletions

No files matched your search

+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
cache-disabled: false
cache-provider: basic
- name: Set up JDK 17
uses: actions/setup-java@v6.0.1
uses: actions/setup-java@v6.1.0
with:
distribution: 'temurin'
java-version: 17
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
cache-disabled: false
cache-provider: basic
- name: Set up JDK 17
uses: actions/setup-java@v6.0.1
uses: actions/setup-java@v6.1.0
with:
distribution: 'temurin'
java-version: 17
@@ -40,5 +40,5 @@ jobs:
- name: Publish to Modrinth
env:
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew modrinth --stacktrace
run: ./gradlew publishMods --stacktrace
continue-on-error: true
@@ -82,7 +82,7 @@ import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "5.12.1";
String MINIMUM_VV_VERSION = "5.12.2";
default void init(final File configFile) {
init(new ViaBackwardsConfig(configFile, getLogger()));
@@ -21,6 +21,7 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.util.Key;
@@ -69,6 +70,28 @@ public class BackwardsRegistryRewriter extends RegistryDataRewriter {
}
}
@Override
protected boolean updateBlockState(final Tag blockStateTag) {
if (!(blockStateTag instanceof CompoundTag blockState) || blockState.getStringTag("Name") == null) {
return super.updateBlockState(blockStateTag);
}
// Up to 26.2, block states use "Name" and "Properties" instead of "id" and "properties"
final FullMappings blockMappings = protocol.getMappingData().getFullBlockMappings();
if (blockMappings == null) {
return false;
}
final int blockId = blockMappings.id(blockState.getString("Name"));
if (blockId == -1 || protocol.getMappingData().hasBlockChanged(blockId)) {
// Replace unknown or changed blocks with a dummy state, else the client will fail to load the registry
blockState.putString("Name", "minecraft:dirt");
blockState.remove("Properties");
return true;
}
return false;
}
private void updateBiomeEffects(final CompoundTag effects) {
updateSound(effects.getCompoundTag("mood_sound"), "sound");
updateSound(effects.getCompoundTag("additions_sound"), "sound");
@@ -101,10 +124,16 @@ public class BackwardsRegistryRewriter extends RegistryDataRewriter {
}
final String mappedSound = protocol.getMappingData().getMappedNamedSound(sound);
if (mappedSound == null) {
if (mappedSound != null) {
tag.putString(name, mappedSound);
} else if (name.equals("sound_id")) {
// If it's already an inlined sound
tag.putString(name, "minecraft:intentionally_empty");
} else {
tag.putString(name, mappedSound);
// Write as custom sound, so the id doesn't actually need to exist later on
final CompoundTag soundEvent = new CompoundTag();
soundEvent.putString("sound_id", "minecraft:intentionally_empty");
tag.put(name, soundEvent);
}
}
}
@@ -33,6 +33,7 @@ import com.viaversion.viaversion.libs.fastutil.ints.Int2IntMap;
import com.viaversion.viaversion.libs.fastutil.objects.ObjectIterator;
import com.viaversion.viaversion.rewriter.IdRewriteFunction;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Limit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -195,7 +196,12 @@ public class StructuredEnchantmentRewriter {
}
final Enchantments enchantments = new Enchantments(tag.remove(itemRewriter.nbtTagName("show_" + key.identifier())) != null);
int i = 0;
for (final CompoundTag enchantment : enchantmentsTag) {
if (i++ > 255) {
break;
}
enchantments.add(enchantment.getInt("id"), enchantment.getInt("lvl"));
}
data.set(key, enchantments);
@@ -40,7 +40,6 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
import com.viaversion.viaversion.protocols.v1_10to1_11.data.EntityMappings1_11;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ServerboundPackets1_9_3;
import com.viaversion.viaversion.util.IdAndData;
import java.util.Arrays;
import java.util.Optional;
@@ -252,7 +251,7 @@ public class BlockItemPacketRewriter1_11 extends LegacyBlockItemRewriter<Clientb
@Override
protected void registerRewrites() {
// Handle spawner block entity (map to itself with custom handler)
MappedLegacyBlockItem data = itemReplacements.computeIfAbsent(IdAndData.toRawData(52), s -> new MappedLegacyBlockItem(52));
MappedLegacyBlockItem data = blockReplacements.computeIfAbsent(compress(52, -1), s -> new MappedLegacyBlockItem(52, (short) -1, null, MappedLegacyBlockItem.Type.BLOCK));
data.setBlockEntityHandler((b, tag) -> EntityMappings1_11.toClientSpawner(tag, true));
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName());
@@ -18,8 +18,10 @@
package com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter;
import com.google.common.primitives.Ints;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntArrayTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.LongArrayTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
@@ -230,6 +232,30 @@ public class BlockItemPacketRewriter1_12 extends LegacyBlockItemRewriter<Clientb
backupTag.put(entry.getKey(), fromLongArrayTag(tag));
iterator.remove();
hasLongArrayTag = true;
} else if (entry.getValue() instanceof ListTag<?> tag) {
if (tag.getElementType() == LongArrayTag.class) {
// Lists can't hold mixed tag types, so the whole list has to be removed
ListTag<IntArrayTag> intArrays = new ListTag<>(IntArrayTag.class);
for (Tag longArrayTag : tag) {
intArrays.add(fromLongArrayTag((LongArrayTag) longArrayTag));
}
backupTag.put(entry.getKey(), intArrays);
iterator.remove();
hasLongArrayTag = true;
} else if (tag.getElementType() == CompoundTag.class) {
// Backed up by list index
CompoundTag listBackupTag = new CompoundTag();
for (int i = 0; i < tag.size(); i++) {
CompoundTag nestedBackupTag = new CompoundTag();
if (handleNbtToClient((CompoundTag) tag.get(i), nestedBackupTag)) {
listBackupTag.put(Integer.toString(i), nestedBackupTag);
}
}
if (!listBackupTag.isEmpty()) {
backupTag.put(entry.getKey(), listBackupTag);
hasLongArrayTag = true;
}
}
}
}
return hasLongArrayTag;
@@ -252,11 +278,33 @@ public class BlockItemPacketRewriter1_12 extends LegacyBlockItemRewriter<Clientb
private void handleNbtToServer(CompoundTag compoundTag, CompoundTag backupTag) {
// Restore the removed long array tags
for (Map.Entry<String, Tag> entry : backupTag) {
if (entry.getValue() instanceof CompoundTag) {
CompoundTag nestedTag = compoundTag.getCompoundTag(entry.getKey());
handleNbtToServer(nestedTag, (CompoundTag) entry.getValue());
} else {
compoundTag.put(entry.getKey(), fromIntArrayTag((IntArrayTag) entry.getValue()));
if (entry.getValue() instanceof CompoundTag nestedBackupTag) {
Tag tag = compoundTag.get(entry.getKey());
if (tag instanceof CompoundTag nestedTag) {
handleNbtToServer(nestedTag, nestedBackupTag);
} else if (tag instanceof ListTag<?> listTag) {
handleListToServer(listTag, nestedBackupTag);
}
} else if (entry.getValue() instanceof IntArrayTag intArrayTag) {
compoundTag.put(entry.getKey(), fromIntArrayTag(intArrayTag));
} else if (entry.getValue() instanceof ListTag<?> intArrays) {
ListTag<LongArrayTag> longArrays = new ListTag<>(LongArrayTag.class);
for (Tag intArrayTag : intArrays) {
if (intArrayTag instanceof IntArrayTag) {
longArrays.add(fromIntArrayTag((IntArrayTag) intArrayTag));
}
}
compoundTag.put(entry.getKey(), longArrays);
}
}
}
private void handleListToServer(ListTag<?> listTag, CompoundTag backupTag) {
for (Map.Entry<String, Tag> entry : backupTag) {
Integer index = Ints.tryParse(entry.getKey());
if (index != null && index >= 0 && index < listTag.size()
&& listTag.get(index) instanceof CompoundTag nestedTag && entry.getValue() instanceof CompoundTag nestedBackupTag) {
handleNbtToServer(nestedTag, nestedBackupTag);
}
}
}
@@ -275,7 +323,7 @@ public class BlockItemPacketRewriter1_12 extends LegacyBlockItemRewriter<Clientb
private LongArrayTag fromIntArrayTag(IntArrayTag tag) {
long[] longArray = new long[tag.length() / 2];
int[] intArray = tag.getValue();
for (int i = 0, j = 0; i < intArray.length; i += 2, j++) {
for (int i = 0, j = 0; j < longArray.length; i += 2, j++) {
longArray[j] = (long) intArray[i] << 32 | ((long) intArray[i + 1] & 0xFFFFFFFFL);
}
return new LongArrayTag(longArray);
@@ -463,8 +463,12 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
if (item.identifier() == 358) { // map
Tag mapTag = tag.remove("map");
if (!gotRawIdFromTag && mapTag instanceof NumberTag) {
item.setData(((NumberTag) mapTag).asShort());
if (!gotRawIdFromTag && mapTag instanceof NumberTag numberTag) {
item.setData((short) (numberTag.asInt() & 0x7FFF));
// Keep original ID if conversion is lossy
if (numberTag.asInt() > Short.MAX_VALUE) {
tag.put("map", numberTag);
}
}
}
@@ -667,7 +671,9 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
}
if (item.identifier() == 358) { // map
if (tag == null) item.setTag(tag = new CompoundTag());
tag.putInt("map", item.data());
if (!tag.contains("map")) {
tag.putInt("map", item.data());
}
}
// NBT Changes
@@ -54,6 +54,7 @@ import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ServerboundPacke
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
import com.viaversion.viaversion.util.CipherUtil;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Limit;
import com.viaversion.viaversion.util.Pair;
import com.viaversion.viaversion.util.TagUtil;
import java.security.SignatureException;
@@ -230,7 +231,7 @@ public final class Protocol1_19_1To1_19 extends BackwardsProtocol<ClientboundPac
final SignableCommandArgumentsProvider argumentsProvider = Via.getManager().getProviders().get(SignableCommandArgumentsProvider.class);
if (chatSession != null && argumentsProvider != null) {
final int signatures = wrapper.read(Types.VAR_INT);
final int signatures = Limit.max(wrapper.read(Types.VAR_INT), 8);
for (int i = 0; i < signatures; i++) {
wrapper.read(Types.STRING); // Argument name
wrapper.read(Types.BYTE_ARRAY_PRIMITIVE); // Signature
@@ -41,7 +41,9 @@ import com.viaversion.viaversion.api.minecraft.signature.storage.ChatSession1_19
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.BitSetType;
import com.viaversion.viaversion.api.type.types.ByteArrayType;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_18;
@@ -61,6 +63,7 @@ import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
import com.viaversion.viaversion.util.CipherUtil;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Limit;
import com.viaversion.viaversion.util.Pair;
import java.security.SignatureException;
import java.util.BitSet;
@@ -70,6 +73,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundPackets1_19_3, ClientboundPackets1_19_1, ServerboundPackets1_19_3, ServerboundPackets1_19_1> {
public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.19.3", "1.19", Protocol1_19_1To1_19_3.class);
private static final Type<PlayerMessageSignature[]> LAST_SEEN_MESSAGES_TYPE = new ArrayType<>(Types.PLAYER_MESSAGE_SIGNATURE, 5);
private final EntityPacketRewriter1_19_3 entityRewriter = new EntityPacketRewriter1_19_3(this);
private final BlockItemPacketRewriter1_19_3 itemRewriter = new BlockItemPacketRewriter1_19_3(this);
private final ParticleRewriter<ClientboundPackets1_19_3> particleRewriter = new ParticleRewriter<>(this);
@@ -207,7 +211,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundP
map(Types.LONG); // Salt
read(Types.BYTE_ARRAY_PRIMITIVE); // Signature
read(Types.BOOLEAN); // Signed preview
read(Types.PLAYER_MESSAGE_SIGNATURE_ARRAY); // Last seen messages
read(LAST_SEEN_MESSAGES_TYPE); // Last seen messages
read(Types.OPTIONAL_PLAYER_MESSAGE_SIGNATURE); // Last received message
handler(wrapper -> {
final ChatSession1_19_3 chatSession = wrapper.user().get(ChatSession1_19_3.class);
@@ -250,7 +254,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundP
final long timestamp = wrapper.get(Types.LONG, 0);
final long salt = wrapper.get(Types.LONG, 1);
final int signatures = wrapper.read(Types.VAR_INT);
final int signatures = Limit.max(wrapper.read(Types.VAR_INT), 8);
for (int i = 0; i < signatures; i++) {
wrapper.read(Types.STRING); // Name
wrapper.read(Types.BYTE_ARRAY_PRIMITIVE); // Signature
@@ -282,7 +286,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundP
wrapper.write(Types.VAR_INT, offset);
wrapper.write(new BitSetType(20), acknowledged);
});
read(Types.PLAYER_MESSAGE_SIGNATURE_ARRAY); // Last seen messages
read(LAST_SEEN_MESSAGES_TYPE); // Last seen messages
read(Types.OPTIONAL_PLAYER_MESSAGE_SIGNATURE); // Last received message
}
});
@@ -24,21 +24,14 @@ import com.viaversion.viabackwards.protocol.v1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viabackwards.protocol.v1_19to1_18_2.storage.LastDeathPosition;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.GlobalBlockPosition;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_18;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.util.MathUtil;
public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter<ClientboundPackets1_19, ServerboundPackets1_17, Protocol1_19To1_18_2> {
@@ -187,6 +180,7 @@ public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter<Cli
final int identifier = item.identifier();
item = super.handleItemToClient(connection, item);
enchantmentRewriter.handleToClient(item);
if (identifier != 834) {
return item;
@@ -205,8 +199,6 @@ public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter<Cli
lodestonePosTag.putInt("X", position.x());
lodestonePosTag.putInt("Y", position.y());
lodestonePosTag.putInt("Z", position.z());
enchantmentRewriter.handleToClient(item);
return item;
}
@@ -56,6 +56,7 @@ import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.rewriter.block.BlockRewriter1_21_5;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.TagUtil;
import java.util.function.Function;
@@ -75,7 +76,7 @@ public final class Protocol1_21_11To1_21_9 extends BackwardsProtocol<Clientbound
private final NBTComponentRewriter<ClientboundPacket1_21_11> translatableRewriter = new ComponentRewriter1_21_11(this);
private final TagRewriter<ClientboundPacket1_21_11> tagRewriter = new TagRewriter<>(this);
private final RecipeDisplayRewriter<ClientboundPacket1_21_11> recipeRewriter = new RecipeDisplayRewriter1_21_5<>(this);
private final BlockRewriter<ClientboundPacket1_21_11> blockRewriter = BlockRewriter.for1_20_2(this, ChunkType1_21_5::new);
private final BlockRewriter<ClientboundPacket1_21_11> blockRewriter = new BlockRewriter1_21_5<>(this, ChunkType1_21_5::new);
private final BackwardsRegistryRewriter registryDataRewriter = new BackwardsRegistryRewriter(this) {
@Override
protected void updateType(final CompoundTag tag, final String key, final FullMappings mappings) {
@@ -18,11 +18,13 @@
package com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPacket1_21_11;
import com.viaversion.viaversion.util.Key;
public final class ComponentRewriter1_21_11 extends NBTComponentRewriter<ClientboundPacket1_21_11> {
@@ -30,6 +32,16 @@ public final class ComponentRewriter1_21_11 extends NBTComponentRewriter<Clientb
super(protocol);
}
@Override
protected void processCompoundTag(final UserConnection connection, final CompoundTag tag) {
super.processCompoundTag(connection, tag);
final StringTag atlas = tag.getStringTag("atlas");
if (atlas != null && Key.stripMinecraftNamespace(atlas.getValue()).equals("items")) {
atlas.setValue("blocks");
}
}
@Override
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
super.handleShowItem(connection, itemTag, componentsTag);
@@ -86,8 +86,6 @@ public final class Protocol1_21_2To1_21 extends BackwardsProtocol<ClientboundPac
wrapper.write(Types.STRING_ARRAY, ArrayUtil.add(enabledFeatures, "bundle"));
});
cancelClientbound(ClientboundPackets1_21_2.MOVE_MINECART_ALONG_TRACK); // TODO
registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> {
wrapper.passthrough(Types.UUID); // UUID
wrapper.passthrough(Types.STRING); // Name
@@ -45,6 +45,7 @@ import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantable;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
@@ -52,11 +53,13 @@ import com.viaversion.viaversion.api.minecraft.item.data.Equippable;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.ItemModel;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData;
import com.viaversion.viaversion.api.minecraft.item.data.Repairable;
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.minecraft.item.data.consumable.ApplyStatusEffects;
import com.viaversion.viaversion.api.minecraft.item.data.consumable.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.consumable.ConsumeEffect;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
@@ -570,6 +573,34 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsFullStructured
backupTag.put("death_protection", tag);
}
final Consumable1_21_2 consumable = data.get(StructuredDataKey.CONSUMABLE1_21_2);
if (consumable != null) {
final CompoundTag tag = new CompoundTag();
tag.putFloat("consume_seconds", consumable.consumeSeconds());
tag.putInt("animation", consumable.animationType());
saveSoundEventHolder(tag, consumable.sound());
tag.putBoolean("has_consume_particles", consumable.hasConsumeParticles());
final ListTag<CompoundTag> effects = new ListTag<>(CompoundTag.class);
for (final ConsumeEffect<?> effect : consumable.consumeEffects()) {
final CompoundTag effectTag = new CompoundTag();
convertConsumableEffect(effectTag, effect);
effects.add(effectTag);
}
tag.put("consume_effects", effects);
backupTag.put("consumable", tag);
}
final DamageResistant1_21_2 damageResistant = data.get(StructuredDataKey.DAMAGE_RESISTANT1_21_2);
if (damageResistant != null) {
backupTag.putString("damage_resistant", damageResistant.typesTagKey().original());
}
final PotionContents potionContents = data.get(StructuredDataKey.POTION_CONTENTS1_21_2);
if (potionContents != null && potionContents.customName() != null) {
backupTag.putString("potion_custom_name", potionContents.customName());
}
if (!backupTag.isEmpty()) {
saveTag(createCustomTag(item), backupTag, "inconvertible_data");
}
@@ -730,6 +761,34 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsFullStructured
data.set(StructuredDataKey.DEATH_PROTECTION1_21_2, new DeathProtection(effects.toArray(ConsumeEffect[]::new)));
}
final CompoundTag consumable = backupTag.getCompoundTag("consumable");
if (consumable != null) {
final List<ConsumeEffect<?>> effects = new ArrayList<>();
for (final CompoundTag effectTag : consumable.getListTag("consume_effects", CompoundTag.class)) {
final ConsumeEffect<?> effect = convertConsumableEffect(effectTag);
if (effect != null) {
effects.add(effect);
}
}
data.set(StructuredDataKey.CONSUMABLE1_21_2, new Consumable1_21_2(
consumable.getFloat("consume_seconds"),
consumable.getInt("animation"),
restoreSoundEventHolder(consumable),
consumable.getBoolean("has_consume_particles"),
effects.toArray(ConsumeEffect[]::new)
));
}
final String damageResistant = backupTag.getString("damage_resistant");
if (damageResistant != null) {
data.set(StructuredDataKey.DAMAGE_RESISTANT1_21_2, new DamageResistant1_21_2(Key.of(damageResistant)));
}
final String potionCustomName = backupTag.getString("potion_custom_name");
if (potionCustomName != null) {
data.replace(StructuredDataKey.POTION_CONTENTS1_21_2, potionContents -> new PotionContents(potionContents.potion(), potionContents.customColor(), potionContents.customEffects(), potionCustomName));
}
removeCustomTag(data, customData);
}
}
@@ -199,6 +199,48 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
writePackedRotation(wrapper, yaw, pitch);
});
protocol.registerClientbound(ClientboundPackets1_21_2.MOVE_MINECART_ALONG_TRACK, ClientboundPackets1_21.TELEPORT_ENTITY, wrapper -> {
// Only sent with the experimental minecart improvements, old clients can only lerp to a single position
final int entityId = wrapper.passthrough(Types.VAR_INT);
final int steps = wrapper.read(Types.VAR_INT);
if (steps == 0) {
wrapper.cancel();
return;
}
double x = 0, y = 0, z = 0;
double movementX = 0, movementY = 0, movementZ = 0;
byte yaw = 0, pitch = 0;
for (int i = 0; i < steps; i++) {
x = wrapper.read(Types.DOUBLE);
y = wrapper.read(Types.DOUBLE);
z = wrapper.read(Types.DOUBLE);
movementX = wrapper.read(Types.DOUBLE);
movementY = wrapper.read(Types.DOUBLE);
movementZ = wrapper.read(Types.DOUBLE);
yaw = wrapper.read(Types.BYTE);
pitch = wrapper.read(Types.BYTE);
wrapper.read(Types.FLOAT); // Weight
}
wrapper.write(Types.DOUBLE, x);
wrapper.write(Types.DOUBLE, y);
wrapper.write(Types.DOUBLE, z);
wrapper.write(Types.BYTE, (byte) (128 - yaw));
wrapper.write(Types.BYTE, pitch);
wrapper.write(Types.BOOLEAN, false); // On ground
wrapper.send(Protocol1_21_2To1_21.class);
wrapper.cancel();
final PacketWrapper entityMotionPacket = wrapper.create(ClientboundPackets1_21.SET_ENTITY_MOTION);
entityMotionPacket.write(Types.VAR_INT, entityId);
entityMotionPacket.write(Types.SHORT, VelocityUtil.toLegacyVelocity(movementX));
entityMotionPacket.write(Types.SHORT, VelocityUtil.toLegacyVelocity(movementY));
entityMotionPacket.write(Types.SHORT, VelocityUtil.toLegacyVelocity(movementZ));
entityMotionPacket.send(Protocol1_21_2To1_21.class);
});
protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_ROTATION, ClientboundPackets1_21.PLAYER_LOOK_AT, wrapper -> {
final float yaw = wrapper.read(Types.FLOAT);
final float pitch = wrapper.read(Types.FLOAT);
@@ -49,6 +49,7 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks;
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks.DamageReduction;
import com.viaversion.viaversion.api.minecraft.item.data.BlocksAttacks.ItemDamageFunction;
import com.viaversion.viaversion.api.minecraft.item.data.BreakSound;
import com.viaversion.viaversion.api.minecraft.item.data.Equippable;
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
import com.viaversion.viaversion.api.minecraft.item.data.TooltipDisplay;
@@ -296,6 +297,10 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
}
final OriginalHashedItem originalHashedItem = backedUpOriginalHashes(originalHashes, item);
if (originalHashedItem == null) {
return null;
}
// Return as regular hashed item if the tag was forced in this protocol and it would otherwise be passed on
// to the final serverbound protocol without the required handling.
return originalHashedItem.backupTagName().equals(nbtTagName()) ? originalHashedItem.asRegularItem() : originalHashedItem;
@@ -485,7 +490,10 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
}
});
saveHolderData(StructuredDataKey.BREAK_SOUND, dataContainer, backupTag, this::saveSoundEvent);
final BreakSound breakSound = dataContainer.get(StructuredDataKey.BREAK_SOUND);
if (breakSound != null) {
backupTag.put(StructuredDataKey.BREAK_SOUND.identifier(), holderToTag(breakSound.sound(), this::saveSoundEvent));
}
}
@Override
@@ -606,7 +614,9 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
restoreIntData(StructuredDataKey.WOLF_VARIANT, data, backupTag);
restoreIntData(StructuredDataKey.WOLF_COLLAR, data, backupTag);
restoreHolderData(StructuredDataKey.BREAK_SOUND, data, backupTag, this::tagToSound);
if (backupTag.contains(StructuredDataKey.BREAK_SOUND.identifier())) {
data.set(StructuredDataKey.BREAK_SOUND, new BreakSound(restoreHolder(backupTag, StructuredDataKey.BREAK_SOUND.identifier(), this::tagToSound)));
}
restoreHolderData(StructuredDataKey.PAINTING_VARIANT, data, backupTag, tag -> {
final int width = tag.getInt("width");
final int height = tag.getInt("height");
@@ -85,7 +85,7 @@ public final class BlockItemPacketRewriter26_3 extends BackwardsStructuredItemRe
final int icons = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < icons; i++) {
final int decorationType = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, Math.min(decorationType, 34)); // Map new ones to trial chambers
wrapper.write(Types.VAR_INT, decorationType > 34 ? 4 : decorationType); // Map new ones to target_x (4)
wrapper.passthrough(Types.BYTE); // X
wrapper.passthrough(Types.BYTE); // Y
wrapper.passthrough(Types.BYTE); // Rotation
@@ -561,7 +561,7 @@ public final class BlockItemPacketRewriter26_3 extends BackwardsStructuredItemRe
final CompoundTag types = new CompoundTag();
for (final Map.Entry<String, Tag> entry : mapDecorations.entrySet()) {
types.put(entry.getKey(), ((CompoundTag) entry.getValue()).getStringTag("type"));
types.put(entry.getKey(), ((CompoundTag) entry.getValue()).getStringTag("type").copy());
}
backupTag.put("map_decorations", types);
}
@@ -40,7 +40,8 @@ public final class ComponentRewriter26_3 extends NBTComponentRewriter<Clientboun
removeDataComponents(componentsTag, StructuredDataKey.PROVIDES_TRIM_MATERIAL26_3, StructuredDataKey.PROVIDES_POTTERY_PATTERN, StructuredDataKey.BLOCK_TRANSFORMER,
StructuredDataKey.COMPOSTABLE, StructuredDataKey.INTERACT_ANIMATION, StructuredDataKey.ATTACK_ANIMATION, StructuredDataKey.TRIM26_3,
StructuredDataKey.COOKING_FUEL, StructuredDataKey.BREWING_FUEL, StructuredDataKey.VILLAGER_FOOD, StructuredDataKey.MOB_VISIBILITY,
StructuredDataKey.SIGN_TEXT_BACK, StructuredDataKey.SIGN_TEXT_FRONT, StructuredDataKey.WAXED, StructuredDataKey.CUSHION_COLOR);
StructuredDataKey.SIGN_TEXT_BACK, StructuredDataKey.SIGN_TEXT_FRONT, StructuredDataKey.WAXED, StructuredDataKey.CUSHION_COLOR,
StructuredDataKey.MAP_DECORATIONS);
removeDataComponents(componentsTag, "pot_decorations");
}
}
@@ -276,7 +276,7 @@ public final class EntityPacketRewriter26_3 extends EntityRewriter<ClientboundPa
@Override
public void onMappingDataLoaded() {
super.onMappingDataLoaded();
mapEntityTypeWithData(EntityTypes26_3.CUSHION, EntityTypes26_3.FALLING_BLOCK).tagName();
mapEntityTypeWithData(EntityTypes26_3.CUSHION, EntityTypes26_3.FALLING_BLOCK);
}
@Override
@@ -34,6 +34,8 @@ public final class RegistryDataRewriter26_3 extends BackwardsRegistryRewriter {
public RegistryDataRewriter26_3(final Protocol26_3To26_2 protocol) {
super(protocol);
addEnchantmentEffectRewriter("replace_disk", this::replaceBlockStateProvider);
addEnchantmentEffectRewriter("replace_block", this::replaceBlockStateProvider);
}
@Override
@@ -86,31 +88,18 @@ public final class RegistryDataRewriter26_3 extends BackwardsRegistryRewriter {
@Override
public boolean updateBlockStateProvider(final CompoundTag tag) {
String type = tag.getString("type");
if (type == null) {
// Move block state to a block provider
final CompoundTag stateTag = tag.copy();
handleFullBlockState(stateTag);
tag.put("state", stateTag);
tag.putString("type", "simple_state_provider");
return true;
}
return false; // Handled in replaceBlockStateProvider, as providers can also be registry references now
}
type = Key.stripMinecraftNamespace(type);
switch (type) {
case "simple_state_provider", "rotated_block_provider" -> {
handleBlockState(tag, "state");
}
case "weighted_state_provider" -> {
for (final CompoundTag entry : tag.getListTag("entries", CompoundTag.class)) {
handleBlockState(entry, "data");
}
}
case "noise_threshold_provider" -> {
handleBlockState(tag, "default_state");
}
}
return super.updateBlockStateProvider(tag);
private void replaceBlockStateProvider(final CompoundTag effect) {
// Provider types were renamed and reworked, but they're only actually used on the server
final CompoundTag state = new CompoundTag();
state.putString("Name", "minecraft:dirt");
final CompoundTag provider = new CompoundTag();
provider.putString("type", "minecraft:simple_state_provider");
provider.put("state", state);
effect.put("block_state", provider);
}
@Override
@@ -121,18 +110,6 @@ public final class RegistryDataRewriter26_3 extends BackwardsRegistryRewriter {
}
}
private void handleBlockState(final CompoundTag parent, final String key) {
final Tag blockStateTag = parent.get(key);
if (blockStateTag instanceof CompoundTag compoundTag) {
handleFullBlockState(compoundTag);
} else if (blockStateTag instanceof StringTag stringTag) {
// Needs to be a compound tag in older versions
final CompoundTag updatedBlockStateTag = new CompoundTag();
updatedBlockStateTag.putString("Name", stringTag.getValue());
parent.put(key, updatedBlockStateTag);
}
}
private void handleFullBlockState(final CompoundTag tag) {
final Tag id = tag.remove("id");
tag.put("Name", id);
+2 -3
View File
@@ -1,7 +1,6 @@
projectVersion=5.12.1
projectVersion=5.12.3-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
# note that modrinth may not have added the version on release yet
mcVersionRange=1.10-26.3
velocityVersion=3.4-4.2.1
+2 -2
View File
@@ -3,14 +3,14 @@ metadata.format.version = "1.1"
[versions]
# ViaVersion
viaver = "5.12.1-SNAPSHOT"
viaver = "5.12.2-SNAPSHOT"
# Common provided
netty = "4.0.20.Final"
guava = "17.0"
log4j = "2.8.1"
checkerQual = "4.3.0"
checkerQual = "4.3.1"
# Platforms
paper = "1.16.5-R0.1-SNAPSHOT"
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=dce76f55f8e251a3a1f130eb120f30b3d271de2b76c9b0729d316b5a1b6dc01f
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.1-bin.zip
distributionSha256Sum=21bd5da2de49b642904077f38c0efdc7778e92b3ed0889392dca61b97e389607
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
+32 -45
View File
@@ -1,8 +1,6 @@
import com.modrinth.minotaur.TaskModrinthUpload
plugins {
id("me.modmuss50.mod-publish-plugin") version "2.2.1"
id("io.papermc.hangar-publish-plugin") version "0.1.4"
id("com.modrinth.minotaur") version "2.+"
// A nice no-conflict comment for patching in downgrading
}
@@ -45,45 +43,37 @@ if (runNumber != null && (!isRelease || isMainBranch)) { // Only publish release
val commitHash = rootProject.latestCommitHash()
"[$commitHash](https://github.com/ViaVersion/ViaBackwards/commit/$commitHash) ${rootProject.latestCommitMessage()}"
}
val mcVersions: List<String> = (property("mcVersions") as String)
.split(",")
.map { it.trim() }
modrinth {
token.set(System.getenv("MODRINTH_TOKEN"))
projectId.set("viabackwards")
versionType.set(if (isRelease) "release" else if (isMainBranch) "beta" else "alpha")
versionNumber.set(suffixedVersion)
versionName.set(suffixedVersion)
changelog.set(changelogContent)
uploadFile.set(tasks.shadowJar.flatMap { it.archiveFile })
gameVersions.set(mcVersions)
loaders.add("paper")
loaders.add("folia")
loaders.add("velocity")
autoAddDependsOn.set(false)
detectLoaders.set(false)
dependencies {
required.project("viaversion")
optional.project("viafabric")
optional.project("viarewind")
val mcVersionRange = property("mcVersionRange") as String
val (mcVersionStart, mcVersionEnd) = mcVersionRange.split("-", limit = 2)
publishMods {
file = tasks.shadowJar.flatMap { it.archiveFile }
type = if (isRelease) STABLE else if (isMainBranch) BETA else ALPHA
version = suffixedVersion
displayName = suffixedVersion
changelog = changelogContent
val modrinthOptions = modrinthOptions {
accessToken = providers.environmentVariable("MODRINTH_TOKEN")
projectId = "NpvuJQoq"
requires("viaversion")
optional("viafabric", "viarewind")
}
}
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
})
modrinth {
from(modrinthOptions)
modLoaders.addAll("paper", "folia", "velocity")
minecraftVersionRange {
start = mcVersionStart
end = mcVersionEnd
}
}
// Fabric requires 1.14+ (18w43b), so it is uploaded separately with only the supported versions...
modrinth("modrinthFabric") {
from(modrinthOptions)
modLoaders.add("fabric")
minecraftVersionRange {
start = "1.14"
end = mcVersionEnd
}
}
}
@@ -97,7 +87,7 @@ if (runNumber != null && (!isRelease || isMainBranch)) { // Only publish release
platforms {
paper {
jar = tasks.shadowJar.flatMap { it.archiveFile }
platformVersions = listOf(property("mcVersionRange") as String)
platformVersions = listOf(mcVersionRange)
dependencies {
hangar("ViaVersion") {
required = true
@@ -122,7 +112,4 @@ if (runNumber != null && (!isRelease || isMainBranch)) { // Only publish release
}
}
}
tasks.named("publishPluginPublicationToHangar") {
notCompatibleWithConfigurationCache("")
}
}
@@ -47,7 +47,7 @@
},
{
"id": "viaversion",
"version": "[5.12.1-SNAPSHOT,)"
"version": "[5.12.2-SNAPSHOT,)"
}
]
},