Fixed several issues

This commit is contained in:
RaphiMC 2023-11-26 23:21:27 +01:00
parent cf93a0453a
commit b74aa3d2bf
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
17 changed files with 135 additions and 48 deletions

View File

@ -24,8 +24,8 @@ import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.save.SaveManager;
import de.florianmichael.viafabricplus.settings.SettingsManager;
import net.fabricmc.loader.api.FabricLoader;
import de.florianmichael.viafabricplus.util.ClassLoaderPriorityUtil;
import net.fabricmc.loader.api.FabricLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -52,11 +52,7 @@ import java.util.concurrent.CompletableFuture;
* - Fix MixinAbstractDonkeyEntity
* - Check TO DO in MixinEntity
* - Fix MixinMultiplayerServerListWidget_ServerEntry
* - Test villagers
* - Test offhand
* - Check if attack cooldown is there or not
* - Test very large 1.8 chests
* - Test block ack
* - Fix bedrock online mode
*/
public class ViaFabricPlus {
private static final ViaFabricPlus instance = new ViaFabricPlus();

View File

@ -28,10 +28,12 @@ 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;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d;
import net.raphimc.vialoader.util.VersionEnum;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.function.Consumer;
@ -60,7 +62,7 @@ public class ClientPlayerInteractionManager1_18_2 {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1)) {
rotation = null;
}
UNACKED_ACTIONS.put(new Pair<>(blockPos, action), new PositionAndRotation(player.getPos().x, player.getPos().y, player.getPos().z, rotation));
UNACKED_ACTIONS.put(new ImmutablePair<>(blockPos, action), new PositionAndRotation(player.getPos(), rotation));
}
public static void handleBlockBreakAck(final BlockPos blockPos, final BlockState expectedState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
@ -68,16 +70,17 @@ public class ClientPlayerInteractionManager1_18_2 {
if (player == null) return;
final var world = MinecraftClient.getInstance().getNetworkHandler().getWorld();
final var oldPlayerState = UNACKED_ACTIONS.remove(new Pair<>(blockPos, action));
final var oldPlayerState = UNACKED_ACTIONS.remove(new ImmutablePair<>(blockPos, action));
final var actualState = world.getBlockState(blockPos);
if ((oldPlayerState == null || !allGood || action != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK && actualState != expectedState) && (actualState != expectedState || ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2))) {
world.setBlockState(blockPos, expectedState, Block.NOTIFY_ALL | Block.FORCE_STATE);
if (oldPlayerState != null && ((ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1) || (world == player.getWorld() && player.collidesWithStateAtPos(blockPos, expectedState))))) {
final Vec3d oldPlayerPosition = oldPlayerState.position;
if (oldPlayerState.rotation != null) {
player.updatePositionAndAngles(oldPlayerState.x, oldPlayerState.y, oldPlayerState.z, oldPlayerState.rotation.x, oldPlayerState.rotation.y);
player.updatePositionAndAngles(oldPlayerPosition.x, oldPlayerPosition.y, oldPlayerPosition.z, oldPlayerState.rotation.x, oldPlayerState.rotation.y);
} else {
player.updatePosition(oldPlayerState.x, oldPlayerState.y, oldPlayerState.z);
player.updatePosition(oldPlayerPosition.x, oldPlayerPosition.y, oldPlayerPosition.z);
}
}
}
@ -88,7 +91,11 @@ public class ClientPlayerInteractionManager1_18_2 {
}
}
public record PositionAndRotation(double x, double y, double z, Vec2f rotation) {
public static void clearUnackedActions() {
UNACKED_ACTIONS.clear();
}
private record PositionAndRotation(Vec3d position, Vec2f rotation) {
}
}

View File

