Implemented old block-ack system (1.18.2 - 1.14.4)

This commit is contained in:
FlorianMichael 2023-06-09 04:07:48 +02:00
parent f1b347d24d
commit bc79e7faf0
No known key found for this signature in database
GPG Key ID: C2FB87E71C425126
8 changed files with 231 additions and 21 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<Pair<BlockPos, PlayerActionC2SPacket.Action>, 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) {
}
}

View File

@ -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 = "<init>", 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();
}
}
}

View File

@ -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());
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
});
}
}

View File

@ -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());
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<ProtocolPathEntry> 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;
}
}

View File

@ -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<ProtocolPathEntry> 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;
}
}

View File

@ -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
}
}