Start working on 23w31a

This commit is contained in:
Nassim Jahnke 2023-08-05 14:12:45 +10:00
parent 2904ad54c6
commit e12d491b53
12 changed files with 712 additions and 7 deletions

View File

@ -5,7 +5,7 @@ plugins {
allprojects {
group = "com.viaversion"
version = "4.7.1-SNAPSHOT"
version = "4.8.0-23w31a-SNAPSHOT"
description = "Allow older clients to join newer server versions."
}

View File

@ -51,6 +51,7 @@ import com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.Protocol1_19_
import com.viaversion.viabackwards.protocol.protocol1_19_3to1_19_4.Protocol1_19_3To1_19_4;
import com.viaversion.viabackwards.protocol.protocol1_19_4to1_20.Protocol1_19_4To1_20;
import com.viaversion.viabackwards.protocol.protocol1_19to1_19_1.Protocol1_19To1_19_1;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.ProtocolManager;
@ -61,7 +62,7 @@ import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "4.7.0";
String MINIMUM_VV_VERSION = "4.8.0";
String IMPL_VERSION = "$IMPL_VERSION";
/**
@ -126,6 +127,7 @@ public interface ViaBackwardsPlatform {
protocolManager.registerProtocol(new Protocol1_19_3To1_19_4(), ProtocolVersion.v1_19_3, ProtocolVersion.v1_19_4);
protocolManager.registerProtocol(new Protocol1_19_4To1_20(), ProtocolVersion.v1_19_4, ProtocolVersion.v1_20);
protocolManager.registerProtocol(new Protocol1_20To1_20_2(), ProtocolVersion.v1_20, ProtocolVersion.v1_20_2);
}
/**

View File

@ -40,6 +40,10 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
super(protocol, true);
}
public ItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType) {
super(protocol, itemType, itemArrayType, true);
}
@Override
public @Nullable Item handleItemToClient(@Nullable Item item) {
if (item == null) {

View File

@ -21,6 +21,7 @@ import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
@ -35,7 +36,11 @@ public abstract class ItemRewriterBase<C extends ClientboundPacketType, S extend
protected final boolean jsonNameFormat;
protected ItemRewriterBase(T protocol, boolean jsonNameFormat) {
super(protocol);
this(protocol, Type.FLAT_VAR_INT_ITEM, Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT, jsonNameFormat);
}
public ItemRewriterBase(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType, boolean jsonNameFormat) {
super(protocol, itemType, itemArrayType);
this.jsonNameFormat = jsonNameFormat;
nbtTagName = "VB|" + protocol.getClass().getSimpleName();
}

View File

@ -240,7 +240,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.UNSIGNED_BYTE);
map(Type.FLAT_ITEM_ARRAY, Type.ITEM_ARRAY);
handler(itemArrayHandler(Type.ITEM_ARRAY));
handler(itemArrayToClientHandler(Type.ITEM_ARRAY));
}
});

View File

@ -203,7 +203,7 @@ public final class BlockItemPackets1_17 extends ItemRewriter<ClientboundPackets1
wrapper.cancel();
}
});
handler(getSpawnParticleHandler(Type.FLAT_VAR_INT_ITEM));
handler(getSpawnParticleHandler());
}
});

View File

@ -134,7 +134,7 @@ public final class BlockItemPackets1_19 extends ItemRewriter<ClientboundPackets1
wrapper.cancel();
}
});
handler(getSpawnParticleHandler(Type.FLAT_VAR_INT_ITEM));
handler(getSpawnParticleHandler());
}
});

View File

@ -0,0 +1,162 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2023 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.viabackwards.protocol.protocol1_20_4to1_20_2;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.rewriter.BlockItemPacketRewriter1_20_2;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.rewriter.EntityPacketRewriter1_20_2;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.storage.ConfigurationPacketStorage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ServerboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
import java.util.UUID;
public final class Protocol1_20To1_20_2 extends BackwardsProtocol<ClientboundPackets1_20_2, ClientboundPackets1_19_4, ServerboundPackets1_20_2, ServerboundPackets1_19_4> {
private final EntityPacketRewriter1_20_2 entityPacketRewriter = new EntityPacketRewriter1_20_2(this);
private final BlockItemPacketRewriter1_20_2 itemPacketRewriter = new BlockItemPacketRewriter1_20_2(this);
public Protocol1_20To1_20_2() {
super(ClientboundPackets1_20_2.class, ClientboundPackets1_19_4.class, ServerboundPackets1_20_2.class, ServerboundPackets1_19_4.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
Via.getManager().debugHandler().setEnabled(true);
registerClientbound(ClientboundPackets1_20_2.SCOREBOARD_OBJECTIVE, wrapper -> {
final int slot = wrapper.read(Type.VAR_INT);
wrapper.write(Type.BYTE, (byte) slot);
});
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), wrapper -> {
final ServerboundLoginPackets ackPacket = ServerboundLoginPackets.LOGIN_ACKNOWLEDGED;
wrapper.create(ackPacket).sendToServer(Protocol1_20To1_20_2.class);
// We can't set the internal state to configuration here as protocols down the line will expect the state to be play
wrapper.user().put(new ConfigurationPacketStorage());
System.out.println(wrapper.user().getProtocolInfo().getState());
});
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION.getId(), ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION.getId(), wrapper -> {
wrapper.cancel();
wrapper.create(ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION).sendToServer(Protocol1_20To1_20_2.class);
wrapper.user().getProtocolInfo().setState(State.PLAY);
});
registerServerbound(State.LOGIN, ServerboundLoginPackets.HELLO.getId(), ServerboundLoginPackets.HELLO.getId(), wrapper -> {
wrapper.passthrough(Type.STRING); // Name
// TODO Bad
final UUID uuid = wrapper.read(Type.OPTIONAL_UUID);
wrapper.write(Type.UUID, uuid != null ? uuid : new UUID(0, 0));
});
cancelClientbound(ClientboundPackets1_20_2.START_CONFIGURATION); // TODO
// Some can be directly remapped to play packets, others need to be queued
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.DISCONNECT.getId(), ClientboundPackets1_19_4.DISCONNECT.getId());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), ClientboundPackets1_19_4.KEEP_ALIVE.getId());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), ClientboundPackets1_19_4.RESOURCE_PACK.getId());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.REGISTRY_DATA.getId(), -1, wrapper -> {
wrapper.cancel();
final CompoundTag registry = wrapper.read(Type.NAMELESS_NBT);
entityPacketRewriter.trackBiomeSize(wrapper.user(), registry);
entityPacketRewriter.cacheDimensionData(wrapper.user(), registry);
wrapper.user().get(ConfigurationPacketStorage.class).setRegistry(registry);
});
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES.getId(), -1, wrapper -> {
wrapper.cancel();
final String[] enabledFeatures = wrapper.read(Type.STRING_ARRAY);
wrapper.user().get(ConfigurationPacketStorage.class).setEnabledFeatures(enabledFeatures);
});
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.UPDATE_TAGS.getId(), -1, wrapper -> {
wrapper.cancel();
wrapper.user().get(ConfigurationPacketStorage.class).addRawPacket(wrapper, ClientboundPackets1_19_4.TAGS);
});
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, wrapper -> {
wrapper.cancel();
wrapper.user().get(ConfigurationPacketStorage.class).addRawPacket(wrapper, ClientboundPackets1_19_4.PLUGIN_MESSAGE);
});
}
@Override
public void transform(final Direction direction, final State state, final PacketWrapper wrapper) throws Exception {
final ConfigurationPacketStorage configurationPacketStorage = wrapper.user().get(ConfigurationPacketStorage.class);
if (configurationPacketStorage == null) {
super.transform(direction, state, wrapper);
return;
}
if (direction == Direction.CLIENTBOUND) {
super.transform(direction, State.CONFIGURATION, wrapper);
return;
}
// Map some of the packets to their configuration counterparts
final int id = wrapper.getId();
if (id == ServerboundPackets1_19_4.PLUGIN_MESSAGE.getId()) {
wrapper.setPacketType(ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD);
} else if (id == ServerboundPackets1_19_4.KEEP_ALIVE.getId()) {
wrapper.setPacketType(ServerboundConfigurationPackets1_20_2.KEEP_ALIVE);
} else if (id == ServerboundPackets1_19_4.PONG.getId()) {
wrapper.setPacketType(ServerboundConfigurationPackets1_20_2.PONG);
} else if (id == ServerboundPackets1_19_4.RESOURCE_PACK_STATUS.getId()) {
wrapper.setPacketType(ServerboundConfigurationPackets1_20_2.RESOURCE_PACK);
} else {
// Can't do
// TODO Queue
System.out.println("Cancelling: " + state + " - " + wrapper.getPacketType() + " " + wrapper.getId());
throw CancelException.generate();
}
}
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, Entity1_19_4Types.PLAYER));
}
@Override
public EntityRewriter<Protocol1_20To1_20_2> getEntityRewriter() {
return entityPacketRewriter;
}
@Override
public ItemRewriter<Protocol1_20To1_20_2> getItemRewriter() {
return itemPacketRewriter;
}
}

View File

@ -0,0 +1,300 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2023 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.viabackwards.protocol.protocol1_20_4to1_20_2.rewriter;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.ChunkPosition;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ServerboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.type.ChunkType1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.Protocol1_20To1_19_4;
import com.viaversion.viaversion.util.MathUtil;
public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<ClientboundPackets1_20_2, ServerboundPackets1_19_4, Protocol1_20To1_20_2> {
public BlockItemPacketRewriter1_20_2(final Protocol1_20To1_20_2 protocol) {
super(protocol, Type.ITEM1_20_2, Type.ITEM1_20_2_VAR_INT_ARRAY);
}
@Override
public void registerPackets() {
protocol.cancelClientbound(ClientboundPackets1_20_2.CHUNK_BATCH_START);
protocol.cancelClientbound(ClientboundPackets1_20_2.CHUNK_BATCH_FINISHED);
protocol.registerClientbound(ClientboundPackets1_20_2.UNLOAD_CHUNK, wrapper -> {
final ChunkPosition chunkPosition = wrapper.read(Type.CHUNK_POSITION);
wrapper.write(Type.INT, chunkPosition.chunkX());
wrapper.write(Type.INT, chunkPosition.chunkZ());
});
protocol.registerClientbound(ClientboundPackets1_20_2.NBT_QUERY, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Transaction id
wrapper.write(Type.NBT, wrapper.read(Type.NAMELESS_NBT));
});
protocol.registerClientbound(ClientboundPackets1_20_2.BLOCK_ENTITY_DATA, wrapper -> {
wrapper.passthrough(Type.POSITION1_14); // Position
wrapper.passthrough(Type.VAR_INT); // Type
wrapper.write(Type.NBT, wrapper.read(Type.NAMELESS_NBT));
});
protocol.registerClientbound(ClientboundPackets1_20_2.CHUNK_DATA, wrapper -> {
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
final Type<Chunk> chunkType = new ChunkType1_20_2(tracker.currentWorldSectionHeight(),
MathUtil.ceilLog2(Protocol1_20To1_19_4.MAPPINGS.getBlockStateMappings().mappedSize()),
MathUtil.ceilLog2(tracker.biomesSent()));
final Chunk chunk = wrapper.read(chunkType);
final Type<Chunk> newChunkType = new Chunk1_18Type(tracker.currentWorldSectionHeight(),
MathUtil.ceilLog2(Protocol1_20To1_19_4.MAPPINGS.getBlockStateMappings().mappedSize()),
MathUtil.ceilLog2(tracker.biomesSent()));
wrapper.write(newChunkType, chunk);
});
// Replace the NBT type everywhere
protocol.registerClientbound(ClientboundPackets1_20_2.WINDOW_ITEMS, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // Window id
map(Type.VAR_INT); // State id
handler(wrapper -> {
wrapper.write(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT, wrapper.read(Type.ITEM1_20_2_VAR_INT_ARRAY)); // Items
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); // Carried item
});
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.SET_SLOT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // Window id
map(Type.VAR_INT); // State id
map(Type.SHORT); // Slot id
map(Type.ITEM1_20_2, Type.FLAT_VAR_INT_ITEM); // Item
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.ADVANCEMENTS, wrapper -> {
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN))
wrapper.passthrough(Type.STRING);
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.COMPONENT); // Title
wrapper.passthrough(Type.COMPONENT); // Description
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); // Icon
wrapper.passthrough(Type.VAR_INT); // Frame type
int flags = wrapper.passthrough(Type.INT); // Flags
if ((flags & 1) != 0) {
wrapper.passthrough(Type.STRING); // Background texture
}
wrapper.passthrough(Type.FLOAT); // X
wrapper.passthrough(Type.FLOAT); // Y
}
wrapper.passthrough(Type.STRING_ARRAY); // Criteria
int arrayLength = wrapper.passthrough(Type.VAR_INT);
for (int array = 0; array < arrayLength; array++) {
wrapper.passthrough(Type.STRING_ARRAY); // String array
}
wrapper.passthrough(Type.BOOLEAN); // Send telemetry
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.ENTITY_EQUIPMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // 0 - Entity ID
handler(wrapper -> {
byte slot;
do {
slot = wrapper.passthrough(Type.BYTE);
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2));
} while ((slot & 0xFFFFFF80) != 0);
});
}
});
protocol.registerServerbound(ServerboundPackets1_19_4.CLICK_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // Window Id
map(Type.VAR_INT); // State id
map(Type.SHORT); // Slot
map(Type.BYTE); // Button
map(Type.VAR_INT); // Mode
handler(wrapper -> {
// Affected items
int length = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Type.SHORT); // Slot
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM));
}
// Carried item
wrapper.write(Type.ITEM1_20_2, wrapper.read(Type.FLAT_VAR_INT_ITEM));
});
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.TRADE_LIST, wrapper -> {
wrapper.cancel();
wrapper.passthrough(Type.VAR_INT); // Container id
int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); // Input
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); // Output
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2)); // Second Item
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
wrapper.passthrough(Type.INT); // XP
wrapper.passthrough(Type.INT); // Special price
wrapper.passthrough(Type.FLOAT); // Price multiplier
wrapper.passthrough(Type.INT); // Demand
}
});
protocol.registerServerbound(ServerboundPackets1_19_4.CREATIVE_INVENTORY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.SHORT); // 0 - Slot
map(Type.FLAT_VAR_INT_ITEM, Type.ITEM1_20_2); // 1 - Clicked Item
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.SPAWN_PARTICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(Type.DOUBLE); // 2 - X
map(Type.DOUBLE); // 3 - Y
map(Type.DOUBLE); // 4 - Z
map(Type.FLOAT); // 5 - Offset X
map(Type.FLOAT); // 6 - Offset Y
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(wrapper -> {
int id = wrapper.get(Type.VAR_INT, 0);
ParticleMappings mappings = Protocol1_20To1_19_4.MAPPINGS.getParticleMappings();
if (mappings.isItemParticle(id)) {
wrapper.write(Type.FLAT_VAR_INT_ITEM, wrapper.read(Type.ITEM1_20_2));
}
});
}
});
new RecipeRewriter1_19_4<ClientboundPackets1_20_2>(protocol) {
@Override
public void handleCraftingShapeless(final PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.VAR_INT); // Crafting book category
handleIngredients(wrapper);
final Item result = wrapper.read(itemType());
rewrite(result);
wrapper.write(Type.FLAT_VAR_INT_ITEM, result);
}
@Override
public void handleSmelting(final PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.VAR_INT); // Crafting book category
handleIngredient(wrapper);
final Item result = wrapper.read(itemType());
rewrite(result);
wrapper.write(Type.FLAT_VAR_INT_ITEM, result);
wrapper.passthrough(Type.FLOAT); // EXP
wrapper.passthrough(Type.VAR_INT); // Cooking time
}
@Override
public void handleCraftingShaped(final PacketWrapper wrapper) throws Exception {
final int ingredients = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.VAR_INT); // Crafting book category
for (int i = 0; i < ingredients; i++) {
handleIngredient(wrapper);
}
final Item result = wrapper.read(itemType());
rewrite(result);
wrapper.write(Type.FLAT_VAR_INT_ITEM, result);
wrapper.passthrough(Type.BOOLEAN); // Show notification
}
@Override
public void handleStonecutting(final PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.STRING); // Group
handleIngredient(wrapper);
final Item result = wrapper.read(itemType());
rewrite(result);
wrapper.write(Type.FLAT_VAR_INT_ITEM, result);
}
@Override
public void handleSmithing(final PacketWrapper wrapper) throws Exception {
handleIngredient(wrapper); // Base
handleIngredient(wrapper); // Addition
final Item result = wrapper.read(itemType());
rewrite(result);
wrapper.write(Type.FLAT_VAR_INT_ITEM, result);
}
@Override
public void handleSmithingTransform(final PacketWrapper wrapper) throws Exception {
handleIngredient(wrapper); // Template
handleIngredient(wrapper); // Base
handleIngredient(wrapper); // Additions
final Item result = wrapper.read(itemType());
rewrite(result);
wrapper.write(Type.FLAT_VAR_INT_ITEM, result);
}
@Override
protected void handleIngredient(final PacketWrapper wrapper) throws Exception {
final Item[] items = wrapper.read(itemArrayType());
wrapper.write(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT, items);
for (final Item item : items) {
rewrite(item);
}
}
}.register(ClientboundPackets1_20_2.DECLARE_RECIPES);
}
}

View File

@ -0,0 +1,137 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2023 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.viabackwards.protocol.protocol1_20_4to1_20_2.rewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.storage.ConfigurationPacketStorage;
import com.viaversion.viaversion.api.minecraft.GlobalPosition;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_20;
import com.viaversion.viaversion.api.type.types.version.Types1_20_2;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
public final class EntityPacketRewriter1_20_2 extends EntityRewriter<ClientboundPackets1_20_2, Protocol1_20To1_20_2> {
public EntityPacketRewriter1_20_2(final Protocol1_20To1_20_2 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
registerTrackerWithData1_19(ClientboundPackets1_20_2.SPAWN_ENTITY, Entity1_19_4Types.FALLING_BLOCK);
registerMetadataRewriter(ClientboundPackets1_20_2.ENTITY_METADATA, Types1_20_2.METADATA_LIST, Types1_20.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_20_2.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_20_2.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
final ConfigurationPacketStorage configurationPacketStorage = wrapper.user().get(ConfigurationPacketStorage.class);
wrapper.passthrough(Type.INT); // Entity id
wrapper.passthrough(Type.BOOLEAN); // Hardcore
final String[] worlds = wrapper.read(Type.STRING_ARRAY);
final int maxPlayers = wrapper.read(Type.VAR_INT);
final int viewDistance = wrapper.read(Type.VAR_INT);
final int simulationDistance = wrapper.read(Type.VAR_INT);
final boolean reducedDebugInfo = wrapper.read(Type.BOOLEAN);
final boolean showRespawnScreen = wrapper.read(Type.BOOLEAN);
final String dimensionType = wrapper.read(Type.STRING);
final String world = wrapper.read(Type.STRING);
final long seed = wrapper.read(Type.LONG);
wrapper.write(Type.UNSIGNED_BYTE, wrapper.read(Type.BYTE).shortValue()); // Gamemode
wrapper.passthrough(Type.BYTE); // Previous gamemode
wrapper.write(Type.STRING_ARRAY, worlds);
wrapper.write(Type.NBT, configurationPacketStorage.registry());
wrapper.write(Type.STRING, dimensionType);
wrapper.write(Type.STRING, world);
wrapper.write(Type.LONG, seed);
wrapper.write(Type.VAR_INT, maxPlayers);
wrapper.write(Type.VAR_INT, viewDistance);
wrapper.write(Type.VAR_INT, simulationDistance);
wrapper.write(Type.BOOLEAN, reducedDebugInfo);
wrapper.write(Type.BOOLEAN, showRespawnScreen);
wrapper.cancel();
wrapper.send(Protocol1_20To1_20_2.class);
final PacketWrapper featuresPacket = wrapper.create(ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES);
featuresPacket.write(Type.STRING_ARRAY, configurationPacketStorage.enabledFeatures());
featuresPacket.send(Protocol1_20To1_20_2.class);
configurationPacketStorage.sendQueuedPackets(wrapper.user());
});
handler(worldDataTrackerHandlerByKey());
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.RESPAWN, new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
wrapper.passthrough(Type.STRING); // Dimension type
wrapper.passthrough(Type.STRING); // World
wrapper.passthrough(Type.LONG); // Seed
wrapper.write(Type.UNSIGNED_BYTE, wrapper.read(Type.BYTE).shortValue()); // Gamemode
wrapper.passthrough(Type.BYTE); // Previous gamemode
wrapper.passthrough(Type.BOOLEAN); // Debug
wrapper.passthrough(Type.BOOLEAN); // Flat
final GlobalPosition lastDeathPosition = wrapper.read(Type.OPTIONAL_GLOBAL_POSITION);
final int portalCooldown = wrapper.read(Type.VAR_INT);
wrapper.passthrough(Type.BYTE); // Data to keep
wrapper.write(Type.OPTIONAL_GLOBAL_POSITION, lastDeathPosition);
wrapper.write(Type.VAR_INT, portalCooldown);
});
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
}
});
protocol.registerClientbound(ClientboundPackets1_20_2.ENTITY_EFFECT, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Entity id
wrapper.passthrough(Type.VAR_INT); // Effect id
wrapper.passthrough(Type.BYTE); // Amplifier
wrapper.passthrough(Type.VAR_INT); // Duration
wrapper.passthrough(Type.BYTE); // Flags
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.write(Type.NBT, wrapper.read(Type.NAMELESS_NBT)); // Factor data
}
});
}
@Override
protected void registerRewrites() {
filter().handler((event, meta) -> meta.setMetaType(Types1_20.META_TYPES.byId(meta.metaType().typeId())));
filter().filterFamily(Entity1_19_4Types.DISPLAY).removeIndex(10);
}
@Override
public EntityType typeFromId(final int type) {
return Entity1_19_4Types.getTypeFromId(type);
}
}

View File

@ -0,0 +1,95 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2023 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.viabackwards.protocol.protocol1_20_4to1_20_2.storage;
import com.viaversion.viabackwards.protocol.protocol1_20_4to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.util.ArrayList;
import java.util.List;
public final class ConfigurationPacketStorage implements StorableObject {
private final List<QueuedPacket> rawPackets = new ArrayList<>();
private CompoundTag registry;
private String[] enabledFeatures;
public CompoundTag registry() {
return registry;
}
public void setRegistry(final CompoundTag registry) {
this.registry = registry;
}
public String[] enabledFeatures() {
return enabledFeatures;
}
public void setEnabledFeatures(final String[] enabledFeatures) {
this.enabledFeatures = enabledFeatures;
}
public List<QueuedPacket> getRawPackets() {
return rawPackets;
}
public void addRawPacket(final PacketWrapper wrapper, final PacketType type) throws Exception {
// It's easier to just copy it to a byte array buffer than to manually read the data
final ByteBuf buf = Unpooled.buffer();
final int id = wrapper.getId();
//noinspection deprecation
wrapper.setId(-1); // Don't write the packet id to the buffer
wrapper.writeToBuffer(buf);
rawPackets.add(new QueuedPacket(buf, type));
}
public void sendQueuedPackets(final UserConnection connection) throws Exception {
for (final QueuedPacket queuedPacket : rawPackets) {
try {
final PacketWrapper packet = PacketWrapper.create(queuedPacket.packetType(), queuedPacket.buf(), connection);
packet.send(Protocol1_20To1_20_2.class);
} finally {
queuedPacket.buf().release();
}
}
}
public static final class QueuedPacket {
private final ByteBuf buf;
private final PacketType packetType;
public QueuedPacket(final ByteBuf buf, final PacketType packetType) {
this.buf = buf;
this.packetType = packetType;
}
public ByteBuf buf() {
return buf;
}
public PacketType packetType() {
return packetType;
}
}
}

View File

@ -3,7 +3,7 @@ metadata.format.version = "1.1"
[versions]
# ViaVersion
viaver = "4.7.1-SNAPSHOT"
viaver = "4.8.0-23w31a-SNAPSHOT"
# Common provided
netty = "4.0.20.Final"