mirror of
https://github.com/ViaVersion/ViaFabricPlus.git
synced 2024-12-23 16:58:30 +01:00
Implemented packet syncing correctly.
This commit is contained in:
parent
b92aa99fd3
commit
8e9f5fa141
@ -19,9 +19,12 @@ package de.florianmichael.viafabricplus.definition;
|
||||
|
||||
import de.florianmichael.viafabricplus.ViaFabricPlus;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.protocolhack.util.BlockStateTranslator;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -29,8 +32,22 @@ import net.minecraft.util.math.Vec2f;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ClientPlayerInteractionManager1_18_2 {
|
||||
public final static Consumer<PacketByteBuf> OLD_PACKET_HANDLER = data -> {
|
||||
try {
|
||||
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(pos, blockState, action, allGood);
|
||||
} catch (Exception e) {
|
||||
ViaFabricPlus.LOGGER.error("Failed to read BlockBreakAck packet data", e);
|
||||
}
|
||||
};
|
||||
|
||||
private final static Object2ObjectLinkedOpenHashMap<Pair<BlockPos, PlayerActionC2SPacket.Action>, PositionAndRotation> UN_ACKED_ACTIONS = new Object2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
public static void trackBlockAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
|
||||
|
@ -31,12 +31,15 @@ import net.minecraft.client.font.FontStorage;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import net.raphimc.vialoader.util.VersionRange;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* This class contains random fields and methods that are used to fix bugs on the client side
|
||||
@ -58,6 +61,16 @@ public class ClientsideFixes {
|
||||
*/
|
||||
private final static Map<Item, Integer> LEGACY_ARMOR_POINTS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Contains all tasks that are waiting for a packet to be received, this system can be used to sync ViaVersion tasks with the correct thread
|
||||
*/
|
||||
private final static Map<String, Consumer<PacketByteBuf>> PENDING_EXECUTION_TASKS = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* This identifier is an internal identifier that is used to identify packets that are sent by ViaFabricPlus
|
||||
*/
|
||||
public final static String PACKET_SYNC_IDENTIFIER = UUID.randomUUID() + ":" + UUID.randomUUID();
|
||||
|
||||
/**
|
||||
* The current chat limit
|
||||
*/
|
||||
@ -123,6 +136,33 @@ public class ClientsideFixes {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a sync task and returns the uuid of the task
|
||||
*
|
||||
* @param task The task to execute
|
||||
* @return The uuid of the task
|
||||
*/
|
||||
public static String executeSyncTask(final Consumer<PacketByteBuf> task) {
|
||||
final var uuid = UUID.randomUUID().toString();
|
||||
PENDING_EXECUTION_TASKS.put(uuid, task);
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public static void handleSyncTask(final PacketByteBuf buf) {
|
||||
buf.resetReaderIndex();
|
||||
|
||||
final var uuid = buf.readString();
|
||||
|
||||
if (PENDING_EXECUTION_TASKS.containsKey(uuid)) {
|
||||
MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread
|
||||
final var task = PENDING_EXECUTION_TASKS.get(uuid);
|
||||
PENDING_EXECUTION_TASKS.remove(uuid);
|
||||
|
||||
task.accept(buf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the armor points of an armor item in legacy versions (<= 1.8.x)
|
||||
*
|
||||
|
@ -17,9 +17,12 @@
|
||||
*/
|
||||
package de.florianmichael.viafabricplus.definition;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import de.florianmichael.viafabricplus.ViaFabricPlus;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreens;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlags;
|
||||
import net.minecraft.resource.featuretoggle.FeatureSet;
|
||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||
@ -27,8 +30,19 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TripleChestHandler1_13_2 {
|
||||
public final static Consumer<PacketByteBuf> TRIPLE_CHEST_HANDLER = data -> {
|
||||
final var byteBuf = data.asByteBuf();
|
||||
|
||||
try {
|
||||
TripleChestHandler1_13_2.handleTripleChestHandler(Type.SHORT.readPrimitive(byteBuf), Type.COMPONENT.read(byteBuf), Type.SHORT.readPrimitive(byteBuf));
|
||||
} catch (Exception e) {
|
||||
ViaFabricPlus.LOGGER.error("Failed to open custom ScreenHandler with dimension 9xN", e);
|
||||
}
|
||||
};
|
||||
|
||||
public static void handleTripleChestHandler(final short windowID, final JsonElement title, final short slots) {
|
||||
int n = slots / 9;
|
||||
final int modulo = slots % 9;
|
||||
|
@ -17,12 +17,15 @@
|
||||
*/
|
||||
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
|
||||
|
||||
import de.florianmichael.viafabricplus.definition.ClientsideFixes;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufPayload;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientCommonNetworkHandler;
|
||||
import net.minecraft.network.listener.ServerPacketListener;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.s2c.common.CommonPingS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@ -37,10 +40,9 @@ import java.time.Duration;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Mixin(ClientCommonNetworkHandler.class)
|
||||
@Mixin(value = ClientCommonNetworkHandler.class, priority = 1 /* Has to be applied before Fabric's Networking API, so it doesn't cancel our custom-payload packets */)
|
||||
public abstract class MixinClientCommonNetworkHandler {
|
||||
|
||||
|
||||
@Shadow @Final protected MinecraftClient client;
|
||||
|
||||
@Shadow protected abstract void send(Packet<? extends ServerPacketListener> packet, BooleanSupplier sendCondition, Duration expiry);
|
||||
@ -73,4 +75,12 @@ public abstract class MixinClientCommonNetworkHandler {
|
||||
|
||||
send(packet, sendCondition, expiry);
|
||||
}
|
||||
|
||||
@Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD"), cancellable = true)
|
||||
public void handleSyncTask(CustomPayloadS2CPacket packet, CallbackInfo ci) {
|
||||
if (packet.payload().id().toString().equals(ClientsideFixes.PACKET_SYNC_IDENTIFIER) && packet.payload() instanceof PacketByteBufPayload payload) {
|
||||
ClientsideFixes.handleSyncTask(payload.data());
|
||||
ci.cancel(); // Cancel the packet, so it doesn't get processed by the client
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,11 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
|
||||
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.packets.InventoryPackets;
|
||||
import de.florianmichael.viafabricplus.definition.ClientsideFixes;
|
||||
import de.florianmichael.viafabricplus.definition.TripleChestHandler1_13_2;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@ -48,7 +48,9 @@ public class MixinInventoryPackets {
|
||||
@Inject(method = "lambda$registerPackets$0", at = @At(value = "INVOKE", target = "Ljava/util/logging/Logger;warning(Ljava/lang/String;)V"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
|
||||
private static void supportCustomSlots(PacketWrapper wrapper, CallbackInfo ci, Short windowId, String type, JsonElement title, Short slots, int typeId) {
|
||||
if (typeId == -1) {
|
||||
wrapper.cancel();
|
||||
wrapper.clearPacket();
|
||||
wrapper.setPacketType(ClientboundPackets1_14.PLUGIN_MESSAGE);
|
||||
wrapper.write(Type.STRING, ClientsideFixes.PACKET_SYNC_IDENTIFIER);
|
||||
|
||||
final List<ProtocolPathEntry> protocolPath = Via.getManager().getProtocolManager().getProtocolPath(SharedConstants.getProtocolVersion(), ProtocolVersion.v1_13_2.getVersion());
|
||||
final var userConnection = ProtocolHack.createFakerUserConnection();
|
||||
@ -63,9 +65,12 @@ public class MixinInventoryPackets {
|
||||
fakeOpenWindow.read(Type.VAR_INT);
|
||||
fakeOpenWindow.read(Type.VAR_INT);
|
||||
|
||||
final var remappedTitle = fakeOpenWindow.read(Type.COMPONENT);
|
||||
final String uuid = ClientsideFixes.executeSyncTask(TripleChestHandler1_13_2.TRIPLE_CHEST_HANDLER);
|
||||
|
||||
MinecraftClient.getInstance().executeSync(() -> TripleChestHandler1_13_2.handleTripleChestHandler(windowId, remappedTitle, slots));
|
||||
wrapper.write(Type.STRING, uuid);
|
||||
wrapper.write(Type.SHORT, windowId);
|
||||
wrapper.write(Type.COMPONENT, fakeOpenWindow.read(Type.COMPONENT));
|
||||
wrapper.write(Type.SHORT, slots);
|
||||
} catch (Exception e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Failed to emulate Triple Chest", e);
|
||||
}
|
||||
|
@ -25,11 +25,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPacke
|
||||
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.ClientPlayerInteractionManager1_18_2;
|
||||
import de.florianmichael.viafabricplus.protocolhack.util.BlockStateTranslator;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import de.florianmichael.viafabricplus.definition.ClientsideFixes;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@ -40,17 +36,16 @@ 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 -> {
|
||||
wrapper.cancel();
|
||||
if (wrapper.user().getProtocolInfo().getPipeline().contains(Protocol1_14_4To1_14_3.class)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
final var pos = wrapper.read(Type.POSITION1_14);
|
||||
final var blockState = Block.STATE_IDS.get(BlockStateTranslator.translateBlockState1_18(wrapper.read(Type.VAR_INT)));
|
||||
final var action = PlayerActionC2SPacket.Action.values()[wrapper.read(Type.VAR_INT)];
|
||||
final var allGood = wrapper.read(Type.BOOLEAN);
|
||||
wrapper.resetReader();
|
||||
final var uuid = ClientsideFixes.executeSyncTask(ClientPlayerInteractionManager1_18_2.OLD_PACKET_HANDLER);
|
||||
|
||||
MinecraftClient.getInstance().executeSync(() -> ClientPlayerInteractionManager1_18_2.handleBlockBreakAck(new BlockPos(pos.x(), pos.y(), pos.z()), blockState, action, allGood));
|
||||
wrapper.write(Type.STRING, ClientsideFixes.PACKET_SYNC_IDENTIFIER);
|
||||
wrapper.write(Type.STRING, uuid);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user