Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 00:22:51 +01:00
More work on the snapshot
Dieser Commit ist enthalten in:
Ursprung
6dfd4747ee
Commit
6586fc1436
@ -77,6 +77,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
|
||||
/**
|
||||
* Creates a protocol with automated id mapping if the respective packet type classes are not null.
|
||||
* They are also required to track the CONFIGURATION state.
|
||||
*/
|
||||
protected AbstractProtocol(@Nullable Class<CU> unmappedClientboundPacketType, @Nullable Class<CM> mappedClientboundPacketType,
|
||||
@Nullable Class<SM> mappedServerboundPacketType, @Nullable Class<SU> unmappedServerboundPacketType) {
|
||||
@ -97,6 +98,12 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
registerPackets();
|
||||
|
||||
// Register the rest of the ids with no handlers if necessary
|
||||
final SU configurationAcknowledgedPacket = configurationAcknowledgedPacket();
|
||||
if (configurationAcknowledgedPacket != null) {
|
||||
// TODO Only register one of those handlers, possibly somehow in the base protocol
|
||||
registerServerbound(configurationAcknowledgedPacket, wrapper -> wrapper.user().getProtocolInfo().setState(State.CONFIGURATION));
|
||||
}
|
||||
|
||||
if (unmappedClientboundPacketType != null && mappedClientboundPacketType != null
|
||||
&& unmappedClientboundPacketType != mappedClientboundPacketType) {
|
||||
registerPacketIdChanges(
|
||||
@ -208,6 +215,12 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
protected @Nullable SU configurationAcknowledgedPacket() {
|
||||
final Map<State, PacketTypeMap<SU>> packetTypes = packetTypesProvider.unmappedServerboundPacketTypes();
|
||||
final PacketTypeMap<SU> packetTypeMap = packetTypes.get(State.PLAY);
|
||||
return packetTypeMap != null ? packetTypeMap.typeByName("CONFIGURATION_ACKNOWLEDGED") : null;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
@ -361,7 +374,7 @@ public abstract class AbstractProtocol<CU extends ClientboundPacketType, CM exte
|
||||
}
|
||||
}
|
||||
|
||||
private void throwRemapError(Direction direction, State state, int unmappedPacketId, int mappedPacketId, InformativeException e) throws InformativeException {
|
||||
protected void throwRemapError(Direction direction, State state, int unmappedPacketId, int mappedPacketId, InformativeException e) throws InformativeException {
|
||||
// Don't print errors during handshake/login/status
|
||||
if (state != State.PLAY && direction == Direction.SERVERBOUND && !Via.getManager().debugHandler().enabled()) {
|
||||
e.setShouldBePrinted(false);
|
||||
|
@ -59,6 +59,7 @@ import com.viaversion.viaversion.api.type.types.VarIntArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.VarIntType;
|
||||
import com.viaversion.viaversion.api.type.types.VarLongType;
|
||||
import com.viaversion.viaversion.api.type.types.VoidType;
|
||||
import com.viaversion.viaversion.api.type.types.minecraft.NamelessNBTType;
|
||||
import com.viaversion.viaversion.api.type.types.minecraft.BlockChangeRecordType;
|
||||
import com.viaversion.viaversion.api.type.types.minecraft.ChunkPositionType;
|
||||
import com.viaversion.viaversion.api.type.types.minecraft.EulerAngleType;
|
||||
@ -165,6 +166,7 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
|
||||
public static final Type<Vector3f> VECTOR3F = new Vector3fType();
|
||||
public static final Type<Quaternion> QUATERNION = new QuaternionType();
|
||||
public static final Type<CompoundTag> NBT = new NBTType();
|
||||
public static final Type<CompoundTag> NAMELESS_NBT = new NamelessNBTType();
|
||||
public static final Type<CompoundTag[]> NBT_ARRAY = new ArrayType<>(Type.NBT);
|
||||
public static final Type<GlobalPosition> GLOBAL_POSITION = new GlobalPositionType();
|
||||
public static final Type<GlobalPosition> OPTIONAL_GLOBAL_POSITION = new GlobalPositionType.OptionalGlobalPositionType();
|
||||
|
@ -22,15 +22,15 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.minecraft;
|
||||
|
||||
import com.github.steveice10.opennbt.NBTIO;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.limiter.TagLimiter;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class NBTType extends Type<CompoundTag> {
|
||||
|
||||
@ -43,23 +43,50 @@ public class NBTType extends Type<CompoundTag> {
|
||||
|
||||
@Override
|
||||
public CompoundTag read(ByteBuf buffer) throws Exception {
|
||||
int readerIndex = buffer.readerIndex();
|
||||
byte b = buffer.readByte();
|
||||
if (b == 0) {
|
||||
return null;
|
||||
} else {
|
||||
buffer.readerIndex(readerIndex);
|
||||
return NBTIO.readTag((DataInput) new ByteBufInputStream(buffer), TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL));
|
||||
}
|
||||
return read(buffer, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, CompoundTag object) throws Exception {
|
||||
if (object == null) {
|
||||
buffer.writeByte(0);
|
||||
} else {
|
||||
ByteBufOutputStream bytebufStream = new ByteBufOutputStream(buffer);
|
||||
NBTIO.writeTag((DataOutput) bytebufStream, object);
|
||||
write(buffer, object, "");
|
||||
}
|
||||
|
||||
public static CompoundTag read(final ByteBuf buffer, final boolean readName) throws Exception {
|
||||
final int readerIndex = buffer.readerIndex();
|
||||
final byte b = buffer.readByte();
|
||||
if (b == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
buffer.readerIndex(readerIndex);
|
||||
|
||||
final ByteBufInputStream in = new ByteBufInputStream(buffer);
|
||||
final int id = in.readByte();
|
||||
if (id != CompoundTag.ID) {
|
||||
throw new IOException(String.format("Expected root tag to be a CompoundTag, was %s", id));
|
||||
}
|
||||
|
||||
if (readName) {
|
||||
in.skipBytes(in.readUnsignedShort());
|
||||
}
|
||||
|
||||
final TagLimiter tagLimiter = TagLimiter.create(MAX_NBT_BYTES, MAX_NESTING_LEVEL);
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.read(in, tagLimiter);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static void write(final ByteBuf buffer, final CompoundTag tag, final @Nullable String name) throws Exception {
|
||||
if (tag == null) {
|
||||
buffer.writeByte(0);
|
||||
return;
|
||||
}
|
||||
|
||||
final ByteBufOutputStream out = new ByteBufOutputStream(buffer);
|
||||
out.writeByte(CompoundTag.ID);
|
||||
if (name != null) {
|
||||
out.writeUTF(name);
|
||||
}
|
||||
tag.write(out);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2023 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.type.types.minecraft;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class NamelessNBTType extends Type<CompoundTag> {
|
||||
|
||||
public NamelessNBTType() {
|
||||
super(CompoundTag.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag read(final ByteBuf buffer) throws Exception {
|
||||
return NBTType.read(buffer, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final ByteBuf buffer, final CompoundTag tag) throws Exception {
|
||||
NBTType.write(buffer, tag, null);
|
||||
}
|
||||
}
|
@ -23,6 +23,11 @@ import java.util.UUID;
|
||||
|
||||
public class BaseProtocol1_16 extends BaseProtocol1_7 {
|
||||
|
||||
@Override
|
||||
protected boolean finishLoginAfterGameprofile() {
|
||||
return false; // Start CONFIGURATION phase after the serverbound ack
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UUID passthroughLoginUUID(final PacketWrapper wrapper) throws Exception {
|
||||
return wrapper.passthrough(Type.UUID);
|
||||
|
@ -33,10 +33,12 @@ import com.viaversion.viaversion.api.protocol.version.VersionProvider;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.protocol.ProtocolManagerImpl;
|
||||
import com.viaversion.viaversion.protocol.ServerProtocolVersionSingleton;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
|
||||
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
import com.viaversion.viaversion.util.ChatColorUtil;
|
||||
import com.viaversion.viaversion.util.GsonUtil;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
@ -45,9 +47,6 @@ public class BaseProtocol1_7 extends AbstractProtocol {
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
/* Outgoing Packets */
|
||||
|
||||
// Status Response Packet
|
||||
registerClientbound(ClientboundStatusPackets.STATUS_RESPONSE, new PacketHandlers() { // Status Response Packet
|
||||
@Override
|
||||
public void register() {
|
||||
@ -122,7 +121,9 @@ public class BaseProtocol1_7 extends AbstractProtocol {
|
||||
// Login Success Packet
|
||||
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
|
||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
info.setState(State.PLAY);
|
||||
if (finishLoginAfterGameprofile()) {
|
||||
info.setState(State.PLAY);
|
||||
}
|
||||
|
||||
UUID uuid = passthroughLoginUUID(wrapper);
|
||||
info.setUuid(uuid);
|
||||
@ -147,7 +148,6 @@ public class BaseProtocol1_7 extends AbstractProtocol {
|
||||
}
|
||||
});
|
||||
|
||||
/* Incoming Packets */
|
||||
// Login Start Packet
|
||||
registerServerbound(ServerboundLoginPackets.HELLO, wrapper -> {
|
||||
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
|
||||
@ -164,6 +164,10 @@ public class BaseProtocol1_7 extends AbstractProtocol {
|
||||
future.addListener(f -> wrapper.user().getChannel().close());
|
||||
}
|
||||
});
|
||||
|
||||
registerServerbound(ServerboundLoginPackets.LOGIN_ACKNOWLEDGED, wrapper -> wrapper.user().getProtocolInfo().setState(State.CONFIGURATION));
|
||||
// TODO AAAAAAAAAAAAAAAAA
|
||||
registerServerbound(ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION, wrapper -> wrapper.user().getProtocolInfo().setState(State.PLAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -188,4 +192,8 @@ public class BaseProtocol1_7 extends AbstractProtocol {
|
||||
}
|
||||
return UUID.fromString(uuidString);
|
||||
}
|
||||
|
||||
protected boolean finishLoginAfterGameprofile() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,24 +17,31 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.protocol1_20_2to1_20;
|
||||
|
||||
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.AbstractProtocol;
|
||||
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.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.handler.BlockItemPacketHandler1_20_2;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.handler.EntityPacketHandler1_20_2;
|
||||
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 com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.FakeProtocolState;
|
||||
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -50,12 +57,9 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
// TODO Stopped at ForgetLevelChunk
|
||||
// TODO New login packets (custom query answer, login ack)
|
||||
// TODO Handle move from and to configuration state
|
||||
// Game profile/serverbound ack -> configuration
|
||||
// Client/serverbound config finish -> play
|
||||
// TODO New helper methods for: join game, respawn,
|
||||
// TODO Updated NBT type used in: block entity, chunk, tag query, entity metadata data, item type, mob effect
|
||||
|
||||
// TODO Handle Enabled features and tags before configuration phase end
|
||||
// TODO Make sure Paper/Velocity handle a 0,0 uuid fine during login
|
||||
|
||||
// Lesser:
|
||||
@ -77,15 +81,96 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
||||
wrapper.write(Type.VAR_INT, (int) slot);
|
||||
});
|
||||
|
||||
registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO.getId(), ClientboundLoginPackets.HELLO.getId(), wrapper -> {
|
||||
registerServerbound(State.LOGIN, ServerboundLoginPackets.HELLO.getId(), ServerboundLoginPackets.HELLO.getId(), wrapper -> {
|
||||
wrapper.passthrough(Type.STRING); // Name
|
||||
final UUID uuid = wrapper.read(Type.OPTIONAL_UUID);
|
||||
wrapper.write(Type.UUID, uuid != null ? uuid : new UUID(0, 0));
|
||||
|
||||
final UUID uuid = wrapper.read(Type.UUID);
|
||||
wrapper.write(Type.OPTIONAL_UUID, uuid);
|
||||
});
|
||||
|
||||
// Deal with the new CONFIGURATION protocol state the client expects
|
||||
registerServerbound(State.LOGIN, ServerboundLoginPackets.LOGIN_ACKNOWLEDGED.getId(), -1, wrapper -> {
|
||||
wrapper.user().get(FakeProtocolState.class).setConfigurationState(true);
|
||||
wrapper.cancel();
|
||||
});
|
||||
|
||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION.getId(), -1, wrapper -> {
|
||||
wrapper.user().get(FakeProtocolState.class).setConfigurationState(false);
|
||||
wrapper.cancel();
|
||||
});
|
||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), ServerboundPackets1_19_4.PLUGIN_MESSAGE.getId(), wrapper -> {
|
||||
});
|
||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), ServerboundPackets1_19_4.KEEP_ALIVE.getId(), wrapper -> {
|
||||
});
|
||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), ServerboundPackets1_19_4.PONG.getId(), wrapper -> {
|
||||
});
|
||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), ServerboundPackets1_19_4.RESOURCE_PACK_STATUS.getId(), wrapper -> {
|
||||
});
|
||||
|
||||
// Sad emoji
|
||||
cancelClientbound(ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES);
|
||||
|
||||
registerServerbound(ServerboundPackets1_20_2.CONFIGURATION_ACKNOWLEDGED, null, wrapper -> {
|
||||
wrapper.user().get(FakeProtocolState.class).setConfigurationState(false);
|
||||
wrapper.cancel();
|
||||
});
|
||||
|
||||
// TODO Check if we can just not send batches (probably fine like this)
|
||||
cancelServerbound(ServerboundPackets1_20_2.CHUNK_BATCH_RECEIVED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
|
||||
final boolean configurationState = packetWrapper.user().get(FakeProtocolState.class).isConfigurationState();
|
||||
if (direction == Direction.SERVERBOUND) {
|
||||
// Redirect packets during the fake configuration phase
|
||||
// This might mess up people using Via API/other protocols down the line, but such is life. We can't have different states for server and client
|
||||
final State newState = configurationState ? State.CONFIGURATION : state;
|
||||
super.transform(direction, newState, packetWrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we don't send the client any packets from another protocol state
|
||||
if (configurationState) {
|
||||
// TODO Queue these packets to send them later
|
||||
Via.getPlatform().getLogger().warning("Cancelled packet " + packetWrapper.getId() + " sent during configuration state");
|
||||
packetWrapper.cancel();
|
||||
super.transform(direction, state, packetWrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
// Map some of them to their configuration state counterparts
|
||||
final int unmappedId = packetWrapper.getId();
|
||||
if (state == State.PLAY && unmappedId != ClientboundPackets1_19_4.JOIN_GAME.getId()) {
|
||||
if (unmappedId == ClientboundPackets1_19_4.PLUGIN_MESSAGE.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD);
|
||||
} else if (unmappedId == ClientboundPackets1_19_4.DISCONNECT.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.DISCONNECT);
|
||||
} else if (unmappedId == ClientboundPackets1_19_4.KEEP_ALIVE.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.KEEP_ALIVE);
|
||||
} else if (unmappedId == ClientboundPackets1_19_4.PING.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.PING);
|
||||
} else if (unmappedId == ClientboundPackets1_19_4.RESOURCE_PACK.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.RESOURCE_PACK);
|
||||
} else if (unmappedId == ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES);
|
||||
} else if (unmappedId == ClientboundPackets1_19_4.TAGS.getId()) {
|
||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_TAGS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
super.transform(direction, state, packetWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ServerboundPackets1_20_2 configurationAcknowledgedPacket() {
|
||||
return null; // Don't handle it in the transitioning protocol
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final UserConnection user) {
|
||||
user.put(new FakeProtocolState());
|
||||
addEntityTracker(user, new EntityTrackerBase(user, Entity1_19_4Types.PLAYER));
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,9 @@ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20.handler;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.metadata.ChunkPosition;
|
||||
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.ClientboundPackets1_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.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
||||
|
||||
public final class BlockItemPacketHandler1_20_2 extends ItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_20_2, Protocol1_20_2To1_20> {
|
||||
@ -35,27 +32,6 @@ public final class BlockItemPacketHandler1_20_2 extends ItemRewriter<Clientbound
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
final BlockRewriter<ClientboundPackets1_19_4> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
|
||||
blockRewriter.registerBlockAction(ClientboundPackets1_19_4.BLOCK_ACTION);
|
||||
blockRewriter.registerBlockChange(ClientboundPackets1_19_4.BLOCK_CHANGE);
|
||||
blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_19_4.MULTI_BLOCK_CHANGE);
|
||||
blockRewriter.registerEffect(ClientboundPackets1_19_4.EFFECT, 1010, 2001);
|
||||
blockRewriter.registerChunkData1_19(ClientboundPackets1_19_4.CHUNK_DATA, Chunk1_18Type::new);
|
||||
blockRewriter.registerBlockEntityData(ClientboundPackets1_19_4.BLOCK_ENTITY_DATA);
|
||||
|
||||
registerSetCooldown(ClientboundPackets1_19_4.COOLDOWN);
|
||||
registerWindowItems1_17_1(ClientboundPackets1_19_4.WINDOW_ITEMS);
|
||||
registerSetSlot1_17_1(ClientboundPackets1_19_4.SET_SLOT);
|
||||
registerAdvancements1_20(ClientboundPackets1_19_4.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
|
||||
registerEntityEquipmentArray(ClientboundPackets1_19_4.ENTITY_EQUIPMENT);
|
||||
registerClickWindow1_17_1(ServerboundPackets1_20_2.CLICK_WINDOW);
|
||||
registerTradeList1_19(ClientboundPackets1_19_4.TRADE_LIST);
|
||||
registerCreativeInvAction(ServerboundPackets1_20_2.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
|
||||
registerWindowPropertyEnchantmentHandler(ClientboundPackets1_19_4.WINDOW_PROPERTY);
|
||||
registerSpawnParticle1_19(ClientboundPackets1_19_4.SPAWN_PARTICLE);
|
||||
|
||||
new RecipeRewriter1_19_4<>(protocol).register(ClientboundPackets1_19_4.DECLARE_RECIPES);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_19_4.UNLOAD_CHUNK, wrapper -> {
|
||||
final int x = wrapper.read(Type.INT);
|
||||
final int z = wrapper.read(Type.INT);
|
||||
|
@ -20,11 +20,13 @@ package com.viaversion.viaversion.protocols.protocol1_20_2to1_20.handler;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
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.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
|
||||
public final class EntityPacketHandler1_20_2 extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_20_2To1_20> {
|
||||
@ -52,10 +54,12 @@ public final class EntityPacketHandler1_20_2 extends EntityRewriter<ClientboundP
|
||||
|
||||
wrapper.passthrough(Type.STRING_ARRAY); // World List
|
||||
|
||||
final CompoundTag dimensionRegistry = wrapper.read(Type.NBT); // TODO AAAAAAAAAAAAAAAAAAAAA
|
||||
final CompoundTag dimensionRegistry = wrapper.read(Type.NBT);
|
||||
final String dimensionType = wrapper.read(Type.STRING);
|
||||
final String world = wrapper.read(Type.STRING);
|
||||
final long seed = wrapper.read(Type.LONG);
|
||||
trackBiomeSize(wrapper.user(), dimensionRegistry); // Caches dimensions to access data like height later
|
||||
cacheDimensionData(wrapper.user(), dimensionRegistry); // Tracks the amount of biomes sent for chunk data
|
||||
|
||||
wrapper.passthrough(Type.VAR_INT); // Max players
|
||||
wrapper.passthrough(Type.VAR_INT); // View distance
|
||||
@ -73,9 +77,23 @@ public final class EntityPacketHandler1_20_2 extends EntityRewriter<ClientboundP
|
||||
wrapper.passthrough(Type.BOOLEAN); // Flat
|
||||
wrapper.passthrough(Type.OPTIONAL_GLOBAL_POSITION); // Last death position
|
||||
wrapper.passthrough(Type.VAR_INT); // Portal cooldown
|
||||
|
||||
// Send configuration packets first before going into the play protocol state
|
||||
final PacketWrapper registryDataPacket = wrapper.create(ClientboundConfigurationPackets1_20_2.REGISTRY_DATA);
|
||||
registryDataPacket.write(Type.NAMELESS_NBT, dimensionRegistry);
|
||||
registryDataPacket.send(Protocol1_20_2To1_20.class);
|
||||
|
||||
// Enabling features is only possible during the configuraton phase
|
||||
// TODO Capture more packets after login to send them later
|
||||
final PacketWrapper enableFeaturesPacket = wrapper.create(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES);
|
||||
enableFeaturesPacket.write(Type.VAR_INT, 1);
|
||||
enableFeaturesPacket.write(Type.STRING, "minecraft:vanilla");
|
||||
enableFeaturesPacket.scheduleSend(Protocol1_20_2To1_20.class);
|
||||
|
||||
// Manually send it at the end and hope nothing breaks
|
||||
wrapper.send(Protocol1_20_2To1_20.class);
|
||||
wrapper.cancel();
|
||||
});
|
||||
handler(dimensionDataHandler()); // Caches dimensions to access data like height later
|
||||
handler(biomeSizeTracker()); // Tracks the amount of biomes sent for chunk data
|
||||
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
|
||||
}
|
||||
});
|
||||
@ -105,16 +123,6 @@ public final class EntityPacketHandler1_20_2 extends EntityRewriter<ClientboundP
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
registerMetaTypeHandler(Types1_20.META_TYPES.itemType, Types1_20.META_TYPES.blockStateType, Types1_20.META_TYPES.optionalBlockStateType, Types1_20.META_TYPES.particleType);
|
||||
|
||||
filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
|
||||
final int blockState = meta.value();
|
||||
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType typeFromId(final int type) {
|
||||
return Entity1_19_4Types.getTypeFromId(type);
|
||||
|
@ -34,8 +34,8 @@ public enum ClientboundPackets1_20_2 implements ClientboundPacketType {
|
||||
BLOCK_CHANGE, // 0x0A
|
||||
BOSSBAR, // 0x0B
|
||||
SERVER_DIFFICULTY, // 0x0C
|
||||
CHUNK_BATCH_FINISHED, // 0x0D // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
CHUNK_BATCH_START, // 0x0E // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
CHUNK_BATCH_FINISHED, // 0x0D
|
||||
CHUNK_BATCH_START, // 0x0E
|
||||
CHUNK_BIOMES, // 0x0F
|
||||
CLEAR_TITLES, // 0x10
|
||||
TAB_COMPLETE, // 0x11
|
||||
@ -46,7 +46,7 @@ public enum ClientboundPackets1_20_2 implements ClientboundPacketType {
|
||||
SET_SLOT, // 0x16
|
||||
COOLDOWN, // 0x17
|
||||
CUSTOM_CHAT_COMPLETIONS, // 0x18
|
||||
PLUGIN_MESSAGE, // 0x19 // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
PLUGIN_MESSAGE, // 0x19
|
||||
DAMAGE_EVENT, // 0x1A
|
||||
DELETE_CHAT_MESSAGE, // 0x1B
|
||||
DISCONNECT, // 0x1C
|
||||
@ -122,7 +122,7 @@ public enum ClientboundPackets1_20_2 implements ClientboundPacketType {
|
||||
TITLE_TIMES, // 0x62
|
||||
ENTITY_SOUND, // 0x63
|
||||
SOUND, // 0x64
|
||||
START_CONFIGURATION, // 0x65 // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
START_CONFIGURATION, // 0x65
|
||||
STOP_SOUND, // 0x66
|
||||
SYSTEM_CHAT, // 0x67
|
||||
TAB_LIST, // 0x68
|
||||
|
@ -28,15 +28,15 @@ public enum ServerboundPackets1_20_2 implements ServerboundPacketType {
|
||||
CHAT_COMMAND, // 0x04
|
||||
CHAT_MESSAGE, // 0x05
|
||||
CHAT_SESSION_UPDATE, // 0x06
|
||||
CHUNK_BATCH_RECEIVED, // 0x07 // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
CHUNK_BATCH_RECEIVED, // 0x07
|
||||
CLIENT_STATUS, // 0x08
|
||||
CLIENT_SETTINGS, // 0x09
|
||||
TAB_COMPLETE, // 0x0A
|
||||
CONFIGURATION_ACKNOWLEDGED, // 0x0B // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
CONFIGURATION_ACKNOWLEDGED, // 0x0B
|
||||
CLICK_WINDOW_BUTTON, // 0x0C
|
||||
CLICK_WINDOW, // 0x0D
|
||||
CLOSE_WINDOW, // 0x0E
|
||||
PLUGIN_MESSAGE, // 0x0F // TODO AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
PLUGIN_MESSAGE, // 0x0F
|
||||
EDIT_BOOK, // 0x10
|
||||
ENTITY_NBT_REQUEST, // 0x11
|
||||
INTERACT_ENTITY, // 0x12
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* 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.viaversion.protocols.protocol1_20_2to1_20.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
|
||||
public class FakeProtocolState implements StorableObject {
|
||||
|
||||
private boolean configurationState;
|
||||
|
||||
public boolean isConfigurationState() {
|
||||
return configurationState;
|
||||
}
|
||||
|
||||
public void setConfigurationState(final boolean configurationState) {
|
||||
this.configurationState = configurationState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOnServerSwitch() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -45,6 +45,8 @@ import com.viaversion.viaversion.data.entity.DimensionDataImpl;
|
||||
import com.viaversion.viaversion.rewriter.meta.MetaFilter;
|
||||
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent;
|
||||
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEventImpl;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@ -52,7 +54,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public abstract class EntityRewriter<C extends ClientboundPacketType, T extends Protocol<C, ?, ?, ?>>
|
||||
extends RewriterBase<T> implements com.viaversion.viaversion.api.rewriter.EntityRewriter<T> {
|
||||
@ -468,32 +469,32 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
|
||||
}
|
||||
|
||||
public PacketHandler biomeSizeTracker() {
|
||||
return wrapper -> {
|
||||
final CompoundTag registry = wrapper.get(Type.NBT, 0);
|
||||
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
|
||||
final ListTag biomes = biomeRegistry.get("value");
|
||||
tracker(wrapper.user()).setBiomesSent(biomes.size());
|
||||
};
|
||||
return wrapper -> trackBiomeSize(wrapper.user(), wrapper.get(Type.NBT, 0));
|
||||
}
|
||||
|
||||
public void trackBiomeSize(final UserConnection connection, final CompoundTag registry) {
|
||||
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
|
||||
final ListTag biomes = biomeRegistry.get("value");
|
||||
tracker(connection).setBiomesSent(biomes.size());
|
||||
}
|
||||
|
||||
public PacketHandler dimensionDataHandler() {
|
||||
return wrapper -> cacheDimensionData(wrapper.user(), wrapper.get(Type.NBT, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler to cache dimension data, later used to get height values and other important info.
|
||||
*
|
||||
* @return handler to cache dimension data
|
||||
* Caches dimension data, later used to get height values and other important info.
|
||||
*/
|
||||
public PacketHandler dimensionDataHandler() {
|
||||
return wrapper -> {
|
||||
final CompoundTag tag = wrapper.get(Type.NBT, 0);
|
||||
final ListTag dimensions = ((CompoundTag) tag.get("minecraft:dimension_type")).get("value");
|
||||
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(dimensions.size());
|
||||
for (final Tag dimension : dimensions) {
|
||||
final CompoundTag dimensionCompound = (CompoundTag) dimension;
|
||||
final CompoundTag element = dimensionCompound.get("element");
|
||||
final String name = (String) dimensionCompound.get("name").getValue();
|
||||
dimensionDataMap.put(name, new DimensionDataImpl(element));
|
||||
}
|
||||
tracker(wrapper.user()).setDimensions(dimensionDataMap);
|
||||
};
|
||||
public void cacheDimensionData(final UserConnection connection, final CompoundTag registry) {
|
||||
final ListTag dimensions = ((CompoundTag) registry.get("minecraft:dimension_type")).get("value");
|
||||
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(dimensions.size());
|
||||
for (final Tag dimension : dimensions) {
|
||||
final CompoundTag dimensionCompound = (CompoundTag) dimension;
|
||||
final CompoundTag element = dimensionCompound.get("element");
|
||||
final String name = (String) dimensionCompound.get("name").getValue();
|
||||
dimensionDataMap.put(name, new DimensionDataImpl(element));
|
||||
}
|
||||
tracker(connection).setDimensions(dimensionDataMap);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren