Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@
import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.rewriter.ComponentRewriter1_19_4;
import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.rewriter.EntityPacketRewriter1_19_4;
import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.storage.EntityTracker1_19_4;
import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.storage.LinkedEntityStorage;
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.EnchantmentsPaintingsStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_19_4;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_18;
import com.viaversion.viaversion.api.type.types.version.Types1_19_3;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ServerboundPackets1_19_3;
Expand All @@ -38,7 +43,10 @@
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;

import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

public final class Protocol1_19_4To1_19_3 extends BackwardsProtocol<ClientboundPackets1_19_4, ClientboundPackets1_19_3, ServerboundPackets1_19_4, ServerboundPackets1_19_3> {

Expand Down Expand Up @@ -87,7 +95,33 @@ public void handleArgument(final PacketWrapper wrapper, final String argumentTyp
wrapper.write(Types.OPTIONAL_STRING, iconBase64);
});

cancelClientbound(ClientboundPackets1_19_4.BUNDLE_DELIMITER);
registerClientbound(ClientboundPackets1_19_4.BUNDLE_DELIMITER, null, wrapper -> {
// Bundles were introduced in 1.19.4
wrapper.cancel();

// 1.19.3+ only sends non-default values, 1.19->1.18 protocol needs entity data to spawn paintings.
// In 1.19.4 we can detect this because add_entity + set_entity_data are always sent in a bundle
EntityTracker1_19_4 tracker = wrapper.user().getEntityTracker(this);
if (tracker.getSpawningPainting() != -1 && tracker.entityType(tracker.getSpawningPainting()) == EntityTypes1_19_4.PAINTING) {
final int paintingId = tracker.getSpawningPainting();
final LinkedEntityStorage storage = tracker.linkedEntityStorage(paintingId);
if (storage != null && !storage.sentPaintingType()) {
// Use first type in registry as default, kebab (0) otherwise.
// kebab has been the default painting for most versions, 1.21+ uses alban instead but probably
// unintentionally (first in registry)
final EnchantmentsPaintingsStorage registry = wrapper.user().get(EnchantmentsPaintingsStorage.class);
final int defaultPainting = registry != null ? registry.mappedDefaultPainting() : 0;
final EntityData type = new EntityData(8, Types1_19_3.ENTITY_DATA_TYPES.paintingVariantType, defaultPainting);

final PacketWrapper packet = PacketWrapper.create(ClientboundPackets1_19_3.SET_ENTITY_DATA, wrapper.user());
packet.write(Types.VAR_INT, paintingId);
packet.write(Types1_19_3.ENTITY_DATA_LIST, List.of(type));
packet.send(Protocol1_19_4To1_19_3.class);
}
}
tracker.setSpawningPainting(-1);
});

cancelClientbound(ClientboundPackets1_19_4.CHUNKS_BIOMES); // We definitely do not want to cache every single chunk just to resent them with new biomes
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ public void register() {
wrapper.set(Types.VAR_INT, 2, protocol.getMappingData().getNewBlockStateId(blockState));
}

final EntityTracker1_19_4 tracker = wrapper.user().getEntityTracker(protocol);
if (entity.entityType() == EntityTypes1_19_4.PAINTING) {
tracker.setSpawningPainting(entityId);
} else {
tracker.setSpawningPainting(-1);
}

final LinkedEntityStorage storage = new LinkedEntityStorage();
final double x = wrapper.get(Types.DOUBLE, 0);
final double z = wrapper.get(Types.DOUBLE, 2);
Expand Down Expand Up @@ -494,6 +501,14 @@ public void registerRewrites() {
}
});

filter().type(EntityTypes1_19_4.PAINTING).index(8).handler((event, data) -> {
// Painting variant
final LinkedEntityStorage storage = event.trackedEntity().get(LinkedEntityStorage.class);
if (storage != null) {
storage.sentPaintingType(true);
}
});

filter().type(EntityTypes1_19_4.INTERACTION).cancel(8); // Width
filter().type(EntityTypes1_19_4.INTERACTION).cancel(9); // Height
filter().type(EntityTypes1_19_4.INTERACTION).cancel(10); // Response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
public final class EntityTracker1_19_4 extends EntityTrackerBase {

private final IntSet generatedEntities = new IntOpenHashSet(); // Track entities spawned to prevent duplicated entity ids
private int spawningPainting = -1;

public EntityTracker1_19_4(final UserConnection connection) {
super(connection, EntityTypes1_19_4.PLAYER);
Expand Down Expand Up @@ -62,6 +63,16 @@ public int spawnEntity(final EntityTypes1_19_3 entityType, final double x, final
return entityId;
}



public void setSpawningPainting(int spawningPainting) {
this.spawningPainting = spawningPainting;
}

public int getSpawningPainting() {
return spawningPainting;
}

@Override
public @Nullable TrackedEntity removeEntity(final int id) {
final TrackedEntity entity = super.removeEntity(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class LinkedEntityStorage extends EntityPositionStorage implements Storab
private int[] entities;
private int[] passengers;
private Integer vehicleId;
private boolean sentPaintingType;

public int @Nullable [] entities() {
return entities;
Expand Down Expand Up @@ -60,6 +61,14 @@ public void setVehicleId(@Nullable final Integer vehicleId) {
this.vehicleId = vehicleId;
}

public boolean sentPaintingType() {
return sentPaintingType;
}

public void sentPaintingType(boolean sentPaintingType) {
this.sentPaintingType = sentPaintingType;
}

public void remove(final UserConnection connection) {
final PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_19_3.REMOVE_ENTITIES, connection);
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, entities);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ public int jubeboxSongToItem(final int id) {
}

public int mappedPainting(final int id) {
return id > 0 && id < paintingMappings.length ? paintingMappings[id] : 0;
return id >= 0 && id < paintingMappings.length ? paintingMappings[id] : 0;
}

public int mappedDefaultPainting() {
return mappedPainting(0);
}

public @Nullable Tag enchantmentDescription(final int id) {
Expand Down