diff --git a/.github/workflows/update-gradle-wrapper.yml b/.github/workflows/update-gradle-wrapper.yml index 925038fa..a6ed992b 100644 --- a/.github/workflows/update-gradle-wrapper.yml +++ b/.github/workflows/update-gradle-wrapper.yml @@ -11,4 +11,4 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Update Gradle Wrapper - uses: gradle-update/update-gradle-wrapper-action@v1 + uses: gradle-update/update-gradle-wrapper-action@v2 diff --git a/.gitignore b/.gitignore index ab25b348..316241dc 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,6 @@ nbdist/ nbactions.xml nb-configuration.xml .nb-gradle/ + +### Run Folder (ViaProxy) ### +common/run/ diff --git a/build-logic/src/main/kotlin/vb.base-conventions.gradle.kts b/build-logic/src/main/kotlin/vb.base-conventions.gradle.kts index 377b40a1..0d4094c9 100644 --- a/build-logic/src/main/kotlin/vb.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/vb.base-conventions.gradle.kts @@ -5,7 +5,7 @@ plugins { tasks { // Variable replacements processResources { - filesMatching(listOf("plugin.yml", "fabric.mod.json")) { + filesMatching(listOf("plugin.yml", "META-INF/sponge_plugins.json", "fabric.mod.json")) { expand("version" to project.version, "description" to project.description, "url" to "https://viaversion.com/backwards") } } @@ -22,4 +22,4 @@ tasks { java { javaTarget(17) withSourcesJar() -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index f32152e1..f5f6243f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,7 @@ val main = setOf( projects.viabackwardsCommon, projects.viabackwardsBukkit, projects.viabackwardsVelocity, + projects.viabackwardsSponge, projects.viabackwardsFabric ).map { it.dependencyProject } diff --git a/bukkit/src/main/java/com/viaversion/viabackwards/BukkitPlugin.java b/bukkit/src/main/java/com/viaversion/viabackwards/BukkitPlugin.java index fd5946fb..32d3f77a 100644 --- a/bukkit/src/main/java/com/viaversion/viabackwards/BukkitPlugin.java +++ b/bukkit/src/main/java/com/viaversion/viabackwards/BukkitPlugin.java @@ -48,7 +48,10 @@ public class BukkitPlugin extends JavaPlugin implements ViaBackwardsPlatform { } } - private void enable() { + @Override + public void enable() { + ViaBackwardsPlatform.super.enable(); + final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().highestSupportedProtocolVersion(); if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_17)) { new PlayerItemDropListener(this).register(); diff --git a/common/build.gradle.kts b/common/build.gradle.kts index bb927cf6..87c49fa6 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -24,3 +24,32 @@ dependencies { java { withJavadocJar() } + +// Task to quickly test/debug code changes using https://github.com/ViaVersion/ViaProxy +// For further instructions see the ViaProxy repository README +tasks.register("runViaProxy") { + dependsOn(tasks.shadowJar) + + val viaProxyConfiguration = configurations.create("viaProxy") + viaProxyConfiguration.dependencies.add(dependencies.create(rootProject.libs.viaProxy.get().copy().setTransitive(false))) + + mainClass.set("net.raphimc.viaproxy.ViaProxy") + classpath = viaProxyConfiguration + workingDir = file("run") + jvmArgs = listOf("-DskipUpdateCheck") + + if (System.getProperty("viaproxy.gui.autoStart") != null) { + jvmArgs("-Dviaproxy.gui.autoStart") + } + + doFirst { + val jarsDir = file("$workingDir/jars") + jarsDir.mkdirs() + file("$jarsDir/${project.name}.jar").writeBytes(tasks.shadowJar.get().archiveFile.get().asFile.readBytes()) + } + + doLast { + file("$workingDir/jars/${project.name}.jar").delete() + file("$workingDir/logs").deleteRecursively() + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/api/ViaBackwardsPlatform.java b/common/src/main/java/com/viaversion/viabackwards/api/ViaBackwardsPlatform.java index 4ab92280..d878aadb 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/ViaBackwardsPlatform.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/ViaBackwardsPlatform.java @@ -54,6 +54,8 @@ import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19; import com.viaversion.viabackwards.protocol.v1_20_3to1_20_2.Protocol1_20_3To1_20_2; import com.viaversion.viabackwards.protocol.v1_20_5to1_20_3.Protocol1_20_5To1_20_3; import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.task.PlayerPacketsTickTask; import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5; import com.viaversion.viabackwards.protocol.v1_9_3to1_9_1.Protocol1_9_3To1_9_1; import com.viaversion.viabackwards.protocol.v1_10to1_9_3.Protocol1_10To1_9_3; @@ -69,7 +71,7 @@ import java.util.logging.Logger; public interface ViaBackwardsPlatform { - String MINIMUM_VV_VERSION = "5.0.4"; + String MINIMUM_VV_VERSION = "5.1.1"; /** * Initialize ViaBackwards. @@ -141,6 +143,14 @@ public interface ViaBackwardsPlatform { protocolManager.registerProtocol(new Protocol1_20_5To1_20_3(), ProtocolVersion.v1_20_3, ProtocolVersion.v1_20_5); protocolManager.registerProtocol(new Protocol1_21To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_21); + protocolManager.registerProtocol(new Protocol1_21_2To1_21(), ProtocolVersion.v1_21, ProtocolVersion.v1_21_2); + } + + default void enable() { + final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().highestSupportedProtocolVersion(); + if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_2)) { + Via.getPlatform().runRepeatingSync(new PlayerPacketsTickTask(), 1L); + } } /** diff --git a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionHandler.java b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionHandler.java index 70741e84..0d53c9d6 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionHandler.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionHandler.java @@ -75,7 +75,11 @@ public class EntityPositionHandler { } } - positionStorage.setCoordinates(x, y, z, relative); + if (relative) { + positionStorage.addRelativePosition(x, y, z); + } else { + positionStorage.setPosition(x, y, z); + } } public EntityPositionStorage getStorage(UserConnection user, int entityId) { diff --git a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionStorage.java b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionStorage.java index 38df14f5..698715ed 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionStorage.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/EntityPositionStorage.java @@ -34,15 +34,15 @@ public abstract class EntityPositionStorage { return z; } - public void setCoordinates(double x, double y, double z, boolean relative) { - if (relative) { - this.x += x; - this.y += y; - this.z += z; - } else { - this.x = x; - this.y = y; - this.z = z; - } + public void setPosition(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public void addRelativePosition(double relX, double relY, double relZ) { + this.x += relX; + this.y += relY; + this.z += relZ; } } diff --git a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/PlayerPositionStorage.java b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/PlayerPositionStorage.java index 2e87dd61..7d70e3bb 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/PlayerPositionStorage.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/PlayerPositionStorage.java @@ -18,8 +18,6 @@ package com.viaversion.viabackwards.api.entities.storage; import com.viaversion.viaversion.api.connection.StorableObject; -import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; -import com.viaversion.viaversion.api.type.Types; public abstract class PlayerPositionStorage implements StorableObject { private double x; @@ -53,19 +51,15 @@ public abstract class PlayerPositionStorage implements StorableObject { this.z = z; } - public void setCoordinates(PacketWrapper wrapper, boolean relative) { - setCoordinates(wrapper.get(Types.DOUBLE, 0), wrapper.get(Types.DOUBLE, 1), wrapper.get(Types.DOUBLE, 2), relative); + public void setPosition(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; } - public void setCoordinates(double x, double y, double z, boolean relative) { - if (relative) { - this.x += x; - this.y += y; - this.z += z; - } else { - this.x = x; - this.y = y; - this.z = z; - } + public void addRelativePosition(double relX, double relY, double relZ) { + this.x += relX; + this.y += relY; + this.z += relZ; } } diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java index 20548761..9869c7b9 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java @@ -20,22 +20,17 @@ package com.viaversion.viabackwards.api.rewriters; import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.nbt.tag.IntTag; import com.viaversion.nbt.tag.ListTag; -import com.viaversion.nbt.tag.NumberTag; import com.viaversion.nbt.tag.Tag; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.data.MappedItem; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.data.FullMappings; -import com.viaversion.viaversion.api.minecraft.Particle; -import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; import com.viaversion.viaversion.api.type.Type; -import com.viaversion.viaversion.libs.fastutil.ints.Int2IntFunction; import com.viaversion.viaversion.rewriter.StructuredItemRewriter; import java.util.ArrayList; import java.util.List; @@ -47,10 +42,9 @@ public class BackwardsStructuredItemRewriter itemType, Type itemArrayType, Type mappedItemType, Type mappedItemArrayType, - Type itemCostType, Type optionalItemCostType, Type mappedItemCostType, Type mappedOptionalItemCostType, - Type particleType, Type mappedParticleType + Type itemCostType, Type optionalItemCostType, Type mappedItemCostType, Type mappedOptionalItemCostType ) { - super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, itemCostType, optionalItemCostType, mappedItemCostType, mappedOptionalItemCostType, particleType, mappedParticleType); + super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, itemCostType, optionalItemCostType, mappedItemCostType, mappedOptionalItemCostType); } public BackwardsStructuredItemRewriter(final T protocol, final Type itemType, final Type itemArrayType, final Type mappedItemType, final Type mappedItemArrayType) { @@ -68,33 +62,9 @@ public class BackwardsStructuredItemRewriter loreData = dataContainer.getNonEmpty(StructuredDataKey.LORE); - if (loreData != null) { - for (final Tag tag : loreData.value()) { - protocol.getComponentRewriter().processTag(connection, tag); - } - } - } - - Int2IntFunction itemIdRewriter = null; - Int2IntFunction blockIdRewriter = null; - if (mappingData != null) { - itemIdRewriter = mappingData.getItemMappings() != null ? mappingData::getNewItemId : null; - blockIdRewriter = mappingData.getBlockMappings() != null ? mappingData::getNewBlockId : null; - } - final MappedItem mappedItem = mappingData != null ? mappingData.getMappedItem(item.identifier()) : null; if (mappedItem == null) { // Just rewrite the id @@ -102,7 +72,7 @@ public class BackwardsStructuredItemRewriter dataComponentMappings.inverse().getNewId(id)); - } + final BackwardsMappingData mappingData = protocol.getMappingData(); + if (mappingData != null && mappingData.getItemMappings() != null) { + item.setIdentifier(mappingData.getOldItemId(item.identifier())); } - - final CompoundTag tag = customTag(item); - if (tag != null) { - final Tag originalId = tag.remove(nbtTagName("id")); - if (originalId instanceof IntTag) { - item.setIdentifier(((NumberTag) originalId).asInt()); + final CompoundTag customData = dataContainer.get(StructuredDataKey.CUSTOM_DATA); + if (customData != null) { + if (customData.remove(nbtTagName("id")) instanceof final IntTag originalTag) { + item.setIdentifier(originalTag.asInt()); } } restoreTextComponents(item); - - Int2IntFunction itemIdRewriter = null; - Int2IntFunction blockIdRewriter = null; - if (mappingData != null) { - itemIdRewriter = mappingData.getItemMappings() != null ? mappingData::getOldItemId : null; - blockIdRewriter = mappingData.getBlockMappings() != null ? mappingData::getOldBlockId : null; - } - updateItemComponents(connection, dataContainer, this::handleItemToServer, itemIdRewriter, blockIdRewriter); + updateItemDataComponents(connection, item, false); return item; } - protected @Nullable CompoundTag customTag(final Item item) { - final StructuredData customData = item.dataContainer().getNonEmpty(StructuredDataKey.CUSTOM_DATA); - return customData != null ? customData.value() : null; - } - protected void saveListTag(CompoundTag tag, ListTag original, String name) { // Multiple places might try to backup data String backupName = nbtTagName(name); diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/EntityRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/EntityRewriter.java index c29b69de..ca85e27c 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/EntityRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/EntityRewriter.java @@ -25,7 +25,6 @@ import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; 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.api.type.types.version.Types1_14; @@ -105,14 +104,11 @@ public abstract class EntityRewriter trackAndMapEntity(wrapper)); - } + protocol.registerClientbound(packetType, wrapper -> { + wrapper.passthrough(Types.VAR_INT); // Entity ID + wrapper.passthrough(Types.UUID); // Entity UUID + wrapper.passthrough(Types.VAR_INT); // Entity Type + trackAndMapEntity(wrapper); }); } @@ -127,7 +123,6 @@ public abstract class EntityRewriter intType) { - return wrapper -> tracker(wrapper.user()).addEntity((int) wrapper.get(intType, 0), entityType); + protected PacketHandler getTrackerHandler(EntityType entityType) { + return wrapper -> tracker(wrapper.user()).addEntity((int) wrapper.get(Types.VAR_INT, 0), entityType); + } + + protected PacketHandler getPlayerTrackerHandler() { + return wrapper -> { + final int entityId = wrapper.get(Types.INT, 0); + + final EntityTracker tracker = tracker(wrapper.user()); + tracker(wrapper.user()).setClientEntityId(entityId); + tracker.addEntity(entityId, tracker.playerType()); + }; } protected PacketHandler getDimensionHandler(int index) { return wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(this.protocol.getClass()); int dimensionId = wrapper.get(Types.INT, index); - clientWorld.setEnvironment(dimensionId); + if (clientWorld.setEnvironment(dimensionId)) { + tracker(wrapper.user()).clearEntities(); + } }; } } diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/LegacyEntityRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/LegacyEntityRewriter.java index 8728902e..08404a2f 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/LegacyEntityRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/LegacyEntityRewriter.java @@ -66,8 +66,10 @@ public abstract class LegacyEntityRewriter { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - clientWorld.setEnvironment(wrapper.get(Types.INT, 0)); + ClientWorld clientWorld = wrapper.user().getClientWorld(protocol.getClass()); + if (clientWorld.setEnvironment(wrapper.get(Types.INT, 0))) { + tracker(wrapper.user()).clearEntities(); + } }); } }); @@ -81,8 +83,8 @@ public abstract class LegacyEntityRewriter { - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); - clientChunks.setEnvironment(wrapper.get(Types.INT, 1)); + ClientWorld clientWorld = wrapper.user().getClientWorld(protocol.getClass()); + clientWorld.setEnvironment(wrapper.get(Types.INT, 1)); final int entityId = wrapper.get(Types.INT, 0); addTrackedEntity(wrapper, entityId, playerType); diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/SoundRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/SoundRewriter.java index f739f4c4..a86dc273 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/SoundRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/SoundRewriter.java @@ -23,7 +23,6 @@ import com.viaversion.viaversion.api.minecraft.SoundEvent; import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; -import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; public class SoundRewriter extends com.viaversion.viaversion.rewriter.SoundRewriter { @@ -36,22 +35,14 @@ public class SoundRewriter extends com.viaversi } public void registerNamedSound(final C packetType) { - protocol.registerClientbound(packetType, new PacketHandlers() { - @Override - public void register() { - map(Types.STRING); // Sound identifier - handler(getNamedSoundHandler()); - } + protocol.registerClientbound(packetType, wrapper -> { + wrapper.passthrough(Types.STRING); // Sound identifier + getNamedSoundHandler().handle(wrapper); }); } public void registerStopSound(final C packetType) { - protocol.registerClientbound(packetType, new PacketHandlers() { - @Override - public void register() { - handler(getStopSoundHandler()); - } - }); + protocol.registerClientbound(packetType, wrapper -> getStopSoundHandler().handle(wrapper)); } public PacketHandler getNamedSoundHandler() { diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/StructuredEnchantmentRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/StructuredEnchantmentRewriter.java index 900cfb2d..9686bb09 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/StructuredEnchantmentRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/StructuredEnchantmentRewriter.java @@ -25,7 +25,6 @@ import com.viaversion.nbt.tag.Tag; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.utils.ChatUtil; import com.viaversion.viaversion.api.data.Mappings; -import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; @@ -66,25 +65,22 @@ public class StructuredEnchantmentRewriter { public void handleToServer(final Item item) { final StructuredDataContainer data = item.dataContainer(); - final StructuredData customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA); - if (customData == null) { - return; + final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); + if (customData != null) { + rewriteEnchantmentsToServer(data, customData, StructuredDataKey.ENCHANTMENTS); + rewriteEnchantmentsToServer(data, customData, StructuredDataKey.STORED_ENCHANTMENTS); } - - final CompoundTag tag = customData.value(); - rewriteEnchantmentsToServer(data, tag, StructuredDataKey.ENCHANTMENTS); - rewriteEnchantmentsToServer(data, tag, StructuredDataKey.STORED_ENCHANTMENTS); } public void rewriteEnchantmentsToClient(final StructuredDataContainer data, final StructuredDataKey key, final IdRewriteFunction rewriteFunction, final DescriptionSupplier descriptionSupplier, final boolean storedEnchant) { - final StructuredData enchantmentsData = data.getNonEmpty(key); - if (enchantmentsData == null || enchantmentsData.value().size() == 0) { + final Enchantments enchantments = data.get(key); + if (enchantments == null || enchantments.size() == 0) { return; } - final Enchantments enchantments = enchantmentsData.value(); final List loreToAdd = new ArrayList<>(); - boolean changed = false; + boolean removedEnchantments = false; + boolean updatedLore = false; final ObjectIterator iterator = enchantments.enchantments().int2IntEntrySet().iterator(); final List updatedIds = new ArrayList<>(); @@ -101,18 +97,20 @@ public class StructuredEnchantmentRewriter { continue; } - final Tag description = descriptionSupplier.get(id, level); - if (description != null) { - if (!changed) { - // Backup original before doing modifications - final CompoundTag customData = data.computeIfAbsent(StructuredDataKey.CUSTOM_DATA, $ -> new CompoundTag()).value(); - itemRewriter.saveListTag(customData, asTag(enchantments), key.identifier()); - changed = true; - } - - loreToAdd.add(description); - iterator.remove(); + if (!removedEnchantments) { + // Backup original before doing modifications + final CompoundTag customData = customData(data); + itemRewriter.saveListTag(customData, asTag(enchantments), key.identifier()); + removedEnchantments = true; } + + final Tag description = descriptionSupplier.get(id, level); + if (description != null && enchantments.showInTooltip()) { + loreToAdd.add(description); + updatedLore = true; + } + + iterator.remove(); } // Remove all first, then add the new ones @@ -123,38 +121,46 @@ public class StructuredEnchantmentRewriter { enchantments.add(change.mappedId(), change.level()); } - if (loreToAdd.isEmpty()) { - // No removed enchantments - return; - } - - // Add glint override if there are no enchantments left - final CompoundTag tag = data.computeIfAbsent(StructuredDataKey.CUSTOM_DATA, $ -> new CompoundTag()).value(); - if (!storedEnchant && enchantments.size() == 0) { - final StructuredData glintOverride = data.getNonEmpty(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE); - if (glintOverride != null) { - tag.putBoolean(itemRewriter.nbtTagName("glint"), glintOverride.value()); - } else { - tag.putBoolean(itemRewriter.nbtTagName("noglint"), true); + if (removedEnchantments) { + final CompoundTag tag = customData(data); + if (!storedEnchant && enchantments.size() == 0) { + // Add glint override if there are no enchantments left + final Boolean glintOverride = data.get(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE); + if (glintOverride != null) { + tag.putBoolean(itemRewriter.nbtTagName("glint"), glintOverride); + } else { + tag.putBoolean(itemRewriter.nbtTagName("noglint"), true); + } + data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true); + } + + if (enchantments.showInTooltip()) { + tag.putBoolean(itemRewriter.nbtTagName("show_" + key.identifier()), true); } - data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true); } - // Save original lore - final StructuredData loreData = data.getNonEmpty(StructuredDataKey.LORE); - if (loreData != null) { - final List loreList = Arrays.asList(loreData.value()); - itemRewriter.saveGenericTagList(tag, loreList, "lore"); - loreToAdd.addAll(loreList); - } else { - tag.putBoolean(itemRewriter.nbtTagName("nolore"), true); + if (updatedLore) { + // Save original lore + final CompoundTag tag = customData(data); + final Tag[] lore = data.get(StructuredDataKey.LORE); + if (lore != null) { + final List loreList = Arrays.asList(lore); + itemRewriter.saveGenericTagList(tag, loreList, "lore"); + loreToAdd.addAll(loreList); + } else { + tag.putBoolean(itemRewriter.nbtTagName("nolore"), true); + } + data.set(StructuredDataKey.LORE, loreToAdd.toArray(new Tag[0])); } + } - if (enchantments.showInTooltip()) { - tag.putBoolean(itemRewriter.nbtTagName("show_" + key.identifier()), true); + private CompoundTag customData(final StructuredDataContainer data) { + CompoundTag tag = data.get(StructuredDataKey.CUSTOM_DATA); + if (tag == null) { + tag = new CompoundTag(); + data.set(StructuredDataKey.CUSTOM_DATA, tag); } - - data.set(StructuredDataKey.LORE, loreToAdd.toArray(new Tag[0])); + return tag; } private ListTag asTag(final Enchantments enchantments) { diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/TranslatableRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/TranslatableRewriter.java index a6f85112..cffa4629 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/TranslatableRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/TranslatableRewriter.java @@ -19,6 +19,7 @@ package com.viaversion.viabackwards.api.rewriters; import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.nbt.tag.StringTag; +import com.viaversion.viabackwards.ViaBackwards; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader; import com.viaversion.viaversion.api.connection.UserConnection; @@ -60,7 +61,7 @@ public class TranslatableRewriter extends Compo super(protocol, type); final Map translatableMappings = getTranslatableMappings(version); if (translatableMappings == null) { - protocol.getLogger().warning("Missing " + version + " translatables!"); + ViaBackwards.getPlatform().getLogger().warning("Missing " + version + " translatables!"); this.translatables = new HashMap<>(); } else { this.translatables = translatableMappings; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/template/BlockItemPacketRewriter1_99.java b/common/src/main/java/com/viaversion/viabackwards/protocol/template/BlockItemPacketRewriter1_99.java index 58db1cab..d06073ca 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/template/BlockItemPacketRewriter1_99.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/template/BlockItemPacketRewriter1_99.java @@ -19,22 +19,22 @@ package com.viaversion.viabackwards.protocol.template; import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter; 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.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; -import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5; -import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; -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.api.type.types.version.Types1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_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.ServerboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; import com.viaversion.viaversion.rewriter.BlockRewriter; +import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter; // To replace if needed: // ChunkType1_20_2 // RecipeRewriter1_20_3 // Types1_21 -final class BlockItemPacketRewriter1_99 extends BackwardsStructuredItemRewriter { +final class BlockItemPacketRewriter1_99 extends BackwardsStructuredItemRewriter { public BlockItemPacketRewriter1_99(final Protocol1_98To1_99 protocol) { - super(protocol, Types1_21.ITEM, Types1_21.ITEM_ARRAY); + super(protocol, Types1_21_2.ITEM, Types1_21_2.ITEM_ARRAY); /*super(protocol, Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_OLD.ITEM, Types1_OLD.ITEM_ARRAY, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_OLD.ITEM_COST, Types1_OLD.OPTIONAL_ITEM_COST, @@ -44,27 +44,29 @@ final class BlockItemPacketRewriter1_99 extends BackwardsStructuredItemRewriter< @Override public void registerPackets() { - final BlockRewriter blockRewriter = BlockRewriter.for1_20_2(protocol); - blockRewriter.registerBlockEvent(ClientboundPackets1_21.BLOCK_EVENT); - blockRewriter.registerBlockUpdate(ClientboundPackets1_21.BLOCK_UPDATE); - blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE); - blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21.LEVEL_EVENT, 2001); - blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new); - blockRewriter.registerBlockEntityData(ClientboundPackets1_21.BLOCK_ENTITY_DATA); + final BlockRewriter blockRewriter = BlockRewriter.for1_20_2(protocol); + blockRewriter.registerBlockEvent(ClientboundPackets1_21_2.BLOCK_EVENT); + blockRewriter.registerBlockUpdate(ClientboundPackets1_21_2.BLOCK_UPDATE); + blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE); + blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_2.LEVEL_EVENT, 2001); + blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new); + blockRewriter.registerBlockEntityData(ClientboundPackets1_21_2.BLOCK_ENTITY_DATA); - // registerOpenWindow(ClientboundPackets1_21.OPEN_WINDOW); - registerCooldown(ClientboundPackets1_21.COOLDOWN); - registerSetContent1_17_1(ClientboundPackets1_21.CONTAINER_SET_CONTENT); - registerSetSlot1_17_1(ClientboundPackets1_21.CONTAINER_SET_SLOT); - registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS); - registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT); - registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK); - registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS); - registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT); - registerContainerSetData(ClientboundPackets1_21.CONTAINER_SET_DATA); - registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES); - registerExplosion(ClientboundPackets1_21.EXPLODE); + // registerOpenScreen(ClientboundPackets1_21_2.OPEN_SCREEN); + protocol.registerClientbound(ClientboundPackets1_21_2.SET_CURSOR_ITEM, this::passthroughClientboundItem); + registerCooldown1_21_2(ClientboundPackets1_21_2.COOLDOWN); + registerSetContent1_21_2(ClientboundPackets1_21_2.CONTAINER_SET_CONTENT); + registerSetSlot1_21_2(ClientboundPackets1_21_2.CONTAINER_SET_SLOT); + registerAdvancements1_20_3(ClientboundPackets1_21_2.UPDATE_ADVANCEMENTS); + registerSetEquipment(ClientboundPackets1_21_2.SET_EQUIPMENT); + registerMerchantOffers1_20_5(ClientboundPackets1_21_2.MERCHANT_OFFERS); + registerContainerSetData(ClientboundPackets1_21_2.CONTAINER_SET_DATA); + registerContainerClick1_21_2(ServerboundPackets1_21_2.CONTAINER_CLICK); + registerSetCreativeModeSlot(ServerboundPackets1_21_2.SET_CREATIVE_MODE_SLOT); - new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES); + final RecipeDisplayRewriter recipeRewriter = new RecipeDisplayRewriter<>(protocol); + recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21_2.UPDATE_RECIPES); + recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21_2.RECIPE_BOOK_ADD); + recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21_2.PLACE_GHOST_RECIPE); } } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/template/ComponentRewriter1_99.java b/common/src/main/java/com/viaversion/viabackwards/protocol/template/ComponentRewriter1_99.java new file mode 100644 index 00000000..1a27d30b --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/template/ComponentRewriter1_99.java @@ -0,0 +1,48 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.template; + +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.viabackwards.api.BackwardsProtocol; +import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2; +import com.viaversion.viaversion.util.SerializerVersion; + +public class ComponentRewriter1_99 extends TranslatableRewriter { + + public ComponentRewriter1_99(final BackwardsProtocol protocol) { + super(protocol, ReadType.NBT); + } + + @Override + protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) { + super.handleShowItem(connection, itemTag, componentsTag); + if (componentsTag == null) { + return; + } + + // Remove or update data from componentsTag + // New added data which is not handled otherwise needs to be removed to prevent errors on the client + } + + @Override + protected SerializerVersion inputSerializerVersion() { + return SerializerVersion.V1_20_5; + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/template/EntityPacketRewriter1_99.java b/common/src/main/java/com/viaversion/viabackwards/protocol/template/EntityPacketRewriter1_99.java index 806bf705..51cfdd3d 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/template/EntityPacketRewriter1_99.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/template/EntityPacketRewriter1_99.java @@ -18,21 +18,19 @@ package com.viaversion.viabackwards.protocol.template; import com.viaversion.viabackwards.api.rewriters.EntityRewriter; -import com.viaversion.viaversion.api.minecraft.RegistryEntry; import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; -import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_20_5; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; -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.util.Key; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2; +import com.viaversion.viaversion.rewriter.RegistryDataRewriter; // Replace if needed // Types1_OLD // Types1_21 -final class EntityPacketRewriter1_99 extends EntityRewriter { +final class EntityPacketRewriter1_99 extends EntityRewriter { public EntityPacketRewriter1_99(final Protocol1_98To1_99 protocol) { super(protocol, Types1_20_5.ENTITY_DATA_TYPES.optionalComponentType, Types1_20_5.ENTITY_DATA_TYPES.booleanType); @@ -40,36 +38,30 @@ final class EntityPacketRewriter1_99 extends EntityRewriter { - final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING)); - final RegistryEntry[] entries = wrapper.passthrough(Types.REGISTRY_ENTRY_ARRAY); - handleRegistryData1_20_5(wrapper.user(), registryKey, entries); // Caches dimensions to access data like height later and tracks the amount of biomes sent for chunk data + final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol); + protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle); + + protocol.registerClientbound(ClientboundPackets1_21_2.LOGIN, wrapper -> { + final int entityId = wrapper.passthrough(Types.INT); // Entity id + wrapper.passthrough(Types.BOOLEAN); // Hardcore + wrapper.passthrough(Types.STRING_ARRAY); // World List + wrapper.passthrough(Types.VAR_INT); // Max players + wrapper.passthrough(Types.VAR_INT); // View distance + wrapper.passthrough(Types.VAR_INT); // Simulation distance + wrapper.passthrough(Types.BOOLEAN); // Reduced debug info + wrapper.passthrough(Types.BOOLEAN); // Show death screen + wrapper.passthrough(Types.BOOLEAN); // Limited crafting + final int dimensionId = wrapper.passthrough(Types.VAR_INT); + final String world = wrapper.passthrough(Types.STRING); + trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world); + trackPlayer(wrapper.user(), entityId); }); - protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() { - @Override - public void register() { - map(Types.INT); // Entity id - map(Types.BOOLEAN); // Hardcore - map(Types.STRING_ARRAY); // World List - map(Types.VAR_INT); // Max players - map(Types.VAR_INT); // View distance - map(Types.VAR_INT); // Simulation distance - map(Types.BOOLEAN); // Reduced debug info - map(Types.BOOLEAN); // Show death screen - map(Types.BOOLEAN); // Limited crafting - map(Types.VAR_INT); // Dimension key - map(Types.STRING); // World - handler(worldDataTrackerHandlerByKey1_20_5(3)); // Tracks world height and name for chunk data and entity (un)tracking - } - }); - - protocol.registerClientbound(ClientboundPackets1_21.RESPAWN, wrapper -> { + protocol.registerClientbound(ClientboundPackets1_21_2.RESPAWN, wrapper -> { final int dimensionId = wrapper.passthrough(Types.VAR_INT); final String world = wrapper.passthrough(Types.STRING); trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world); // Tracks world height and name for chunk data and entity (un)tracking diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/template/Protocol1_98To1_99.java b/common/src/main/java/com/viaversion/viabackwards/protocol/template/Protocol1_98To1_99.java index 3a17f03e..39865c8b 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/template/Protocol1_98To1_99.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/template/Protocol1_98To1_99.java @@ -20,20 +20,20 @@ package com.viaversion.viabackwards.protocol.template; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; -import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; +import com.viaversion.viaversion.api.type.types.version.Types1_21_2; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5; -import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5; -import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; -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.rewriter.ComponentRewriter.ReadType; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_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.ServerboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; @@ -42,52 +42,59 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap; // Placeholders to replace (in the entire package): // Protocol1_98To1_99, EntityPacketRewriter1_99, BlockItemPacketRewriter1_99 // Protocol1_20_5To1_21 (the ViaVersion protocol class the mappings depend on) -// ClientboundPacket1_21 -// ServerboundPacket1_20_5 +// ClientboundPacket1_21_2 +// ServerboundPacket1_21_2 // ClientboundConfigurationPackets1_21 // ServerboundConfigurationPackets1_20_5 // EntityTypes1_20_5 (UNMAPPED type) +// Types1_21_2.PARTICLE // 1.99, 1.98 -final class Protocol1_98To1_99 extends BackwardsProtocol { +final class Protocol1_98To1_99 extends BackwardsProtocol { // ViaBackwards uses its own mappings and also needs a translatablerewriter for translation mappings public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.99", "1.98", Protocol1_20_5To1_21.class); private final EntityPacketRewriter1_99 entityRewriter = new EntityPacketRewriter1_99(this); private final BlockItemPacketRewriter1_99 itemRewriter = new BlockItemPacketRewriter1_99(this); - private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ReadType.NBT); - private final TagRewriter tagRewriter = new TagRewriter<>(this); + private final ParticleRewriter particleRewriter = new ParticleRewriter<>(this, Types1_21_2.PARTICLE/*, Types1_OLD.PARTICLE*/); + private final ComponentRewriter1_99 translatableRewriter = new ComponentRewriter1_99(this); + private final TagRewriter tagRewriter = new TagRewriter<>(this); public Protocol1_98To1_99() { - super(ClientboundPacket1_21.class, ClientboundPacket1_21.class, ServerboundPacket1_20_5.class, ServerboundPacket1_20_5.class); + super(ClientboundPacket1_21_2.class, ClientboundPacket1_21_2.class, ServerboundPacket1_21_2.class, ServerboundPacket1_21_2.class); } @Override protected void registerPackets() { super.registerPackets(); - tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS); + tagRewriter.registerGeneric(ClientboundPackets1_21_2.UPDATE_TAGS); tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS); - final SoundRewriter soundRewriter = new SoundRewriter<>(this); - soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND); - soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY); - soundRewriter.registerStopSound(ClientboundPackets1_21.STOP_SOUND); + final SoundRewriter soundRewriter = new SoundRewriter<>(this); + soundRewriter.registerSound1_19_3(ClientboundPackets1_21_2.SOUND); + soundRewriter.registerSound1_19_3(ClientboundPackets1_21_2.SOUND_ENTITY); + soundRewriter.registerStopSound(ClientboundPackets1_21_2.STOP_SOUND); - new StatisticsRewriter<>(this).register(ClientboundPackets1_21.AWARD_STATS); - //new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21.ENTITY_PROPERTIES); + new StatisticsRewriter<>(this).register(ClientboundPackets1_21_2.AWARD_STATS); + //new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21_2.UPDATE_ATTRIBUTES); // Registers translatable mappings (missing a whole bunch still) - //translatableRewriter.registerOpenWindow(ClientboundPackets1_21.OPEN_WINDOW); // Handled by registerOpenWindow in item rewriters - translatableRewriter.registerComponentPacket(ClientboundPackets1_21.SET_ACTION_BAR_TEXT); - translatableRewriter.registerComponentPacket(ClientboundPackets1_21.SET_TITLE_TEXT); - translatableRewriter.registerComponentPacket(ClientboundPackets1_21.SET_SUBTITLE_TEXT); - translatableRewriter.registerBossEvent(ClientboundPackets1_21.BOSS_EVENT); - translatableRewriter.registerComponentPacket(ClientboundPackets1_21.DISCONNECT); - translatableRewriter.registerTabList(ClientboundPackets1_21.TAB_LIST); - translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21.PLAYER_COMBAT_KILL); - translatableRewriter.registerComponentPacket(ClientboundPackets1_21.SYSTEM_CHAT); - translatableRewriter.registerComponentPacket(ClientboundPackets1_21.DISGUISED_CHAT); + //translatableRewriter.registerOpenScreen(ClientboundPackets1_21_2.OPEN_SCREEN); // Handled by registerOpenScreen in item rewriters + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_ACTION_BAR_TEXT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_TITLE_TEXT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_SUBTITLE_TEXT); + translatableRewriter.registerBossEvent(ClientboundPackets1_21_2.BOSS_EVENT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISCONNECT); + translatableRewriter.registerTabList(ClientboundPackets1_21_2.TAB_LIST); + translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_2.PLAYER_COMBAT_KILL); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SYSTEM_CHAT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISGUISED_CHAT); + translatableRewriter.registerPlayerInfoUpdate1_21_2(ClientboundPackets1_21_2.PLAYER_INFO_UPDATE); translatableRewriter.registerPing(); + + // If needed for any particle, item, or block changes. Extend ParticleRewriter for particle serializer changes + particleRewriter.registerLevelParticles1_20_5(ClientboundPackets1_21_2.LEVEL_PARTICLES); + particleRewriter.registerExplode1_21_2(ClientboundPackets1_21_2.EXPLODE); } @Override @@ -111,22 +118,27 @@ final class Protocol1_98To1_99 extends BackwardsProtocol getComponentRewriter() { + public ParticleRewriter getParticleRewriter() { + return particleRewriter; + } + + @Override + public ComponentRewriter1_99 getComponentRewriter() { return translatableRewriter; } @Override - public TagRewriter getTagRewriter() { + public TagRewriter getTagRewriter() { return tagRewriter; } @Override - protected PacketTypesProvider createPacketTypesProvider() { + protected PacketTypesProvider createPacketTypesProvider() { return new SimplePacketTypesProvider<>( - packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class), - packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class), - packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class), - packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class) + packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class), + packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class), + packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class), + packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class) ); } } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_10to1_9_3/Protocol1_10To1_9_3.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_10to1_9_3/Protocol1_10To1_9_3.java index d5eae4bc..a4ea27d4 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_10to1_9_3/Protocol1_10To1_9_3.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_10to1_9_3/Protocol1_10To1_9_3.java @@ -98,11 +98,8 @@ public class Protocol1_10To1_9_3 extends BackwardsProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_10To1_9_3.class); ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); Chunk chunk = wrapper.passthrough(type); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_11_1to1_11/Protocol1_11_1To1_11.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_11_1to1_11/Protocol1_11_1To1_11.java index 0c7482a9..0f128d3f 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_11_1to1_11/Protocol1_11_1To1_11.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_11_1to1_11/Protocol1_11_1To1_11.java @@ -39,11 +39,8 @@ public class Protocol1_11_1To1_11 extends BackwardsProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_11To1_10.class); ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); // Use the 1.10 Chunk type since nothing changed. Chunk chunk = wrapper.passthrough(type); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/Protocol1_12To1_11_1.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/Protocol1_12To1_11_1.java index 7ea21aa9..43831b8c 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/Protocol1_12To1_11_1.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/Protocol1_12To1_11_1.java @@ -71,11 +71,8 @@ public class Protocol1_12To1_11_1 extends BackwardsProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_12To1_11_1.class); ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); // Use the 1.9.4 Chunk type since nothing changed. Chunk chunk = wrapper.passthrough(type); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/rewriter/EntityPacketRewriter1_12.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/rewriter/EntityPacketRewriter1_12.java index b6a73f53..23d06457 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/rewriter/EntityPacketRewriter1_12.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_12to1_11_1/rewriter/EntityPacketRewriter1_12.java @@ -119,9 +119,8 @@ public class EntityPacketRewriter1_12 extends LegacyEntityRewriter { ShoulderTracker tracker = wrapper.user().get(ShoulderTracker.class); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/Protocol1_13_1To1_13.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/Protocol1_13_1To1_13.java index d811253b..1ad6880d 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/Protocol1_13_1To1_13.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/Protocol1_13_1To1_13.java @@ -41,6 +41,7 @@ import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPacke import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13; import com.viaversion.viaversion.protocols.v1_13to1_13_1.Protocol1_13To1_13_1; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.ComponentUtil; @@ -50,6 +51,7 @@ public class Protocol1_13_1To1_13 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -72,6 +74,8 @@ public class Protocol1_13_1To1_13 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + public TranslatableRewriter translatableRewriter() { return translatableRewriter; } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/rewriter/EntityPacketRewriter1_13_1.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/rewriter/EntityPacketRewriter1_13_1.java index b63a5bad..88e0a038 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/rewriter/EntityPacketRewriter1_13_1.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_1to1_13/rewriter/EntityPacketRewriter1_13_1.java @@ -22,8 +22,8 @@ import com.viaversion.viabackwards.protocol.v1_13_1to1_13.Protocol1_13_1To1_13; import com.viaversion.viaversion.api.minecraft.Particle; import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13; -import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; +import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_13; @@ -138,7 +138,7 @@ public class EntityPacketRewriter1_13_1 extends LegacyEntityRewriter blockRewriter = BlockRewriter.legacy(protocol); protocol.registerClientbound(ClientboundPackets1_13.LEVEL_CHUNK, wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13_1To1_13.class); Chunk chunk = wrapper.passthrough(ChunkType1_13.forEnvironment(clientWorld.getEnvironment())); blockRewriter.handleChunk(chunk); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_2to1_13_1/rewriter/EntityPacketRewriter1_13_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_2to1_13_1/rewriter/EntityPacketRewriter1_13_2.java index c77eed48..ef40175d 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_2to1_13_1/rewriter/EntityPacketRewriter1_13_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13_2to1_13_1/rewriter/EntityPacketRewriter1_13_2.java @@ -18,9 +18,12 @@ package com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.rewriter; import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1; +import com.viaversion.viaversion.api.minecraft.Particle; import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; +import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; -import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_13; import com.viaversion.viaversion.api.type.types.version.Types1_13_2; @@ -47,11 +50,7 @@ public class EntityPacketRewriter1_13_2 { map(Types.SHORT); // 11 - Velocity Z map(Types1_13_2.ENTITY_DATA_LIST, Types1_13.ENTITY_DATA_LIST); // 12 - Entity data - handler(wrapper -> { - for (EntityData entityData : wrapper.get(Types1_13.ENTITY_DATA_LIST, 0)) { - entityData.setDataType(Types1_13.ENTITY_DATA_TYPES.byId(entityData.dataType().typeId())); - } - }); + handler(EntityPacketRewriter1_13_2::updateEntityData); } }); @@ -67,11 +66,7 @@ public class EntityPacketRewriter1_13_2 { map(Types.BYTE); // 6 - Pitch map(Types1_13_2.ENTITY_DATA_LIST, Types1_13.ENTITY_DATA_LIST); // 7 - Entity data - handler(wrapper -> { - for (EntityData entityData : wrapper.get(Types1_13.ENTITY_DATA_LIST, 0)) { - entityData.setDataType(Types1_13.ENTITY_DATA_TYPES.byId(entityData.dataType().typeId())); - } - }); + handler(EntityPacketRewriter1_13_2::updateEntityData); } }); @@ -81,13 +76,23 @@ public class EntityPacketRewriter1_13_2 { map(Types.VAR_INT); // 0 - Entity ID map(Types1_13_2.ENTITY_DATA_LIST, Types1_13.ENTITY_DATA_LIST); // 1 - Entity data list - handler(wrapper -> { - for (EntityData entityData : wrapper.get(Types1_13.ENTITY_DATA_LIST, 0)) { - entityData.setDataType(Types1_13.ENTITY_DATA_TYPES.byId(entityData.dataType().typeId())); - } - }); + handler(EntityPacketRewriter1_13_2::updateEntityData); } }); } + private static void updateEntityData(final PacketWrapper wrapper) { + for (final EntityData data : wrapper.get(Types1_13.ENTITY_DATA_LIST, 0)) { + final EntityDataType dataType = Types1_13.ENTITY_DATA_TYPES.byId(data.dataType().typeId()); + data.setDataType(dataType); + + if (dataType == Types1_13.ENTITY_DATA_TYPES.particleType) { + final Particle particle = data.value(); + if (particle.id() == 27) { + final Item item = particle.getArgument(0).getValue(); + particle.set(0, Types.ITEM1_13, item); + } + } + } + } } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/Protocol1_13To1_12_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/Protocol1_13To1_12_2.java index 8d07e4f7..3a2b0c1f 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/Protocol1_13To1_12_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/Protocol1_13To1_12_2.java @@ -114,11 +114,8 @@ public class Protocol1_13To1_12_2 extends BackwardsProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13To1_12_2.class); ChunkType1_9_3 type_old = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); ChunkType1_13 type = ChunkType1_13.forEnvironment(clientWorld.getEnvironment()); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/rewriter/EntityPacketRewriter1_13.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/rewriter/EntityPacketRewriter1_13.java index 0d9bc3ef..a1e8cf27 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/rewriter/EntityPacketRewriter1_13.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_13to1_12_2/rewriter/EntityPacketRewriter1_13.java @@ -27,13 +27,15 @@ import com.viaversion.viabackwards.protocol.v1_13to1_12_2.data.ParticleIdMapping import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.BackwardsBlockStorage; import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.NoteBlockStorage; import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.PlayerPositionStorage1_13; +import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.minecraft.Particle; import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13; -import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_12; +import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_12; @@ -172,7 +174,7 @@ public class EntityPacketRewriter1_13 extends LegacyEntityRewriter { int motive = wrapper.read(Types.VAR_INT); String title = PaintingNames1_13.getStringId(motive); @@ -188,10 +190,15 @@ public class EntityPacketRewriter1_13 extends LegacyEntityRewriter { - wrapper.user().get(BackwardsBlockStorage.class).clear(); - wrapper.user().get(NoteBlockStorage.class).clear(); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13To1_12_2.class); + int dimensionId = wrapper.get(Types.INT, 0); + + if (clientWorld.setEnvironment(dimensionId)) { + tracker(wrapper.user()).clearEntities(); + wrapper.user().get(BackwardsBlockStorage.class).clear(); + wrapper.user().get(NoteBlockStorage.class).clear(); + } }); } }); @@ -231,14 +238,11 @@ public class EntityPacketRewriter1_13 extends LegacyEntityRewriter wrapper.user().get(PlayerPositionStorage1_13.class).setCoordinates(wrapper, false)); - } + PacketHandler movementRemapper = wrapper -> { + final double x = wrapper.passthrough(Types.DOUBLE); + final double y = wrapper.passthrough(Types.DOUBLE); + final double z = wrapper.passthrough(Types.DOUBLE); + wrapper.user().get(PlayerPositionStorage1_13.class).setPosition(x, y, z); }; protocol.registerServerbound(ServerboundPackets1_12_1.MOVE_PLAYER_POS, movementRemapper); // Player Position protocol.registerServerbound(ServerboundPackets1_12_1.MOVE_PLAYER_POS_ROT, movementRemapper); // Player Position And Look (serverbound) diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/Protocol1_14To1_13_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/Protocol1_14To1_13_2.java index 7af0a097..199aba12 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/Protocol1_14To1_13_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/Protocol1_14To1_13_2.java @@ -20,8 +20,8 @@ package com.viaversion.viabackwards.protocol.v1_14to1_13_2; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; -import com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter.CommandRewriter1_14; import com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter.BlockItemPacketRewriter1_14; +import com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter.CommandRewriter1_14; import com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter.EntityPacketRewriter1_14; import com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter.PlayerPacketRewriter1_14; import com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter.SoundPacketRewriter1_14; @@ -38,6 +38,7 @@ import com.viaversion.viaversion.protocols.v1_13_2to1_14.Protocol1_13_2To1_14; import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14; import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPackets1_14; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; public class Protocol1_14To1_13_2 extends BackwardsProtocol { @@ -45,6 +46,7 @@ public class Protocol1_14To1_13_2 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); public Protocol1_14To1_13_2() { @@ -63,6 +65,8 @@ public class Protocol1_14To1_13_2 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TranslatableRewriter getComponentRewriter() { return translatableRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/rewriter/BlockItemPacketRewriter1_14.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/rewriter/BlockItemPacketRewriter1_14.java index db874a78..6629d7f0 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/rewriter/BlockItemPacketRewriter1_14.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_14to1_13_2/rewriter/BlockItemPacketRewriter1_14.java @@ -18,6 +18,9 @@ package com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter; import com.google.common.collect.ImmutableSet; +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter; import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter; import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; @@ -35,8 +38,8 @@ import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14; -import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; +import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_13; @@ -45,9 +48,6 @@ import com.viaversion.viaversion.api.type.types.version.Types1_13; import com.viaversion.viaversion.api.type.types.version.Types1_13_2; import com.viaversion.viaversion.libs.gson.JsonElement; import com.viaversion.viaversion.libs.gson.JsonObject; -import com.viaversion.nbt.tag.CompoundTag; -import com.viaversion.nbt.tag.ListTag; -import com.viaversion.nbt.tag.StringTag; import com.viaversion.viaversion.libs.gson.JsonParseException; import com.viaversion.viaversion.libs.mcstructs.text.utils.TextUtils; import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13; @@ -360,7 +360,7 @@ public class BlockItemPacketRewriter1_14 extends BackwardsItemRewriter { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_14To1_13_2.class); Chunk chunk = wrapper.read(ChunkType1_14.TYPE); wrapper.write(ChunkType1_13.forEnvironment(clientWorld.getEnvironment()), chunk); @@ -369,7 +369,7 @@ public class BlockItemPacketRewriter1_14 extends BackwardsItemRewriter { short difficulty = wrapper.user().get(DifficultyStorage.class).getDifficulty(); wrapper.write(Types.UNSIGNED_BYTE, difficulty); @@ -329,14 +329,16 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_14To1_13_2.class); int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); + + if (clientWorld.setEnvironment(dimensionId)) { + tracker(wrapper.user()).clearEntities(); + wrapper.user().get(ChunkLightStorage.class).clear(); + } short difficulty = wrapper.user().get(DifficultyStorage.class).getDifficulty(); wrapper.write(Types.UNSIGNED_BYTE, difficulty); - - wrapper.user().get(ChunkLightStorage.class).clear(); }); } }); @@ -375,7 +377,7 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter { - rewriteParticle(event.user(), (Particle) data.getValue()); + protocol.getParticleRewriter().rewriteParticle(event.user(), (Particle) data.getValue()); }); filter().type(EntityTypes1_14.FIREWORK_ROCKET).index(8).handler((event, data) -> { diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/Protocol1_15To1_14_4.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/Protocol1_15To1_14_4.java index eedaa693..d0cce1a7 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/Protocol1_15To1_14_4.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/Protocol1_15To1_14_4.java @@ -21,10 +21,11 @@ import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; -import com.viaversion.viabackwards.protocol.v1_15to1_14_4.storage.ImmediateRespawnStorage; import com.viaversion.viabackwards.protocol.v1_15to1_14_4.rewriter.BlockItemPacketRewriter1_15; import com.viaversion.viabackwards.protocol.v1_15to1_14_4.rewriter.EntityPacketRewriter1_15; +import com.viaversion.viabackwards.protocol.v1_15to1_14_4.storage.ImmediateRespawnStorage; import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.minecraft.RegistryType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_15; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; @@ -36,6 +37,7 @@ import com.viaversion.viaversion.protocols.v1_14_3to1_14_4.packet.ClientboundPac import com.viaversion.viaversion.protocols.v1_14_4to1_15.Protocol1_14_4To1_15; import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; @@ -44,6 +46,7 @@ public class Protocol1_15To1_14_4 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -102,8 +105,10 @@ public class Protocol1_15To1_14_4 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TagRewriter getTagRewriter() { return tagRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/rewriter/EntityPacketRewriter1_15.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/rewriter/EntityPacketRewriter1_15.java index 45eb30c7..835cfd1b 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/rewriter/EntityPacketRewriter1_15.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_15to1_14_4/rewriter/EntityPacketRewriter1_15.java @@ -96,6 +96,7 @@ public class EntityPacketRewriter1_15 extends EntityRewriter { boolean immediateRespawn = !wrapper.read(Types.BOOLEAN); // Inverted @@ -138,7 +139,7 @@ public class EntityPacketRewriter1_15 extends EntityRewriter wrapper.write(Types1_14.ENTITY_DATA_LIST, new ArrayList<>())); // Entity data is no longer sent in 1.15, so we have to send an empty one - handler(getTrackerHandler(EntityTypes1_15.PLAYER, Types.VAR_INT)); + handler(getTrackerHandler(EntityTypes1_15.PLAYER)); } }); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/Protocol1_16_2To1_16_1.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/Protocol1_16_2To1_16_1.java index a78d15c5..e9313f29 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/Protocol1_16_2To1_16_1.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/Protocol1_16_2To1_16_1.java @@ -21,8 +21,8 @@ import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; -import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.CommandRewriter1_16_2; import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.BlockItemPacketRewriter1_16_2; +import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.CommandRewriter1_16_2; import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.EntityPacketRewriter1_16_2; import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.storage.BiomeStorage; import com.viaversion.viaversion.api.connection.UserConnection; @@ -38,6 +38,7 @@ import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.Protocol1_16_1To1_16_ import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2; import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.ProtocolLogger; @@ -48,6 +49,7 @@ public class Protocol1_16_2To1_16_1 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -67,6 +69,8 @@ public class Protocol1_16_2To1_16_1 extends BackwardsProtocol soundRewriter = new SoundRewriter<>(this); @@ -151,6 +155,11 @@ public class Protocol1_16_2To1_16_1 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TagRewriter getTagRewriter() { return tagRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/BlockItemPacketRewriter1_16_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/BlockItemPacketRewriter1_16_2.java index bd371d0f..2f437f56 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/BlockItemPacketRewriter1_16_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/BlockItemPacketRewriter1_16_2.java @@ -114,8 +114,6 @@ public class BlockItemPacketRewriter1_16_2 extends BackwardsItemRewriter handleItemToServer(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2))); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/EntityPacketRewriter1_16_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/EntityPacketRewriter1_16_2.java index 1721b191..5034b24c 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/EntityPacketRewriter1_16_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16_2to1_16_1/rewriter/EntityPacketRewriter1_16_2.java @@ -101,13 +101,15 @@ public class EntityPacketRewriter1_16_2 extends EntityRewriter { CompoundTag dimensionData = wrapper.read(Types.NAMED_COMPOUND_TAG); wrapper.write(Types.STRING, getDimensionFromData(dimensionData)); + + tracker(wrapper.user()).clearEntities(); }); } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java index 348c60c3..8cd66bf9 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java @@ -19,14 +19,14 @@ package com.viaversion.viabackwards.protocol.v1_16to1_15_2; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; -import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.TranslatableRewriter1_16; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.data.BackwardsMappingData1_16; -import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.CommandRewriter1_16; -import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.PlayerAttributesStorage; -import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WorldNameTracker; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.BlockItemPacketRewriter1_16; +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.CommandRewriter1_16; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.EntityPacketRewriter1_16; +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.TranslatableRewriter1_16; +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.PlayerAttributesStorage; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.PlayerSneakStorage; +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WorldNameTracker; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.minecraft.RegistryType; @@ -43,6 +43,7 @@ import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPacke import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15; import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16; import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ServerboundPackets1_16; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.GsonUtil; @@ -53,6 +54,7 @@ public class Protocol1_16To1_15_2 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter1_16 translatableRewriter = new TranslatableRewriter1_16(this); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -71,9 +73,11 @@ public class Protocol1_16To1_15_2 extends BackwardsProtocol { + registerClientbound(State.STATUS, ClientboundStatusPackets.STATUS_RESPONSE, wrapper -> { String original = wrapper.passthrough(Types.STRING); JsonObject object = GsonUtil.getGson().fromJson(original, JsonObject.class); JsonElement description = object.get("description"); @@ -116,7 +120,7 @@ public class Protocol1_16To1_15_2 extends BackwardsProtocol { + registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> { // Transform uuid to plain string UUID uuid = wrapper.read(Types.UUID); wrapper.write(Types.STRING, uuid.toString()); @@ -168,14 +172,12 @@ public class Protocol1_16To1_15_2 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TagRewriter getTagRewriter() { return tagRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/BlockItemPacketRewriter1_16.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/BlockItemPacketRewriter1_16.java index a5976495..69970dc4 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/BlockItemPacketRewriter1_16.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/BlockItemPacketRewriter1_16.java @@ -17,12 +17,18 @@ */ package com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter; +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.IntArrayTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.LongArrayTag; +import com.viaversion.nbt.tag.StringTag; +import com.viaversion.nbt.tag.Tag; import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter; import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter; import com.viaversion.viabackwards.api.rewriters.MapColorRewriter; +import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.storage.BiomeStorage; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.data.MapColorMappings1_15_2; -import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.storage.BiomeStorage; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; @@ -33,12 +39,6 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_15; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_16; import com.viaversion.viaversion.libs.gson.JsonElement; import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPackets1_14; -import com.viaversion.nbt.tag.CompoundTag; -import com.viaversion.nbt.tag.IntArrayTag; -import com.viaversion.nbt.tag.ListTag; -import com.viaversion.nbt.tag.LongArrayTag; -import com.viaversion.nbt.tag.StringTag; -import com.viaversion.nbt.tag.Tag; import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15; import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16; import com.viaversion.viaversion.protocols.v1_15_2to1_16.rewriter.ItemPacketRewriter1_16; @@ -179,8 +179,6 @@ public class BlockItemPacketRewriter1_16 extends BackwardsItemRewriter { - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); - clientChunks.setEnvironment(wrapper.get(Types.INT, 1)); - tracker(wrapper.user()).addEntity(wrapper.get(Types.INT, 0), EntityTypes1_16.PLAYER); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_16To1_15_2.class); + clientWorld.setEnvironment(wrapper.get(Types.INT, 1)); wrapper.write(Types.STRING, "default"); // Level type @@ -262,7 +263,7 @@ public class EntityPacketRewriter1_16 extends EntityRewriter particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -170,8 +171,6 @@ public final class Protocol1_17To1_16_4 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TagRewriter getTagRewriter() { return tagRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/rewriter/BlockItemPacketRewriter1_17.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/rewriter/BlockItemPacketRewriter1_17.java index b315d92d..10fbb3ef 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/rewriter/BlockItemPacketRewriter1_17.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/rewriter/BlockItemPacketRewriter1_17.java @@ -26,7 +26,6 @@ import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter; import com.viaversion.viabackwards.api.rewriters.MapColorRewriter; import com.viaversion.viabackwards.protocol.v1_17to1_16_4.Protocol1_17To1_16_4; import com.viaversion.viabackwards.protocol.v1_17to1_16_4.data.MapColorMappings1_16_4; -import com.viaversion.viabackwards.protocol.v1_17to1_16_4.storage.PingRequests; import com.viaversion.viabackwards.protocol.v1_17to1_16_4.storage.PlayerLastCursorItem; import com.viaversion.viaversion.api.data.entity.EntityTracker; import com.viaversion.viaversion.api.minecraft.BlockChangeRecord; @@ -167,7 +166,7 @@ public final class BlockItemPacketRewriter1_17 extends BackwardsItemRewriter { CompoundTag registry = wrapper.get(Types.NAMED_COMPOUND_TAG, 0); @@ -185,7 +188,7 @@ public final class EntityPacketRewriter1_17 extends EntityRewriter { @@ -42,6 +42,7 @@ public final class Protocol1_18To1_17_1 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -151,6 +152,11 @@ public final class Protocol1_18To1_17_1 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TranslatableRewriter getComponentRewriter() { return translatableRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_18to1_17_1/rewriter/EntityPacketRewriter1_18.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_18to1_17_1/rewriter/EntityPacketRewriter1_18.java index 685ec209..7e060fdc 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_18to1_17_1/rewriter/EntityPacketRewriter1_18.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_18to1_17_1/rewriter/EntityPacketRewriter1_18.java @@ -17,6 +17,9 @@ */ package com.viaversion.viabackwards.protocol.v1_18to1_17_1.rewriter; +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; import com.viaversion.viabackwards.api.rewriters.EntityRewriter; import com.viaversion.viabackwards.protocol.v1_18to1_17_1.Protocol1_18To1_17_1; import com.viaversion.viaversion.api.minecraft.Particle; @@ -28,9 +31,6 @@ import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_17; import com.viaversion.viaversion.api.type.types.version.Types1_18; import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18; -import com.viaversion.nbt.tag.CompoundTag; -import com.viaversion.nbt.tag.ListTag; -import com.viaversion.nbt.tag.StringTag; import com.viaversion.viaversion.util.TagUtil; public final class EntityPacketRewriter1_18 extends EntityRewriter { @@ -110,7 +110,7 @@ public final class EntityPacketRewriter1_18 extends EntityRewriter particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -95,6 +96,8 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol soundRewriter = new SoundRewriter<>(this); soundRewriter.registerStopSound(ClientboundPackets1_19_3.STOP_SOUND); registerClientbound(ClientboundPackets1_19_3.SOUND, wrapper -> { @@ -171,7 +174,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public EntityPacketRewriter1_19_3 getEntityRewriter() { return entityRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_3to1_19_1/rewriter/BlockItemPacketRewriter1_19_3.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_3to1_19_1/rewriter/BlockItemPacketRewriter1_19_3.java index c42800b7..ea0147bf 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_3to1_19_1/rewriter/BlockItemPacketRewriter1_19_3.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_3to1_19_1/rewriter/BlockItemPacketRewriter1_19_3.java @@ -54,7 +54,6 @@ public final class BlockItemPacketRewriter1_19_3 extends BackwardsItemRewriter { - private static final BitSetType PROFILE_ACTIONS_ENUM_TYPE = new BitSetType(6); private static final int[] PROFILE_ACTIONS = {2, 3, 4, 5}; // Ignore initialize chat; add player already handled before private static final int ADD_PLAYER = 0; private static final int INITIALIZE_CHAT = 1; @@ -123,7 +121,7 @@ public final class EntityPacketRewriter1_19_3 extends EntityRewriter { wrapper.cancel(); - final BitSet actions = wrapper.read(PROFILE_ACTIONS_ENUM_TYPE); + final BitSet actions = wrapper.read(Types.PROFILE_ACTIONS_ENUM1_19_3); final int entries = wrapper.read(Types.VAR_INT); if (actions.get(ADD_PLAYER)) { // Special case, as we need to write everything into one action diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/Protocol1_19_4To1_19_3.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/Protocol1_19_4To1_19_3.java index 8906a768..636f248c 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/Protocol1_19_4To1_19_3.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/Protocol1_19_4To1_19_3.java @@ -35,6 +35,7 @@ import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPac import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4; import com.viaversion.viaversion.rewriter.CommandRewriter; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import java.nio.charset.StandardCharsets; @@ -45,6 +46,7 @@ public final class Protocol1_19_4To1_19_3 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -73,6 +75,8 @@ public final class Protocol1_19_4To1_19_3 extends BackwardsProtocol(this) { @Override public void handleArgument(final PacketWrapper wrapper, final String argumentType) { @@ -122,6 +126,11 @@ public final class Protocol1_19_4To1_19_3 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public EntityPacketRewriter1_19_4 getEntityRewriter() { return entityRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/BlockItemPacketRewriter1_19_4.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/BlockItemPacketRewriter1_19_4.java index ea85e512..ed281470 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/BlockItemPacketRewriter1_19_4.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/BlockItemPacketRewriter1_19_4.java @@ -73,7 +73,6 @@ public final class BlockItemPacketRewriter1_19_4 extends BackwardsItemRewriter recipeRewriter = new RecipeRewriter1_19_3<>(protocol) { @Override @@ -121,4 +120,4 @@ public final class BlockItemPacketRewriter1_19_4 extends BackwardsItemRewriter { final int value = data.value(); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/Protocol1_19To1_18_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/Protocol1_19To1_18_2.java index de77de02..4635fcea 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/Protocol1_19To1_18_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/Protocol1_19To1_18_2.java @@ -18,17 +18,17 @@ package com.viaversion.viabackwards.protocol.v1_19to1_18_2; import com.google.common.primitives.Longs; -import com.viaversion.viabackwards.ViaBackwards; +import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; +import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19; import com.viaversion.viabackwards.protocol.v1_19to1_18_2.data.BackwardsMappingData1_19; -import com.viaversion.viabackwards.protocol.v1_19to1_18_2.rewriter.CommandRewriter1_19; import com.viaversion.viabackwards.protocol.v1_19to1_18_2.rewriter.BlockItemPacketRewriter1_19; +import com.viaversion.viabackwards.protocol.v1_19to1_18_2.rewriter.CommandRewriter1_19; import com.viaversion.viabackwards.protocol.v1_19to1_18_2.rewriter.EntityPacketRewriter1_19; import com.viaversion.viabackwards.protocol.v1_19to1_18_2.storage.DimensionRegistryStorage; import com.viaversion.viabackwards.protocol.v1_19to1_18_2.storage.NonceStorage; -import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.RegistryType; @@ -42,7 +42,6 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.libs.gson.JsonElement; -import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets; import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17; @@ -53,6 +52,7 @@ import com.viaversion.viaversion.protocols.v1_19to1_19_1.Protocol1_19To1_19_1; import com.viaversion.viaversion.protocols.v1_19to1_19_1.data.ChatDecorationResult; import com.viaversion.viaversion.rewriter.CommandRewriter; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.Pair; @@ -69,6 +69,7 @@ public final class Protocol1_19To1_18_2 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -291,7 +292,7 @@ public final class Protocol1_19To1_18_2 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TagRewriter getTagRewriter() { return tagRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/BlockItemPacketRewriter1_19.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/BlockItemPacketRewriter1_19.java index a9254766..4f6b491e 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/BlockItemPacketRewriter1_19.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/BlockItemPacketRewriter1_19.java @@ -141,7 +141,7 @@ public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter= 8) { diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/Protocol1_20_2To1_20.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/Protocol1_20_2To1_20.java index 168bc0e1..422fdd2b 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/Protocol1_20_2To1_20.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/Protocol1_20_2To1_20.java @@ -17,6 +17,7 @@ */ package com.viaversion.viabackwards.protocol.v1_20_2to1_20; +import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; @@ -36,7 +37,6 @@ import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.exception.CancelException; import com.viaversion.viaversion.exception.InformativeException; -import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4; @@ -46,6 +46,7 @@ import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundConfi import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2; import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundConfigurationPackets1_20_2; import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import java.util.UUID; @@ -54,6 +55,7 @@ public final class Protocol1_20_2To1_20 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TagRewriter tagRewriter = new TagRewriter<>(this); public Protocol1_20_2To1_20() { @@ -71,12 +73,14 @@ public final class Protocol1_20_2To1_20 extends BackwardsProtocol { final int slot = wrapper.read(Types.VAR_INT); wrapper.write(Types.BYTE, (byte) slot); }); - registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), wrapper -> { + registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> { // We can't set the internal state to configuration here as protocols down the line will expect the state to be play // Add this *before* sending the ack since the server might immediately answer wrapper.user().put(new ConfigurationPacketStorage()); @@ -88,7 +92,7 @@ public final class Protocol1_20_2To1_20 extends BackwardsProtocol { + registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION, wrapper -> { wrapper.cancel(); wrapper.user().getProtocolInfo().setServerState(State.PLAY); wrapper.user().get(ConfigurationPacketStorage.class).setFinished(true); @@ -97,7 +101,7 @@ public final class Protocol1_20_2To1_20 extends BackwardsProtocol { + registerServerbound(State.LOGIN, ServerboundLoginPackets.HELLO, wrapper -> { wrapper.passthrough(Types.STRING); // Name // TODO Bad @@ -225,6 +229,11 @@ public final class Protocol1_20_2To1_20 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TagRewriter getTagRewriter() { return tagRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/BlockItemPacketRewriter1_20_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/BlockItemPacketRewriter1_20_2.java index f2baf774..15bede89 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/BlockItemPacketRewriter1_20_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/BlockItemPacketRewriter1_20_2.java @@ -26,7 +26,6 @@ import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20; import com.viaversion.viabackwards.protocol.v1_20_2to1_20.provider.AdvancementCriteriaProvider; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.data.ParticleMappings; import com.viaversion.viaversion.api.data.entity.EntityTracker; import com.viaversion.viaversion.api.minecraft.ChunkPosition; import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity; @@ -70,7 +69,6 @@ public final class BlockItemPacketRewriter1_20_2 extends BackwardsItemRewriter { diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java index d4445f65..15efccdd 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/rewriter/EntityPacketRewriter1_20_2.java @@ -108,7 +108,7 @@ public final class EntityPacketRewriter1_20_2 extends EntityRewriter { - final ConfigurationPacketStorage configurationPacketStorage = wrapper.user().remove(ConfigurationPacketStorage.class); + final ConfigurationPacketStorage configurationPacketStorage = wrapper.user().get(ConfigurationPacketStorage.class); wrapper.passthrough(Types.INT); // Entity id wrapper.passthrough(Types.BOOLEAN); // Hardcore diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/storage/ConfigurationPacketStorage.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/storage/ConfigurationPacketStorage.java index a3952ac4..41cde0cf 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/storage/ConfigurationPacketStorage.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_2to1_20/storage/ConfigurationPacketStorage.java @@ -18,13 +18,13 @@ package com.viaversion.viabackwards.protocol.v1_20_2to1_20.storage; import com.google.common.base.Preconditions; +import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20; import com.viaversion.viaversion.api.connection.StorableObject; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.protocol.packet.PacketType; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4; -import com.viaversion.nbt.tag.CompoundTag; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.util.ArrayList; @@ -77,17 +77,21 @@ public final class ConfigurationPacketStorage implements StorableObject { public void sendQueuedPackets(final UserConnection connection) { // Send resource pack at the end + List packets = rawPackets; if (resourcePack != null) { - rawPackets.add(resourcePack); + packets = new ArrayList<>(rawPackets); + packets.add(resourcePack); resourcePack = null; } - for (final QueuedPacket queuedPacket : rawPackets) { + for (final QueuedPacket queuedPacket : packets) { + // Don't clear the list or use the original buffer, we might need them later if a server skips subsequent config phases + final ByteBuf buf = queuedPacket.buf().copy(); try { - final PacketWrapper packet = PacketWrapper.create(queuedPacket.packetType(), queuedPacket.buf(), connection); + final PacketWrapper packet = PacketWrapper.create(queuedPacket.packetType(), buf, connection); packet.send(Protocol1_20_2To1_20.class); } finally { - queuedPacket.buf().release(); + buf.release(); } } } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_3to1_20_2/Protocol1_20_3To1_20_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_3to1_20_2/Protocol1_20_3To1_20_2.java index 40b72057..699c2b89 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_3to1_20_2/Protocol1_20_3To1_20_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_3to1_20_2/Protocol1_20_3To1_20_2.java @@ -17,6 +17,7 @@ */ package com.viaversion.viabackwards.protocol.v1_20_3to1_20_2; +import com.viaversion.nbt.tag.Tag; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.rewriters.SoundRewriter; @@ -36,21 +37,21 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.libs.fastutil.Pair; -import com.viaversion.nbt.tag.Tag; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter.CommandRewriter1_19_4; -import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundConfigurationPackets1_20_2; -import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPacket1_20_2; -import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2; -import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundConfigurationPackets1_20_2; -import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPacket1_20_2; -import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundConfigurationPackets1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPacket1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ClientboundPackets1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPacket1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPackets1_20_3; +import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundConfigurationPackets1_20_2; +import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPacket1_20_2; +import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2; +import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundConfigurationPackets1_20_2; +import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPacket1_20_2; +import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ServerboundPackets1_20_2; import com.viaversion.viaversion.rewriter.ComponentRewriter.ReadType; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.ComponentUtil; @@ -64,6 +65,7 @@ public final class Protocol1_20_3To1_20_2 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ReadType.NBT); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -283,7 +285,7 @@ public final class Protocol1_20_3To1_20_2 extends BackwardsProtocol { - final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM); + final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM1_19_3); final int entries = wrapper.passthrough(Types.VAR_INT); for (int i = 0; i < entries; i++) { wrapper.passthrough(Types.UUID); @@ -392,6 +394,11 @@ public final class Protocol1_20_3To1_20_2 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public EntityPacketRewriter1_20_3 getEntityRewriter() { return entityRewriter; @@ -416,4 +423,4 @@ public final class Protocol1_20_3To1_20_2 extends BackwardsProtocol { @@ -87,7 +85,7 @@ public final class BlockItemPacketRewriter1_20_3 extends BackwardsItemRewriter particleRewriter = new ParticleRewriter<>(this); private final TranslatableRewriter translatableRewriter = new TranslatableRewriter<>(this, ReadType.NBT); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -109,6 +111,7 @@ public final class Protocol1_20_5To1_20_3 extends BackwardsProtocol { @@ -157,7 +160,7 @@ public final class Protocol1_20_5To1_20_3 extends BackwardsProtocol { + registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> { wrapper.passthrough(Types.UUID); // UUID wrapper.passthrough(Types.STRING); // Name @@ -246,6 +249,11 @@ public final class Protocol1_20_5To1_20_3 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TranslatableRewriter getComponentRewriter() { return translatableRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java index 86f6e4a3..d3072043 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java @@ -30,7 +30,6 @@ import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.Holder; import com.viaversion.viaversion.api.minecraft.Particle; import com.viaversion.viaversion.api.minecraft.SoundEvent; -import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; @@ -41,7 +40,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_20_3; import com.viaversion.viaversion.api.type.types.version.Types1_20_5; -import com.viaversion.viaversion.libs.fastutil.ints.Int2IntFunction; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPacket1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPackets1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; @@ -109,7 +107,7 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem // Move it to the beginning, move out arguments here final Particle particle = wrapper.read(Types1_20_5.PARTICLE); - rewriteParticle(wrapper.user(), particle); + protocol.getParticleRewriter().rewriteParticle(wrapper.user(), particle); if (particle.id() == protocol.getMappingData().getParticleMappings().mappedId("entity_effect")) { // Remove color argument final int color = particle.removeArgument(0).getValue(); @@ -145,8 +143,8 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem final Particle smallExplosionParticle = wrapper.passthroughAndMap(Types1_20_5.PARTICLE, Types1_20_3.PARTICLE); final Particle largeExplosionParticle = wrapper.passthroughAndMap(Types1_20_5.PARTICLE, Types1_20_3.PARTICLE); - rewriteParticle(wrapper.user(), smallExplosionParticle); - rewriteParticle(wrapper.user(), largeExplosionParticle); + protocol.getParticleRewriter().rewriteParticle(wrapper.user(), smallExplosionParticle); + protocol.getParticleRewriter().rewriteParticle(wrapper.user(), largeExplosionParticle); final Holder soundEventHolder = wrapper.read(Types.SOUND_EVENT); if (soundEventHolder.isDirect()) { @@ -355,27 +353,38 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem return null; } + final StructuredDataContainer data = item.dataContainer(); item.dataContainer().setIdLookup(protocol, true); enchantmentRewriter.handleToClient(item); super.handleItemToClient(connection, item); + // Text components since we skip the usual rewrite method + updateComponent(connection, item, StructuredDataKey.ITEM_NAME, "item_name"); + updateComponent(connection, item, StructuredDataKey.CUSTOM_NAME, "custom_name"); + final Tag[] lore = data.get(StructuredDataKey.LORE); + if (lore != null) { + for (final Tag tag : lore) { + protocol.getComponentRewriter().processTag(connection, tag); + } + } + // In 1.20.6, some items have default values which are not written into the components - final StructuredDataContainer data = item.dataContainer(); - if (item.identifier() == 1105 && !data.contains(StructuredDataKey.FIREWORKS)) { + if (item.identifier() == 1105 && !data.has(StructuredDataKey.FIREWORKS)) { data.set(StructuredDataKey.FIREWORKS, new Fireworks(1, new FireworkExplosion[0])); } - final StructuredData customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA); + final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); final Item oldItem = vvProtocol.getItemRewriter().toOldItem(connection, item, DATA_CONVERTER); if (customData != null) { // We later don't know which tags are custom data and which are not because the VV conversion // keeps converted data, so we backup the original custom data and restore it later - oldItem.tag().put(nbtTagName(), customData.value().copy()); - } - - if (oldItem.tag() != null && oldItem.tag().isEmpty()) { + if (oldItem.tag() == null) { + oldItem.setTag(new CompoundTag()); + } + oldItem.tag().put(nbtTagName(), customData.copy()); + } else if (oldItem.tag() != null && oldItem.tag().isEmpty()) { // Improve item equality checks by removing empty tags oldItem.setTag(null); } @@ -383,7 +392,7 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem } @Override - protected void updateItemComponents(final UserConnection connection, final StructuredDataContainer container, final ItemHandler itemHandler, @Nullable final Int2IntFunction idRewriter, @Nullable final Int2IntFunction blockIdRewriter) { + protected void updateItemDataComponents(final UserConnection connection, final Item item, final boolean clientbound) { // Items and data within components are handled in this protocol } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/EntityPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/EntityPacketRewriter1_20_5.java index 4104f7c8..9775c982 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/EntityPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20_5to1_20_3/rewriter/EntityPacketRewriter1_20_5.java @@ -77,9 +77,12 @@ public final class EntityPacketRewriter1_20_5 extends EntityRewriter { @@ -240,14 +243,26 @@ public final class EntityPacketRewriter1_20_5 extends EntityRewriter { wrapper.passthrough(Types.VAR_INT); // Entity ID - wrapper.passthrough(Types.VAR_INT); // Effect ID + final int effectId = wrapper.passthrough(Types.VAR_INT); final int amplifier = wrapper.read(Types.VAR_INT); wrapper.write(Types.BYTE, (byte) MathUtil.clamp(amplifier, Byte.MIN_VALUE, Byte.MAX_VALUE)); wrapper.passthrough(Types.VAR_INT); // Duration wrapper.passthrough(Types.BYTE); // Flags - wrapper.write(Types.OPTIONAL_COMPOUND_TAG, null); // Add empty factor data + + if (effectId == 32) { // Darkness, keep a stable effect + final CompoundTag factorData = new CompoundTag(); + factorData.putInt("padding_duration", 22); + factorData.putBoolean("had_effect_last_tick", true); + factorData.putFloat("factor_previous_frame", 0); + factorData.putFloat("factor_start", 1); + factorData.putFloat("factor_target", 1); + factorData.putFloat("factor_current", 1); + wrapper.write(Types.OPTIONAL_COMPOUND_TAG, factorData); + } else { + wrapper.write(Types.OPTIONAL_COMPOUND_TAG, null); + } }); protocol.registerClientbound(ClientboundPackets1_20_5.UPDATE_ATTRIBUTES, wrapper -> { diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/Protocol1_20To1_19_4.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/Protocol1_20To1_19_4.java index e8a941ae..cadae68d 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/Protocol1_20To1_19_4.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/Protocol1_20To1_19_4.java @@ -26,12 +26,12 @@ import com.viaversion.viabackwards.protocol.v1_20to1_19_4.rewriter.EntityPacketR import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.RegistryType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_19_4; -import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4; import com.viaversion.viaversion.rewriter.ComponentRewriter; +import com.viaversion.viaversion.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.ArrayUtil; @@ -42,6 +42,7 @@ public final class Protocol1_20To1_19_4 extends BackwardsProtocol translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON); private final EntityPacketRewriter1_20 entityRewriter = new EntityPacketRewriter1_20(this); private final BlockItemPacketRewriter1_20 itemRewriter = new BlockItemPacketRewriter1_20(this); + private final ParticleRewriter particleRewriter = new ParticleRewriter<>(this); private final TagRewriter tagRewriter = new TagRewriter<>(this); public Protocol1_20To1_19_4() { @@ -60,6 +61,8 @@ public final class Protocol1_20To1_19_4 extends BackwardsProtocol(this).register(ClientboundPackets1_19_4.AWARD_STATS); translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.SET_ACTION_BAR_TEXT); @@ -108,6 +111,11 @@ public final class Protocol1_20To1_19_4 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TranslatableRewriter getComponentRewriter() { return translatableRewriter; @@ -117,4 +125,4 @@ public final class Protocol1_20To1_19_4 extends BackwardsProtocol getTagRewriter() { return tagRewriter; } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/rewriter/BlockItemPacketRewriter1_20.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/rewriter/BlockItemPacketRewriter1_20.java index a25f34da..7d9e4d6d 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/rewriter/BlockItemPacketRewriter1_20.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_20to1_19_4/rewriter/BlockItemPacketRewriter1_20.java @@ -17,6 +17,10 @@ */ package com.viaversion.viabackwards.protocol.v1_20to1_19_4.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.viabackwards.api.rewriters.BackwardsItemRewriter; import com.viaversion.viabackwards.protocol.v1_20to1_19_4.Protocol1_20To1_19_4; import com.viaversion.viabackwards.protocol.v1_20to1_19_4.storage.BackSignEditStorage; @@ -28,10 +32,6 @@ import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_18; -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.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4; import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.rewriter.RecipeRewriter1_19_4; @@ -100,7 +100,6 @@ public final class BlockItemPacketRewriter1_20 extends BackwardsItemRewriter { wrapper.passthrough(Types.BOOLEAN); // Reset/clear @@ -232,4 +231,4 @@ public final class BlockItemPacketRewriter1_20 extends BackwardsItemRewriter. + */ +package com.viaversion.viabackwards.protocol.v1_21_2to1_21; + +import com.viaversion.viabackwards.api.BackwardsProtocol; +import com.viaversion.viabackwards.api.data.BackwardsMappingData; +import com.viaversion.viabackwards.api.rewriters.SoundRewriter; +import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter.BlockItemPacketRewriter1_21_2; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter.ComponentRewriter1_21_2; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter.EntityPacketRewriter1_21_2; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter.ParticleRewriter1_21_2; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryStateIdStorage; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.ItemTagStorage; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.packet.State; +import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; +import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.data.entity.EntityTrackerBase; +import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; +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.ClientboundPacket1_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.ServerboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; +import com.viaversion.viaversion.rewriter.AttributeRewriter; +import com.viaversion.viaversion.rewriter.StatisticsRewriter; +import com.viaversion.viaversion.rewriter.TagRewriter; +import com.viaversion.viaversion.util.ArrayUtil; + +import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap; + +public final class Protocol1_21_2To1_21 extends BackwardsProtocol { + + public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.21.2", "1.21", Protocol1_21To1_21_2.class); + private final EntityPacketRewriter1_21_2 entityRewriter = new EntityPacketRewriter1_21_2(this); + private final BlockItemPacketRewriter1_21_2 itemRewriter = new BlockItemPacketRewriter1_21_2(this); + private final ParticleRewriter1_21_2 particleRewriter = new ParticleRewriter1_21_2(this); + private final TranslatableRewriter translatableRewriter = new ComponentRewriter1_21_2(this); + private final TagRewriter tagRewriter = new TagRewriter<>(this); + + public Protocol1_21_2To1_21() { + super(ClientboundPacket1_21_2.class, ClientboundPacket1_21.class, ServerboundPacket1_21_2.class, ServerboundPacket1_20_5.class); + } + + @Override + protected void registerPackets() { + super.registerPackets(); + + registerClientbound(ClientboundPackets1_21_2.UPDATE_TAGS, this::storeTags); + registerClientbound(ClientboundConfigurationPackets1_21.UPDATE_TAGS, this::storeTags); + + final SoundRewriter soundRewriter = new SoundRewriter<>(this); + soundRewriter.registerSound1_19_3(ClientboundPackets1_21_2.SOUND); + soundRewriter.registerSound1_19_3(ClientboundPackets1_21_2.SOUND_ENTITY); + soundRewriter.registerStopSound(ClientboundPackets1_21_2.STOP_SOUND); + + particleRewriter.registerLevelParticles1_20_5(ClientboundPackets1_21_2.LEVEL_PARTICLES); + + new StatisticsRewriter<>(this).register(ClientboundPackets1_21_2.AWARD_STATS); + new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21_2.UPDATE_ATTRIBUTES); + + translatableRewriter.registerOpenScreen(ClientboundPackets1_21_2.OPEN_SCREEN); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_ACTION_BAR_TEXT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_TITLE_TEXT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SET_SUBTITLE_TEXT); + translatableRewriter.registerBossEvent(ClientboundPackets1_21_2.BOSS_EVENT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISCONNECT); + translatableRewriter.registerTabList(ClientboundPackets1_21_2.TAB_LIST); + translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_2.PLAYER_COMBAT_KILL); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SYSTEM_CHAT); + translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISGUISED_CHAT); + translatableRewriter.registerPing(); + + registerServerbound(ServerboundPackets1_20_5.CLIENT_INFORMATION, this::clientInformation); + registerServerbound(ServerboundConfigurationPackets1_20_5.CLIENT_INFORMATION, this::clientInformation); + + registerClientbound(ClientboundConfigurationPackets1_21.UPDATE_ENABLED_FEATURES, wrapper -> { + final String[] enabledFeatures = wrapper.read(Types.STRING_ARRAY); + wrapper.write(Types.STRING_ARRAY, ArrayUtil.add(enabledFeatures, "bundle")); + }); + + cancelClientbound(ClientboundPackets1_21_2.MOVE_MINECART_ALONG_TRACK); // TODO + + registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, wrapper -> { + wrapper.passthrough(Types.UUID); // UUID + wrapper.passthrough(Types.STRING); // Name + + final int properties = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < properties; i++) { + wrapper.passthrough(Types.STRING); // Name + wrapper.passthrough(Types.STRING); // Value + wrapper.passthrough(Types.OPTIONAL_STRING); // Signature + } + + wrapper.write(Types.BOOLEAN, true); // Strict error handling. Always enabled for newer clients, so mimic that behavior + }); + + registerClientbound(ClientboundPackets1_21_2.SET_TIME, wrapper -> { + wrapper.passthrough(Types.LONG); // Game time + + long dayTime = wrapper.read(Types.LONG); + final boolean daylightCycle = wrapper.read(Types.BOOLEAN); + if (!daylightCycle) { + if (dayTime == 0) { + dayTime = -1; + } else { + dayTime = -dayTime; + } + } + wrapper.write(Types.LONG, dayTime); + }); + } + + private void storeTags(final PacketWrapper wrapper) { + tagRewriter.handleGeneric(wrapper); + wrapper.resetReader(); + wrapper.user().get(ItemTagStorage.class).readItemTags(wrapper); + } + + private void clientInformation(final PacketWrapper wrapper) { + wrapper.passthrough(Types.STRING); // Locale + wrapper.passthrough(Types.BYTE); // View distance + wrapper.passthrough(Types.VAR_INT); // Chat visibility + wrapper.passthrough(Types.BOOLEAN); // Chat colors + wrapper.passthrough(Types.UNSIGNED_BYTE); // Skin parts + wrapper.passthrough(Types.VAR_INT); // Main hand + wrapper.passthrough(Types.BOOLEAN); // Text filtering enabled + wrapper.passthrough(Types.BOOLEAN); // Allow listing + wrapper.write(Types.VAR_INT, 0); // Particle status, assume 'all' + } + + @Override + public void init(final UserConnection user) { + addEntityTracker(user, new EntityTrackerBase(user, EntityTypes1_20_5.PLAYER)); + user.put(new InventoryStateIdStorage()); + user.put(new ItemTagStorage()); + user.put(new RecipeStorage(this)); + user.put(new PlayerStorage()); + } + + @Override + public BackwardsMappingData getMappingData() { + return MAPPINGS; + } + + @Override + public EntityPacketRewriter1_21_2 getEntityRewriter() { + return entityRewriter; + } + + @Override + public BlockItemPacketRewriter1_21_2 getItemRewriter() { + return itemRewriter; + } + + @Override + public ParticleRewriter1_21_2 getParticleRewriter() { + return particleRewriter; + } + + @Override + public TranslatableRewriter getComponentRewriter() { + return translatableRewriter; + } + + @Override + public TagRewriter getTagRewriter() { + return tagRewriter; + } + + @Override + protected PacketTypesProvider createPacketTypesProvider() { + return new SimplePacketTypesProvider<>( + packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class), + packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class), + packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class), + packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class) + ); + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java new file mode 100644 index 00000000..3f4c08d6 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java @@ -0,0 +1,264 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.rewriter; + +import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryStateIdStorage; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.data.MappingData; +import com.viaversion.viaversion.api.minecraft.Particle; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +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_3to1_20_5.packet.ServerboundPacket1_20_5; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2; +import com.viaversion.viaversion.rewriter.BlockRewriter; +import com.viaversion.viaversion.rewriter.SoundRewriter; +import com.viaversion.viaversion.util.Key; + +import static com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2.downgradeItemData; +import static com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2.updateItemData; + +public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItemRewriter { + + public BlockItemPacketRewriter1_21_2(final Protocol1_21_2To1_21 protocol) { + super(protocol, + Types1_21_2.ITEM, Types1_21_2.ITEM_ARRAY, Types1_21.ITEM, Types1_21.ITEM_ARRAY, + Types1_21_2.ITEM_COST, Types1_21_2.OPTIONAL_ITEM_COST, Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST + ); + } + + @Override + public void registerPackets() { + final BlockRewriter blockRewriter = BlockRewriter.for1_20_2(protocol); + blockRewriter.registerBlockEvent(ClientboundPackets1_21_2.BLOCK_EVENT); + blockRewriter.registerBlockUpdate(ClientboundPackets1_21_2.BLOCK_UPDATE); + blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE); + blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_2.LEVEL_EVENT, 2001); + blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new); + blockRewriter.registerBlockEntityData(ClientboundPackets1_21_2.BLOCK_ENTITY_DATA); + + registerAdvancements1_20_3(ClientboundPackets1_21_2.UPDATE_ADVANCEMENTS); + registerSetEquipment(ClientboundPackets1_21_2.SET_EQUIPMENT); + registerMerchantOffers1_20_5(ClientboundPackets1_21_2.MERCHANT_OFFERS); + registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT); + + protocol.registerClientbound(ClientboundPackets1_21_2.COOLDOWN, wrapper -> { + final MappingData mappingData = protocol.getMappingData(); + final String itemIdentifier = wrapper.read(Types.STRING); + final int id = mappingData.getFullItemMappings().id(itemIdentifier); + if (id != -1) { + final int mappedId = mappingData.getFullItemMappings().getNewId(id); + wrapper.write(Types.VAR_INT, mappedId); + } else { + wrapper.cancel(); + } + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.SET_CURSOR_ITEM, ClientboundPackets1_21.CONTAINER_SET_SLOT, wrapper -> { + wrapper.write(Types.UNSIGNED_BYTE, (short) -1); // Player inventory + wrapper.write(Types.VAR_INT, wrapper.user().get(InventoryStateIdStorage.class).stateId()); // State id; re-use the last known one + wrapper.write(Types.SHORT, (short) -1); // Cursor + final Item item = wrapper.passthrough(Types1_21_2.ITEM); + handleItemToClient(wrapper.user(), item); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.CONTAINER_SET_CONTENT, wrapper -> { + updateContainerId(wrapper); + + final int stateId = wrapper.passthrough(Types.VAR_INT); + wrapper.user().get(InventoryStateIdStorage.class).setStateId(stateId); + + 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]); + } + passthroughClientboundItem(wrapper); + }); + protocol.registerClientbound(ClientboundPackets1_21_2.CONTAINER_SET_SLOT, wrapper -> { + updateContainerId(wrapper); + + final int stateId = wrapper.passthrough(Types.VAR_INT); + wrapper.user().get(InventoryStateIdStorage.class).setStateId(stateId); + + wrapper.passthrough(Types.SHORT); // Slot id + passthroughClientboundItem(wrapper); + }); + protocol.registerClientbound(ClientboundPackets1_21_2.SET_HELD_SLOT, ClientboundPackets1_21.SET_CARRIED_ITEM); + protocol.registerClientbound(ClientboundPackets1_21_2.CONTAINER_CLOSE, this::updateContainerId); + protocol.registerClientbound(ClientboundPackets1_21_2.CONTAINER_SET_DATA, this::updateContainerId); + protocol.registerClientbound(ClientboundPackets1_21_2.HORSE_SCREEN_OPEN, this::updateContainerId); + protocol.registerServerbound(ServerboundPackets1_20_5.CONTAINER_CLOSE, this::updateContainerIdServerbound); + protocol.registerServerbound(ServerboundPackets1_20_5.CONTAINER_CLICK, wrapper -> { + updateContainerIdServerbound(wrapper); + wrapper.passthrough(Types.VAR_INT); // State id + wrapper.passthrough(Types.SHORT); // Slot + wrapper.passthrough(Types.BYTE); // Button + wrapper.passthrough(Types.VAR_INT); // Mode + final int length = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < length; i++) { + wrapper.passthrough(Types.SHORT); // Slot + passthroughServerboundItem(wrapper); + } + passthroughServerboundItem(wrapper); + }); + + protocol.registerServerbound(ServerboundPackets1_20_5.USE_ITEM_ON, wrapper -> { + wrapper.passthrough(Types.VAR_INT); // Hand + wrapper.passthrough(Types.BLOCK_POSITION1_14); // Block position + wrapper.passthrough(Types.VAR_INT); // Direction + wrapper.passthrough(Types.FLOAT); // X + wrapper.passthrough(Types.FLOAT); // Y + wrapper.passthrough(Types.FLOAT); // Z + wrapper.passthrough(Types.BOOLEAN); // Inside + wrapper.write(Types.BOOLEAN, false); // World border hit + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.SET_PLAYER_INVENTORY, ClientboundPackets1_21.CONTAINER_SET_SLOT, wrapper -> { + wrapper.write(Types.UNSIGNED_BYTE, (short) -2); // Player inventory + wrapper.write(Types.VAR_INT, 0); // 0 state id + final int slot = wrapper.read(Types.VAR_INT); + wrapper.write(Types.SHORT, (short) slot); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.EXPLODE, wrapper -> { + wrapper.passthrough(Types.DOUBLE); // Center X + wrapper.passthrough(Types.DOUBLE); // Center Y + wrapper.passthrough(Types.DOUBLE); // Center Z + + // The server will already send block changes separately + wrapper.write(Types.FLOAT, 0F); // Power + wrapper.write(Types.VAR_INT, 0); // No blocks affected + + double knockbackX = 0; + double knockbackY = 0; + double knockbackZ = 0; + if (wrapper.read(Types.BOOLEAN)) { + knockbackX = wrapper.read(Types.DOUBLE); + knockbackY = wrapper.read(Types.DOUBLE); + knockbackZ = wrapper.read(Types.DOUBLE); + } + wrapper.write(Types.FLOAT, (float) knockbackX); + wrapper.write(Types.FLOAT, (float) knockbackY); + wrapper.write(Types.FLOAT, (float) knockbackZ); + + wrapper.write(Types.VAR_INT, 0); // Block interaction type + + final Particle explosionParticle = wrapper.read(Types1_21.PARTICLE); + protocol.getParticleRewriter().rewriteParticle(wrapper.user(), explosionParticle); + // As small and large explosion particle + wrapper.write(Types1_21_2.PARTICLE, explosionParticle); + wrapper.write(Types1_21_2.PARTICLE, explosionParticle); + + new SoundRewriter<>(protocol).soundHolderHandler().handle(wrapper); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.RECIPE_BOOK_ADD, null, wrapper -> { + final RecipeStorage recipeStorage = wrapper.user().get(RecipeStorage.class); + final int size = wrapper.read(Types.VAR_INT); + for (int i = 0; i < size; i++) { + recipeStorage.readRecipe(wrapper); + } + + final boolean replace = wrapper.read(Types.BOOLEAN); + if (replace) { + recipeStorage.clearRecipes(); + } + + recipeStorage.sendRecipes(wrapper.user()); + wrapper.cancel(); + }); + protocol.registerClientbound(ClientboundPackets1_21_2.RECIPE_BOOK_REMOVE, ClientboundPackets1_21.RECIPE, wrapper -> { + final RecipeStorage recipeStorage = wrapper.user().get(RecipeStorage.class); + final int[] ids = wrapper.read(Types.VAR_INT_ARRAY_PRIMITIVE); + recipeStorage.lockRecipes(wrapper, ids); + }); + protocol.registerClientbound(ClientboundPackets1_21_2.RECIPE_BOOK_SETTINGS, null, wrapper -> { + final RecipeStorage recipeStorage = wrapper.user().get(RecipeStorage.class); + final boolean[] settings = new boolean[RecipeStorage.RECIPE_BOOK_SETTINGS]; + for (int i = 0; i < RecipeStorage.RECIPE_BOOK_SETTINGS; i++) { + settings[i] = wrapper.read(Types.BOOLEAN); + } + recipeStorage.setRecipeBookSettings(settings); + + wrapper.cancel(); + }); + protocol.registerClientbound(ClientboundPackets1_21_2.UPDATE_RECIPES, wrapper -> { + // Inputs for furnaces etc. Old clients get these from the full recipes + final int size = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < size; i++) { + wrapper.read(Types.STRING); // Recipe group + wrapper.read(Types.VAR_INT_ARRAY_PRIMITIVE); // Items + } + + final RecipeStorage recipeStorage = wrapper.user().get(RecipeStorage.class); + recipeStorage.readStoneCutterRecipes(wrapper); + + // Send later with the recipe book init + wrapper.cancel(); + }); + protocol.registerClientbound(ClientboundPackets1_21_2.PLACE_GHOST_RECIPE, wrapper -> { + this.updateContainerId(wrapper); + wrapper.cancel(); // Full recipe display, this doesn't look mappable + }); + protocol.registerServerbound(ServerboundPackets1_20_5.PLACE_RECIPE, wrapper -> { + this.updateContainerIdServerbound(wrapper); + + final String recipe = Key.stripMinecraftNamespace(wrapper.read(Types.STRING)); + wrapper.write(Types.VAR_INT, Integer.parseInt(recipe)); + }); + protocol.registerServerbound(ServerboundPackets1_20_5.RECIPE_BOOK_SEEN_RECIPE, wrapper -> { + final String recipe = Key.stripMinecraftNamespace(wrapper.read(Types.STRING)); + wrapper.write(Types.VAR_INT, Integer.parseInt(recipe)); + }); + } + + private void updateContainerId(final PacketWrapper wrapper) { + final int containerId = wrapper.read(Types.VAR_INT); + wrapper.write(Types.UNSIGNED_BYTE, (short) containerId); + } + + private void updateContainerIdServerbound(final PacketWrapper wrapper) { + final short containerId = wrapper.read(Types.UNSIGNED_BYTE); + final int intId = (byte) containerId; + wrapper.write(Types.VAR_INT, intId); + } + + @Override + public Item handleItemToClient(final UserConnection connection, final Item item) { + super.handleItemToClient(connection, item); + downgradeItemData(item); + return item; + } + + @Override + public Item handleItemToServer(final UserConnection connection, final Item item) { + super.handleItemToServer(connection, item); + updateItemData(item); + return item; + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/ComponentRewriter1_21_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/ComponentRewriter1_21_2.java new file mode 100644 index 00000000..acc69d51 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/ComponentRewriter1_21_2.java @@ -0,0 +1,75 @@ +/* + * 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.viabackwards.protocol.v1_21_2to1_21.rewriter; + +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2; +import com.viaversion.viaversion.util.SerializerVersion; +import com.viaversion.viaversion.util.TagUtil; + +public final class ComponentRewriter1_21_2 extends TranslatableRewriter { + + public ComponentRewriter1_21_2(final Protocol1_21_2To1_21 protocol) { + super(protocol, ReadType.NBT); + } + + @Override + protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) { + super.handleShowItem(connection, itemTag, componentsTag); + if (componentsTag == null) { + return; + } + + com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.ComponentRewriter1_21_2.convertAttributes(componentsTag, protocol.getMappingData().getAttributeMappings()); + + final CompoundTag instrument = TagUtil.getNamespacedCompoundTag(componentsTag, "instrument"); + if (instrument != null) { + instrument.remove("description"); + } + + final CompoundTag useRemainder = TagUtil.getNamespacedCompoundTag(componentsTag, "use_remainder"); + final CompoundTag food = TagUtil.getNamespacedCompoundTag(componentsTag, "food"); + if (food != null) { + if (useRemainder != null) { + food.put("using_converts_to", useRemainder); + } + food.putFloat("eat_seconds", 1.6F); + } + + TagUtil.removeNamespaced(componentsTag, "repairable"); + TagUtil.removeNamespaced(componentsTag, "enchantable"); + TagUtil.removeNamespaced(componentsTag, "consumable"); + TagUtil.removeNamespaced(componentsTag, "use_remainder"); + TagUtil.removeNamespaced(componentsTag, "use_cooldown"); + TagUtil.removeNamespaced(componentsTag, "item_model"); + TagUtil.removeNamespaced(componentsTag, "equippable"); + TagUtil.removeNamespaced(componentsTag, "glider"); + TagUtil.removeNamespaced(componentsTag, "tooltip_style"); + TagUtil.removeNamespaced(componentsTag, "death_protection"); + TagUtil.removeNamespaced(componentsTag, "damage_resistant"); + TagUtil.removeNamespaced(componentsTag, "lock"); + } + + @Override + protected SerializerVersion inputSerializerVersion() { + return SerializerVersion.V1_20_5; + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/EntityPacketRewriter1_21_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/EntityPacketRewriter1_21_2.java new file mode 100644 index 00000000..0b19f6ac --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/EntityPacketRewriter1_21_2.java @@ -0,0 +1,609 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.rewriter; + +import com.viaversion.nbt.tag.Tag; +import com.viaversion.viabackwards.ViaBackwards; +import com.viaversion.viabackwards.api.rewriters.EntityRewriter; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage; +import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.minecraft.Particle; +import com.viaversion.viaversion.api.minecraft.RegistryEntry; +import com.viaversion.viaversion.api.minecraft.SoundEvent; +import com.viaversion.viaversion.api.minecraft.entities.EntityType; +import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_2; +import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; +import com.viaversion.viaversion.api.type.Types; +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_3to1_20_5.packet.ServerboundPackets1_20_5; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_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.RegistryDataRewriter; +import com.viaversion.viaversion.util.Key; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +public final class EntityPacketRewriter1_21_2 extends EntityRewriter { + + private static final int REL_X = 0; + private static final int REL_Y = 1; + private static final int REL_Z = 2; + private static final int REL_Y_ROT = 3; + private static final int REL_X_ROT = 4; + private static final int REL_DELTA_X = 5; + private static final int REL_DELTA_Y = 6; + private static final int REL_DELTA_Z = 7; + private static final int REL_ROTATE_DELTA = 8; + private boolean warned = ViaBackwards.getConfig().suppressEmulationWarnings(); + + public EntityPacketRewriter1_21_2(final Protocol1_21_2To1_21 protocol) { + super(protocol, Types1_21.ENTITY_DATA_TYPES.optionalComponentType, Types1_21.ENTITY_DATA_TYPES.booleanType); + } + + @Override + public void registerPackets() { + registerSetEntityData(ClientboundPackets1_21_2.SET_ENTITY_DATA, Types1_21_2.ENTITY_DATA_LIST, Types1_21.ENTITY_DATA_LIST); + registerRemoveEntities(ClientboundPackets1_21_2.REMOVE_ENTITIES); + protocol.registerClientbound(ClientboundPackets1_21_2.ADD_ENTITY, wrapper -> { + final int entityId = wrapper.passthrough(Types.VAR_INT); + wrapper.passthrough(Types.UUID); // Entity UUID + final int entityTypeId = wrapper.passthrough(Types.VAR_INT); + wrapper.passthrough(Types.DOUBLE); // X + wrapper.passthrough(Types.DOUBLE); // Y + wrapper.passthrough(Types.DOUBLE); // Z + wrapper.passthrough(Types.BYTE); // Pitch + wrapper.passthrough(Types.BYTE); // Yaw + wrapper.passthrough(Types.BYTE); // Head yaw + wrapper.passthrough(Types.VAR_INT); // Data + getSpawnTrackerWithDataHandler1_19(EntityTypes1_21_2.FALLING_BLOCK).handle(wrapper); + + final EntityType type = EntityTypes1_21_2.getTypeFromId(entityTypeId); + if (type.isOrHasParent(EntityTypes1_21_2.ABSTRACT_BOAT)) { + wrapper.send(Protocol1_21_2To1_21.class); + wrapper.cancel(); + + // Add boat type to entity data + final List data = new ArrayList<>(); + final int boatType = type.isOrHasParent(EntityTypes1_21_2.ABSTRACT_CHEST_BOAT) ? chestBoatTypeFromEntityType(type) : boatTypeFromEntityType(type); + data.add(new EntityData(11, Types1_21.ENTITY_DATA_TYPES.varIntType, boatType)); + + final PacketWrapper entityDataPacket = wrapper.create(ClientboundPackets1_21.SET_ENTITY_DATA); + entityDataPacket.write(Types.VAR_INT, entityId); + entityDataPacket.write(Types1_21.ENTITY_DATA_LIST, data); + entityDataPacket.send(Protocol1_21_2To1_21.class); + } + }); + + final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol); + registryDataRewriter.addEnchantmentEffectRewriter("change_item_damage", tag -> tag.putString("type", "damage_item")); + protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> { + final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING)); + if (registryKey.equals("instrument")) { + wrapper.cancel(); + return; + } + + final RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY); + wrapper.write(Types.REGISTRY_ENTRY_ARRAY, registryDataRewriter.handle(wrapper.user(), registryKey, entries)); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.LOGIN, new PacketHandlers() { + @Override + public void register() { + map(Types.INT); // Entity id + map(Types.BOOLEAN); // Hardcore + map(Types.STRING_ARRAY); // World List + map(Types.VAR_INT); // Max players + map(Types.VAR_INT); // View distance + map(Types.VAR_INT); // Simulation distance + map(Types.BOOLEAN); // Reduced debug info + map(Types.BOOLEAN); // Show death screen + map(Types.BOOLEAN); // Limited crafting + map(Types.VAR_INT); // Dimension key + map(Types.STRING); // World + map(Types.LONG); // Seed + map(Types.BYTE); // Gamemode + map(Types.BYTE); // Previous gamemode + map(Types.BOOLEAN); // Debug + map(Types.BOOLEAN); // Flat + map(Types.OPTIONAL_GLOBAL_POSITION); // Last death location + map(Types.VAR_INT); // Portal cooldown + handler(worldDataTrackerHandlerByKey1_20_5(3)); + handler(playerTrackerHandler()); + read(Types.VAR_INT); // Sea level + } + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.RESPAWN, wrapper -> { + final int dimensionId = wrapper.passthrough(Types.VAR_INT); + final String world = wrapper.passthrough(Types.STRING); + wrapper.passthrough(Types.LONG); // Seed + wrapper.passthrough(Types.BYTE); // Gamemode + wrapper.passthrough(Types.BYTE); // Previous gamemode + wrapper.passthrough(Types.BOOLEAN); // Debug + wrapper.passthrough(Types.BOOLEAN); // Flat + wrapper.passthrough(Types.OPTIONAL_GLOBAL_POSITION); // Last death location + wrapper.passthrough(Types.VAR_INT); // Portal cooldown + + wrapper.read(Types.VAR_INT); // Sea level + trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.ENTITY_POSITION_SYNC, ClientboundPackets1_21.TELEPORT_ENTITY, 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.read(Types.DOUBLE); // Delta movement X + wrapper.read(Types.DOUBLE); // Delta movement Y + wrapper.read(Types.DOUBLE); // Delta movement Z + + final float yaw = wrapper.read(Types.FLOAT); + final float pitch = wrapper.read(Types.FLOAT); + writePackedRotation(wrapper, yaw, pitch); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_ROTATION, ClientboundPackets1_21.PLAYER_LOOK_AT, wrapper -> { + final float yaw = wrapper.passthrough(Types.FLOAT); + final float pitch = wrapper.passthrough(Types.FLOAT); + + final double yRadians = Math.toRadians(yaw); + final double xRadians = Math.toRadians(pitch); + + final double factor = -Math.cos(-xRadians); + final double deltaX = Math.sin(-yRadians - (float) Math.PI) * factor; + final double deltaY = Math.sin(-xRadians); + final double deltaZ = Math.cos(-yRadians - (float) Math.PI) * factor; + + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + wrapper.write(Types.VAR_INT, 0); // From anchor + wrapper.write(Types.DOUBLE, storage.x() + deltaX); // X + wrapper.write(Types.DOUBLE, storage.y() + deltaY); // Y + wrapper.write(Types.DOUBLE, storage.z() + deltaZ); // Z + wrapper.write(Types.BOOLEAN, false); // At entity + + final PacketWrapper entityMotionPacket = PacketWrapper.create(ServerboundPackets1_21_2.MOVE_PLAYER_ROT, wrapper.user()); + entityMotionPacket.write(Types.FLOAT, yaw); + entityMotionPacket.write(Types.FLOAT, pitch); + entityMotionPacket.write(Types.UNSIGNED_BYTE, (short) 0); // On ground and horizontal collision + entityMotionPacket.sendToServer(Protocol1_21_2To1_21.class); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.TELEPORT_ENTITY, wrapper -> { + wrapper.passthrough(Types.VAR_INT); // Entity ID + final double x = wrapper.passthrough(Types.DOUBLE); + final double y = wrapper.passthrough(Types.DOUBLE); + final double z = wrapper.passthrough(Types.DOUBLE); + + final double movementX = wrapper.read(Types.DOUBLE); + final double movementY = wrapper.read(Types.DOUBLE); + final double movementZ = wrapper.read(Types.DOUBLE); + + final float yaw = wrapper.read(Types.FLOAT); + final float pitch = wrapper.read(Types.FLOAT); + writePackedRotation(wrapper, yaw, pitch); + + final int relativeArguments = wrapper.read(Types.INT); + + // Send alongside separate entity motion + wrapper.send(Protocol1_21_2To1_21.class); + wrapper.cancel(); + + handleRelativeArguments(wrapper, x, y, z, yaw, pitch, relativeArguments, movementX, movementY, movementZ); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_POSITION, wrapper -> { + final int teleportId = wrapper.read(Types.VAR_INT); + + final double x = wrapper.passthrough(Types.DOUBLE); + final double y = wrapper.passthrough(Types.DOUBLE); + final double z = wrapper.passthrough(Types.DOUBLE); + + final double movementX = wrapper.read(Types.DOUBLE); + final double movementY = wrapper.read(Types.DOUBLE); + final double movementZ = wrapper.read(Types.DOUBLE); + + final float yaw = wrapper.passthrough(Types.FLOAT); + final float pitch = wrapper.passthrough(Types.FLOAT); + + // Just keep the new values in there + final int relativeArguments = wrapper.read(Types.INT); + wrapper.write(Types.BYTE, (byte) relativeArguments); + wrapper.write(Types.VAR_INT, teleportId); + + // Send alongside separate entity motion + wrapper.send(Protocol1_21_2To1_21.class); + wrapper.cancel(); + + handleRelativeArguments(wrapper, x, y, z, yaw, pitch, relativeArguments, movementX, movementY, movementZ); + }); + + protocol.registerServerbound(ServerboundPackets1_20_5.PLAYER_COMMAND, wrapper -> { + wrapper.passthrough(Types.VAR_INT); + final int action = wrapper.passthrough(Types.VAR_INT); + + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + if (action == 0) { + storage.setPlayerCommandTrackedSneaking(true); + } else if (action == 1) { + storage.setPlayerCommandTrackedSneaking(false); + } else if (action == 3) { + storage.setPlayerCommandTrackedSprinting(true); + } else if (action == 4) { + storage.setPlayerCommandTrackedSprinting(false); + } + }); + + // Now also sent by the player if not in a vehicle, but we can't emulate that here, and otherwise only used in predicates + protocol.registerServerbound(ServerboundPackets1_20_5.PLAYER_INPUT, wrapper -> { + final float sideways = wrapper.read(Types.FLOAT); + final float forward = wrapper.read(Types.FLOAT); + final byte flags = wrapper.read(Types.BYTE); + + byte updatedFlags = 0; + if (forward > 0) { + updatedFlags |= 1; + } else if (forward < 0) { + updatedFlags |= 1 << 1; + } + + if (sideways < 0) { + updatedFlags |= 1 << 2; + } else if (sideways > 0) { + updatedFlags |= 1 << 3; + } + + if ((flags & 1) != 0) { // Jumping + updatedFlags |= 1 << 4; + } + + final boolean sneaking = (flags & 2) != 0; + if (sneaking) { + updatedFlags |= 1 << 5; + } + + // Sprinting we don't know... + + wrapper.write(Types.BYTE, updatedFlags); + + // Player input no longer sets the sneaking state on the server + // Send the change separately if needed (= when in a vehicle and player commands aren't sent by the old client) + final PlayerStorage sneakingStorage = wrapper.user().get(PlayerStorage.class); + if (sneakingStorage.setSneaking(sneaking)) { + final PacketWrapper playerCommandPacket = wrapper.create(ServerboundPackets1_21_2.PLAYER_COMMAND); + playerCommandPacket.write(Types.VAR_INT, tracker(wrapper.user()).clientEntityId()); + playerCommandPacket.write(Types.VAR_INT, sneaking ? 0 : 1); // Start/stop sneaking + playerCommandPacket.write(Types.VAR_INT, 0); // Data + playerCommandPacket.sendToServer(Protocol1_21_2To1_21.class); + } + }); + + protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_POS, wrapper -> { + final double x = wrapper.passthrough(Types.DOUBLE); + final double y = wrapper.passthrough(Types.DOUBLE); + final double z = wrapper.passthrough(Types.DOUBLE); + fixOnGround(wrapper); + + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + storage.setPosition(x, y, z); + }); + protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_POS_ROT, wrapper -> { + final double x = wrapper.passthrough(Types.DOUBLE); + final double y = wrapper.passthrough(Types.DOUBLE); + final double z = wrapper.passthrough(Types.DOUBLE); + final float yaw = wrapper.passthrough(Types.FLOAT); + final float pitch = wrapper.passthrough(Types.FLOAT); + fixOnGround(wrapper); + + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + storage.setPosition(x, y, z); + storage.setRotation(yaw, pitch); + }); + protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_ROT, wrapper -> { + final float yaw = wrapper.passthrough(Types.FLOAT); + final float pitch = wrapper.passthrough(Types.FLOAT); + fixOnGround(wrapper); + + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + storage.setRotation(yaw, pitch); + }); + protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_STATUS_ONLY, this::fixOnGround); + protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_VEHICLE, wrapper -> { + final double x = wrapper.passthrough(Types.DOUBLE); + final double y = wrapper.passthrough(Types.DOUBLE); + final double z = wrapper.passthrough(Types.DOUBLE); + final float yaw = wrapper.passthrough(Types.FLOAT); + final float pitch = wrapper.passthrough(Types.FLOAT); + + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + storage.setPosition(x, y, z); + storage.setRotation(yaw, pitch); + }); + + protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_INFO_UPDATE, wrapper -> { + final BitSet actions = wrapper.read(Types.PROFILE_ACTIONS_ENUM1_21_2); + // We need to recreate the BitSet field itself to remove the new action + final BitSet updatedActions = new BitSet(6); + for (int i = 0; i < 6; i++) { + if (actions.get(i)) { + updatedActions.set(i); + } + } + wrapper.write(Types.PROFILE_ACTIONS_ENUM1_19_3, updatedActions); + + final int entries = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < entries; i++) { + wrapper.passthrough(Types.UUID); + if (actions.get(0)) { + wrapper.passthrough(Types.STRING); // Player Name + + final int properties = wrapper.passthrough(Types.VAR_INT); + for (int j = 0; j < properties; j++) { + wrapper.passthrough(Types.STRING); // Name + wrapper.passthrough(Types.STRING); // Value + wrapper.passthrough(Types.OPTIONAL_STRING); // Signature + } + } + if (actions.get(1) && wrapper.passthrough(Types.BOOLEAN)) { + wrapper.passthrough(Types.UUID); // Session UUID + wrapper.passthrough(Types.PROFILE_KEY); + } + if (actions.get(2)) { + wrapper.passthrough(Types.VAR_INT); // Gamemode + } + if (actions.get(3)) { + wrapper.passthrough(Types.BOOLEAN); // Listed + } + if (actions.get(4)) { + wrapper.passthrough(Types.VAR_INT); // Latency + } + if (actions.get(5)) { + final Tag displayName = wrapper.passthrough(Types.OPTIONAL_TAG); + protocol.getComponentRewriter().processTag(wrapper.user(), displayName); + } + + // New one + if (actions.get(6)) { + actions.clear(6); + wrapper.read(Types.VAR_INT); // List order + } + } + }); + protocol.registerClientbound(ClientboundPackets1_21_2.SET_PASSENGERS, wrapper -> { + final int vehicleId = wrapper.passthrough(Types.VAR_INT); + final int[] passengerIds = wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE); + final ClientVehicleStorage storage = wrapper.user().get(ClientVehicleStorage.class); + if (storage != null && vehicleId == storage.vehicleId()) { + wrapper.user().remove(ClientVehicleStorage.class); + } + + final int clientEntityId = tracker(wrapper.user()).clientEntityId(); + for (final int passenger : passengerIds) { + if (passenger == clientEntityId) { + wrapper.user().put(new ClientVehicleStorage(vehicleId)); + break; + } + } + }); + protocol.appendClientbound(ClientboundPackets1_21_2.REMOVE_ENTITIES, wrapper -> { + final ClientVehicleStorage vehicleStorage = wrapper.user().get(ClientVehicleStorage.class); + if (vehicleStorage == null) { + return; + } + + final int[] entityIds = wrapper.get(Types.VAR_INT_ARRAY_PRIMITIVE, 0); + for (final int entityId : entityIds) { + if (entityId == vehicleStorage.vehicleId()) { + wrapper.user().remove(ClientVehicleStorage.class); + break; + } + } + }); + } + + private void writePackedRotation(final PacketWrapper wrapper, final float yaw, final float pitch) { + // Pack y and x rot + wrapper.write(Types.BYTE, (byte) Math.floor(yaw * 256F / 360F)); + wrapper.write(Types.BYTE, (byte) Math.floor(pitch * 256F / 360F)); + } + + private void handleRelativeArguments( + final PacketWrapper wrapper, + double x, double y, double z, + float yaw, float pitch, + final int relativeArguments, + double movementX, double movementY, double movementZ + ) { + // Position and rotation + final PlayerStorage storage = wrapper.user().get(PlayerStorage.class); + if ((relativeArguments & 1 << REL_X) != 0) { + x += storage.x(); + } + if ((relativeArguments & 1 << REL_Y) != 0) { + y += storage.y(); + } + if ((relativeArguments & 1 << REL_Z) != 0) { + z += storage.z(); + } + if ((relativeArguments & 1 << REL_Y_ROT) != 0) { + yaw += storage.yaw(); + } + if ((relativeArguments & 1 << REL_X_ROT) != 0) { + pitch += storage.pitch(); + } + + // Movement rotation + if ((relativeArguments & 1 << REL_ROTATE_DELTA) != 0) { + final double deltaYaw = Math.toRadians(storage.yaw() - yaw); + final double deltaYawCos = Math.cos(deltaYaw); + final double deltaYawSin = Math.sin(deltaYaw); + movementX = movementX * deltaYawCos + movementZ * deltaYawSin; + movementZ = movementZ * deltaYawCos - movementX * deltaYawSin; + + final double deltaPitch = Math.toRadians(storage.pitch() - pitch); + final double deltaPitchCos = Math.cos(deltaPitch); + final double deltaPitchSin = Math.sin(deltaPitch); + movementY = movementY * deltaPitchCos + movementZ * deltaPitchSin; + movementZ = movementZ * deltaPitchCos - movementY * deltaPitchSin; + } + + final boolean relativeDeltaX = (relativeArguments & 1 << REL_DELTA_X) != 0; + final boolean relativeDeltaY = (relativeArguments & 1 << REL_DELTA_Y) != 0; + final boolean relativeDeltaZ = (relativeArguments & 1 << REL_DELTA_Z) != 0; + + // Movement + if (relativeDeltaX && relativeDeltaY && relativeDeltaZ) { + final PacketWrapper explosionPacket = wrapper.create(ClientboundPackets1_21.EXPLODE); + explosionPacket.write(Types.DOUBLE, 0.0); // Center X + explosionPacket.write(Types.DOUBLE, 0.0); // Center Y + explosionPacket.write(Types.DOUBLE, 0.0); // Center Z + explosionPacket.write(Types.FLOAT, 0F); // Power + explosionPacket.write(Types.VAR_INT, 0); // Blocks affected + explosionPacket.write(Types.FLOAT, (float) movementX); + explosionPacket.write(Types.FLOAT, (float) movementY); + explosionPacket.write(Types.FLOAT, (float) movementZ); + explosionPacket.write(Types.VAR_INT, 0); // Block interaction + explosionPacket.write(Types1_21.PARTICLE, new Particle(0)); // Small explosion + explosionPacket.write(Types1_21.PARTICLE, new Particle(0)); // Large explosion + explosionPacket.write(Types.SOUND_EVENT, Holder.of(new SoundEvent("", null))); // Explosion sound + + explosionPacket.send(Protocol1_21_2To1_21.class); + } else if (!relativeDeltaX && !relativeDeltaY && !relativeDeltaZ) { + final PacketWrapper entityMotionPacket = wrapper.create(ClientboundPackets1_21.SET_ENTITY_MOTION); + entityMotionPacket.write(Types.VAR_INT, tracker(wrapper.user()).clientEntityId()); + entityMotionPacket.write(Types.SHORT, (short) (movementX * 8000)); + entityMotionPacket.write(Types.SHORT, (short) (movementY * 8000)); + entityMotionPacket.write(Types.SHORT, (short) (movementZ * 8000)); + + entityMotionPacket.send(Protocol1_21_2To1_21.class); + } else if (!warned) { + // Mixed combinations of relative and absolute would require tracking the previous delta movement + // which is quite impossible without doing massive player simulation on protocol level. + + // This is bad but so is life. + protocol.getLogger().warning("Mixed combinations of relative and absolute delta movements are not supported for 1.21.1 players. " + + "This will result in incorrect movement for the player. "); + warned = true; + } + + // Update at the end + storage.setPosition(x, y, z); + storage.setRotation(yaw, pitch); + } + + private int boatTypeFromEntityType(final EntityType type) { + if (type == EntityTypes1_21_2.OAK_BOAT) { + return 0; + } else if (type == EntityTypes1_21_2.SPRUCE_BOAT) { + return 1; + } else if (type == EntityTypes1_21_2.BIRCH_BOAT) { + return 2; + } else if (type == EntityTypes1_21_2.JUNGLE_BOAT) { + return 3; + } else if (type == EntityTypes1_21_2.ACACIA_BOAT) { + return 4; + } else if (type == EntityTypes1_21_2.CHERRY_BOAT) { + return 5; + } else if (type == EntityTypes1_21_2.DARK_OAK_BOAT) { + return 6; + } else if (type == EntityTypes1_21_2.MANGROVE_BOAT) { + return 7; + } else if (type == EntityTypes1_21_2.BAMBOO_RAFT) { + return 8; + } else { + return 0; + } + } + + private int chestBoatTypeFromEntityType(final EntityType type) { + if (type == EntityTypes1_21_2.OAK_CHEST_BOAT) { + return 0; + } else if (type == EntityTypes1_21_2.SPRUCE_CHEST_BOAT) { + return 1; + } else if (type == EntityTypes1_21_2.BIRCH_CHEST_BOAT) { + return 2; + } else if (type == EntityTypes1_21_2.JUNGLE_CHEST_BOAT) { + return 3; + } else if (type == EntityTypes1_21_2.ACACIA_CHEST_BOAT) { + return 4; + } else if (type == EntityTypes1_21_2.CHERRY_CHEST_BOAT) { + return 5; + } else if (type == EntityTypes1_21_2.DARK_OAK_CHEST_BOAT) { + return 6; + } else if (type == EntityTypes1_21_2.MANGROVE_CHEST_BOAT) { + return 7; + } else if (type == EntityTypes1_21_2.BAMBOO_CHEST_RAFT) { + return 8; + } else { + return 0; + } + } + + private void fixOnGround(final PacketWrapper wrapper) { + final boolean data = wrapper.read(Types.BOOLEAN); + wrapper.write(Types.UNSIGNED_BYTE, data ? (short) 1 : 0); // Carries more data now + } + + @Override + protected void registerRewrites() { + filter().mapDataType(Types1_21.ENTITY_DATA_TYPES::byId); + registerEntityDataTypeHandler1_20_3( + Types1_21.ENTITY_DATA_TYPES.itemType, + Types1_21.ENTITY_DATA_TYPES.blockStateType, + Types1_21.ENTITY_DATA_TYPES.optionalBlockStateType, + Types1_21.ENTITY_DATA_TYPES.particleType, + Types1_21.ENTITY_DATA_TYPES.particlesType, + Types1_21.ENTITY_DATA_TYPES.componentType, + Types1_21.ENTITY_DATA_TYPES.optionalComponentType + ); + registerBlockStateHandler(EntityTypes1_21_2.ABSTRACT_MINECART, 11); + + filter().type(EntityTypes1_21_2.CREAKING).cancel(17); // Active + filter().type(EntityTypes1_21_2.CREAKING).cancel(16); // Can move + + filter().type(EntityTypes1_21_2.ABSTRACT_BOAT).addIndex(11); // Boat type + filter().type(EntityTypes1_21_2.SALMON).removeIndex(17); // Data type + filter().type(EntityTypes1_21_2.AGEABLE_WATER_CREATURE).removeIndex(16); // Baby + + filter().type(EntityTypes1_21_2.ABSTRACT_ARROW).removeIndex(10); // In ground + } + + @Override + public EntityType typeFromId(final int type) { + return EntityTypes1_21_2.getTypeFromId(type); + } + + @Override + public void onMappingDataLoaded() { + mapTypes(); + + mapEntityTypeWithData(EntityTypes1_21_2.CREAKING, EntityTypes1_21_2.WARDEN).tagName(); + mapEntityTypeWithData(EntityTypes1_21_2.CREAKING_TRANSIENT, EntityTypes1_21_2.WARDEN).tagName(); + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/ParticleRewriter1_21_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/ParticleRewriter1_21_2.java new file mode 100644 index 00000000..f40f0c06 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/ParticleRewriter1_21_2.java @@ -0,0 +1,62 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.rewriter; + +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.Particle; +import com.viaversion.viaversion.api.protocol.Protocol; +import com.viaversion.viaversion.api.type.Types; +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_21to1_21_2.packet.ClientboundPacket1_21_2; +import com.viaversion.viaversion.rewriter.ParticleRewriter; + +public final class ParticleRewriter1_21_2 extends ParticleRewriter { + + public ParticleRewriter1_21_2(final Protocol protocol) { + super(protocol, Types1_21_2.PARTICLE, Types1_21.PARTICLE); + } + + @Override + public void rewriteParticle(final UserConnection connection, final Particle particle) { + final String identifier = protocol.getMappingData().getParticleMappings().identifier(particle.id()); + super.rewriteParticle(connection, particle); + + if (identifier.equals("minecraft:dust_color_transition")) { + argbToVector(particle, 0); + argbToVector(particle, 3); + } else if (identifier.equals("minecraft:dust")) { + argbToVector(particle, 0); + } else if (identifier.equals("minecraft:trail")) { + // Remove target + particle.removeArgument(2); + particle.removeArgument(1); + particle.removeArgument(0); + } + } + + private void argbToVector(final Particle particle, final int index) { + final int argb = particle.removeArgument(index).getValue(); + final float r = ((argb >> 16) & 0xFF) / 255F; + final float g = ((argb >> 8) & 0xFF) / 255F; + final float b = (argb & 0xFF) / 255F; + particle.add(index, Types.FLOAT, r); + particle.add(index + 1, Types.FLOAT, g); + particle.add(index + 2, Types.FLOAT, b); + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/storage/PingRequests.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/InventoryStateIdStorage.java similarity index 67% rename from common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/storage/PingRequests.java rename to common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/InventoryStateIdStorage.java index f2a9a4d8..0f6064fa 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_17to1_16_4/storage/PingRequests.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/InventoryStateIdStorage.java @@ -15,20 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.viaversion.viabackwards.protocol.v1_17to1_16_4.storage; +package com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage; import com.viaversion.viaversion.api.connection.StorableObject; -import com.viaversion.viaversion.libs.fastutil.ints.IntOpenHashSet; -import com.viaversion.viaversion.libs.fastutil.ints.IntSet; -public final class PingRequests implements StorableObject { - private final IntSet ids = new IntOpenHashSet(); +public final class InventoryStateIdStorage implements StorableObject { - public void addId(short id) { - ids.add(id); + private int stateId = -1; + + public int stateId() { + return stateId; } - public boolean removeId(short id) { - return ids.remove(id); + public void setStateId(final int stateId) { + this.stateId = stateId; } } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/ItemTagStorage.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/ItemTagStorage.java new file mode 100644 index 00000000..fcc6de84 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/ItemTagStorage.java @@ -0,0 +1,56 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.storage; + +import com.viaversion.viaversion.api.connection.StorableObject; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.util.Key; +import java.util.HashMap; +import java.util.Map; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class ItemTagStorage implements StorableObject { + + private Map itemTags = new HashMap<>(); + + public int @Nullable [] itemTag(final String key) { + return itemTags.get(Key.stripMinecraftNamespace(key)); + } + + public void readItemTags(final PacketWrapper wrapper) { + final int length = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < length; i++) { + final String registryKey = wrapper.passthrough(Types.STRING); + final int tagsSize = wrapper.passthrough(Types.VAR_INT); + + final boolean itemRegistry = Key.stripMinecraftNamespace(registryKey).equals("item"); + if (itemRegistry) { + this.itemTags = new HashMap<>(tagsSize); + } + + for (int j = 0; j < tagsSize; j++) { + final String key = wrapper.passthrough(Types.STRING); + final int[] ids = wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE); + if (itemRegistry) { + this.itemTags.put(Key.stripMinecraftNamespace(key), ids); + } + } + } + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/PlayerStorage.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/PlayerStorage.java new file mode 100644 index 00000000..93c49af2 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/PlayerStorage.java @@ -0,0 +1,117 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.storage; + +import com.viaversion.viabackwards.api.entities.storage.PlayerPositionStorage; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; + +public final class PlayerStorage extends PlayerPositionStorage { + private static final PlayerInput EMPTY = new PlayerInput(false, false, false, false, false, false, false); + private static final float PLAYER_JUMP_HEIGHT = 0.42F; + + private float yaw; + private float pitch; + + private boolean playerCommandTrackedSneaking; + private boolean playerCommandTrackedSprinting; + + private PlayerInput lastInput = EMPTY; + private double prevX; + private double prevY; + private double prevZ; + + public void tick(final UserConnection user) { + final double deltaX = x() - prevX; + final double deltaY = y() - prevY; + final double deltaZ = z() - prevZ; + + final double magnitude = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ); + double directionX = magnitude > 0 ? deltaX / magnitude : 0; + double directionZ = magnitude > 0 ? deltaZ / magnitude : 0; + + directionX = Math.max(-1, Math.min(1, directionX)); + directionZ = Math.max(-1, Math.min(1, directionZ)); + + final double angle = Math.toRadians(-yaw); + final double newDirectionX = directionX * Math.cos(angle) - directionZ * Math.sin(angle); + final double newDirectionZ = directionX * Math.sin(angle) + directionZ * Math.cos(angle); + + final boolean forward = newDirectionZ >= 0.65F; + final boolean backwards = newDirectionZ <= -0.65F; + final boolean left = newDirectionX >= 0.65F; + final boolean right = newDirectionX <= -0.65F; + final boolean jump = Math.abs(deltaY - PLAYER_JUMP_HEIGHT) <= 1E-4F; + + final PlayerInput input = new PlayerInput(forward, backwards, left, right, jump, playerCommandTrackedSneaking, playerCommandTrackedSprinting); + if (!lastInput.equals(input)) { + final PacketWrapper playerInputPacket = PacketWrapper.create(ServerboundPackets1_21_2.PLAYER_INPUT, user); + byte flags = 0; + flags = (byte) (flags | (input.forward() ? 1 : 0)); + flags = (byte) (flags | (input.backward() ? 2 : 0)); + flags = (byte) (flags | (input.left() ? 4 : 0)); + flags = (byte) (flags | (input.right() ? 8 : 0)); + flags = (byte) (flags | (input.jump() ? 16 : 0)); + flags = (byte) (flags | (input.sneak() ? 32 : 0)); + flags = (byte) (flags | (input.sprint() ? 64 : 0)); + playerInputPacket.write(Types.BYTE, flags); + + playerInputPacket.sendToServer(Protocol1_21_2To1_21.class); + lastInput = input; + } + + this.prevX = x(); + this.prevY = y(); + this.prevZ = z(); + } + + public float yaw() { + return yaw; + } + + public float pitch() { + return pitch; + } + + public void setRotation(final float yaw, final float pitch) { + this.yaw = yaw; + this.pitch = pitch; + } + + public void setPlayerCommandTrackedSneaking(final boolean playerCommandTrackedSneaking) { + this.playerCommandTrackedSneaking = playerCommandTrackedSneaking; + } + + public void setPlayerCommandTrackedSprinting(final boolean playerCommandTrackedSprinting) { + this.playerCommandTrackedSprinting = playerCommandTrackedSprinting; + } + + public boolean setSneaking(final boolean sneaking) { + final boolean changed = this.playerCommandTrackedSneaking != sneaking; + this.playerCommandTrackedSneaking = sneaking; + return changed; + } + + public record PlayerInput(boolean forward, boolean backward, boolean left, boolean right, boolean jump, + boolean sneak, boolean sprint) { + } + +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/RecipeStorage.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/RecipeStorage.java new file mode 100644 index 00000000..eecb0e2e --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/storage/RecipeStorage.java @@ -0,0 +1,464 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.storage; + +import com.google.common.base.Preconditions; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viaversion.api.connection.StorableObject; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.HolderSet; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.minecraft.item.StructuredItem; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.version.Types1_21_2; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +// Mostly a lost cause as the server will not send all the necessary data. +// Recipe displays can also be different from the actual recipe - at the end of the same, +// the server will still properly handle inputs, but we can't fully reconstruct the recipe book. +public final class RecipeStorage implements StorableObject { + + // Pairs of open + filtering for: Crafting, furnace, blast furnace, smoker + public static final int RECIPE_BOOK_SETTINGS = 4 * 2; + private static final String[] EMPTY_STRINGS = new String[0]; + private final List recipes = new ArrayList<>(); + private final List tempRecipes = new ArrayList<>(); + private final List stoneCutterRecipes = new ArrayList<>(); + private boolean[] recipeBookSettings = new boolean[RECIPE_BOOK_SETTINGS]; + private final Protocol1_21_2To1_21 protocol; + + public RecipeStorage(final Protocol1_21_2To1_21 protocol) { + this.protocol = protocol; + } + + abstract static class Recipe { + private static final int FOOD_CRAFTING_BOOK_CATEGORY = 0; + private static final int BLOCKS_CRAFTING_BOOK_CATEGORY = 1; + private static final int MISC_CRAFTING_BOOK_CATEGORY = 2; + protected int index; + private Integer group; + private int category; + private boolean highlight; + private boolean locked; + + abstract void write(PacketWrapper wrapper); + + void writeGroup(final PacketWrapper wrapper) { + wrapper.write(Types.STRING, group != null ? Integer.toString(group) : ""); + } + + void writeIngredients(final PacketWrapper wrapper, final Item[][] ingredients) { + wrapper.write(Types.VAR_INT, ingredients.length); + for (final Item[] ingredient : ingredients) { + writeIngredient(wrapper, ingredient); + } + } + + void writeIngredient(final PacketWrapper wrapper, final Item[] ingredient) { + final Item[] copy = new Item[ingredient.length]; + for (int i = 0; i < ingredient.length; i++) { + copy[i] = ingredient[i].copy(); + } + wrapper.write(Types1_21_2.ITEM_ARRAY, copy); + } + + void writeResult(final PacketWrapper wrapper, final Item result) { + wrapper.write(Types1_21_2.ITEM, result.copy()); + } + + void writeCategory(final PacketWrapper wrapper) { + // TODO Doesn't translate exactly + final int craftingBookCategory = switch (category) { + case 4, 9, 12 -> FOOD_CRAFTING_BOOK_CATEGORY; + case 0, 5, 7, 10 -> BLOCKS_CRAFTING_BOOK_CATEGORY; + case 1, 2, 3, 6, 8, 11 -> MISC_CRAFTING_BOOK_CATEGORY; + default -> MISC_CRAFTING_BOOK_CATEGORY; + }; + wrapper.write(Types.VAR_INT, craftingBookCategory); + } + + int category() { + return category; + } + } + + public void sendRecipes(final UserConnection connection) { + // Fill from temp recipes so we can clear before if needed + if (!tempRecipes.isEmpty()) { + this.recipes.addAll(tempRecipes); + tempRecipes.clear(); + } + + int highestIndex = -1; + for (final Recipe recipe : recipes) { + highestIndex = Math.max(highestIndex, recipe.index); + } + + // Add stonecutter recipes from update_recipes + final List recipes = new ArrayList<>(this.recipes); + for (final StoneCutterRecipe recipe : stoneCutterRecipes) { + recipe.index = ++highestIndex; + recipes.add(recipe); + } + + // Sort by id + recipes.sort(Comparator.comparingInt(a -> a.index)); + + // Since the server only sends unlocked recipes, we need to re-send all recipes in UPDATE_RECIPES + final PacketWrapper updateRecipesPacket = PacketWrapper.create(ClientboundPackets1_21.UPDATE_RECIPES, connection); + updateRecipesPacket.write(Types.VAR_INT, recipes.size()); + for (final Recipe recipe : recipes) { + updateRecipesPacket.write(Types.STRING, identifier(recipe.index)); + recipe.write(updateRecipesPacket); + } + updateRecipesPacket.send(Protocol1_21_2To1_21.class); + + sendUnlockedRecipes(connection, recipes); + } + + private static String identifier(final int recipeIndex) { + // Use index as the recipe identifier, add leading zeros to keept it sorted + return String.format("%06d", recipeIndex); + } + + public void lockRecipes(final PacketWrapper wrapper, final int[] ids) { + for (final int id : ids) { + recipes.get(id).locked = true; + } + + wrapper.write(Types.VAR_INT, 2); // Remove recipes + for (final boolean recipeBookSetting : recipeBookSettings) { + wrapper.write(Types.BOOLEAN, recipeBookSetting); + } + + final String[] recipeKeys = new String[ids.length]; + for (int i = 0; i < ids.length; i++) { + recipeKeys[i] = identifier(ids[i]); + } + wrapper.write(Types.STRING_ARRAY, recipeKeys); + } + + private void sendUnlockedRecipes(final UserConnection connection, final List recipes) { + final PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_21.RECIPE, connection); + wrapper.write(Types.VAR_INT, 0); // Init recipes + + for (final boolean recipeBookSetting : recipeBookSettings) { + wrapper.write(Types.BOOLEAN, recipeBookSetting); + } + + // Use index as the recipe identifier. We only know the unlocked ones, so send all + final String[] recipeKeys = new String[recipes.size()]; + final List highlightRecipes = new ArrayList<>(); + for (int i = 0; i < recipes.size(); i++) { + recipeKeys[i] = identifier(i); + if (recipes.get(i).highlight) { + highlightRecipes.add(recipeKeys[i]); + } + } + wrapper.write(Types.STRING_ARRAY, recipeKeys); + + wrapper.write(Types.STRING_ARRAY, highlightRecipes.toArray(EMPTY_STRINGS)); + wrapper.send(Protocol1_21_2To1_21.class); + } + + public void readRecipe(final PacketWrapper wrapper) { + final int id = wrapper.read(Types.VAR_INT); + final int type = wrapper.passthrough(Types.VAR_INT); + final Recipe recipe = switch (type) { + case 0 -> readShapeless(wrapper); + case 1 -> readShaped(wrapper); + case 2 -> readFurnace(wrapper); + case 3 -> readStoneCutter(wrapper); + case 4 -> readSmithing(wrapper); + default -> null; + }; + + final Integer group = wrapper.read(Types.OPTIONAL_VAR_INT); + final int category = wrapper.read(Types.VAR_INT); + if (wrapper.read(Types.BOOLEAN)) { + final int ingredientsSize = wrapper.read(Types.VAR_INT); + for (int j = 0; j < ingredientsSize; j++) { + //handleIngredient(wrapper); // Items //TODO ? + wrapper.read(Types.HOLDER_SET); + } + } + final byte flags = wrapper.read(Types.BYTE); + + if (recipe != null) { + recipe.index = id; + recipe.group = group; + recipe.category = category; + recipe.highlight = (flags & 2) != 0; + } + } + + private Recipe readShapeless(final PacketWrapper wrapper) { + final Item[][] ingredients = readSlotDisplayList(wrapper); + final Item result = readSingleSlotDisplay(wrapper); + readSlotDisplay(wrapper); // Crafting station + return add(new ShapelessRecipe(ingredients, result)); + } + + private Recipe readShaped(final PacketWrapper wrapper) { + final int width = wrapper.passthrough(Types.VAR_INT); + final int height = wrapper.passthrough(Types.VAR_INT); + final Item[][] ingredients = readSlotDisplayList(wrapper); + final Item result = readSingleSlotDisplay(wrapper); + readSlotDisplay(wrapper); // Crafting station + return add(new ShapedRecipe(width, height, ingredients, result)); + } + + private Recipe readFurnace(final PacketWrapper wrapper) { + final Item[] ingredient = readSlotDisplay(wrapper); + readSlotDisplay(wrapper); // Fuel + final Item result = readSingleSlotDisplay(wrapper); + readSlotDisplay(wrapper); // Crafting station + final int duration = wrapper.read(Types.VAR_INT); + final float experience = wrapper.read(Types.FLOAT); + return add(new FurnaceRecipe(ingredient, result, duration, experience)); + } + + private Recipe readStoneCutter(final PacketWrapper wrapper) { + // Use values from UPDATE_RECIPES instead + readSlotDisplay(wrapper); // Input + readSlotDisplay(wrapper); // Result + readSlotDisplay(wrapper); // Crafting station + return null; + } + + private Recipe readSmithing(final PacketWrapper wrapper) { + // TODO Combine with update_recipes? + readSlotDisplay(wrapper); // Template + readSlotDisplay(wrapper); // Base + readSlotDisplay(wrapper); // Addition + readSlotDisplay(wrapper); // Result + readSlotDisplay(wrapper); // Crafting station + return null; + } + + private Recipe add(final Recipe recipe) { + tempRecipes.add(recipe); + return recipe; + } + + private Item[][] readSlotDisplayList(final PacketWrapper wrapper) { + final int size = wrapper.passthrough(Types.VAR_INT); + final Item[][] ingredients = new Item[size][]; + for (int i = 0; i < size; i++) { + ingredients[i] = readSlotDisplay(wrapper); + } + return ingredients; + } + + private Item readSingleSlotDisplay(final PacketWrapper wrapper) { + final Item[] items = readSlotDisplay(wrapper); + return items.length == 0 ? new StructuredItem(1, 1) : items[0]; + } + + private Item[] readSlotDisplay(final PacketWrapper wrapper) { + // empty, any_fuel, smithing_trim are empty + final int type = wrapper.read(Types.VAR_INT); + return switch (type) { + case 2 -> { + final int id = wrapper.read(Types.VAR_INT); + if (id == 0) { + protocol.getLogger().warning("Empty item id in recipe"); + yield new Item[0]; + } + yield new Item[]{new StructuredItem(rewriteItemId(id), 1)}; + } + case 3 -> { + final Item item = wrapper.read(Types1_21_2.ITEM); + protocol.getItemRewriter().handleItemToClient(wrapper.user(), item); + if (item.isEmpty()) { + protocol.getLogger().warning("Empty item in recipe"); + yield new Item[0]; + } + yield new Item[]{item}; + } + case 4 -> { + wrapper.read(Types.STRING); // Tag key // TODO Probably not even worth the effort + yield new Item[0]; + } + case 5 -> { + readSlotDisplay(wrapper); // Base + readSlotDisplay(wrapper); // Material + readSlotDisplay(wrapper); // Pattern + yield new Item[0]; + } + case 6 -> { + readSlotDisplay(wrapper); // Input + readSlotDisplay(wrapper); // Remainder + yield new Item[0]; + } + case 7 -> readSlotDisplayList(wrapper)[0]; // Composite + default -> new Item[0]; + }; + } + + private int rewriteItemId(final int id) { + return protocol.getMappingData().getNewItemId(id); + } + + public void readStoneCutterRecipes(final PacketWrapper wrapper) { + stoneCutterRecipes.clear(); + final int stonecutterRecipesSize = wrapper.read(Types.VAR_INT); + for (int i = 0; i < stonecutterRecipesSize; i++) { + // The ingredients are what's actually used in client prediction, they're the important part + final Item[] ingredient = readHolderSet(wrapper); + // TODO Probably not actually the result, might have to combine with update_recipes + final Item result = readSingleSlotDisplay(wrapper); + stoneCutterRecipes.add(new StoneCutterRecipe(ingredient, result)); + } + } + + private Item[] readHolderSet(final PacketWrapper wrapper) { + final HolderSet holderSet = wrapper.read(Types.HOLDER_SET); + if (holderSet.hasTagKey()) { + return new Item[]{new StructuredItem(1, 1)}; // TODO Probably not even worth the effort + } + + final int[] ids = holderSet.ids(); + for (int i = 0; i < ids.length; i++) { + ids[i] = rewriteItemId(ids[i]); + } + + final Item[] ingredient = new Item[ids.length]; + for (int i = 0; i < ingredient.length; i++) { + ingredient[i] = new StructuredItem(ids[i], 1); + } + return ingredient; + } + + private static final class ShapelessRecipe extends Recipe { + private static final int SERIALIZER_ID = 1; + private final Item[][] ingredients; + private final Item result; + + private ShapelessRecipe(final Item[][] ingredients, final Item result) { + this.ingredients = ingredients; + this.result = result; + } + + @Override + public void write(final PacketWrapper wrapper) { + wrapper.write(Types.VAR_INT, SERIALIZER_ID); + writeGroup(wrapper); + writeCategory(wrapper); + writeIngredients(wrapper, ingredients); + writeResult(wrapper, result); + } + } + + private static final class ShapedRecipe extends Recipe { + private static final int SERIALIZER_ID = 0; + private final int width; + private final int height; + private final Item[][] ingredients; + private final Item result; + + private ShapedRecipe(final int width, final int height, final Item[][] ingredients, final Item result) { + this.width = width; + this.height = height; + this.ingredients = ingredients; + this.result = result; + } + + @Override + public void write(final PacketWrapper wrapper) { + wrapper.write(Types.VAR_INT, SERIALIZER_ID); + writeGroup(wrapper); + writeCategory(wrapper); + wrapper.write(Types.VAR_INT, width); + wrapper.write(Types.VAR_INT, height); + Preconditions.checkArgument(width * height == ingredients.length, "Invalid shaped recipe"); + // No length prefix + for (final Item[] ingredient : ingredients) { + writeIngredient(wrapper, ingredient); + } + writeResult(wrapper, result); + wrapper.write(Types.BOOLEAN, false); // Doesn't matter for the init + } + } + + private static final class FurnaceRecipe extends Recipe { + private final Item[] ingredient; + private final Item result; + private final float experience; + private final int cookingTime; + + private FurnaceRecipe(final Item[] ingredient, final Item result, final int cookingTime, final float experience) { + this.ingredient = ingredient; + this.result = result; + this.experience = experience; + this.cookingTime = cookingTime; + } + + @Override + public void write(final PacketWrapper wrapper) { + wrapper.write(Types.VAR_INT, serializerId()); + writeGroup(wrapper); + writeCategory(wrapper); + writeIngredient(wrapper, ingredient); + writeResult(wrapper, result); + wrapper.write(Types.FLOAT, experience); + wrapper.write(Types.VAR_INT, cookingTime); + } + + private int serializerId() { + return switch (category()) { + case 4, 5, 6 -> 15; // Furnace food, bocks, misc + case 7, 8 -> 16; // Blast furnace blocks, misc + case 9 -> 17; // Smoker + case 12 -> 18; // Campfire + default -> 15; + }; + } + } + + private static final class StoneCutterRecipe extends Recipe { + private static final int SERIALIZER_ID = 19; + private final Item[] ingredient; + private final Item result; + + private StoneCutterRecipe(final Item[] ingredient, final Item result) { + this.ingredient = ingredient; + this.result = result; + } + + @Override + public void write(final PacketWrapper wrapper) { + wrapper.write(Types.VAR_INT, SERIALIZER_ID); + writeGroup(wrapper); + writeIngredient(wrapper, ingredient); + writeResult(wrapper, result); + } + } + + public void setRecipeBookSettings(final boolean[] recipeBookSettings) { + this.recipeBookSettings = recipeBookSettings; + } + + public void clearRecipes() { + recipes.clear(); + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/task/PlayerPacketsTickTask.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/task/PlayerPacketsTickTask.java new file mode 100644 index 00000000..eb234be2 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/task/PlayerPacketsTickTask.java @@ -0,0 +1,63 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * 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.viabackwards.protocol.v1_21_2to1_21.task; + +import com.viaversion.viabackwards.ViaBackwards; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; +import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.packet.State; +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 io.netty.channel.Channel; +import java.util.logging.Level; + +public final class PlayerPacketsTickTask implements Runnable { + + @Override + public void run() { + for (final UserConnection user : Via.getManager().getConnectionManager().getConnections()) { + if (user.getProtocolInfo().getClientState() != State.PLAY || !user.getProtocolInfo().getPipeline().contains(Protocol1_21_2To1_21.class)) { + continue; + } + + final Channel channel = user.getChannel(); + channel.eventLoop().submit(() -> { + if (!channel.isActive()) { + return; + } + try { + if (!user.has(ClientVehicleStorage.class)) { + final PlayerStorage playerStorage = user.get(PlayerStorage.class); + playerStorage.tick(user); + } + } catch (Throwable t) { + ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "Error while sending player input packet.", t); + } + try { + final PacketWrapper clientTickEndPacket = PacketWrapper.create(ServerboundPackets1_21_2.CLIENT_TICK_END, user); + clientTickEndPacket.sendToServer(Protocol1_21_2To1_21.class); + } catch (Throwable t) { + ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "Error while sending client tick end packet.", t); + } + }); + } + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/Protocol1_21To1_20_5.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/Protocol1_21To1_20_5.java index e18759c8..2dfafe16 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/Protocol1_21To1_20_5.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/Protocol1_21To1_20_5.java @@ -34,6 +34,8 @@ import com.viaversion.viaversion.api.minecraft.item.data.ChatType; import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.version.Types1_20_5; +import com.viaversion.viaversion.api.type.types.version.Types1_21; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundConfigurationPackets1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPacket1_20_5; @@ -45,6 +47,7 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; 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.rewriter.ParticleRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.util.ArrayUtil; @@ -56,6 +59,7 @@ public final class Protocol1_21To1_20_5 extends BackwardsProtocol particleRewriter = new ParticleRewriter<>(this, Types1_21.PARTICLE, Types1_20_5.PARTICLE); private final TranslatableRewriter translatableRewriter = new ComponentRewriter1_21(this); private final TagRewriter tagRewriter = new TagRewriter<>(this); @@ -75,6 +79,9 @@ public final class Protocol1_21To1_20_5 extends BackwardsProtocol(this).register(ClientboundPackets1_21.AWARD_STATS); translatableRewriter.registerComponentPacket(ClientboundPackets1_21.SET_ACTION_BAR_TEXT); @@ -206,6 +213,11 @@ public final class Protocol1_21To1_20_5 extends BackwardsProtocol getParticleRewriter() { + return particleRewriter; + } + @Override public TranslatableRewriter getComponentRewriter() { return translatableRewriter; diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java index 933fb0be..4be17c25 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java @@ -28,7 +28,6 @@ import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.EnchantmentsPa import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.OpenScreenStorage; import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.PlayerRotationStorage; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; @@ -38,6 +37,7 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; import com.viaversion.viaversion.api.type.types.version.Types1_20_5; import com.viaversion.viaversion.api.type.types.version.Types1_21; import com.viaversion.viaversion.libs.fastutil.ints.Int2IntMap; +import com.viaversion.viaversion.libs.mcstructs.core.TextFormatting; import com.viaversion.viaversion.libs.mcstructs.text.components.StringComponent; import com.viaversion.viaversion.libs.mcstructs.text.components.TranslationComponent; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; @@ -63,8 +63,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe public BlockItemPacketRewriter1_21(final Protocol1_21To1_20_5 protocol) { super(protocol, Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY, - Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_20_5.ITEM_COST, Types1_20_5.OPTIONAL_ITEM_COST, - Types1_21.PARTICLE, Types1_20_5.PARTICLE + Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_20_5.ITEM_COST, Types1_20_5.OPTIONAL_ITEM_COST ); } @@ -85,8 +84,6 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK); registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS); registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT); - registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES); - registerExplosion(ClientboundPackets1_21.EXPLODE); protocol.registerClientbound(ClientboundPackets1_21.OPEN_SCREEN, wrapper -> { wrapper.passthrough(Types.VAR_INT); // Id @@ -177,6 +174,8 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe } final var component = SerializerVersion.V1_20_5.toComponent(description); + component.getStyle().setItalic(false); + component.getStyle().setFormatting(TextFormatting.GRAY); component.getSiblings().add(new StringComponent(" ")); component.getSiblings().add(new TranslationComponent(EnchantmentRewriter.ENCHANTMENT_LEVEL_TRANSLATION.formatted(level))); @@ -192,7 +191,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe downgradeItemData(item); final StructuredDataContainer dataContainer = item.dataContainer(); - if (dataContainer.contains(StructuredDataKey.RARITY)) { + if (dataContainer.has(StructuredDataKey.RARITY)) { return item; } @@ -230,12 +229,11 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe } private void rewriteEnchantmentToServer(final EnchantmentsPaintingsStorage storage, final Item item, final StructuredDataKey key) { - final StructuredData enchantmentsData = item.dataContainer().getNonEmpty(key); - if (enchantmentsData == null) { + final Enchantments enchantments = item.dataContainer().get(key); + if (enchantments == null) { return; } - final Enchantments enchantments = enchantmentsData.value(); final List updatedIds = new ArrayList<>(); for (final Int2IntMap.Entry entry : enchantments.enchantments().int2IntEntrySet()) { final int id = entry.getIntKey(); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/ComponentRewriter1_21.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/ComponentRewriter1_21.java index e08c1338..834c463e 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/ComponentRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/ComponentRewriter1_21.java @@ -23,9 +23,11 @@ import com.viaversion.nbt.tag.ListTag; import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter; import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5; import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Attributes1_20_5; import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.data.AttributeModifierMappings1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; +import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.SerializerVersion; import com.viaversion.viaversion.util.TagUtil; import com.viaversion.viaversion.util.UUIDUtil; @@ -43,7 +45,17 @@ public final class ComponentRewriter1_21 extends TranslatableRewriter modifiers = attributeModifiers.getListTag("modifiers", CompoundTag.class); - for (final CompoundTag modifier : modifiers) { + int size = modifiers.size(); + for (int i = 0; i < size; i++) { + final CompoundTag modifier = modifiers.get(i); + final String type = Key.stripMinecraftNamespace(modifier.getString("type")); + if (Attributes1_20_5.keyToId(type) == -1) { + // Ignore new attributes + modifiers.remove(i--); + size--; + continue; + } + final String id = modifier.getString("id"); final UUID uuid = Protocol1_20_5To1_21.mapAttributeId(id); final String name = AttributeModifierMappings1_21.idToName(id); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java index 98b98000..f04f15a3 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java @@ -40,6 +40,7 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.data.Paintings1_20_5; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; 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.rewriter.RegistryDataRewriter; import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.KeyMappings; import java.util.HashMap; @@ -64,6 +65,7 @@ public final class EntityPacketRewriter1_21 extends EntityRewriter { final String key = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING)); final RegistryEntry[] entries = wrapper.passthrough(Types.REGISTRY_ENTRY_ARRAY); @@ -99,7 +101,7 @@ public final class EntityPacketRewriter1_21 extends EntityRewriter { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_3To1_9_1.class); ChunkType1_9_3 newType = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); ChunkType1_9_1 oldType = ChunkType1_9_1.forEnvironment(clientWorld.getEnvironment()); // Get the old type to not write Block Entities @@ -89,10 +89,10 @@ public class Protocol1_9_3To1_9_1 extends BackwardsProtocol { - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_3To1_9_1.class); int dimensionId = wrapper.get(Types.INT, 1); - clientChunks.setEnvironment(dimensionId); + clientWorld.setEnvironment(dimensionId); }); } }); @@ -103,7 +103,7 @@ public class Protocol1_9_3To1_9_1 extends BackwardsProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_3To1_9_1.class); int dimensionId = wrapper.get(Types.INT, 0); clientWorld.setEnvironment(dimensionId); @@ -117,8 +117,6 @@ public class Protocol1_9_3To1_9_1 extends BackwardsProtocol=0.14.0", - "viafabric": ">=0.4.10" + "viafabric": ">=0.4.14" }, "custom": { "modmenu:api": true, diff --git a/gradle.properties b/gradle.properties index a0191ef8..a03f4081 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ -projectVersion=5.0.4-SNAPSHOT +projectVersion=5.1.1-SNAPSHOT # Smile emoji -mcVersions=1.21.1,1.21,1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10 -mcVersionRange=1.10-1.21.1 +mcVersions=1.21.3,1.21.2,1.21.1,1.21,1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10 +mcVersionRange=1.10-1.21.3 velocityVersion=3.3 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9212a8c8..29850cb3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ metadata.format.version = "1.1" [versions] # ViaVersion -viaver = "5.0.4-SNAPSHOT" +viaver = "5.1.1-SNAPSHOT" # Common provided netty = "4.0.20.Final" @@ -16,7 +16,7 @@ checkerQual = "3.39.0" paper = "1.16.5-R0.1-SNAPSHOT" velocity = "3.1.1" fabricLoader = "0.11.6" - +viaProxy = "3.3.5-SNAPSHOT" [libraries] @@ -31,3 +31,4 @@ checkerQual = { group = "org.checkerframework", name = "checker-qual", version.r paper = { group = "com.destroystokyo.paper", name = "paper-api", version.ref = "paper" } velocity = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity" } fabricLoader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabricLoader" } +viaProxy = { group = "net.raphimc", name = "ViaProxy", version.ref = "viaProxy" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2b189974..fb602ee2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index c6d9406c..312d288c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,6 +24,7 @@ includeBuild("build-logic") setupViaSubproject("common") setupViaSubproject("bukkit") setupViaSubproject("velocity") +setupViaSubproject("sponge") setupViaSubproject("fabric") setupSubproject("viabackwards") { diff --git a/sponge/src/main/resources/META-INF/sponge_plugins.json b/sponge/src/main/resources/META-INF/sponge_plugins.json new file mode 100644 index 00000000..3490a648 --- /dev/null +++ b/sponge/src/main/resources/META-INF/sponge_plugins.json @@ -0,0 +1,62 @@ +{ + "loader": { + "name": "java_plain", + "version": "1.0" + }, + "license": "GNU GPLv3", + "global": { + "version": "${version}", + "links": { + "source": "https://github.com/ViaVersion/ViaBackwards", + "issues": "https://github.com/ViaVersion/ViaBackwards/issues" + }, + "contributors": [ + { + "name": "Matsv", + "description": "Maintainer" + }, + { + "name": "kennytv", + "description": "Maintainer" + }, + { + "name": "Gerrygames", + "description": "Contributor" + }, + { + "name": "creeper123123321", + "description": "Contributor" + }, + { + "name": "ForceUpdate1", + "description": "Contributor" + }, + { + "name": "EnZaXD", + "description": "Maintainer" + } + ], + "dependencies": [ + { + "id": "spongeapi", + "version": "8.0.0" + }, + { + "id": "viasponge", + "version": "1.1.0" + }, + { + "id": "viaversion", + "version": "[5.0.4-SNAPSHOT,)" + } + ] + }, + "plugins": [ + { + "id": "viabackwards", + "name": "ViaBackwards", + "entrypoint": "com.viaversion.sponge.util.DummyEntrypoint", + "description": "${description}" + } + ] +} diff --git a/universal/build.gradle.kts b/universal/build.gradle.kts index b33b8178..3dbd030c 100644 --- a/universal/build.gradle.kts +++ b/universal/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { api(projects.viabackwardsBukkit) api(projects.viabackwardsVelocity) api(projects.viabackwardsFabric) + api(projects.viabackwardsSponge) } tasks { diff --git a/velocity/src/main/java/com/viaversion/viabackwards/VelocityPlugin.java b/velocity/src/main/java/com/viaversion/viabackwards/VelocityPlugin.java index f7dcb0fb..65257643 100644 --- a/velocity/src/main/java/com/viaversion/viabackwards/VelocityPlugin.java +++ b/velocity/src/main/java/com/viaversion/viabackwards/VelocityPlugin.java @@ -52,6 +52,7 @@ public class VelocityPlugin implements ViaBackwardsPlatform { public void onProxyStart(ProxyInitializeEvent event) { this.logger = new LoggerWrapper(loggerSlf4j); Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml"))); + Via.getManager().addPostEnableListener(this::enable); } @Override