@ -20,21 +20,20 @@
package de.florianmichael.viafabricplus.fixes;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.event.DisconnectCallback;
import de.florianmichael.viafabricplus.event.LoadClassicProtocolExtensionCallback;
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
import de.florianmichael.viafabricplus.fixes.classic.CustomClassicProtocolExtensions;
import de.florianmichael.viafabricplus.fixes.classic.screen.ClassicItemSelectionScreen;
import de.florianmichael.viafabricplus.injection.ViaFabricPlusMixinPlugin;
import net.lenni0451.reflect.stream.RStream;
import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.FontStorage;
import net.minecraft.network.PacketByteBuf;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import net.raphimc.vialoader.util.VersionEnum;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@ -67,6 +66,13 @@ public class ClientsideFixes {
BlockFixes.init();
});
DisconnectCallback.EVENT.register(() -> {
// Reset the MP-pass
ViaFabricPlusClassicMPPassProvider.classiCubeMPPass = null;
// Remove all previous unacked player actions
ClientPlayerInteractionManager1_18_2.clearUnackedActions();
});
// Reloads some clientside stuff when the protocol version changes
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> {
// Calculates the current chat length limit
@ -99,12 +105,6 @@ public class ClientsideFixes {
currentChatLength = Short.MAX_VALUE * 2;
}
});
// Force unload some FabricAPI mixins because FabricAPI overwrites some of the elytra code
final Set<String> loadedMixins = RStream.of("org.spongepowered.asm.mixin.transformer.MixinConfig").fields().by("globalMixinList").get();
Collections.addAll(loadedMixins, "net.fabricmc.fabric.mixin.client.entity.event.elytra.ClientPlayerEntityMixin",
"net.fabricmc.fabric.mixin.entity.event.elytra.LivingEntityMixin",
"net.fabricmc.fabric.mixin.entity.event.elytra.PlayerEntityMixin");
}
/**

View File

@ -21,7 +21,6 @@ package de.florianmichael.viafabricplus.fixes.tracker;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
@ -41,11 +40,10 @@ public class WolfHealthTracker extends StoredObject {
this.healthDataMap.put(entityId, wolfHealth);
}
public static WolfHealthTracker get() {
final var connection = ProtocolHack.getPlayNetworkUserConnection();
var tracker = connection.get(WolfHealthTracker.class);
public static WolfHealthTracker get(final UserConnection userConnection) {
var tracker = userConnection.get(WolfHealthTracker.class);
if (tracker == null) {
connection.put(tracker = new WolfHealthTracker(connection));
userConnection.put(tracker = new WolfHealthTracker(userConnection));
}
return tracker;

View File

@ -20,10 +20,12 @@
package de.florianmichael.viafabricplus.injection;
import net.fabricmc.loader.api.FabricLoader;
import net.lenni0451.reflect.stream.RStream;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@ -48,6 +50,14 @@ public class ViaFabricPlusMixinPlugin implements IMixinConfigPlugin {
DASH_LOADER_PRESENT = loader.isModLoaded("dashloader");
ARMOR_SKIN_PRESENT = loader.isModLoaded("armorskin");
IPNEXT_PRESENT = loader.isModLoaded("inventoryprofilesnext");
// Force unload some FabricAPI mixins because FabricAPI overwrites some of the elytra code
final Set<String> loadedMixins = RStream.of("org.spongepowered.asm.mixin.transformer.MixinConfig").fields().by("globalMixinList").get();
Collections.addAll(loadedMixins,
"net.fabricmc.fabric.mixin.client.entity.event.elytra.ClientPlayerEntityMixin",
"net.fabricmc.fabric.mixin.entity.event.elytra.LivingEntityMixin",
"net.fabricmc.fabric.mixin.entity.event.elytra.PlayerEntityMixin"
);
}
@Override
@ -71,7 +81,8 @@ public class ViaFabricPlusMixinPlugin implements IMixinConfigPlugin {
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
@ -79,8 +90,10 @@ public class ViaFabricPlusMixinPlugin implements IMixinConfigPlugin {
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}

View File

@ -99,7 +99,7 @@ public abstract class MixinWolfEntity extends TameableEntity implements Angerabl
@Unique
private float getWolfHealth() {
return WolfHealthTracker.get().getWolfHealth(this.getId(), this.getHealth());
return WolfHealthTracker.get(ProtocolHack.getPlayNetworkUserConnection()).getWolfHealth(this.getId(), this.getHealth());
}
}

View File

@ -45,7 +45,7 @@ import java.time.Duration;
import java.util.function.BooleanSupplier;
@SuppressWarnings("UnstableApiUsage")
@Mixin(value = ClientCommonNetworkHandler.class, priority = 1001 /* Has to be applied before Fabric's Networking API, so it doesn't cancel our custom-payload packets */)
@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

