From d0fecb895160055ebd7cbc0c9a99416f01afa92c Mon Sep 17 00:00:00 2001 From: FlorianMichael <60033407+FlorianMichael@users.noreply.github.com> Date: Sat, 11 May 2024 17:18:00 +0200 Subject: [PATCH] Merge rewriter and packet classes (entities and items) in 1.8->1.9 --- .../v1_10to1_11/Protocol1_10To1_11.java | 8 +- ...1To1_10.java => MetadataRewriter1_11.java} | 4 +- .../protocols/v1_8to1_9/Protocol1_8To1_9.java | 15 +- .../data/{Effect.java => EffectIds.java} | 2 +- .../protocols/v1_8to1_9/data/EntityIds.java | 97 +++++ .../{metadata => data}/MetaIndex.java | 2 +- .../protocols/v1_8to1_9/data/PotionIds.java | 189 +++++++++ .../metadata/MetadataRewriter1_9To1_8.java | 153 ------- .../v1_8to1_9/rewriter/ChatRewriter.java | 50 --- .../rewriter/EntityPacketRewriter1_9.java | 154 ++++++- .../rewriter/ItemPacketRewriter1_9.java | 218 ++++++++-- .../v1_8to1_9/rewriter/ItemRewriter.java | 396 ------------------ .../v1_8to1_9/rewriter/PlayerPackets1_9.java | 43 +- .../v1_8to1_9/rewriter/SpawnPackets1_9.java | 8 +- .../rewriter/WorldPacketRewriter1_9.java | 8 +- 15 files changed, 660 insertions(+), 687 deletions(-) rename common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/metadata/{MetadataRewriter1_11To1_10.java => MetadataRewriter1_11.java} (98%) rename common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/{Effect.java => EffectIds.java} (98%) create mode 100644 common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/EntityIds.java rename common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/{metadata => data}/MetaIndex.java (99%) create mode 100644 common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIds.java delete mode 100644 common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetadataRewriter1_9To1_8.java delete mode 100644 common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ChatRewriter.java delete mode 100644 common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemRewriter.java diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java index c8d587416..992934c7b 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java @@ -33,7 +33,7 @@ import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3; import com.viaversion.viaversion.api.type.types.version.Types1_9; import com.viaversion.viaversion.protocols.v1_10to1_11.data.PotionColorMapping; -import com.viaversion.viaversion.protocols.v1_10to1_11.metadata.MetadataRewriter1_11To1_10; +import com.viaversion.viaversion.protocols.v1_10to1_11.metadata.MetadataRewriter1_11; import com.viaversion.viaversion.protocols.v1_10to1_11.rewriter.BlockEntityRewriter; import com.viaversion.viaversion.protocols.v1_10to1_11.rewriter.EntityIdRewriter; import com.viaversion.viaversion.protocols.v1_10to1_11.rewriter.ItemPacketRewriter1_11; @@ -51,7 +51,7 @@ public class Protocol1_10To1_11 extends AbstractProtocol { +public class MetadataRewriter1_11 extends EntityRewriter { - public MetadataRewriter1_11To1_10(Protocol1_10To1_11 protocol) { + public MetadataRewriter1_11(Protocol1_10To1_11 protocol) { super(protocol); } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java index 56c94fdd0..424c48a96 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java @@ -32,7 +32,6 @@ import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; import com.viaversion.viaversion.protocols.v1_8.packet.ServerboundPackets1_8; -import com.viaversion.viaversion.protocols.v1_8to1_9.metadata.MetadataRewriter1_9To1_8; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.providers.BossBarProvider; @@ -63,7 +62,8 @@ public class Protocol1_8To1_9 extends AbstractProtocol. + */ +package com.viaversion.viaversion.protocols.v1_8to1_9.data; + +import java.util.HashMap; +import java.util.Map; + +public class EntityIds { + + public static final Map ENTITY_NAME_TO_ID = new HashMap<>(); + public static final Map ENTITY_ID_TO_NAME = new HashMap<>(); + + static { + register(1, "Item"); + register(2, "XPOrb"); + register(7, "ThrownEgg"); + register(8, "LeashKnot"); + register(9, "Painting"); + register(10, "Arrow"); + register(11, "Snowball"); + register(12, "Fireball"); + register(13, "SmallFireball"); + register(14, "ThrownEnderpearl"); + register(15, "EyeOfEnderSignal"); + register(16, "ThrownPotion"); + register(17, "ThrownExpBottle"); + register(18, "ItemFrame"); + register(19, "WitherSkull"); + register(20, "PrimedTnt"); + register(21, "FallingSand"); + register(22, "FireworksRocketEntity"); + register(30, "ArmorStand"); + register(40, "MinecartCommandBlock"); + register(41, "Boat"); + register(42, "MinecartRideable"); + register(43, "MinecartChest"); + register(44, "MinecartFurnace"); + register(45, "MinecartTNT"); + register(46, "MinecartHopper"); + register(47, "MinecartSpawner"); + register(48, "Mob"); + register(49, "Monster"); + register(50, "Creeper"); + register(51, "Skeleton"); + register(52, "Spider"); + register(53, "Giant"); + register(54, "Zombie"); + register(55, "Slime"); + register(56, "Ghast"); + register(57, "PigZombie"); + register(58, "Enderman"); + register(59, "CaveSpider"); + register(60, "Silverfish"); + register(61, "Blaze"); + register(62, "LavaSlime"); + register(63, "EnderDragon"); + register(64, "WitherBoss"); + register(65, "Bat"); + register(66, "Witch"); + register(67, "Endermite"); + register(68, "Guardian"); + register(90, "Pig"); + register(91, "Sheep"); + register(92, "Cow"); + register(93, "Chicken"); + register(94, "Squid"); + register(95, "Wolf"); + register(96, "MushroomCow"); + register(97, "SnowMan"); + register(98, "Ozelot"); + register(99, "VillagerGolem"); + register(100, "EntityHorse"); + register(101, "Rabbit"); + register(120, "Villager"); + register(200, "EnderCrystal"); + } + + private static void register(final int id, final String name) { + ENTITY_ID_TO_NAME.put(id, name); + ENTITY_NAME_TO_ID.put(name, id); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetaIndex.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/MetaIndex.java similarity index 99% rename from common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetaIndex.java rename to common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/MetaIndex.java index e40b5e151..e710195c9 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetaIndex.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/MetaIndex.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.viaversion.viaversion.protocols.v1_8to1_9.metadata; +package com.viaversion.viaversion.protocols.v1_8to1_9.data; import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10; diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIds.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIds.java new file mode 100644 index 000000000..8e21ddc88 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIds.java @@ -0,0 +1,189 @@ +/* + * 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 . + */ +package com.viaversion.viaversion.protocols.v1_8to1_9.data; + +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.util.ComponentUtil; +import com.viaversion.viaversion.util.SerializerVersion; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import java.util.HashMap; +import java.util.Map; + +public class PotionIds { + + public static final Map POTION_NAME_TO_ID = new HashMap<>(); + public static final Map POTION_ID_TO_NAME = new HashMap<>(); + + public static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36, .99F); + + static { + register(-1, "empty"); + register(0, "water"); + register(64, "mundane"); + register(32, "thick"); + register(16, "awkward"); + + register(8198, "night_vision"); + register(8262, "long_night_vision"); + + register(8206, "invisibility"); + register(8270, "long_invisibility"); + + register(8203, "leaping"); + register(8267, "long_leaping"); + register(8235, "strong_leaping"); + + register(8195, "fire_resistance"); + register(8259, "long_fire_resistance"); + + register(8194, "swiftness"); + register(8258, "long_swiftness"); + register(8226, "strong_swiftness"); + + register(8202, "slowness"); + register(8266, "long_slowness"); + + register(8205, "water_breathing"); + register(8269, "long_water_breathing"); + + register(8261, "healing"); + register(8229, "strong_healing"); + + register(8204, "harming"); + register(8236, "strong_harming"); + + register(8196, "poison"); + register(8260, "long_poison"); + register(8228, "strong_poison"); + + register(8193, "regeneration"); + register(8257, "long_regeneration"); + register(8225, "strong_regeneration"); + + register(8201, "strength"); + register(8265, "long_strength"); + register(8233, "strong_strength"); + + register(8200, "weakness"); + register(8264, "long_weakness"); + + } + + public static String potionNameFromDamage(short damage) { + String cached = POTION_ID_TO_NAME.get((int) damage); + if (cached != null) { + return cached; + } + if (damage == 0) { + return "water"; + } + + int effect = damage & 0xF; + int name = damage & 0x3F; + boolean enhanced = (damage & 0x20) > 0; + boolean extended = (damage & 0x40) > 0; + + boolean canEnhance = true; + boolean canExtend = true; + + String id; + switch (effect) { + case 1 -> id = "regeneration"; + case 2 -> id = "swiftness"; + case 3 -> { + id = "fire_resistance"; + canEnhance = false; + } + case 4 -> id = "poison"; + case 5 -> { + id = "healing"; + canExtend = false; + } + case 6 -> { + id = "night_vision"; + canEnhance = false; + } + case 8 -> { + id = "weakness"; + canEnhance = false; + } + case 9 -> id = "strength"; + case 10 -> { + id = "slowness"; + canEnhance = false; + } + case 11 -> id = "leaping"; + case 12 -> { + id = "harming"; + canExtend = false; + } + case 13 -> { + id = "water_breathing"; + canEnhance = false; + } + case 14 -> { + id = "invisibility"; + canEnhance = false; + } + default -> { + canEnhance = false; + canExtend = false; + id = switch (name) { + case 0 -> "mundane"; + case 16 -> "awkward"; + case 32 -> "thick"; + default -> "empty"; + }; + } + } + + if (effect > 0) { + if (canEnhance && enhanced) { + id = "strong_" + id; + } else if (canExtend && extended) { + id = "long_" + id; + } + } + + return id; + } + + public static int getNewPotionID(int oldID) { + if (oldID >= 16384) { + oldID -= 8192; + } + + int index = POTION_INDEX.get(oldID); + if (index != -1) { + return index; + } + + oldID = POTION_NAME_TO_ID.get(potionNameFromDamage((short) oldID)); + return (index = POTION_INDEX.get(oldID)) != -1 ? index : 0; + } + + private static void register(final int id, final String name) { + POTION_INDEX.put(id, POTION_ID_TO_NAME.size()); + POTION_ID_TO_NAME.put(id, name); + POTION_NAME_TO_ID.put(name, id); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetadataRewriter1_9To1_8.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetadataRewriter1_9To1_8.java deleted file mode 100644 index 9ef91342e..000000000 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/metadata/MetadataRewriter1_9To1_8.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 . - */ -package com.viaversion.viaversion.protocols.v1_8to1_9.metadata; - -import com.viaversion.viaversion.api.minecraft.EulerAngle; -import com.viaversion.viaversion.api.minecraft.Vector; -import com.viaversion.viaversion.api.minecraft.entities.EntityType; -import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10; -import com.viaversion.viaversion.api.minecraft.item.Item; -import com.viaversion.viaversion.api.minecraft.metadata.MetaType; -import com.viaversion.viaversion.api.minecraft.metadata.Metadata; -import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8; -import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; -import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ItemRewriter; -import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; -import com.viaversion.viaversion.rewriter.EntityRewriter; -import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent; -import com.viaversion.viaversion.util.ComponentUtil; -import com.viaversion.viaversion.util.SerializerVersion; -import java.util.UUID; - -public class MetadataRewriter1_9To1_8 extends EntityRewriter { - - public MetadataRewriter1_9To1_8(Protocol1_8To1_9 protocol) { - super(protocol); - } - - @Override - protected void registerRewrites() { - filter().handler(this::handleMetadata); - } - - private void handleMetadata(MetaHandlerEvent event, Metadata metadata) { - EntityType type = event.entityType(); - MetaIndex metaIndex = MetaIndex.searchIndex(type, metadata.id()); - if (metaIndex == null) { - // Almost certainly bad data, remove it - event.cancel(); - return; - } - - if (metaIndex.getNewType() == null) { - event.cancel(); - return; - } - - metadata.setId(metaIndex.getNewIndex()); - metadata.setMetaTypeUnsafe(metaIndex.getNewType()); - - Object value = metadata.getValue(); - switch (metaIndex.getNewType()) { - case BYTE: - // convert from int, byte - if (metaIndex.getOldType() == MetaType1_8.BYTE) { - metadata.setValue(value); - } - if (metaIndex.getOldType() == MetaType1_8.INT) { - metadata.setValue(((Integer) value).byteValue()); - } - // After writing the last one - if (metaIndex == MetaIndex.ENTITY_STATUS && type == EntityTypes1_10.EntityType.PLAYER) { - byte val = 0; - if ((((Byte) value) & 0x10) == 0x10) { // Player eating/aiming/drinking - val = 1; - } - int newIndex = MetaIndex.PLAYER_HAND.getNewIndex(); - MetaType metaType = MetaIndex.PLAYER_HAND.getNewType(); - event.createExtraMeta(new Metadata(newIndex, metaType, val)); - } - break; - case OPTIONAL_UUID: - String owner = (String) value; - UUID toWrite = null; - if (!owner.isEmpty()) { - try { - toWrite = UUID.fromString(owner); - } catch (Exception ignored) { - } - } - metadata.setValue(toWrite); - break; - case VAR_INT: - // convert from int, short, byte - if (metaIndex.getOldType() == MetaType1_8.BYTE) { - metadata.setValue(((Byte) value).intValue()); - } - if (metaIndex.getOldType() == MetaType1_8.SHORT) { - metadata.setValue(((Short) value).intValue()); - } - if (metaIndex.getOldType() == MetaType1_8.INT) { - metadata.setValue(value); - } - break; - case FLOAT, STRING: - metadata.setValue(value); - break; - case BOOLEAN: - if (metaIndex == MetaIndex.AGEABLE_CREATURE_AGE) - metadata.setValue((Byte) value < 0); - else - metadata.setValue((Byte) value != 0); - break; - case ITEM: - metadata.setValue(value); - ItemRewriter.toClient((Item) metadata.getValue()); - break; - case BLOCK_POSITION: - Vector vector = (Vector) value; - metadata.setValue(vector); - break; - case ROTATIONS: - EulerAngle angle = (EulerAngle) value; - metadata.setValue(angle); - break; - case COMPONENT: - // Was previously also a component, so just convert it - String text = (String) value; - metadata.setValue(ComponentUtil.convertJsonOrEmpty(text, SerializerVersion.V1_8, SerializerVersion.V1_9)); - break; - case OPTIONAL_BLOCK_STATE: - // Convert from int, short, byte - metadata.setValue(((Number) value).intValue()); - break; - default: - throw new RuntimeException("Unhandled MetaDataType: " + metaIndex.getNewType()); - } - } - - @Override - public EntityType typeFromId(int type) { - return EntityTypes1_10.getTypeFromId(type, false); - } - - @Override - public EntityType objectTypeFromId(int type) { - return EntityTypes1_10.getTypeFromId(type, true); - } -} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ChatRewriter.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ChatRewriter.java deleted file mode 100644 index 89eda1583..000000000 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ChatRewriter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 . - */ -package com.viaversion.viaversion.protocols.v1_8to1_9.rewriter; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; -import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; - -public class ChatRewriter { - /** - * Rewrite chat being sent to the client so that gamemode issues don't occur. - * - * @param obj The json object being sent by the server - * @param user The player involved. (Required for Gamemode info) - */ - public static void toClient(JsonObject obj, UserConnection user) { - //Check gamemode change - if (obj.get("translate") != null && obj.get("translate").getAsString().equals("gameMode.changed")) { - EntityTracker1_9 tracker = user.getEntityTracker(Protocol1_8To1_9.class); - String gameMode = tracker.getGameMode().getText(); - - JsonObject gameModeObject = new JsonObject(); - gameModeObject.addProperty("text", gameMode); - gameModeObject.addProperty("color", "gray"); - gameModeObject.addProperty("italic", true); - - JsonArray array = new JsonArray(); - array.add(gameModeObject); - - obj.add("with", array); - } - } -} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/EntityPacketRewriter1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/EntityPacketRewriter1_9.java index a85956f8b..d1a060047 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/EntityPacketRewriter1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/EntityPacketRewriter1_9.java @@ -19,23 +19,31 @@ package com.viaversion.viaversion.protocols.v1_8to1_9.rewriter; import com.google.common.collect.ImmutableList; import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.minecraft.EulerAngle; +import com.viaversion.viaversion.api.minecraft.Vector; +import com.viaversion.viaversion.api.minecraft.entities.EntityType; +import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10; import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.minecraft.metadata.MetaType; import com.viaversion.viaversion.api.minecraft.metadata.Metadata; +import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer; -import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_8; import com.viaversion.viaversion.api.type.types.version.Types1_9; import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; -import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ItemRewriter; import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; -import com.viaversion.viaversion.protocols.v1_8to1_9.metadata.MetadataRewriter1_9To1_8; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.MetaIndex1_8; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; +import com.viaversion.viaversion.rewriter.EntityRewriter; +import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent; +import com.viaversion.viaversion.util.ComponentUtil; import com.viaversion.viaversion.util.Pair; +import com.viaversion.viaversion.util.SerializerVersion; import com.viaversion.viaversion.util.Triple; import java.util.ArrayList; import java.util.HashMap; @@ -43,7 +51,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; -public class EntityPacketRewriter1_9 { +public class EntityPacketRewriter1_9 extends EntityRewriter { public static final ValueTransformer toNewShort = new ValueTransformer<>(Types.SHORT) { @Override public Short transform(PacketWrapper wrapper, Byte inputValue) { @@ -51,7 +59,12 @@ public class EntityPacketRewriter1_9 { } }; - public static void register(Protocol1_8To1_9 protocol) { + public EntityPacketRewriter1_9(Protocol1_8To1_9 protocol) { + super(protocol); + } + + @Override + protected void registerPackets() { // Attach Entity Packet protocol.registerClientbound(ClientboundPackets1_8.SET_ENTITY_LINK, new PacketHandlers() { @@ -175,7 +188,7 @@ public class EntityPacketRewriter1_9 { // Item Rewriter handler(wrapper -> { Item stack = wrapper.get(Types.ITEM1_8, 0); - ItemRewriter.toClient(stack); + protocol.getItemRewriter().handleItemToClient(wrapper.user(), stack); }); // Blocking handler(wrapper -> { @@ -203,7 +216,7 @@ public class EntityPacketRewriter1_9 { int entityId = wrapper.get(Types.VAR_INT, 0); EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); if (tracker.hasEntity(entityId)) { - protocol.get(MetadataRewriter1_9To1_8.class).handleMetadata(entityId, metadataList, wrapper.user()); + handleMetadata(entityId, metadataList, wrapper.user()); } else { wrapper.cancel(); } @@ -280,11 +293,11 @@ public class EntityPacketRewriter1_9 { List> modifiers = new ArrayList<>(modifiersToRead); for (int j = 0; j < modifiersToRead; j++) { modifiers.add( - new Triple<>( - wrapper.read(Types.UUID), - wrapper.read(Types.DOUBLE), // Amount - wrapper.read(Types.BYTE) // Operation - ) + new Triple<>( + wrapper.read(Types.UUID), + wrapper.read(Types.DOUBLE), // Amount + wrapper.read(Types.BYTE) // Operation + ) ); } properties.put(key, new Pair<>(value, modifiers)); @@ -294,9 +307,9 @@ public class EntityPacketRewriter1_9 { // Higher values hides the cooldown but it bugs visual animation on hand // when removing item from hand with inventory gui properties.put("generic.attackSpeed", new Pair<>(15.9, ImmutableList.of( // Neutralize modifiers - new Triple<>(UUID.fromString("FA233E1C-4180-4865-B01B-BCCE9785ACA3"), 0.0, (byte) 0), // Tool and weapon modifier - new Triple<>(UUID.fromString("AF8B6E3F-3328-4C0A-AA36-5BA2BB9DBEF3"), 0.0, (byte) 2), // Dig speed - new Triple<>(UUID.fromString("55FCED67-E92A-486E-9800-B47F202C4386"), 0.0, (byte) 2) // Dig slow down + new Triple<>(UUID.fromString("FA233E1C-4180-4865-B01B-BCCE9785ACA3"), 0.0, (byte) 0), // Tool and weapon modifier + new Triple<>(UUID.fromString("AF8B6E3F-3328-4C0A-AA36-5BA2BB9DBEF3"), 0.0, (byte) 2), // Dig speed + new Triple<>(UUID.fromString("55FCED67-E92A-486E-9800-B47F202C4386"), 0.0, (byte) 2) // Dig slow down ))); wrapper.write(Types.INT, properties.size()); @@ -372,4 +385,115 @@ public class EntityPacketRewriter1_9 { } }); } + + @Override + protected void registerRewrites() { + filter().handler(this::handleMetadata); + } + + private void handleMetadata(MetaHandlerEvent event, Metadata metadata) { + EntityType type = event.entityType(); + MetaIndex metaIndex = MetaIndex.searchIndex(type, metadata.id()); + if (metaIndex == null) { + // Almost certainly bad data, remove it + event.cancel(); + return; + } + + if (metaIndex.getNewType() == null) { + event.cancel(); + return; + } + + metadata.setId(metaIndex.getNewIndex()); + metadata.setMetaTypeUnsafe(metaIndex.getNewType()); + + Object value = metadata.getValue(); + switch (metaIndex.getNewType()) { + case BYTE: + // convert from int, byte + if (metaIndex.getOldType() == MetaType1_8.BYTE) { + metadata.setValue(value); + } + if (metaIndex.getOldType() == MetaType1_8.INT) { + metadata.setValue(((Integer) value).byteValue()); + } + // After writing the last one + if (metaIndex == MetaIndex.ENTITY_STATUS && type == EntityTypes1_10.EntityType.PLAYER) { + byte val = 0; + if ((((Byte) value) & 0x10) == 0x10) { // Player eating/aiming/drinking + val = 1; + } + int newIndex = MetaIndex.PLAYER_HAND.getNewIndex(); + MetaType metaType = MetaIndex.PLAYER_HAND.getNewType(); + event.createExtraMeta(new Metadata(newIndex, metaType, val)); + } + break; + case OPTIONAL_UUID: + String owner = (String) value; + UUID toWrite = null; + if (!owner.isEmpty()) { + try { + toWrite = UUID.fromString(owner); + } catch (Exception ignored) { + } + } + metadata.setValue(toWrite); + break; + case VAR_INT: + // convert from int, short, byte + if (metaIndex.getOldType() == MetaType1_8.BYTE) { + metadata.setValue(((Byte) value).intValue()); + } + if (metaIndex.getOldType() == MetaType1_8.SHORT) { + metadata.setValue(((Short) value).intValue()); + } + if (metaIndex.getOldType() == MetaType1_8.INT) { + metadata.setValue(value); + } + break; + case FLOAT, STRING: + metadata.setValue(value); + break; + case BOOLEAN: + if (metaIndex == MetaIndex1_8.AGEABLE_CREATURE_AGE) + metadata.setValue((Byte) value < 0); + else + metadata.setValue((Byte) value != 0); + break; + case ITEM: + metadata.setValue(value); + protocol.getItemRewriter().handleItemToClient(event.user(), (Item) metadata.getValue()); + break; + case BLOCK_POSITION: + Vector vector = (Vector) value; + metadata.setValue(vector); + break; + case ROTATIONS: + EulerAngle angle = (EulerAngle) value; + metadata.setValue(angle); + break; + case COMPONENT: + // Was previously also a component, so just convert it + String text = (String) value; + metadata.setValue(ComponentUtil.convertJsonOrEmpty(text, SerializerVersion.V1_8, SerializerVersion.V1_9)); + break; + case OPTIONAL_BLOCK_STATE: + // Convert from int, short, byte + metadata.setValue(((Number) value).intValue()); + break; + default: + throw new RuntimeException("Unhandled MetaDataType: " + metaIndex.getNewType()); + } + } + + @Override + public EntityType typeFromId(int type) { + return EntityTypes1_10.getTypeFromId(type, false); + } + + @Override + public EntityType objectTypeFromId(int type) { + return EntityTypes1_10.getTypeFromId(type, true); + } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemPacketRewriter1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemPacketRewriter1_9.java index 5c997d77c..38b75b2dc 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemPacketRewriter1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemPacketRewriter1_9.java @@ -17,22 +17,38 @@ */ package com.viaversion.viaversion.protocols.v1_8to1_9.rewriter; +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; -import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ItemRewriter; import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.EntityIds; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.PotionIds; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.InventoryTracker; +import com.viaversion.viaversion.rewriter.ItemRewriter; +import com.viaversion.viaversion.util.ComponentUtil; +import com.viaversion.viaversion.util.Key; +import com.viaversion.viaversion.util.SerializerVersion; +import org.checkerframework.checker.nullness.qual.Nullable; +import java.util.Collections; -public class ItemPacketRewriter1_9 { +public class ItemPacketRewriter1_9 extends ItemRewriter { - public static void register(Protocol1_8To1_9 protocol) { + public ItemPacketRewriter1_9(final Protocol1_8To1_9 protocol) { + super(protocol, null, null); + } + + @Override + protected void registerPackets() { protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_DATA, new PacketHandlers() { @Override @@ -98,7 +114,7 @@ public class ItemPacketRewriter1_9 { Item stack = wrapper.get(Types.ITEM1_8, 0); boolean showShieldWhenSwordInHand = Via.getConfig().isShowShieldWhenSwordInHand() - && Via.getConfig().isShieldBlocking(); + && Via.getConfig().isShieldBlocking(); // Check if it is the inventory of the player if (showShieldWhenSwordInHand) { @@ -115,7 +131,7 @@ public class ItemPacketRewriter1_9 { entityTracker.syncShieldWithSword(); } - ItemRewriter.toClient(stack); + handleItemToServer(wrapper.user(), stack); }); // Brewing patch handler(wrapper -> { @@ -145,7 +161,7 @@ public class ItemPacketRewriter1_9 { EntityTracker1_9 entityTracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); boolean showShieldWhenSwordInHand = Via.getConfig().isShowShieldWhenSwordInHand() - && Via.getConfig().isShieldBlocking(); + && Via.getConfig().isShieldBlocking(); for (short i = 0; i < stacks.length; i++) { Item stack = stacks[i]; @@ -155,7 +171,7 @@ public class ItemPacketRewriter1_9 { inventoryTracker.setItemId(windowId, i, stack == null ? 0 : stack.identifier()); } - ItemRewriter.toClient(stack); + handleItemToClient(wrapper.user(), stack); } // Sync shield item in offhand with main hand @@ -222,7 +238,7 @@ public class ItemPacketRewriter1_9 { Item stack = wrapper.get(Types.ITEM1_8, 0); boolean showShieldWhenSwordInHand = Via.getConfig().isShowShieldWhenSwordInHand() - && Via.getConfig().isShieldBlocking(); + && Via.getConfig().isShieldBlocking(); if (showShieldWhenSwordInHand) { InventoryTracker inventoryTracker = wrapper.user().get(InventoryTracker.class); @@ -236,7 +252,7 @@ public class ItemPacketRewriter1_9 { entityTracker.syncShieldWithSword(); } - ItemRewriter.toServer(stack); + handleItemToServer(wrapper.user(), stack); }); // Elytra throw patch handler(wrapper -> { @@ -280,7 +296,7 @@ public class ItemPacketRewriter1_9 { inventoryTracker.handleWindowClick(wrapper.user(), windowId, mode, hoverSlot, button); } - ItemRewriter.toServer(stack); + handleItemToServer(wrapper.user(), stack); }); // Brewing patch and elytra throw patch handler(wrapper -> { @@ -315,51 +331,165 @@ public class ItemPacketRewriter1_9 { protocol.registerServerbound(ServerboundPackets1_9.CONTAINER_CLOSE, new - PacketHandlers() { + PacketHandlers() { - @Override - public void register() { - map(Types.UNSIGNED_BYTE); // 0 - Window ID + @Override + public void register() { + map(Types.UNSIGNED_BYTE); // 0 - Window ID - // Inventory tracking - handler(wrapper -> { - InventoryTracker inventoryTracker = wrapper.user().get(InventoryTracker.class); - inventoryTracker.setInventory(null); - inventoryTracker.resetInventory(wrapper.get(Types.UNSIGNED_BYTE, 0)); - }); - } - }); + // Inventory tracking + handler(wrapper -> { + InventoryTracker inventoryTracker = wrapper.user().get(InventoryTracker.class); + inventoryTracker.setInventory(null); + inventoryTracker.resetInventory(wrapper.get(Types.UNSIGNED_BYTE, 0)); + }); + } + }); protocol.registerServerbound(ServerboundPackets1_9.SET_CARRIED_ITEM, new - PacketHandlers() { - @Override - public void register() { - map(Types.SHORT); // 0 - Slot id + PacketHandlers() { + @Override + public void register() { + map(Types.SHORT); // 0 - Slot id - // Blocking patch - handler(wrapper -> { - boolean showShieldWhenSwordInHand = Via.getConfig().isShowShieldWhenSwordInHand() - && Via.getConfig().isShieldBlocking(); + // Blocking patch + handler(wrapper -> { + boolean showShieldWhenSwordInHand = Via.getConfig().isShowShieldWhenSwordInHand() + && Via.getConfig().isShieldBlocking(); - EntityTracker1_9 entityTracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); - if (entityTracker.isBlocking()) { - entityTracker.setBlocking(false); + EntityTracker1_9 entityTracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); + if (entityTracker.isBlocking()) { + entityTracker.setBlocking(false); - if (!showShieldWhenSwordInHand) { - entityTracker.setSecondHand(null); - } + if (!showShieldWhenSwordInHand) { + entityTracker.setSecondHand(null); } + } - if (showShieldWhenSwordInHand) { - // Update current held item slot index - entityTracker.setHeldItemSlot(wrapper.get(Types.SHORT, 0)); + if (showShieldWhenSwordInHand) { + // Update current held item slot index + entityTracker.setHeldItemSlot(wrapper.get(Types.SHORT, 0)); - // Sync shield item in offhand with main hand - entityTracker.syncShieldWithSword(); - } - }); + // Sync shield item in offhand with main hand + entityTracker.syncShieldWithSword(); + } + }); + } + }); + } + + @Override + public @Nullable Item handleItemToClient(final UserConnection connection, @Nullable final Item item) { + if (item == null) return null; + if (item.identifier() == 383 && item.data() != 0) { // Monster Egg + CompoundTag tag = item.tag(); + if (tag == null) { + tag = new CompoundTag(); + } + CompoundTag entityTag = new CompoundTag(); + String entityName = EntityIds.ENTITY_ID_TO_NAME.get((int) item.data()); + if (entityName != null) { + StringTag id = new StringTag(entityName); + entityTag.put("id", id); + tag.put("EntityTag", entityTag); + } + item.setTag(tag); + item.setData((short) 0); + } + if (item.identifier() == 373) { // Potion + CompoundTag tag = item.tag(); + if (tag == null) { + tag = new CompoundTag(); + } + if (item.data() >= 16384) { + item.setIdentifier(438); // splash id + item.setData((short) (item.data() - 8192)); + } + String name = PotionIds.potionNameFromDamage(item.data()); + StringTag potion = new StringTag(Key.namespaced(name)); + tag.put("Potion", potion); + item.setTag(tag); + item.setData((short) 0); + } + if (item.identifier() == 387) { // WRITTEN_BOOK + CompoundTag tag = item.tag(); + if (tag == null) { + tag = new CompoundTag(); + } + + ListTag pages = tag.getListTag("pages", StringTag.class); + if (pages == null) { + pages = new ListTag<>(Collections.singletonList(new StringTag(ComponentUtil.emptyJsonComponent().toString()))); + tag.put("pages", pages); + } else { + for (int i = 0; i < pages.size(); i++) { + final StringTag page = pages.get(i); + page.setValue(ComponentUtil.convertJsonOrEmpty(page.getValue(), SerializerVersion.V1_8, SerializerVersion.V1_9).toString()); + } + } + item.setTag(tag); + } + return item; + } + + @Override + public @Nullable Item handleItemToServer(final UserConnection connection, @Nullable final Item item) { + if (item == null) return null; + if (item.identifier() == 383 && item.data() == 0) { // Monster Egg + CompoundTag tag = item.tag(); + int data = 0; + if (tag != null && tag.getCompoundTag("EntityTag") != null) { + CompoundTag entityTag = tag.getCompoundTag("EntityTag"); + StringTag id = entityTag.getStringTag("id"); + if (id != null) { + if (EntityIds.ENTITY_NAME_TO_ID.containsKey(id.getValue())) { + data = EntityIds.ENTITY_NAME_TO_ID.get(id.getValue()); } - }); + } + tag.remove("EntityTag"); + } + item.setTag(tag); + item.setData((short) data); + } + if (item.identifier() == 373) { // Potion + CompoundTag tag = item.tag(); + int data = 0; + if (tag != null && tag.getStringTag("Potion") != null) { + StringTag potion = tag.getStringTag("Potion"); + String potionName = Key.stripMinecraftNamespace(potion.getValue()); + if (PotionIds.POTION_NAME_TO_ID.containsKey(potionName)) { + data = PotionIds.POTION_NAME_TO_ID.get(potionName); + } + tag.remove("Potion"); + } + item.setTag(tag); + item.setData((short) data); + } + // Splash potion + if (item.identifier() == 438) { + CompoundTag tag = item.tag(); + int data = 0; + item.setIdentifier(373); // Potion + if (tag != null && tag.getStringTag("Potion") != null) { + StringTag potion = tag.getStringTag("Potion"); + String potionName = Key.stripMinecraftNamespace(potion.getValue()); + if (PotionIds.POTION_NAME_TO_ID.containsKey(potionName)) { + data = PotionIds.POTION_NAME_TO_ID.get(potionName) + 8192; + } + tag.remove("Potion"); + } + item.setTag(tag); + item.setData((short) data); + } + + boolean newItem = item.identifier() >= 198 && item.identifier() <= 212; + newItem |= item.identifier() == 397 && item.data() == 5; + newItem |= item.identifier() >= 432 && item.identifier() <= 448; + if (newItem) { // Replace server-side unknown items + item.setIdentifier(1); + item.setData((short) 0); + } + return item; } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemRewriter.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemRewriter.java deleted file mode 100644 index 22ac4c0ac..000000000 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/ItemRewriter.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * 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 . - */ -package com.viaversion.viaversion.protocols.v1_8to1_9.rewriter; - -import com.viaversion.nbt.tag.CompoundTag; -import com.viaversion.nbt.tag.ListTag; -import com.viaversion.nbt.tag.StringTag; -import com.viaversion.viaversion.api.minecraft.item.Item; -import com.viaversion.viaversion.util.ComponentUtil; -import com.viaversion.viaversion.util.Key; -import com.viaversion.viaversion.util.SerializerVersion; -import it.unimi.dsi.fastutil.ints.Int2IntMap; -import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -public class ItemRewriter { - - public static final Map ENTITY_NAME_TO_ID = new HashMap<>(); - public static final Map ENTITY_ID_TO_NAME = new HashMap<>(); - public static final Map POTION_NAME_TO_ID = new HashMap<>(); - public static final Map POTION_ID_TO_NAME = new HashMap<>(); - - public static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36, .99F); - - static { - /* Entities */ - registerEntity(1, "Item"); - registerEntity(2, "XPOrb"); - registerEntity(7, "ThrownEgg"); - registerEntity(8, "LeashKnot"); - registerEntity(9, "Painting"); - registerEntity(10, "Arrow"); - registerEntity(11, "Snowball"); - registerEntity(12, "Fireball"); - registerEntity(13, "SmallFireball"); - registerEntity(14, "ThrownEnderpearl"); - registerEntity(15, "EyeOfEnderSignal"); - registerEntity(16, "ThrownPotion"); - registerEntity(17, "ThrownExpBottle"); - registerEntity(18, "ItemFrame"); - registerEntity(19, "WitherSkull"); - registerEntity(20, "PrimedTnt"); - registerEntity(21, "FallingSand"); - registerEntity(22, "FireworksRocketEntity"); - registerEntity(30, "ArmorStand"); - registerEntity(40, "MinecartCommandBlock"); - registerEntity(41, "Boat"); - registerEntity(42, "MinecartRideable"); - registerEntity(43, "MinecartChest"); - registerEntity(44, "MinecartFurnace"); - registerEntity(45, "MinecartTNT"); - registerEntity(46, "MinecartHopper"); - registerEntity(47, "MinecartSpawner"); - registerEntity(48, "Mob"); - registerEntity(49, "Monster"); - registerEntity(50, "Creeper"); - registerEntity(51, "Skeleton"); - registerEntity(52, "Spider"); - registerEntity(53, "Giant"); - registerEntity(54, "Zombie"); - registerEntity(55, "Slime"); - registerEntity(56, "Ghast"); - registerEntity(57, "PigZombie"); - registerEntity(58, "Enderman"); - registerEntity(59, "CaveSpider"); - registerEntity(60, "Silverfish"); - registerEntity(61, "Blaze"); - registerEntity(62, "LavaSlime"); - registerEntity(63, "EnderDragon"); - registerEntity(64, "WitherBoss"); - registerEntity(65, "Bat"); - registerEntity(66, "Witch"); - registerEntity(67, "Endermite"); - registerEntity(68, "Guardian"); - registerEntity(90, "Pig"); - registerEntity(91, "Sheep"); - registerEntity(92, "Cow"); - registerEntity(93, "Chicken"); - registerEntity(94, "Squid"); - registerEntity(95, "Wolf"); - registerEntity(96, "MushroomCow"); - registerEntity(97, "SnowMan"); - registerEntity(98, "Ozelot"); - registerEntity(99, "VillagerGolem"); - registerEntity(100, "EntityHorse"); - registerEntity(101, "Rabbit"); - registerEntity(120, "Villager"); - registerEntity(200, "EnderCrystal"); - - /* Potions */ - registerPotion(-1, "empty"); - registerPotion(0, "water"); - registerPotion(64, "mundane"); - registerPotion(32, "thick"); - registerPotion(16, "awkward"); - - registerPotion(8198, "night_vision"); - registerPotion(8262, "long_night_vision"); - - registerPotion(8206, "invisibility"); - registerPotion(8270, "long_invisibility"); - - registerPotion(8203, "leaping"); - registerPotion(8267, "long_leaping"); - registerPotion(8235, "strong_leaping"); - - registerPotion(8195, "fire_resistance"); - registerPotion(8259, "long_fire_resistance"); - - registerPotion(8194, "swiftness"); - registerPotion(8258, "long_swiftness"); - registerPotion(8226, "strong_swiftness"); - - registerPotion(8202, "slowness"); - registerPotion(8266, "long_slowness"); - - registerPotion(8205, "water_breathing"); - registerPotion(8269, "long_water_breathing"); - - registerPotion(8261, "healing"); - registerPotion(8229, "strong_healing"); - - registerPotion(8204, "harming"); - registerPotion(8236, "strong_harming"); - - registerPotion(8196, "poison"); - registerPotion(8260, "long_poison"); - registerPotion(8228, "strong_poison"); - - registerPotion(8193, "regeneration"); - registerPotion(8257, "long_regeneration"); - registerPotion(8225, "strong_regeneration"); - - registerPotion(8201, "strength"); - registerPotion(8265, "long_strength"); - registerPotion(8233, "strong_strength"); - - registerPotion(8200, "weakness"); - registerPotion(8264, "long_weakness"); - - } - - public static void toServer(Item item) { - if (item != null) { - if (item.identifier() == 383 && item.data() == 0) { // Monster Egg - CompoundTag tag = item.tag(); - int data = 0; - if (tag != null && tag.getCompoundTag("EntityTag") != null) { - CompoundTag entityTag = tag.getCompoundTag("EntityTag"); - StringTag id = entityTag.getStringTag("id"); - if (id != null) { - if (ENTITY_NAME_TO_ID.containsKey(id.getValue())) - data = ENTITY_NAME_TO_ID.get(id.getValue()); - } - tag.remove("EntityTag"); - } - item.setTag(tag); - item.setData((short) data); - } - if (item.identifier() == 373) { // Potion - CompoundTag tag = item.tag(); - int data = 0; - if (tag != null && tag.getStringTag("Potion") != null) { - StringTag potion = tag.getStringTag("Potion"); - String potionName = Key.stripMinecraftNamespace(potion.getValue()); - if (POTION_NAME_TO_ID.containsKey(potionName)) { - data = POTION_NAME_TO_ID.get(potionName); - } - tag.remove("Potion"); - } - item.setTag(tag); - item.setData((short) data); - } - // Splash potion - if (item.identifier() == 438) { - CompoundTag tag = item.tag(); - int data = 0; - item.setIdentifier(373); // Potion - if (tag != null && tag.getStringTag("Potion") != null) { - StringTag potion = tag.getStringTag("Potion"); - String potionName = Key.stripMinecraftNamespace(potion.getValue()); - if (POTION_NAME_TO_ID.containsKey(potionName)) { - data = POTION_NAME_TO_ID.get(potionName) + 8192; - } - tag.remove("Potion"); - } - item.setTag(tag); - item.setData((short) data); - } - - boolean newItem = item.identifier() >= 198 && item.identifier() <= 212; - newItem |= item.identifier() == 397 && item.data() == 5; - newItem |= item.identifier() >= 432 && item.identifier() <= 448; - if (newItem) { // Replace server-side unknown items - item.setIdentifier(1); - item.setData((short) 0); - } - } - } - - public static void rewriteBookToServer(Item item) { - int id = item.identifier(); - if (id != 387) { - return; - } - - CompoundTag tag = item.tag(); - ListTag pages = tag.getListTag("pages", StringTag.class); - if (pages == null) { - return; - } - - for (int i = 0; i < pages.size(); i++) { - final StringTag pageTag = pages.get(i); - final String value = pageTag.getValue(); - - pageTag.setValue(ComponentUtil.convertJson(value, SerializerVersion.V1_9, SerializerVersion.V1_8).toString()); - } - } - - public static void toClient(Item item) { - if (item != null) { - if (item.identifier() == 383 && item.data() != 0) { // Monster Egg - CompoundTag tag = item.tag(); - if (tag == null) { - tag = new CompoundTag(); - } - CompoundTag entityTag = new CompoundTag(); - String entityName = ENTITY_ID_TO_NAME.get((int) item.data()); - if (entityName != null) { - StringTag id = new StringTag(entityName); - entityTag.put("id", id); - tag.put("EntityTag", entityTag); - } - item.setTag(tag); - item.setData((short) 0); - } - if (item.identifier() == 373) { // Potion - CompoundTag tag = item.tag(); - if (tag == null) { - tag = new CompoundTag(); - } - if (item.data() >= 16384) { - item.setIdentifier(438); // splash id - item.setData((short) (item.data() - 8192)); - } - String name = potionNameFromDamage(item.data()); - StringTag potion = new StringTag(Key.namespaced(name)); - tag.put("Potion", potion); - item.setTag(tag); - item.setData((short) 0); - } - if (item.identifier() == 387) { // WRITTEN_BOOK - CompoundTag tag = item.tag(); - if (tag == null) { - tag = new CompoundTag(); - } - - ListTag pages = tag.getListTag("pages", StringTag.class); - if (pages == null) { - pages = new ListTag<>(Collections.singletonList(new StringTag(ComponentUtil.emptyJsonComponent().toString()))); - tag.put("pages", pages); - item.setTag(tag); - return; - } - - for (int i = 0; i < pages.size(); i++) { - final StringTag page = pages.get(i); - page.setValue(ComponentUtil.convertJsonOrEmpty(page.getValue(), SerializerVersion.V1_8, SerializerVersion.V1_9).toString()); - } - item.setTag(tag); - } - } - } - - public static String potionNameFromDamage(short damage) { - String cached = POTION_ID_TO_NAME.get((int) damage); - if (cached != null) { - return cached; - } - if (damage == 0) { - return "water"; - } - - int effect = damage & 0xF; - int name = damage & 0x3F; - boolean enhanced = (damage & 0x20) > 0; - boolean extended = (damage & 0x40) > 0; - - boolean canEnhance = true; - boolean canExtend = true; - - String id; - switch (effect) { - case 1 -> id = "regeneration"; - case 2 -> id = "swiftness"; - case 3 -> { - id = "fire_resistance"; - canEnhance = false; - } - case 4 -> id = "poison"; - case 5 -> { - id = "healing"; - canExtend = false; - } - case 6 -> { - id = "night_vision"; - canEnhance = false; - } - case 8 -> { - id = "weakness"; - canEnhance = false; - } - case 9 -> id = "strength"; - case 10 -> { - id = "slowness"; - canEnhance = false; - } - case 11 -> id = "leaping"; - case 12 -> { - id = "harming"; - canExtend = false; - } - case 13 -> { - id = "water_breathing"; - canEnhance = false; - } - case 14 -> { - id = "invisibility"; - canEnhance = false; - } - default -> { - canEnhance = false; - canExtend = false; - id = switch (name) { - case 0 -> "mundane"; - case 16 -> "awkward"; - case 32 -> "thick"; - default -> "empty"; - }; - } - } - - if (effect > 0) { - if (canEnhance && enhanced) { - id = "strong_" + id; - } else if (canExtend && extended) { - id = "long_" + id; - } - } - - return id; - } - - public static int getNewEffectID(int oldID) { - if (oldID >= 16384) { - oldID -= 8192; - } - - int index = POTION_INDEX.get(oldID); - if (index != -1) { - return index; - } - - oldID = POTION_NAME_TO_ID.get(potionNameFromDamage((short) oldID)); - return (index = POTION_INDEX.get(oldID)) != -1 ? index : 0; - } - - private static void registerEntity(int id, String name) { - ENTITY_ID_TO_NAME.put(id, name); - ENTITY_NAME_TO_ID.put(name, id); - } - - private static void registerPotion(int id, String name) { - POTION_INDEX.put(id, POTION_ID_TO_NAME.size()); - POTION_ID_TO_NAME.put(id, name); - POTION_NAME_TO_ID.put(name, id); - } -} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/PlayerPackets1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/PlayerPackets1_9.java index f4baf65a8..cf448d83d 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/PlayerPackets1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/PlayerPackets1_9.java @@ -17,7 +17,11 @@ */ package com.viaversion.viaversion.protocols.v1_8to1_9.rewriter; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_10; @@ -27,10 +31,9 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; -import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ItemRewriter; import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; -import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ChatRewriter; import com.viaversion.viaversion.protocols.v1_8to1_9.data.GameMode; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.PotionIds; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.providers.CommandBlockProvider; import com.viaversion.viaversion.protocols.v1_8to1_9.providers.CompressionProvider; @@ -38,6 +41,8 @@ import com.viaversion.viaversion.protocols.v1_8to1_9.providers.MainHandProvider; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.ClientChunks; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.MovementTracker; +import com.viaversion.viaversion.util.ComponentUtil; +import com.viaversion.viaversion.util.SerializerVersion; public class PlayerPackets1_9 { public static void register(Protocol1_8To1_9 protocol) { @@ -49,7 +54,20 @@ public class PlayerPackets1_9 { handler(wrapper -> { JsonObject obj = (JsonObject) wrapper.get(Types.COMPONENT, 0); - ChatRewriter.toClient(obj, wrapper.user()); + if (obj.get("translate") != null && obj.get("translate").getAsString().equals("gameMode.changed")) { + EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); + String gameMode = tracker.getGameMode().getText(); + + JsonObject gameModeObject = new JsonObject(); + gameModeObject.addProperty("text", gameMode); + gameModeObject.addProperty("color", "gray"); + gameModeObject.addProperty("italic", true); + + JsonArray array = new JsonArray(); + array.add(gameModeObject); + + obj.add("with", array); + } }); } }); @@ -270,16 +288,16 @@ public class PlayerPackets1_9 { for (int i = 0; i < size; ++i) { Item item1 = wrapper.passthrough(Types.ITEM1_8); - ItemRewriter.toClient(item1); + protocol.getItemRewriter().handleItemToClient(wrapper.user(), item1); Item item2 = wrapper.passthrough(Types.ITEM1_8); - ItemRewriter.toClient(item2); + protocol.getItemRewriter().handleItemToClient(wrapper.user(), item2); boolean present = wrapper.passthrough(Types.BOOLEAN); if (present) { Item item3 = wrapper.passthrough(Types.ITEM1_8); - ItemRewriter.toClient(item3); + protocol.getItemRewriter().handleItemToClient(wrapper.user(), item3); } wrapper.passthrough(Types.BOOLEAN); @@ -406,7 +424,18 @@ public class PlayerPackets1_9 { Item item = wrapper.passthrough(Types.ITEM1_8); if (item != null) { item.setIdentifier(387); // Written Book - ItemRewriter.rewriteBookToServer(item); + CompoundTag tag = item.tag(); + ListTag pages = tag.getListTag("pages", StringTag.class); + if (pages == null) { + return; + } + + for (int i = 0; i < pages.size(); i++) { + final StringTag pageTag = pages.get(i); + final String value = pageTag.getValue(); + + pageTag.setValue(ComponentUtil.convertJson(value, SerializerVersion.V1_9, SerializerVersion.V1_8).toString()); + } } } if (name.equals("MC|AutoCmd")) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/SpawnPackets1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/SpawnPackets1_9.java index 1bca713bd..c2ecd02d9 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/SpawnPackets1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/SpawnPackets1_9.java @@ -33,7 +33,7 @@ import com.viaversion.viaversion.api.type.types.version.Types1_8; import com.viaversion.viaversion.api.type.types.version.Types1_9; import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; -import com.viaversion.viaversion.protocols.v1_8to1_9.metadata.MetadataRewriter1_9To1_8; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.PotionIds; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; import java.util.ArrayList; @@ -107,7 +107,7 @@ public class SpawnPackets1_9 { wrapper1.write(Types.VAR_INT, entityID); List meta = new ArrayList<>(); Item item = new DataItem(373, (byte) 1, (short) data, null); // Potion - ItemRewriter.toClient(item); // Rewrite so that it gets the right nbt + protocol.getItemRewriter().handleItemToClient(wrapper.user(), item); // Rewrite so that it gets the right nbt // TEMP FIX FOR POTIONS UNTIL WE FIGURE OUT HOW TO TRANSFORM SENT PACKETS Metadata potion = new Metadata(5, MetaType1_9.ITEM, item); meta.add(potion); @@ -199,7 +199,7 @@ public class SpawnPackets1_9 { int entityId = wrapper.get(Types.VAR_INT, 0); EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); if (tracker.hasEntity(entityId)) { - protocol.get(MetadataRewriter1_9To1_8.class).handleMetadata(entityId, metadataList, wrapper.user()); + protocol.getEntityRewriter().handleMetadata(entityId, metadataList, wrapper.user()); } else { Via.getPlatform().getLogger().warning("Unable to find entity for metadata, entity ID: " + entityId); metadataList.clear(); @@ -277,7 +277,7 @@ public class SpawnPackets1_9 { int entityId = wrapper.get(Types.VAR_INT, 0); EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); if (tracker.hasEntity(entityId)) { - protocol.get(MetadataRewriter1_9To1_8.class).handleMetadata(entityId, metadataList, wrapper.user()); + protocol.getEntityRewriter().handleMetadata(entityId, metadataList, wrapper.user()); } else { Via.getPlatform().getLogger().warning("Unable to find entity for metadata, entity ID: " + entityId); metadataList.clear(); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java index 0b98fded8..b26280145 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java @@ -37,12 +37,12 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_8; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_1; import com.viaversion.viaversion.protocols.v1_8.packet.ClientboundPackets1_8; import com.viaversion.viaversion.protocols.v1_8.packet.ServerboundPackets1_8; -import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ItemRewriter; import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.PotionIds; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.providers.CommandBlockProvider; -import com.viaversion.viaversion.protocols.v1_8to1_9.data.Effect; +import com.viaversion.viaversion.protocols.v1_8to1_9.data.EffectIds; import com.viaversion.viaversion.protocols.v1_8to1_9.data.SoundEffect; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.ClientChunks; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; @@ -77,7 +77,7 @@ public class WorldPacketRewriter1_9 { handler(wrapper -> { int id = wrapper.get(Types.INT, 0); - id = Effect.getNewId(id); + id = EffectIds.getNewId(id); wrapper.set(Types.INT, 0, id); }); // Rewrite potion effect as it changed to use a dynamic registry @@ -85,7 +85,7 @@ public class WorldPacketRewriter1_9 { int id = wrapper.get(Types.INT, 0); if (id == 2002) { int data = wrapper.get(Types.INT, 1); - int newData = ItemRewriter.getNewEffectID(data); + int newData = PotionIds.getNewPotionID(data); wrapper.set(Types.INT, 1, newData); } });