diff --git a/src/main/java/de/florianmichael/viafabricplus/definition/v1_18_2/ClientPlayerInteractionManager1_18_2.java b/src/main/java/de/florianmichael/viafabricplus/definition/v1_18_2/ClientPlayerInteractionManager1_18_2.java
new file mode 100644
index 00000000..c8b41a98
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/definition/v1_18_2/ClientPlayerInteractionManager1_18_2.java
@@ -0,0 +1,74 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD 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 de.florianmichael.viafabricplus.definition.v1_18_2;
+
+import de.florianmichael.viafabricplus.ViaFabricPlus;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
+import net.minecraft.block.BlockState;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
+import net.minecraft.util.Pair;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec2f;
+import net.raphimc.vialoader.util.VersionEnum;
+
+public class ClientPlayerInteractionManager1_18_2 {
+ private final static Object2ObjectLinkedOpenHashMap, PositionAndRotation> unAckedActions = new Object2ObjectLinkedOpenHashMap<>();
+
+ public final static String ACK_TRANSFORMER_IDENTIFIER = "viafabricplus:acknowledge_player_digging";
+
+ public static void trackBlockAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
+ final var player = MinecraftClient.getInstance().player;
+ if (player == null) return;
+
+ var rotation = new Vec2f(player.getYaw(), player.getPitch());
+ if (ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_16_2)) {
+ rotation = null;
+ }
+ unAckedActions.put(new Pair<>(blockPos, action), new PositionAndRotation(player.getPos().x, player.getPos().y, player.getPos().z, rotation));
+ }
+
+ public static void handleBlockBreakAck(final ClientWorld world, final BlockPos blockPos, final BlockState blockState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
+ final var player = MinecraftClient.getInstance().player;
+ if (player == null) return;
+
+ final var next = unAckedActions.remove(new Pair<>(blockPos, action));
+ final var blockStateFromPos = world.getBlockState(blockPos);
+
+ if ((next == null || !allGood || action != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK && blockStateFromPos != blockState) && blockStateFromPos != blockState) {
+ world.setBlockState(blockPos, blockState);
+ if (next != null && world == player.getWorld() && player.collidesWithStateAtPos(blockPos, blockState)) {
+ if (next.rotation != null) {
+ player.updatePositionAndAngles(next.x, next.y, next.z, next.rotation.x, next.rotation.y);
+ } else {
+ player.updatePosition(next.x, next.y, next.z);
+ }
+ }
+ }
+
+ while (unAckedActions.size() >= 50) {
+ ViaFabricPlus.LOGGER.error("Too many unacked block actions, dropping {}", unAckedActions.firstKey());
+ unAckedActions.removeFirst();
+ }
+ }
+
+ public record PositionAndRotation(double x, double y, double z, Vec2f rotation) {
+ }
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayNetworkHandler.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayNetworkHandler.java
index 9c0b8537..464a4eb1 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayNetworkHandler.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayNetworkHandler.java
@@ -19,8 +19,12 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
import com.mojang.authlib.GameProfile;
+import de.florianmichael.viafabricplus.definition.v1_18_2.ClientPlayerInteractionManager1_18_2;
+import de.florianmichael.viafabricplus.protocolhack.usage.BlockStateTranslator;
+import net.minecraft.block.Block;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.raphimc.vialoader.util.VersionEnum;
-import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.base.settings.groups.VisualSettings;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
@@ -39,10 +43,7 @@ import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.*;
import net.minecraft.screen.ScreenHandler;
import org.slf4j.Logger;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Mutable;
-import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -73,6 +74,8 @@ public abstract class MixinClientPlayNetworkHandler {
@Shadow @Final private ClientConnection connection;
+ @Shadow private ClientWorld world;
+
@Inject(method = "", at = @At("RETURN"))
public void fixPlayerListOrdering(MinecraftClient client, Screen screen, ClientConnection connection, ServerInfo serverInfo, GameProfile profile, WorldSession worldSession, CallbackInfo ci) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
@@ -160,4 +163,21 @@ public abstract class MixinClientPlayNetworkHandler {
ci.cancel();
}
}
+
+ @Inject(method = "onCustomPayload", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", shift = At.Shift.AFTER), cancellable = true)
+ public void handlePseudoPackets(CustomPayloadS2CPacket packet, CallbackInfo ci) {
+ final var channel = packet.getChannel().toString();
+ final var data = packet.getData();
+
+ if (channel.equals(ClientPlayerInteractionManager1_18_2.ACK_TRANSFORMER_IDENTIFIER)) {
+ final var pos = data.readBlockPos();
+ final var blockState = Block.STATE_IDS.get(BlockStateTranslator.translateBlockState1_18(data.readVarInt()));
+ final var action = data.readEnumConstant(PlayerActionC2SPacket.Action.class);
+ final var allGood = data.readBoolean();
+
+ ClientPlayerInteractionManager1_18_2.handleBlockBreakAck(world, pos, blockState, action, allGood);
+
+ ci.cancel();
+ }
+ }
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java
index 1551786f..f34604f9 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java
@@ -21,6 +21,10 @@ import com.llamalad7.mixinextras.injector.WrapWithCondition;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
+import de.florianmichael.viafabricplus.definition.v1_18_2.ClientPlayerInteractionManager1_18_2;
+import net.minecraft.client.network.SequencedPacketCreator;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.raphimc.vialoader.util.VersionEnum;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ServerboundPackets1_16_2;
@@ -131,7 +135,7 @@ public abstract class MixinClientPlayerInteractionManager {
final byte button = (byte) clickSlot.getButton();
final short lastActionId = ((IScreenHandler) client.player.currentScreenHandler).viafabricplus_getAndIncrementLastActionId();
final int actionType = clickSlot.getActionType().ordinal();
- final Item item = ItemTranslator.minecraftToViaVersion(viaConnection, slotItemBeforeModification, VersionEnum.r1_16.getVersion());
+ final Item item = ItemTranslator.minecraftToViaVersion(slotItemBeforeModification, VersionEnum.r1_16.getVersion());
viaConnection.getChannel().eventLoop().submit(() -> {
final PacketWrapper clickSlotPacket = PacketWrapper.create(ServerboundPackets1_16_2.CLICK_WINDOW, viaConnection);
@@ -194,4 +198,11 @@ public abstract class MixinClientPlayerInteractionManager {
}
return interactBlockInternal(player, hand, hitResult);
}
+
+ @Inject(method = "sendSequencedPacket", at = @At("HEAD"))
+ public void handleBlockAcknowledgements(ClientWorld world, SequencedPacketCreator packetCreator, CallbackInfo ci) {
+ if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_18_2, VersionEnum.r1_14_4) && packetCreator instanceof PlayerActionC2SPacket playerActionC2SPacket) {
+ ClientPlayerInteractionManager1_18_2.trackBlockAction(playerActionC2SPacket.getAction(), playerActionC2SPacket.getPos());
+ }
+ }
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19to1_18_2/MixinWorldPackets.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19to1_18_2/MixinWorldPackets.java
new file mode 100644
index 00000000..86b60330
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19to1_18_2/MixinWorldPackets.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD 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 de.florianmichael.viafabricplus.injection.mixin.fixes.viaversion.protocol1_19to1_18_2;
+
+import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
+import com.viaversion.viaversion.api.type.Type;
+import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.Protocol1_14_4To1_14_3;
+import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
+import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
+import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
+import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.WorldPackets;
+import de.florianmichael.viafabricplus.definition.v1_18_2.ClientPlayerInteractionManager1_18_2;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+@Mixin(value = WorldPackets.class, remap = false)
+public class MixinWorldPackets {
+
+ @Redirect(method = "register", at = @At(value = "INVOKE", target = "Lcom/viaversion/viaversion/protocols/protocol1_19to1_18_2/Protocol1_19To1_18_2;cancelClientbound(Lcom/viaversion/viaversion/api/protocol/packet/ClientboundPacketType;)V"))
+ private static void passAcknowledgePlayerDigging(Protocol1_19To1_18_2 instance, ClientboundPacketType clientboundPacketType) {
+ instance.registerClientbound(ClientboundPackets1_18.ACKNOWLEDGE_PLAYER_DIGGING, ClientboundPackets1_19.PLUGIN_MESSAGE, wrapper -> {
+ if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocol1_14_4To1_14_3.class)) {
+ wrapper.cancel();
+ return;
+ }
+
+ wrapper.resetReader();
+ wrapper.write(Type.STRING, ClientPlayerInteractionManager1_18_2.ACK_TRANSFORMER_IDENTIFIER);
+ });
+ }
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/viaversion/ViaFabricPlusHandItemProvider.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/viaversion/ViaFabricPlusHandItemProvider.java
index 773ebc58..83ce6a51 100644
--- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/viaversion/ViaFabricPlusHandItemProvider.java
+++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/viaversion/ViaFabricPlusHandItemProvider.java
@@ -20,7 +20,6 @@ package de.florianmichael.viafabricplus.protocolhack.provider.viaversion;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import net.raphimc.vialoader.util.VersionEnum;
-import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import de.florianmichael.viafabricplus.protocolhack.usage.ItemTranslator;
import net.minecraft.item.ItemStack;
@@ -33,6 +32,6 @@ public class ViaFabricPlusHandItemProvider extends HandItemProvider {
if (lastUsedItem == null) {
return null;
}
- return ItemTranslator.minecraftToViaVersion(info, lastUsedItem, VersionEnum.r1_8.getVersion());
+ return ItemTranslator.minecraftToViaVersion(lastUsedItem, VersionEnum.r1_8.getVersion());
}
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/BlockStateTranslator.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/BlockStateTranslator.java
new file mode 100644
index 00000000..e4ae3a18
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/BlockStateTranslator.java
@@ -0,0 +1,59 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD 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 de.florianmichael.viafabricplus.protocolhack.usage;
+
+import com.viaversion.viaversion.api.Via;
+import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
+import com.viaversion.viaversion.api.protocol.packet.Direction;
+import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
+import com.viaversion.viaversion.api.protocol.packet.State;
+import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
+import com.viaversion.viaversion.api.type.Type;
+import com.viaversion.viaversion.connection.UserConnectionImpl;
+import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
+import io.netty.buffer.Unpooled;
+import net.minecraft.SharedConstants;
+import net.minecraft.network.PacketByteBuf;
+import net.minecraft.util.math.BlockPos;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class BlockStateTranslator {
+
+ public static int translateBlockState1_18(int oldId) {
+ final List protocolPath = Via.getManager().getProtocolManager().getProtocolPath(SharedConstants.getProtocolVersion(), ProtocolVersion.v1_18_2.getVersion());
+ if (protocolPath == null) return oldId;
+
+ final PacketByteBuf inputData = new PacketByteBuf(Unpooled.buffer());
+ inputData.writeBlockPos(new BlockPos(0, 0, 0));
+ inputData.writeVarInt(oldId);
+
+ try {
+ var wrapper = PacketWrapper.create(ClientboundPackets1_18.BLOCK_CHANGE, inputData.asByteBuf(), new UserConnectionImpl(null, true));
+ wrapper.apply(Direction.CLIENTBOUND, State.PLAY, 0, protocolPath.stream().map(ProtocolPathEntry::protocol).collect(Collectors.toList()), true);
+
+ wrapper.read(Type.POSITION1_14);
+ return wrapper.read(Type.VAR_INT);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return oldId;
+ }
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/ItemTranslator.java b/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/ItemTranslator.java
index d21db634..51696214 100644
--- a/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/ItemTranslator.java
+++ b/src/main/java/de/florianmichael/viafabricplus/protocolhack/usage/ItemTranslator.java
@@ -25,6 +25,7 @@ import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.type.Type;
+import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
import io.netty.buffer.Unpooled;
import net.minecraft.SharedConstants;
@@ -39,7 +40,7 @@ import java.util.stream.Collectors;
public class ItemTranslator {
- public static Item minecraftToViaVersion(final UserConnection user, final ItemStack stack, final int targetVersion) {
+ public static Item minecraftToViaVersion(final ItemStack stack, final int targetVersion) {
final List protocolPath = Via.getManager().getProtocolManager().getProtocolPath(SharedConstants.getProtocolVersion(), targetVersion);
if (protocolPath == null) return null;
@@ -47,17 +48,17 @@ public class ItemTranslator {
final PacketByteBuf emptyBuf = new PacketByteBuf(Unpooled.buffer());
dummyPacket.write(emptyBuf);
- final Integer id = NetworkState.PLAY.getPacketId(NetworkSide.SERVERBOUND, dummyPacket);
- if (id == null) return null;
+ final int id = NetworkState.PLAY.getPacketId(NetworkSide.SERVERBOUND, dummyPacket);
- final PacketWrapper wrapper = new PacketWrapperImpl(id, emptyBuf, user);
try {
+ final PacketWrapper wrapper = new PacketWrapperImpl(id, emptyBuf, new UserConnectionImpl(null, true));
wrapper.apply(Direction.SERVERBOUND, State.PLAY, 0, protocolPath.stream().map(ProtocolPathEntry::protocol).collect(Collectors.toList()));
wrapper.read(Type.SHORT);
return wrapper.read(Type.ITEM);
} catch (Exception e) {
- throw new RuntimeException(e);
+ e.printStackTrace();
}
+ return null;
}
}
diff --git a/src/main/resources/viafabricplus.mixins.json b/src/main/resources/viafabricplus.mixins.json
index 4df47707..23d77d52 100644
--- a/src/main/resources/viafabricplus.mixins.json
+++ b/src/main/resources/viafabricplus.mixins.json
@@ -162,15 +162,14 @@
"fixes.viaversion.protocol1_9to1_8.MixinViaIdleThread",
"jsonwebtoken.MixinClasses",
"jsonwebtoken.MixinDefaultCompressionCodecResolver",
- "jsonwebtoken.MixinDefaultJwtParserBuilder"
- ],
- "injectors": {
- "defaultRequire": 1
- },
- "mixins": [
+ "jsonwebtoken.MixinDefaultJwtParserBuilder",
"fixes.minecraft.block.MixinAbstractSignBlock",
"fixes.minecraft.entity.MixinBoatEntity",
"fixes.minecraft.entity.MixinCamelEntity",
- "fixes.minecraft.item.MixinBrushItem"
- ]
+ "fixes.minecraft.item.MixinBrushItem",
+ "fixes.viaversion.protocol1_19to1_18_2.MixinWorldPackets"
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
}