View File

@ -48,7 +48,7 @@ public abstract class MixinInventoryPackets {
wrapper.write(Type.STRING, uuid);
wrapper.write(Type.UNSIGNED_BYTE, windowId);
wrapper.write(Type.UNSIGNED_BYTE, slots);
wrapper.write(Type.COMPONENT, TextComponentTranslator.via1_13_2toViaLatest(title));
wrapper.write(Type.COMPONENT, TextComponentTranslator.via1_14toViaLatest(title));
}
}

View File

@ -43,7 +43,7 @@ public abstract class MixinMetadataRewriter1_15To1_14_4 extends EntityRewriter<C
@Inject(method = "handleMetadata", at = @At(value = "INVOKE", target = "Ljava/util/List;remove(Ljava/lang/Object;)Z", shift = At.Shift.BEFORE), remap = false)
private void trackHealth(int entityId, EntityType type, Metadata metadata, List<Metadata> metadatas, UserConnection connection, CallbackInfo ci) {
WolfHealthTracker.get().setWolfHealth(entityId, metadata.value());
WolfHealthTracker.get(connection).setWolfHealth(entityId, metadata.value());
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC 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;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import de.florianmichael.viafabricplus.util.NoPacketSendChannel;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = UserConnectionImpl.class, remap = false)
public abstract class MixinUserConnectionImpl {
@Shadow
@Final
private Channel channel;
@Inject(method = "sendRawPacket(Lio/netty/buffer/ByteBuf;Z)V", at = @At("HEAD"), cancellable = true)
private void handleNoPacketSendChannel(ByteBuf packet, boolean currentThread, CallbackInfo ci) {
if (this.channel instanceof NoPacketSendChannel) {
ci.cancel();
}
}
}

View File

@ -35,7 +35,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
public abstract class MixinWorldPackets1_19 {
@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) {
private static void handleLegacyAcknowledgePlayerDigging(Protocol1_19To1_18_2 instance, ClientboundPacketType clientboundPacketType) {
instance.registerClientbound(ClientboundPackets1_18.ACKNOWLEDGE_PLAYER_DIGGING, ClientboundPackets1_19.PLUGIN_MESSAGE, wrapper -> {
wrapper.resetReader();

View File

@ -38,6 +38,7 @@ import de.florianmichael.viafabricplus.protocolhack.impl.ViaFabricPlusVLInjector
import de.florianmichael.viafabricplus.protocolhack.impl.ViaFabricPlusVLLoader;
import de.florianmichael.viafabricplus.protocolhack.impl.platform.ViaFabricPlusViaLegacyPlatformImpl;
import de.florianmichael.viafabricplus.protocolhack.netty.ViaFabricPlusVLLegacyPipeline;
import de.florianmichael.viafabricplus.util.NoPacketSendChannel;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
@ -140,7 +141,7 @@ public class ProtocolHack {
* @return Creates a dummy UserConnection class with a valid protocol pipeline to emulate packets
*/
public static UserConnection createDummyUserConnection(final VersionEnum clientVersion, final VersionEnum serverVersion) {
final UserConnection user = new UserConnectionImpl(null, true);
final UserConnection user = new UserConnectionImpl(NoPacketSendChannel.INSTANCE, true);
final ProtocolPipeline pipeline = new ProtocolPipelineImpl(user);
final List<ProtocolPathEntry> path = Via.getManager().getProtocolManager().getProtocolPath(clientVersion.getVersion(), serverVersion.getVersion());
for (ProtocolPathEntry pair : path) {

View File

@ -39,7 +39,7 @@ public class BlockStateTranslator {
public static BlockState via1_18_2toMc(final int blockStateId) {
try {
var wrapper = PacketWrapper.create(ClientboundPackets1_18.EFFECT, null, DUMMY_USER_CONNECTION);
var wrapper = PacketWrapper.create(ClientboundPackets1_18.EFFECT, DUMMY_USER_CONNECTION);
wrapper.write(Type.INT, 2001); // eventId
wrapper.write(Type.POSITION1_14, new Position(0, 0, 0)); // position
wrapper.write(Type.INT, blockStateId); // data

View File

@ -25,18 +25,18 @@ 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.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.raphimc.vialoader.util.VersionEnum;
public class TextComponentTranslator {
private static final UserConnection DUMMY_USER_CONNECTION = ProtocolHack.createDummyUserConnection(ProtocolHack.NATIVE_VERSION, VersionEnum.r1_13_2);
private static final UserConnection DUMMY_USER_CONNECTION = ProtocolHack.createDummyUserConnection(ProtocolHack.NATIVE_VERSION, VersionEnum.r1_14);
public static JsonElement via1_13_2toViaLatest(final JsonElement component) {
public static JsonElement via1_14toViaLatest(final JsonElement component) {
try {
var wrapper = PacketWrapper.create(ClientboundPackets1_13.OPEN_WINDOW, DUMMY_USER_CONNECTION);
var wrapper = PacketWrapper.create(ClientboundPackets1_14.OPEN_WINDOW, DUMMY_USER_CONNECTION);
wrapper.write(Type.VAR_INT, 1); // window id
wrapper.write(Type.VAR_INT, 0); // type id
wrapper.write(Type.COMPONENT, component); // title
@ -48,7 +48,7 @@ public class TextComponentTranslator {
wrapper.read(Type.VAR_INT); // type id
return wrapper.read(Type.COMPONENT); // title
} catch (Throwable t) {
ViaFabricPlus.global().getLogger().error("Error converting ViaVersion 1.13.2 text component to native text component", t);
ViaFabricPlus.global().getLogger().error("Error converting ViaVersion 1.14 text component to native text component", t);
return null;
}
}

View File

@ -22,8 +22,6 @@ package de.florianmichael.viafabricplus.save.impl;
import com.google.gson.JsonObject;
import de.florianmichael.classic4j.model.classicube.account.CCAccount;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.event.DisconnectCallback;
import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
import de.florianmichael.viafabricplus.save.AbstractSave;
import net.raphimc.minecraftauth.MinecraftAuth;
import net.raphimc.minecraftauth.step.bedrock.session.StepFullBedrockSession;
@ -37,11 +35,6 @@ public class AccountsSave extends AbstractSave {
public AccountsSave() {
super("accounts");
DisconnectCallback.EVENT.register(() -> {
// Reset the MP-pass when the user disconnects
ViaFabricPlusClassicMPPassProvider.classiCubeMPPass = null;
});
}
@Override

View File

@ -0,0 +1,31 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC 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.util;
import io.netty.channel.local.LocalChannel;
public class NoPacketSendChannel extends LocalChannel {
public static final NoPacketSendChannel INSTANCE = new NoPacketSendChannel();
private NoPacketSendChannel() {
}
}

View File

@ -185,6 +185,7 @@
"fixes.viaversion.MixinProtocol1_11To1_10",
"fixes.viaversion.MixinProtocol1_12To1_11_1",
"fixes.viaversion.MixinTagType",
"fixes.viaversion.MixinUserConnectionImpl",
"fixes.viaversion.MixinWorldPackets1_13",
"fixes.viaversion.MixinWorldPackets1_16_2",
"fixes.viaversion.MixinWorldPackets1_17",