Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 00:22:51 +01:00
WIP 24w40a
Dieser Commit ist enthalten in:
Ursprung
57d5652cd5
Commit
f58afd434d
@ -36,4 +36,8 @@ public record RegistryEntry(String key, @Nullable Tag tag) {
|
||||
public RegistryEntry withKey(final String key) {
|
||||
return new RegistryEntry(key, tag != null ? tag.copy() : null);
|
||||
}
|
||||
|
||||
public RegistryEntry copy() {
|
||||
return new RegistryEntry(key, tag != null ? tag.copy() : null);
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,8 @@ public enum EntityTypes1_21_2 implements EntityType {
|
||||
MANGROVE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
OAK_BOAT(ABSTRACT_BOAT),
|
||||
OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
PALE_OAK_BOAT(ABSTRACT_BOAT),
|
||||
PALE_OAK_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
SPRUCE_BOAT(ABSTRACT_BOAT),
|
||||
SPRUCE_CHEST_BOAT(ABSTRACT_CHEST_BOAT),
|
||||
|
||||
@ -209,6 +211,8 @@ public enum EntityTypes1_21_2 implements EntityType {
|
||||
BREEZE(ABSTRACT_MONSTER),
|
||||
ZOGLIN(ABSTRACT_MONSTER),
|
||||
WARDEN(ABSTRACT_MONSTER),
|
||||
CREAKING(ABSTRACT_MONSTER),
|
||||
CREAKING_TRANSIENT(ABSTRACT_MONSTER),
|
||||
|
||||
ABSTRACT_SKELETON(ABSTRACT_MONSTER, null),
|
||||
SKELETON(ABSTRACT_SKELETON),
|
||||
|
@ -86,7 +86,7 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4));
|
||||
public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6));
|
||||
public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1));
|
||||
public static final ProtocolVersion v1_21_2 = register(768, 211, "1.21.2");
|
||||
public static final ProtocolVersion v1_21_2 = register(768, 212, "1.21.2");
|
||||
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
|
||||
|
||||
public static ProtocolVersion register(int version, String name) {
|
||||
|
@ -137,6 +137,12 @@ public class ParticleType extends DynamicType<Particle> {
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Delay
|
||||
};
|
||||
public static final DataReader<Particle> COLOR = (buf, particle) -> particle.add(Types.INT, buf.readInt());
|
||||
public static final DataReader<Particle> TRAIL = (buf, particle) -> {
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target X
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target Y
|
||||
particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Target Z
|
||||
particle.add(Types.INT, buf.readInt()); // Color
|
||||
};
|
||||
|
||||
public static DataReader<Particle> item(Type<Item> item) {
|
||||
return (buf, particle) -> particle.add(item, item.read(buf));
|
||||
|
@ -105,16 +105,19 @@ final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPacket1_21, Cl
|
||||
// EntityTypes1_20_5.initialize(this);
|
||||
|
||||
// Uncomment if a new particle was added = ids shifted; requires a new Types_ class copied from the last
|
||||
/*Types1_21.PARTICLE.filler(this)
|
||||
.reader("block", ParticleType.Readers.BLOCK)
|
||||
.reader("block_marker", ParticleType.Readers.BLOCK)
|
||||
.reader("dust", ParticleType.Readers.DUST)
|
||||
.reader("falling_dust", ParticleType.Readers.BLOCK)
|
||||
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
|
||||
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
|
||||
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
|
||||
.reader("shriek", ParticleType.Readers.SHRIEK)
|
||||
.reader("item", ParticleType.Readers.item(...));*/
|
||||
/*Types1_21_2.PARTICLE.filler(this)
|
||||
.reader("block", ParticleType.Readers.BLOCK)
|
||||
.reader("block_marker", ParticleType.Readers.BLOCK)
|
||||
.reader("dust", ParticleType.Readers.DUST)
|
||||
.reader("dust_pillar", ParticleType.Readers.BLOCK)
|
||||
.reader("falling_dust", ParticleType.Readers.BLOCK)
|
||||
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
|
||||
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
|
||||
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
|
||||
.reader("shriek", ParticleType.Readers.SHRIEK)
|
||||
.reader("entity_effect", ParticleType.Readers.COLOR)
|
||||
.reader("trail", ParticleType.Readers.TRAIL)
|
||||
.reader("item", ParticleType.Readers.item(...));*/
|
||||
|
||||
super.onMappingDataLoaded(); // Calls load methods on rewriters. Last in case the rewriters access the above filled data
|
||||
}
|
||||
|
@ -143,11 +143,14 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPack
|
||||
.reader("block", ParticleType.Readers.BLOCK)
|
||||
.reader("block_marker", ParticleType.Readers.BLOCK)
|
||||
.reader("dust", ParticleType.Readers.DUST)
|
||||
.reader("dust_pillar", ParticleType.Readers.BLOCK)
|
||||
.reader("falling_dust", ParticleType.Readers.BLOCK)
|
||||
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
|
||||
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
|
||||
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
|
||||
.reader("shriek", ParticleType.Readers.SHRIEK)
|
||||
.reader("entity_effect", ParticleType.Readers.COLOR)
|
||||
.reader("trail", ParticleType.Readers.TRAIL)
|
||||
.reader("item", ParticleType.Readers.item(Types1_21_2.ITEM));
|
||||
Types1_21_2.STRUCTURED_DATA.filler(this).add(StructuredDataKey.CUSTOM_DATA, StructuredDataKey.MAX_STACK_SIZE, StructuredDataKey.MAX_DAMAGE,
|
||||
StructuredDataKey.UNBREAKABLE, StructuredDataKey.RARITY, StructuredDataKey.HIDE_TOOLTIP, StructuredDataKey.DAMAGE_RESISTANT,
|
||||
|
@ -51,6 +51,7 @@ public enum ClientboundPackets1_21_2 implements ClientboundPacket1_21_2 {
|
||||
DISCONNECT, // 0x1D
|
||||
DISGUISED_CHAT, // 0x1E
|
||||
ENTITY_EVENT, // 0x1F
|
||||
ENTITY_POSITION_SYNC, // 0x73
|
||||
EXPLODE, // 0x20
|
||||
FORGET_LEVEL_CHUNK, // 0x21
|
||||
GAME_EVENT, // 0x22
|
||||
@ -85,7 +86,10 @@ public enum ClientboundPackets1_21_2 implements ClientboundPacket1_21_2 {
|
||||
PLAYER_INFO_UPDATE, // 0x3F
|
||||
PLAYER_LOOK_AT, // 0x40
|
||||
PLAYER_POSITION, // 0x41
|
||||
RECIPE, // 0x42
|
||||
PLAYER_ROTATION, // 0x41
|
||||
RECIPE_BOOK_ADD, // 0x42
|
||||
RECIPE_BOOK_REMOVE, // 0x42
|
||||
RECIPE_BOOK_SETTINGS, // 0x42
|
||||
REMOVE_ENTITIES, // 0x43
|
||||
REMOVE_MOB_EFFECT, // 0x44
|
||||
RESET_SCORE, // 0x45
|
||||
|
@ -20,9 +20,9 @@ package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
@ -38,7 +38,6 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
@ -51,6 +50,7 @@ import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import com.viaversion.viaversion.util.Unit;
|
||||
import java.util.Set;
|
||||
|
||||
public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<ClientboundPacket1_21, ServerboundPacket1_21_2, Protocol1_21To1_21_2> {
|
||||
|
||||
@ -88,7 +88,7 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_CONTENT, wrapper -> {
|
||||
updateContainerId(wrapper);
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
Item[] items = wrapper.read(itemArrayType());
|
||||
final Item[] items = wrapper.read(itemArrayType());
|
||||
wrapper.write(mappedItemArrayType(), items);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
@ -104,10 +104,8 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_CLOSE, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_DATA, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.HORSE_SCREEN_OPEN, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.PLACE_GHOST_RECIPE, this::updateContainerId);
|
||||
protocol.registerClientbound(ClientboundPackets1_21.SET_CARRIED_ITEM, ClientboundPackets1_21_2.SET_HELD_SLOT);
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLOSE, this::updateContainerIdServerbound);
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.PLACE_RECIPE, this::updateContainerIdServerbound);
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLICK, wrapper -> {
|
||||
updateContainerIdServerbound(wrapper);
|
||||
wrapper.passthrough(Types.VAR_INT); // State id
|
||||
@ -121,6 +119,26 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
|
||||
}
|
||||
passthroughServerboundItem(wrapper);
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_21.PLACE_GHOST_RECIPE, wrapper -> {
|
||||
this.updateContainerId(wrapper);
|
||||
|
||||
final String recipe = wrapper.read(Types.STRING);
|
||||
wrapper.write(Types.VAR_INT, recipeDisplay(recipe)); // TODO
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.PLACE_RECIPE, wrapper -> {
|
||||
this.updateContainerIdServerbound(wrapper);
|
||||
|
||||
final String recipe = wrapper.read(Types.STRING);
|
||||
wrapper.write(Types.VAR_INT, 0); // TODO Display id, from recipe packet
|
||||
wrapper.cancel();
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.RECIPE_BOOK_SEEN_RECIPE, wrapper -> {
|
||||
this.updateContainerIdServerbound(wrapper);
|
||||
|
||||
final String recipe = wrapper.read(Types.STRING);
|
||||
wrapper.write(Types.VAR_INT, 0); // TODO Display id, from recipe packet
|
||||
wrapper.cancel();
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.USE_ITEM_ON, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Hand
|
||||
@ -174,68 +192,64 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
|
||||
new SoundRewriter<>(protocol).soundHolderHandler().handle(wrapper);
|
||||
});
|
||||
|
||||
new RecipeRewriter1_20_3<>(protocol) {
|
||||
@Override
|
||||
protected void handleIngredient(final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
|
||||
}
|
||||
protocol.registerClientbound(ClientboundPackets1_21.UPDATE_RECIPES, wrapper -> {
|
||||
final RecipeRewriter rewriter = new RecipeRewriter(protocol);
|
||||
wrapper.cancel(); // TODO
|
||||
|
||||
@Override
|
||||
public void handleCraftingShaped(final PacketWrapper wrapper) {
|
||||
wrapper.passthrough(Types.STRING); // Group
|
||||
wrapper.passthrough(Types.VAR_INT); // Crafting book category
|
||||
final int width = wrapper.passthrough(Types.VAR_INT);
|
||||
final int height = wrapper.passthrough(Types.VAR_INT);
|
||||
final int ingredients = width * height;
|
||||
final int size = wrapper.passthrough(Types.VAR_INT);
|
||||
int newSize = size;
|
||||
for (int i = 0; i < size; i++) {
|
||||
final String recipeIdentifier = wrapper.read(Types.STRING);
|
||||
|
||||
wrapper.write(Types.VAR_INT, ingredients);
|
||||
for (int i = 0; i < ingredients; i++) {
|
||||
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
|
||||
}
|
||||
|
||||
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result
|
||||
wrapper.passthrough(Types.BOOLEAN); // Show notification
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCraftingShapeless(final PacketWrapper wrapper) {
|
||||
wrapper.passthrough(Types.STRING); // Group
|
||||
wrapper.passthrough(Types.VAR_INT); // Crafting book category
|
||||
|
||||
final int ingredients = wrapper.read(Types.VAR_INT);
|
||||
final HolderSet[] ingredient = new HolderSet[ingredients];
|
||||
for (int i = 0; i < ingredients; i++) {
|
||||
ingredient[i] = ingredient(wrapper);
|
||||
}
|
||||
|
||||
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
|
||||
|
||||
// Also moved below here
|
||||
wrapper.write(Types.VAR_INT, ingredients);
|
||||
for (final HolderSet item : ingredient) {
|
||||
wrapper.write(Types.HOLDER_SET, item);
|
||||
}
|
||||
}
|
||||
|
||||
private HolderSet ingredient(final PacketWrapper wrapper) {
|
||||
final Item[] items = wrapper.read(itemArrayType());
|
||||
final int[] ids = new int[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
final Item item = rewrite(wrapper.user(), items[i]);
|
||||
ids[i] = item.identifier();
|
||||
}
|
||||
return HolderSet.of(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRecipeType(final PacketWrapper wrapper, final String type) {
|
||||
if (type.equals("crafting_special_suspiciousstew") || type.equals("crafting_special_shulkerboxcoloring")) {
|
||||
wrapper.read(Types.VAR_INT); // Crafting book category
|
||||
final FullMappings recipeSerializerMappings = protocol.getMappingData().getRecipeSerializerMappings();
|
||||
final int typeId = wrapper.read(Types.VAR_INT);
|
||||
final int mappedId = recipeSerializerMappings.getNewId(typeId);
|
||||
if (mappedId != -1) {
|
||||
wrapper.write(Types.STRING, recipeIdentifier);
|
||||
wrapper.write(Types.VAR_INT, mappedId);
|
||||
} else {
|
||||
super.handleRecipeType(wrapper, type);
|
||||
wrapper.set(Types.VAR_INT, 0, --newSize);
|
||||
}
|
||||
|
||||
rewriter.handleRecipeType(wrapper, Key.stripMinecraftNamespace(recipeSerializerMappings.identifier(typeId))); // Use the original
|
||||
}
|
||||
}.register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.RECIPE, ClientboundPackets1_21_2.RECIPE_BOOK_ADD, wrapper -> {
|
||||
final int state = wrapper.passthrough(Types.VAR_INT);
|
||||
|
||||
// Pairs of open + filtering for: Crafting, furnace, blast furnace, smoker
|
||||
final PacketWrapper settingsPacket = wrapper.create(ClientboundPackets1_21_2.RECIPE_BOOK_SETTINGS);
|
||||
for (int i = 0; i < 4 * 2; i++) {
|
||||
settingsPacket.write(Types.BOOLEAN, wrapper.read(Types.BOOLEAN));
|
||||
}
|
||||
settingsPacket.send(Protocol1_21To1_21_2.class);
|
||||
|
||||
// TODO
|
||||
wrapper.cancel();
|
||||
|
||||
final String[] recipes = wrapper.passthrough(Types.STRING_ARRAY);
|
||||
Set<String> toHighlight = Set.of();
|
||||
if (state == 0) { // Init (1=Add, 2=Remove)
|
||||
final String[] highlightRecipes = wrapper.passthrough(Types.STRING_ARRAY);
|
||||
toHighlight = Set.of(highlightRecipes);
|
||||
}
|
||||
|
||||
wrapper.write(Types.VAR_INT, recipes.length);
|
||||
for (final String recipe : recipes) {
|
||||
// Display id
|
||||
// Display type
|
||||
// Optional group
|
||||
// Category type
|
||||
// Item contents
|
||||
|
||||
byte flags = 0;
|
||||
if (toHighlight.contains(recipe)) {
|
||||
flags |= (1 << 1); // Highlight
|
||||
}
|
||||
wrapper.write(Types.BYTE, flags);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -252,6 +266,18 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
|
||||
return item;
|
||||
}
|
||||
|
||||
private int recipeDisplay(String type) {
|
||||
type = Key.stripMinecraftNamespace(type);
|
||||
return switch (type) {
|
||||
case "crafting_shapeless" -> 0;
|
||||
case "crafting_shaped" -> 1;
|
||||
case "furnace" -> 2;
|
||||
case "stonecutter" -> 3;
|
||||
case "smithing" -> 4;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
private void updateContainerId(final PacketWrapper wrapper) {
|
||||
// Container id handling was always a bit whack with most reading them as unsigned bytes, some as bytes, some already as var ints.
|
||||
// In VV they're generally read as unsigned bytesto not have to look the type up every time, but we need to make sure they're
|
||||
|
@ -18,9 +18,6 @@
|
||||
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2;
|
||||
@ -33,12 +30,11 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfi
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ClientVehicleStorage;
|
||||
import com.viaversion.viaversion.rewriter.EntityRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import java.util.Arrays;
|
||||
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
|
||||
|
||||
public final class EntityPacketRewriter1_21_2 extends EntityRewriter<ClientboundPacket1_21, Protocol1_21To1_21_2> {
|
||||
|
||||
@ -80,32 +76,8 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
instrumentsPacket.send(Protocol1_21To1_21_2.class);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> {
|
||||
final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
|
||||
RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY);
|
||||
if (registryKey.equals("enchantment")) {
|
||||
updateEnchantmentAttributes(entries, protocol.getMappingData().getAttributeMappings());
|
||||
} else if (registryKey.equals("damage_type")) {
|
||||
// Add new damage types
|
||||
final int length = entries.length;
|
||||
entries = Arrays.copyOf(entries, length + 2);
|
||||
|
||||
final CompoundTag enderpearlData = new CompoundTag();
|
||||
enderpearlData.putString("scaling", "when_caused_by_living_non_player");
|
||||
enderpearlData.putString("message_id", "fall");
|
||||
enderpearlData.putFloat("exhaustion", 0.0F);
|
||||
entries[length] = new RegistryEntry("minecraft:ender_pearl", enderpearlData);
|
||||
|
||||
final CompoundTag maceSmashData = new CompoundTag();
|
||||
maceSmashData.putString("scaling", "when_caused_by_living_non_player");
|
||||
maceSmashData.putString("message_id", "mace_smash");
|
||||
maceSmashData.putFloat("exhaustion", 0.1F);
|
||||
entries[length + 1] = new RegistryEntry("minecraft:mace_smash", maceSmashData);
|
||||
}
|
||||
|
||||
wrapper.write(Types.REGISTRY_ENTRY_ARRAY, entries);
|
||||
handleRegistryData1_20_5(wrapper.user(), registryKey, entries);
|
||||
});
|
||||
final RegistryDataRewriter registryDataRewriter = registryDataRewriter();
|
||||
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() {
|
||||
@Override
|
||||
@ -233,6 +205,25 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
wrapper.write(Types.BYTE, updatedFlags);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_21.TELEPORT_ENTITY, ClientboundPackets1_21_2.ENTITY_POSITION_SYNC, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Entity ID
|
||||
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
|
||||
// Unused...
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement X
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement Y
|
||||
wrapper.write(Types.DOUBLE, 0D); // Delta movement Z
|
||||
|
||||
// Unpack y and x rot
|
||||
final byte yaw = wrapper.read(Types.BYTE);
|
||||
final byte pitch = wrapper.read(Types.BYTE);
|
||||
wrapper.write(Types.FLOAT, yaw * 360F / 256F);
|
||||
wrapper.write(Types.FLOAT, pitch * 360F / 256F);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS, wrapper -> {
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
@ -255,66 +246,25 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, this::readOnGround);
|
||||
}
|
||||
|
||||
public static void updateEnchantmentAttributes(final RegistryEntry[] entries, final FullMappings mappings) {
|
||||
for (final RegistryEntry entry : entries) {
|
||||
if (entry.tag() == null) {
|
||||
continue;
|
||||
}
|
||||
private RegistryDataRewriter registryDataRewriter() {
|
||||
final CompoundTag enderpearlData = new CompoundTag();
|
||||
enderpearlData.putString("scaling", "when_caused_by_living_non_player");
|
||||
enderpearlData.putString("message_id", "fall");
|
||||
enderpearlData.putFloat("exhaustion", 0.0F);
|
||||
|
||||
final CompoundTag effects = ((CompoundTag) entry.tag()).getCompoundTag("effects");
|
||||
if (effects != null) {
|
||||
updateLocationChangedAttributes(effects, mappings);
|
||||
updateAttributesFields(effects, mappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
final CompoundTag maceSmashData = new CompoundTag();
|
||||
maceSmashData.putString("scaling", "when_caused_by_living_non_player");
|
||||
maceSmashData.putString("message_id", "mace_smash");
|
||||
maceSmashData.putFloat("exhaustion", 0.1F);
|
||||
|
||||
private static void updateAttributesFields(final CompoundTag effects, final FullMappings mappings) {
|
||||
final ListTag<CompoundTag> attributesList = TagUtil.getNamespacedCompoundTagList(effects, "attributes");
|
||||
if (attributesList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CompoundTag attributeData : attributesList) {
|
||||
updateAttributeField(attributeData, mappings);
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateLocationChangedAttributes(final CompoundTag effects, final FullMappings mappings) {
|
||||
final ListTag<CompoundTag> locationChanged = TagUtil.getNamespacedCompoundTagList(effects, "location_changed");
|
||||
if (locationChanged == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CompoundTag data : locationChanged) {
|
||||
final CompoundTag effect = data.getCompoundTag("effect");
|
||||
if (effect == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
updateAttributeField(effect, mappings);
|
||||
|
||||
final ListTag<CompoundTag> innerEffects = effect.getListTag("effects", CompoundTag.class);
|
||||
if (innerEffects != null) {
|
||||
for (final CompoundTag innerEffect : innerEffects) {
|
||||
updateAttributeField(innerEffect, mappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateAttributeField(final CompoundTag attributeData, final FullMappings mappings) {
|
||||
final StringTag attributeTag = attributeData.getStringTag("attribute");
|
||||
if (attributeTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String attribute = Key.stripMinecraftNamespace(attributeTag.getValue());
|
||||
String mappedAttribute = mappings.mappedIdentifier(attribute);
|
||||
if (mappedAttribute == null) {
|
||||
mappedAttribute = mappings.mappedIdentifier(0); // Dummy
|
||||
}
|
||||
attributeTag.setValue(mappedAttribute);
|
||||
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
|
||||
registryDataRewriter.addEntries(
|
||||
"damage_type",
|
||||
new RegistryEntry("minecraft:ender_pearl", enderpearlData),
|
||||
new RegistryEntry("minecraft:mace_smash", maceSmashData)
|
||||
);
|
||||
registryDataRewriter.addEnchantmentEffectRewriter("damage_item", tag -> tag.putString("type", "change_item_damage"));
|
||||
return registryDataRewriter;
|
||||
}
|
||||
|
||||
private void readOnGround(final PacketWrapper wrapper) {
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 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.v1_21to1_21_2.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
|
||||
final class RecipeRewriter extends RecipeRewriter1_20_3<ClientboundPacket1_21> {
|
||||
|
||||
RecipeRewriter(final Protocol<ClientboundPacket1_21, ?, ?, ?> protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleIngredient(final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCraftingShaped(final PacketWrapper wrapper) {
|
||||
wrapper.passthrough(Types.STRING); // Group
|
||||
wrapper.passthrough(Types.VAR_INT); // Crafting book category
|
||||
final int width = wrapper.passthrough(Types.VAR_INT);
|
||||
final int height = wrapper.passthrough(Types.VAR_INT);
|
||||
final int ingredients = width * height;
|
||||
|
||||
wrapper.write(Types.VAR_INT, ingredients);
|
||||
for (int i = 0; i < ingredients; i++) {
|
||||
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
|
||||
}
|
||||
|
||||
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result
|
||||
wrapper.passthrough(Types.BOOLEAN); // Show notification
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCraftingShapeless(final PacketWrapper wrapper) {
|
||||
wrapper.passthrough(Types.STRING); // Group
|
||||
wrapper.passthrough(Types.VAR_INT); // Crafting book category
|
||||
|
||||
final int ingredients = wrapper.read(Types.VAR_INT);
|
||||
final HolderSet[] ingredient = new HolderSet[ingredients];
|
||||
for (int i = 0; i < ingredients; i++) {
|
||||
ingredient[i] = ingredient(wrapper);
|
||||
}
|
||||
|
||||
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
|
||||
|
||||
// Also moved below here
|
||||
wrapper.write(Types.VAR_INT, ingredients);
|
||||
for (final HolderSet item : ingredient) {
|
||||
wrapper.write(Types.HOLDER_SET, item);
|
||||
}
|
||||
}
|
||||
|
||||
private HolderSet ingredient(final PacketWrapper wrapper) {
|
||||
final Item[] items = wrapper.read(itemArrayType());
|
||||
final int[] ids = new int[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
final Item item = rewrite(wrapper.user(), items[i]);
|
||||
ids[i] = item.identifier();
|
||||
}
|
||||
return HolderSet.of(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRecipeType(final PacketWrapper wrapper, final String type) {
|
||||
if (type.equals("crafting_special_suspiciousstew") || type.equals("crafting_special_shulkerboxcoloring")) {
|
||||
wrapper.read(Types.VAR_INT); // Crafting book category
|
||||
} else {
|
||||
super.handleRecipeType(wrapper, type);
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
|
||||
|
||||
// Dead as of 1.21.2, the server only sends simple recipe display data instead of full results
|
||||
public class RecipeRewriter1_21_2<C extends ClientboundPacketType> extends RecipeRewriter1_20_3<C> {
|
||||
|
||||
public RecipeRewriter1_21_2(final Protocol<C, ?, ?, ?> protocol) {
|
||||
|
@ -88,6 +88,7 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
int newSize = size;
|
||||
for (int i = 0; i < size; i++) {
|
||||
final String recipeIdentifier = wrapper.read(Types.STRING);
|
||||
// TODO Recipe identifier, then int array item ids and that's it
|
||||
|
||||
final FullMappings recipeSerializerMappings = protocol.getMappingData().getRecipeSerializerMappings();
|
||||
final int typeId = wrapper.read(Types.VAR_INT);
|
||||
@ -101,6 +102,11 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
|
||||
|
||||
handleRecipeType(wrapper, Key.stripMinecraftNamespace(recipeSerializerMappings.identifier(typeId))); // Use the original
|
||||
}
|
||||
|
||||
// Stonecutter recipes on their own
|
||||
// List of:
|
||||
// Ingredient (item holder set)
|
||||
// Slot display id
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 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.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.entity.DimensionData;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.DimensionDataImpl;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class RegistryDataRewriter {
|
||||
private final Map<String, Consumer<CompoundTag>> enchantmentEffectRewriters = new Object2ObjectArrayMap<>();
|
||||
private final Map<String, List<RegistryEntry>> toAdd = new Object2ObjectArrayMap<>();
|
||||
private final Protocol<?, ?, ?, ?> protocol;
|
||||
|
||||
public RegistryDataRewriter(Protocol<?, ?, ?, ?> protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void handle(final PacketWrapper wrapper) {
|
||||
final String registryKey = wrapper.passthrough(Types.STRING);
|
||||
RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY);
|
||||
entries = handle(wrapper.user(), registryKey, entries);
|
||||
wrapper.write(Types.REGISTRY_ENTRY_ARRAY, entries);
|
||||
}
|
||||
|
||||
public RegistryEntry[] handle(final UserConnection connection, String key, RegistryEntry[] entries) {
|
||||
key = Key.stripMinecraftNamespace(key);
|
||||
if (key.equals("enchantment")) {
|
||||
updateEnchantments(entries);
|
||||
}
|
||||
|
||||
final List<RegistryEntry> toAdd = this.toAdd.get(key);
|
||||
if (toAdd != null) {
|
||||
final int length = entries.length;
|
||||
final int toAddLength = toAdd.size();
|
||||
entries = Arrays.copyOf(entries, length + toAddLength);
|
||||
for (int i = 0; i < toAddLength; i++) {
|
||||
entries[length + i] = toAdd.get(i).copy();
|
||||
}
|
||||
}
|
||||
|
||||
trackDimensionAndBiomes(connection, key, entries);
|
||||
return entries;
|
||||
}
|
||||
|
||||
public void addEntries(final String registryKey, final RegistryEntry... entries) {
|
||||
toAdd.computeIfAbsent(Key.stripMinecraftNamespace(registryKey), $ -> new ArrayList<>()).addAll(List.of(entries));
|
||||
}
|
||||
|
||||
public void addEnchantmentEffectRewriter(final String key, final Consumer<CompoundTag> rewriter) {
|
||||
enchantmentEffectRewriters.put(Key.stripMinecraftNamespace(key), rewriter);
|
||||
}
|
||||
|
||||
public void trackDimensionAndBiomes(final UserConnection connection, final String registryKey, final RegistryEntry[] entries) {
|
||||
if (registryKey.equals("worldgen/biome")) {
|
||||
protocol.getEntityRewriter().tracker(connection).setBiomesSent(entries.length);
|
||||
} else if (registryKey.equals("dimension_type")) {
|
||||
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(entries.length);
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
final RegistryEntry entry = entries[i];
|
||||
final String key = Key.stripMinecraftNamespace(entry.key());
|
||||
final DimensionData dimensionData = entry.tag() != null
|
||||
? new DimensionDataImpl(i, (CompoundTag) entry.tag())
|
||||
: DimensionDataImpl.withDefaultsFor(key, i);
|
||||
dimensionDataMap.put(key, dimensionData);
|
||||
}
|
||||
protocol.getEntityRewriter().tracker(connection).setDimensions(dimensionDataMap);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateEnchantments(final RegistryEntry[] entries) {
|
||||
for (final RegistryEntry entry : entries) {
|
||||
if (entry.tag() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final CompoundTag effects = ((CompoundTag) entry.tag()).getCompoundTag("effects");
|
||||
if (effects == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go through all effects, almost all of them may contain an "effect" element
|
||||
for (final Map.Entry<String, Tag> effectEntry : effects.entrySet()) {
|
||||
if (effectEntry.getValue() instanceof final CompoundTag compoundTag) {
|
||||
updateNestedEffect(compoundTag);
|
||||
} else if (effectEntry.getValue() instanceof final ListTag<?> listTag && listTag.getElementType() == CompoundTag.class) {
|
||||
for (final Tag tag : listTag) {
|
||||
updateNestedEffect((CompoundTag) tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateAttributesFields(effects);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNestedEffect(final CompoundTag effectsTag) {
|
||||
final CompoundTag effect = effectsTag.getCompoundTag("effect");
|
||||
if (effect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
runEffectRewriters(effect);
|
||||
|
||||
final ListTag<CompoundTag> innerEffects = effect.getListTag("effects", CompoundTag.class);
|
||||
if (innerEffects == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CompoundTag innerEffect : innerEffects) {
|
||||
runEffectRewriters(innerEffect);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttributesFields(final CompoundTag effects) {
|
||||
if (!hasAttributeMappings()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> attributesList = TagUtil.getNamespacedCompoundTagList(effects, "attributes");
|
||||
if (attributesList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final CompoundTag attributeData : attributesList) {
|
||||
updateAttributeField(attributeData);
|
||||
}
|
||||
}
|
||||
|
||||
private void runEffectRewriters(final CompoundTag effectTag) {
|
||||
String effect = effectTag.getString("type");
|
||||
if (effect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
effect = Key.stripMinecraftNamespace(effect);
|
||||
updateAttributeField(effectTag);
|
||||
|
||||
final Consumer<CompoundTag> rewriter = enchantmentEffectRewriters.get(effect);
|
||||
if (rewriter != null) {
|
||||
rewriter.accept(effectTag);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttributeField(final CompoundTag attributeData) {
|
||||
final StringTag attributeTag = attributeData.getStringTag("attribute");
|
||||
if (attributeTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final FullMappings mappings = protocol.getMappingData().getAttributeMappings();
|
||||
final String attribute = Key.stripMinecraftNamespace(attributeTag.getValue());
|
||||
String mappedAttribute = mappings.mappedIdentifier(attribute);
|
||||
if (mappedAttribute == null) {
|
||||
mappedAttribute = mappings.mappedIdentifier(0); // Dummy
|
||||
}
|
||||
attributeTag.setValue(mappedAttribute);
|
||||
}
|
||||
|
||||
private boolean hasAttributeMappings() {
|
||||
return protocol.getMappingData() != null && protocol.getMappingData().getAttributeMappings() != null;
|
||||
}
|
||||
}
|
Binäre Datei nicht angezeigt.
Binäre Datei nicht angezeigt.
Binäre Datei nicht angezeigt.
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren